Date: Wed, 23 Sep 2020 00:13:59 +0000 (UTC) From: Brandon Bergren <bdragon@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r366038 - head/sys/powerpc/pseries Message-ID: <202009230013.08N0DxWk022386@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: bdragon Date: Wed Sep 23 00:13:58 2020 New Revision: 366038 URL: https://svnweb.freebsd.org/changeset/base/366038 Log: [PowerPC64LE] Fix endianness issues in phyp_vscsi. Unlike virtio, which in legacy mode is guest endian, the hypervisor vscsi interface operates in big endian, so we must convert back and forth in several places. These changes are enough to attach a rootdisk. Sponsored by: Tag1 Consulting, Inc. Modified: head/sys/powerpc/pseries/phyp_vscsi.c Modified: head/sys/powerpc/pseries/phyp_vscsi.c ============================================================================== --- head/sys/powerpc/pseries/phyp_vscsi.c Wed Sep 23 00:09:29 2020 (r366037) +++ head/sys/powerpc/pseries/phyp_vscsi.c Wed Sep 23 00:13:58 2020 (r366038) @@ -506,7 +506,8 @@ vscsi_srp_login(struct vscsi_softc *sc) TAILQ_INSERT_TAIL(&sc->active_xferq, xp, queue); /* Set up command */ - xp->srp_iu_size = crq.iu_length = 64; + xp->srp_iu_size = 64; + crq.iu_length = htobe16(xp->srp_iu_size); err = vmem_alloc(xp->sc->srp_iu_arena, xp->srp_iu_size, M_BESTFIT | M_NOWAIT, &xp->srp_iu_offset); if (err) @@ -524,11 +525,12 @@ vscsi_srp_login(struct vscsi_softc *sc) /* Create CRQ entry */ crq.valid = 0x80; crq.format = 0x01; - crq.iu_data = xp->sc->srp_iu_phys + xp->srp_iu_offset; + crq.iu_data = htobe64(xp->sc->srp_iu_phys + xp->srp_iu_offset); bus_dmamap_sync(sc->crq_tag, sc->crq_map, BUS_DMASYNC_PREWRITE); - err = phyp_hcall(H_SEND_CRQ, xp->sc->unit, ((uint64_t *)(&crq))[0], - ((uint64_t *)(&crq))[1]); + err = phyp_hcall(H_SEND_CRQ, xp->sc->unit, + be64toh(((uint64_t *)(&crq))[0]), + be64toh(((uint64_t *)(&crq))[1])); if (err != 0) panic("CRQ send failure (%d)", err); } @@ -550,7 +552,8 @@ vscsi_task_management(struct vscsi_softc *sc, union cc TAILQ_REMOVE(&sc->free_xferq, xp, queue); TAILQ_INSERT_TAIL(&sc->active_xferq, xp, queue); - xp->srp_iu_size = crq.iu_length = sizeof(*cmd); + xp->srp_iu_size = sizeof(*cmd); + crq.iu_length = htobe16(xp->srp_iu_size); err = vmem_alloc(xp->sc->srp_iu_arena, xp->srp_iu_size, M_BESTFIT | M_NOWAIT, &xp->srp_iu_offset); if (err) @@ -577,10 +580,11 @@ vscsi_task_management(struct vscsi_softc *sc, union cc /* Create CRQ entry */ crq.valid = 0x80; crq.format = 0x01; - crq.iu_data = xp->sc->srp_iu_phys + xp->srp_iu_offset; + crq.iu_data = htobe64(xp->sc->srp_iu_phys + xp->srp_iu_offset); - err = phyp_hcall(H_SEND_CRQ, xp->sc->unit, ((uint64_t *)(&crq))[0], - ((uint64_t *)(&crq))[1]); + err = phyp_hcall(H_SEND_CRQ, xp->sc->unit, + be64toh(((uint64_t *)(&crq))[0]), + be64toh(((uint64_t *)(&crq))[1])); if (err != 0) panic("CRQ send failure (%d)", err); } @@ -605,9 +609,9 @@ vscsi_scsi_command(void *xxp, bus_dma_segment_t *segs, ccb->csio.cdb_io.cdb_ptr : ccb->csio.cdb_io.cdb_bytes; /* Command format from Table 20, page 37 of SRP spec */ - crq.iu_length = 48 + ((nsegs > 1) ? 20 : 16) + + xp->srp_iu_size = 48 + ((nsegs > 1) ? 20 : 16) + ((ccb->csio.cdb_len > 16) ? (ccb->csio.cdb_len - 16) : 0); - xp->srp_iu_size = crq.iu_length; + crq.iu_length = htobe16(xp->srp_iu_size); if (nsegs > 1) xp->srp_iu_size += nsegs*16; xp->srp_iu_size = roundup(xp->srp_iu_size, 16); @@ -644,19 +648,20 @@ vscsi_scsi_command(void *xxp, bus_dma_segment_t *segs, desc_start = ((ccb->csio.cdb_len > 16) ? ccb->csio.cdb_len - 16 : 0); - chunk_addr = xp->sc->srp_iu_phys + xp->srp_iu_offset + 20 + - desc_start + sizeof(*cmd); - chunk_size = 16*nsegs; + chunk_addr = htobe64(xp->sc->srp_iu_phys + xp->srp_iu_offset + 20 + + desc_start + sizeof(*cmd)); + chunk_size = htobe32(16*nsegs); memcpy(&cmd->data_payload[desc_start], &chunk_addr, 8); memcpy(&cmd->data_payload[desc_start+12], &chunk_size, 4); chunk_size = 0; for (i = 0; i < nsegs; i++) chunk_size += segs[i].ds_len; + chunk_size = htobe32(chunk_size); memcpy(&cmd->data_payload[desc_start+16], &chunk_size, 4); desc_start += 20; for (i = 0; i < nsegs; i++) { - chunk_addr = segs[i].ds_addr; - chunk_size = segs[i].ds_len; + chunk_addr = htobe64(segs[i].ds_addr); + chunk_size = htobe32(segs[i].ds_len); memcpy(&cmd->data_payload[desc_start + 16*i], &chunk_addr, 8); @@ -685,8 +690,8 @@ vscsi_scsi_command(void *xxp, bus_dma_segment_t *segs, * 4 byte length */ - chunk_addr = segs[0].ds_addr; - chunk_size = segs[0].ds_len; + chunk_addr = htobe64(segs[0].ds_addr); + chunk_size = htobe32(segs[0].ds_len); desc_start = ((ccb->csio.cdb_len > 16) ? ccb->csio.cdb_len - 16 : 0); @@ -703,10 +708,11 @@ vscsi_scsi_command(void *xxp, bus_dma_segment_t *segs, /* Create CRQ entry */ crq.valid = 0x80; crq.format = 0x01; - crq.iu_data = xp->sc->srp_iu_phys + xp->srp_iu_offset; + crq.iu_data = htobe64(xp->sc->srp_iu_phys + xp->srp_iu_offset); - err = phyp_hcall(H_SEND_CRQ, xp->sc->unit, ((uint64_t *)(&crq))[0], - ((uint64_t *)(&crq))[1]); + err = phyp_hcall(H_SEND_CRQ, xp->sc->unit, + be64toh(((uint64_t *)(&crq))[0]), + be64toh(((uint64_t *)(&crq))[1])); if (err != 0) panic("CRQ send failure (%d)", err); } @@ -768,8 +774,9 @@ vscsi_setup_bus(struct vscsi_softc *sc) sc->n_crqs*sizeof(sc->crq_queue[0])); KASSERT(error == 0, ("CRQ registration success")); - error = phyp_hcall(H_SEND_CRQ, sc->unit, ((uint64_t *)(&crq))[0], - ((uint64_t *)(&crq))[1]); + error = phyp_hcall(H_SEND_CRQ, sc->unit, + be64toh(((uint64_t *)(&crq))[0]), + be64toh(((uint64_t *)(&crq))[1])); if (error != 0) panic("CRQ setup failure (%d)", error); @@ -777,15 +784,15 @@ vscsi_setup_bus(struct vscsi_softc *sc) vscsi_check_response_queue(sc); /* Send MAD adapter info */ - mad_adapter_info.type = MAD_ADAPTER_INFO_REQUEST; + mad_adapter_info.type = htobe32(MAD_ADAPTER_INFO_REQUEST); mad_adapter_info.status = 0; - mad_adapter_info.length = sizeof(mad_adapter_info.payload); + mad_adapter_info.length = htobe16(sizeof(mad_adapter_info.payload)); strcpy(mad_adapter_info.payload.srp_version, "16.a"); strcpy(mad_adapter_info.payload.partition_name, "UNKNOWN"); mad_adapter_info.payload.partition_number = -1; - mad_adapter_info.payload.mad_version = 1; - mad_adapter_info.payload.os_type = 2; /* Claim we are Linux */ + mad_adapter_info.payload.mad_version = htobe32(1); + mad_adapter_info.payload.os_type = htobe32(2); /* Claim we are Linux */ mad_adapter_info.payload.port_max_txu[0] = 0; /* If this fails, we get the defaults above */ OF_getprop(OF_finddevice("/"), "ibm,partition-name", @@ -799,19 +806,21 @@ vscsi_setup_bus(struct vscsi_softc *sc) xp->ccb = NULL; TAILQ_REMOVE(&sc->free_xferq, xp, queue); TAILQ_INSERT_TAIL(&sc->active_xferq, xp, queue); - xp->srp_iu_size = crq.iu_length = sizeof(mad_adapter_info); + xp->srp_iu_size = sizeof(mad_adapter_info); + crq.iu_length = htobe16(xp->srp_iu_size); vmem_alloc(xp->sc->srp_iu_arena, xp->srp_iu_size, M_BESTFIT | M_NOWAIT, &xp->srp_iu_offset); - mad_adapter_info.buffer = xp->sc->srp_iu_phys + xp->srp_iu_offset + 24; + mad_adapter_info.buffer = htobe64(xp->sc->srp_iu_phys + xp->srp_iu_offset + 24); mad_adapter_info.tag = (uint64_t)xp; memcpy((uint8_t *)xp->sc->srp_iu_queue + (uintptr_t)xp->srp_iu_offset, &mad_adapter_info, sizeof(mad_adapter_info)); crq.valid = 0x80; crq.format = 0x02; - crq.iu_data = xp->sc->srp_iu_phys + xp->srp_iu_offset; + crq.iu_data = htobe64(xp->sc->srp_iu_phys + xp->srp_iu_offset); bus_dmamap_sync(sc->crq_tag, sc->crq_map, BUS_DMASYNC_PREWRITE); - phyp_hcall(H_SEND_CRQ, xp->sc->unit, ((uint64_t *)(&crq))[0], - ((uint64_t *)(&crq))[1]); + phyp_hcall(H_SEND_CRQ, xp->sc->unit, + be64toh(((uint64_t *)(&crq))[0]), + be64toh(((uint64_t *)(&crq))[1])); while (TAILQ_EMPTY(&sc->free_xferq)) vscsi_check_response_queue(sc);
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202009230013.08N0DxWk022386>