svn commit: r366038 - head/sys/powerpc/pseries
Brandon Bergren
bdragon at FreeBSD.org
Wed Sep 23 00:13:59 UTC 2020
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);
More information about the svn-src-all
mailing list