svn commit: r259204 - in stable/10: lib/libcam sbin/camcontrol sys/cam sys/cam/scsi sys/powerpc/pseries

Nathan Whitehorn nwhitehorn at FreeBSD.org
Tue Dec 10 22:55:24 UTC 2013


Author: nwhitehorn
Date: Tue Dec 10 22:55:22 2013
New Revision: 259204
URL: http://svnweb.freebsd.org/changeset/base/259204

Log:
  MFC r257345,257382,257388:
  
  Implement extended LUN support. If PIM_EXTLUNS is set by a SIM, encode
  the upper 32-bits of the LUN, if possible, into the target_lun field as
  passed directly from the REPORT LUNs response. This allows extended LUN
  support to work for all LUNs with zeros in the lower 32-bits, which covers
  most addressing modes without breaking KBI. Behavior for drivers not
  setting PIM_EXTLUNS is unchanged. No user-facing interfaces are modified.
  
  Extended LUNs are stored with swizzled 16-bit word order so that, for
  devices implementing LUN addressing (like SCSI-2), the numerical
  representation of the LUN is identical with and without PIM_EXTLUNS. Thus
  setting PIM_EXTLUNS keeps most behavior, and user-facing LUN IDs, unchanged.
  This follows the strategy used in Solaris. A macro (CAM_EXTLUN_BYTE_SWIZZLE)
  is provided to transform a lun_id_t into a uint64_t ordered for the wire.
  
  This is the second part of work for full 64-bit extended LUN support and is
  designed to a bridge for stable/10 to the final 64-bit LUN code. The
  third and final part will involve widening lun_id_t to 64 bits and will
  not be MFCed. This third part will break the KBI but will keep the KPI
  unchanged so that all drivers that will care about this can be updated now
  and not require code changes between HEAD and stable/10.
  
  Reviewed by:	scottl

Modified:
  stable/10/lib/libcam/camlib.c
  stable/10/sbin/camcontrol/camcontrol.c
  stable/10/sys/cam/cam.h
  stable/10/sys/cam/cam_xpt.c
  stable/10/sys/cam/scsi/scsi_xpt.c
  stable/10/sys/powerpc/pseries/phyp_vscsi.c
Directory Properties:
  stable/10/   (props changed)

Modified: stable/10/lib/libcam/camlib.c
==============================================================================
--- stable/10/lib/libcam/camlib.c	Tue Dec 10 22:33:02 2013	(r259203)
+++ stable/10/lib/libcam/camlib.c	Tue Dec 10 22:55:22 2013	(r259204)
@@ -30,6 +30,7 @@ __FBSDID("$FreeBSD$");
 #include <sys/param.h>
 #include <stdio.h>
 #include <stdlib.h>
+#include <stdint.h>
 #include <string.h>
 #include <fcntl.h>
 #include <unistd.h>
@@ -348,16 +349,16 @@ cam_open_btl(path_id_t path_id, target_i
 	if (ccb.cdm.status == CAM_DEV_MATCH_MORE) {
 		snprintf(cam_errbuf, CAM_ERRBUF_SIZE,
 			 "%s: CDM reported more than one"
-			 " passthrough device at %d:%d:%d!!\n",
-			 func_name, path_id, target_id, target_lun);
+			 " passthrough device at %d:%d:%jx!!\n",
+			 func_name, path_id, target_id, (uintmax_t)target_lun);
 		goto btl_bailout;
 	}
 
 	if (ccb.cdm.num_matches == 0) {
 		snprintf(cam_errbuf, CAM_ERRBUF_SIZE,
 			 "%s: no passthrough device found at"
-			 " %d:%d:%d", func_name, path_id, target_id,
-			 target_lun);
+			 " %d:%d:%jx", func_name, path_id, target_id,
+			 (uintmax_t)target_lun);
 		goto btl_bailout;
 	}
 
@@ -687,14 +688,14 @@ cam_path_string(struct cam_device *dev, 
 		return(str);
 	}
 
-	snprintf(str, len, "(%s%d:%s%d:%d:%d:%d): ",
+	snprintf(str, len, "(%s%d:%s%d:%d:%d:%jx): ",
 		 (dev->device_name[0] != '\0') ? dev->device_name : "pass",
 		 dev->dev_unit_num,
 		 (dev->sim_name[0] != '\0') ? dev->sim_name : "unknown",
 		 dev->sim_unit_number,
 		 dev->bus_id,
 		 dev->target_id,
-		 dev->target_lun);
+		 (uintmax_t)dev->target_lun);
 
 	return(str);
 }

Modified: stable/10/sbin/camcontrol/camcontrol.c
==============================================================================
--- stable/10/sbin/camcontrol/camcontrol.c	Tue Dec 10 22:33:02 2013	(r259203)
+++ stable/10/sbin/camcontrol/camcontrol.c	Tue Dec 10 22:55:22 2013	(r259204)
@@ -566,11 +566,11 @@ getdevtree(void)
 				}
 
 				fprintf(stdout, "%-33s  at scbus%d "
-					"target %d lun %d (",
+					"target %d lun %jx (",
 					tmpstr,
 					dev_result->path_id,
 					dev_result->target_id,
-					dev_result->target_lun);
+					(uintmax_t)dev_result->target_lun);
 
 				need_close = 1;
 

Modified: stable/10/sys/cam/cam.h
==============================================================================
--- stable/10/sys/cam/cam.h	Tue Dec 10 22:33:02 2013	(r259203)
+++ stable/10/sys/cam/cam.h	Tue Dec 10 22:55:22 2013	(r259204)
@@ -50,6 +50,12 @@ typedef union {
 #define	CAM_TARGET_WILDCARD ((target_id_t)~0)
 #define	CAM_LUN_WILDCARD ((lun_id_t)~0)
 
+#define CAM_EXTLUN_BYTE_SWIZZLE(lun) (	\
+	((((u_int64_t)lun) & 0xffff000000000000L) >> 48) | \
+	((((u_int64_t)lun) & 0x0000ffff00000000L) >> 16) | \
+	((((u_int64_t)lun) & 0x00000000ffff0000L) << 16) | \
+	((((u_int64_t)lun) & 0x000000000000ffffL) << 48))
+
 /*
  * Maximum length for a CAM CDB.  
  */

Modified: stable/10/sys/cam/cam_xpt.c
==============================================================================
--- stable/10/sys/cam/cam_xpt.c	Tue Dec 10 22:33:02 2013	(r259203)
+++ stable/10/sys/cam/cam_xpt.c	Tue Dec 10 22:55:22 2013	(r259204)
@@ -1025,14 +1025,14 @@ xpt_announce_periph(struct cam_periph *p
 	mtx_assert(periph->sim->mtx, MA_OWNED);
 	periph->flags |= CAM_PERIPH_ANNOUNCED;
 
-	printf("%s%d at %s%d bus %d scbus%d target %d lun %d\n",
+	printf("%s%d at %s%d bus %d scbus%d target %d lun %jx\n",
 	       periph->periph_name, periph->unit_number,
 	       path->bus->sim->sim_name,
 	       path->bus->sim->unit_number,
 	       path->bus->sim->bus_id,
 	       path->bus->path_id,
 	       path->target->target_id,
-	       path->device->lun_id);
+	       (uintmax_t)path->device->lun_id);
 	printf("%s%d: ", periph->periph_name, periph->unit_number);
 	if (path->device->protocol == PROTO_SCSI)
 		scsi_print_inquiry(&path->device->inq_data);
@@ -1078,14 +1078,14 @@ xpt_denounce_periph(struct cam_periph *p
 	struct	cam_path *path = periph->path;
 
 	mtx_assert(periph->sim->mtx, MA_OWNED);
-	printf("%s%d at %s%d bus %d scbus%d target %d lun %d\n",
+	printf("%s%d at %s%d bus %d scbus%d target %d lun %jx\n",
 	       periph->periph_name, periph->unit_number,
 	       path->bus->sim->sim_name,
 	       path->bus->sim->unit_number,
 	       path->bus->sim->bus_id,
 	       path->bus->path_id,
 	       path->target->target_id,
-	       path->device->lun_id);
+	       (uintmax_t)path->device->lun_id);
 	printf("%s%d: ", periph->periph_name, periph->unit_number);
 	if (path->device->protocol == PROTO_SCSI)
 		scsi_print_inquiry_short(&path->device->inq_data);
@@ -3652,7 +3652,7 @@ xpt_print_path(struct cam_path *path)
 			printf("X:");
 
 		if (path->device != NULL)
-			printf("%d): ", path->device->lun_id);
+			printf("%jx): ", (uintmax_t)path->device->lun_id);
 		else
 			printf("X): ");
 	}
@@ -3665,11 +3665,11 @@ xpt_print_device(struct cam_ed *device)
 	if (device == NULL)
 		printf("(nopath): ");
 	else {
-		printf("(noperiph:%s%d:%d:%d:%d): ", device->sim->sim_name,
+		printf("(noperiph:%s%d:%d:%d:%jx): ", device->sim->sim_name,
 		       device->sim->unit_number,
 		       device->sim->bus_id,
 		       device->target->target_id,
-		       device->lun_id);
+		       (uintmax_t)device->lun_id);
 	}
 }
 
@@ -3717,7 +3717,8 @@ xpt_path_string(struct cam_path *path, c
 			sbuf_printf(&sb, "X:");
 
 		if (path->device != NULL)
-			sbuf_printf(&sb, "%d): ", path->device->lun_id);
+			sbuf_printf(&sb, "%jx): ",
+			    (uintmax_t)path->device->lun_id);
 		else
 			sbuf_printf(&sb, "X): ");
 	}

Modified: stable/10/sys/cam/scsi/scsi_xpt.c
==============================================================================
--- stable/10/sys/cam/scsi/scsi_xpt.c	Tue Dec 10 22:33:02 2013	(r259203)
+++ stable/10/sys/cam/scsi/scsi_xpt.c	Tue Dec 10 22:55:22 2013	(r259204)
@@ -100,6 +100,12 @@ SYSCTL_PROC(_kern_cam, OID_AUTO, cam_src
 		(lval) <<= 8;						\
 		(lval) |=  (lp)->luns[(i)].lundata[1];			\
 	}
+#define	CAM_GET_LUN(lp, i, lval)					\
+	(lval) = scsi_4btoul((lp)->luns[(i)].lundata);			\
+	(lval) = ((lval) >> 16) | ((lval) << 16);
+#define CAM_LUN_ONLY_32BITS(lp, i)				\
+	(scsi_4btoul(&((lp)->luns[(i)].lundata[4])) == 0)
+
 /*
  * If we're not quirked to search <= the first 8 luns
  * and we are either quirked to search above lun 8,
@@ -175,7 +181,8 @@ do {									\
 typedef enum {
 	PROBE_INQUIRY_CKSUM	= 0x01,
 	PROBE_SERIAL_CKSUM	= 0x02,
-	PROBE_NO_ANNOUNCE	= 0x04
+	PROBE_NO_ANNOUNCE	= 0x04,
+	PROBE_EXTLUN		= 0x08
 } probe_flags;
 
 typedef struct {
@@ -561,10 +568,9 @@ static void	 proberequestdefaultnegotiat
 static int       proberequestbackoff(struct cam_periph *periph,
 				     struct cam_ed *device);
 static void	 probedone(struct cam_periph *periph, union ccb *done_ccb);
-static int	 probe_strange_rpl_data(struct scsi_report_luns_data *rp,
-					uint32_t maxlun);
 static void	 probe_purge_old(struct cam_path *path,
-				 struct scsi_report_luns_data *new);
+				 struct scsi_report_luns_data *new,
+				 probe_flags flags);
 static void	 probecleanup(struct cam_periph *periph);
 static void	 scsi_find_quirk(struct cam_ed *device);
 static void	 scsi_scan_bus(struct cam_periph *periph, union ccb *ccb);
@@ -699,6 +705,11 @@ probeschedule(struct cam_periph *periph)
 	else
 		softc->flags &= ~PROBE_NO_ANNOUNCE;
 
+	if (cpi.hba_misc & PIM_EXTLUNS)
+		softc->flags |= PROBE_EXTLUN;
+	else
+		softc->flags &= ~PROBE_EXTLUN;
+
 	xpt_schedule(periph, CAM_PRIORITY_XPT);
 }
 
@@ -1277,13 +1288,6 @@ out:
 			 */
 			free(lp, M_CAMXPT);
 			lp = NULL;
-		} else if (probe_strange_rpl_data(lp, maxlun)) {
-			/*
-			 * If we can't understand the lun format
-			 * of any entry, bail.
-			 */
-			free(lp, M_CAMXPT);
-			lp = NULL;
 		} else {
 			lun_id_t lun;
 			int idx;
@@ -1291,14 +1295,14 @@ out:
 			CAM_DEBUG(path, CAM_DEBUG_PROBE,
 			   ("Probe: %u lun(s) reported\n", nlun));
 
-			CAM_GET_SIMPLE_LUN(lp, 0, lun);
+			CAM_GET_LUN(lp, 0, lun);
 			/*
 			 * If the first lun is not lun 0, then either there
 			 * is no lun 0 in the list, or the list is unsorted.
 			 */
 			if (lun != 0) {
 				for (idx = 0; idx < nlun; idx++) {
-					CAM_GET_SIMPLE_LUN(lp, idx, lun);
+					CAM_GET_LUN(lp, idx, lun);
 					if (lun == 0) {
 						break;
 					}
@@ -1330,7 +1334,7 @@ out:
 			 * This function will also install the new list
 			 * in the target structure.
 			 */
-			probe_purge_old(path, lp);
+			probe_purge_old(path, lp, softc->flags);
 			lp = NULL;
 		}
 		if (path->device->flags & CAM_DEV_INQUIRY_DATA_VALID) {
@@ -1702,26 +1706,14 @@ probe_device_check:
 	}
 }
 
-static int
-probe_strange_rpl_data(struct scsi_report_luns_data *rp, uint32_t maxlun)
-{
-	uint32_t idx;
-	uint32_t nlun = MIN(maxlun, (scsi_4btoul(rp->length) / 8));
-
-	for (idx = 0; idx < nlun; idx++) {
-		if (!CAM_CAN_GET_SIMPLE_LUN(rp, idx)) {
-			return (-1);
-		}
-	}
-	return (0);
-}
-
 static void
-probe_purge_old(struct cam_path *path, struct scsi_report_luns_data *new)
+probe_purge_old(struct cam_path *path, struct scsi_report_luns_data *new,
+    probe_flags flags)
 {
 	struct cam_path *tp;
 	struct scsi_report_luns_data *old;
-	u_int idx1, idx2, nlun_old, nlun_new, this_lun;
+	u_int idx1, idx2, nlun_old, nlun_new;
+	lun_id_t this_lun;
 	u_int8_t *ol, *nl;
 
 	if (path->target == NULL) {
@@ -1755,17 +1747,26 @@ probe_purge_old(struct cam_path *path, s
 		 * that would be what the probe state
 		 * machine is currently working on,
 		 * so we won't do that.
-		 *
-		 * We also cannot nuke it if it is
-		 * not in a lun format we understand.
 		 */
-		if (!CAM_CAN_GET_SIMPLE_LUN(old, idx1)) {
-			continue;
-		}
-		CAM_GET_SIMPLE_LUN(old, idx1, this_lun);
+		CAM_GET_LUN(old, idx1, this_lun);
 		if (this_lun == 0) {
 			continue;
 		}
+
+		/*
+		 * We also cannot nuke it if it is
+		 * not in a lun format we understand
+		 * and replace the LUN with a "simple" LUN
+		 * if that is all the HBA supports.
+		 */
+		if (!(flags & PROBE_EXTLUN)) {
+			if (!CAM_CAN_GET_SIMPLE_LUN(old, idx1))
+				continue;
+			CAM_GET_SIMPLE_LUN(old, idx1, this_lun);
+		}
+		if (!CAM_LUN_ONLY_32BITS(old, idx1))
+			continue;
+
 		if (xpt_create_path(&tp, NULL, xpt_path_path_id(path),
 		    xpt_path_target_id(path), this_lun) == CAM_REQ_CMP) {
 			xpt_async(AC_LOST_DEVICE, tp, NULL);
@@ -2001,7 +2002,7 @@ scsi_scan_bus(struct cam_periph *periph,
 		next_target = 1;
 
 		if (target->luns) {
-			uint32_t first;
+			lun_id_t first;
 			u_int nluns = scsi_4btoul(target->luns->length) / 8;
 
 			/*
@@ -2009,19 +2010,44 @@ scsi_scan_bus(struct cam_periph *periph,
 			 * of the list as we've actually just finished probing
 			 * it.
 			 */
-			CAM_GET_SIMPLE_LUN(target->luns, 0, first);
+			CAM_GET_LUN(target->luns, 0, first);
 			if (first == 0 && scan_info->lunindex[target_id] == 0) {
 				scan_info->lunindex[target_id]++;
 			} 
 
+			/*
+			 * Skip any LUNs that the HBA can't deal with.
+			 */
+			while (scan_info->lunindex[target_id] < nluns) {
+				if (scan_info->cpi->hba_misc & PIM_EXTLUNS) {
+					CAM_GET_LUN(target->luns,
+					    scan_info->lunindex[target_id],
+					    lun_id);
+					break;
+				}
+
+				/* XXX print warning? */
+				if (!CAM_LUN_ONLY_32BITS(target->luns,
+				    scan_info->lunindex[target_id]))
+					continue;
+				if (CAM_CAN_GET_SIMPLE_LUN(target->luns,
+				    scan_info->lunindex[target_id])) {
+					CAM_GET_SIMPLE_LUN(target->luns,
+					    scan_info->lunindex[target_id],
+					    lun_id);
+					break;
+				}
+					
+				scan_info->lunindex[target_id]++;
+			}
+
 			if (scan_info->lunindex[target_id] < nluns) {
-				CAM_GET_SIMPLE_LUN(target->luns,
-				    scan_info->lunindex[target_id], lun_id);
 				next_target = 0;
 				CAM_DEBUG(request_ccb->ccb_h.path,
 				    CAM_DEBUG_PROBE,
-				   ("next lun to try at index %u is %u\n",
-				   scan_info->lunindex[target_id], lun_id));
+				   ("next lun to try at index %u is %jx\n",
+				   scan_info->lunindex[target_id],
+				   (uintmax_t)lun_id));
 				scan_info->lunindex[target_id]++;
 			} else {
 				/*

Modified: stable/10/sys/powerpc/pseries/phyp_vscsi.c
==============================================================================
--- stable/10/sys/powerpc/pseries/phyp_vscsi.c	Tue Dec 10 22:33:02 2013	(r259203)
+++ stable/10/sys/powerpc/pseries/phyp_vscsi.c	Tue Dec 10 22:55:22 2013	(r259204)
@@ -548,12 +548,6 @@ vscsi_task_management(struct vscsi_softc
 	TAILQ_REMOVE(&sc->free_xferq, xp, queue);
 	TAILQ_INSERT_TAIL(&sc->active_xferq, xp, queue);
 
-	if (!(ccb->ccb_h.xflags & CAM_EXTLUN_VALID)) {
-		ccb->ccb_h.xflags |= CAM_EXTLUN_VALID;
-		ccb->ccb_h.ext_lun.lun64 = (0x1UL << 62) |
-		    ((uint64_t)ccb->ccb_h.target_lun << 48);
-	}
-
 	xp->srp_iu_size = crq.iu_length = sizeof(*cmd);
 	err = vmem_alloc(xp->sc->srp_iu_arena, xp->srp_iu_size,
 	    M_BESTFIT | M_NOWAIT, &xp->srp_iu_offset);
@@ -565,7 +559,7 @@ vscsi_task_management(struct vscsi_softc
 	bzero(cmd, xp->srp_iu_size);
 	cmd->type = SRP_TSK_MGMT;
 	cmd->tag = (uint64_t)xp;
-	cmd->lun = ccb->ccb_h.ext_lun.lun64;
+	cmd->lun = htobe64(CAM_EXTLUN_BYTE_SWIZZLE(ccb->ccb_h.target_lun));
 
 	switch (ccb->ccb_h.func_code) {
 	case XPT_RESET_DEV:
@@ -608,12 +602,6 @@ vscsi_scsi_command(void *xxp, bus_dma_se
 	cdb = (ccb->ccb_h.flags & CAM_CDB_POINTER) ?
 	    ccb->csio.cdb_io.cdb_ptr : ccb->csio.cdb_io.cdb_bytes;
 
-	if (!(ccb->ccb_h.xflags & CAM_EXTLUN_VALID)) {
-		ccb->ccb_h.xflags |= CAM_EXTLUN_VALID;
-		ccb->ccb_h.ext_lun.lun64 = (0x1UL << 62) |
-		    ((uint64_t)ccb->ccb_h.target_lun << 48);
-	}
-
 	/* Command format from Table 20, page 37 of SRP spec */
 	crq.iu_length = 48 + ((nsegs > 1) ? 20 : 16) + 
 	    ((ccb->csio.cdb_len > 16) ? (ccb->csio.cdb_len - 16) : 0);
@@ -635,7 +623,7 @@ vscsi_scsi_command(void *xxp, bus_dma_se
 	memcpy(cmd->cdb, cdb, ccb->csio.cdb_len);
 
 	cmd->tag = (uint64_t)(xp); /* Let the responder find this again */
-	cmd->lun = ccb->ccb_h.ext_lun.lun64;
+	cmd->lun = htobe64(CAM_EXTLUN_BYTE_SWIZZLE(ccb->ccb_h.target_lun));
 
 	if (nsegs > 1) {
 		/* Use indirect descriptors */


More information about the svn-src-all mailing list