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