[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.
This commit is contained in:
Brandon Bergren 2020-09-23 00:13:58 +00:00
parent 4efb1ca7d2
commit c0290b3de8
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=366038

View File

@ -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 ccb *ccb)
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 ccb *ccb)
/* 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, int nsegs, int err)
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, int nsegs, int err)
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, int nsegs, int err)
* 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, int nsegs, int err)
/* 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);