svn commit: r259397 - in head/sys/cam: . scsi

Nathan Whitehorn nwhitehorn at FreeBSD.org
Sat Dec 14 22:07:42 UTC 2013


Author: nwhitehorn
Date: Sat Dec 14 22:07:40 2013
New Revision: 259397
URL: http://svnweb.freebsd.org/changeset/base/259397

Log:
  Widen lun_id_t to 64 bits. This is a follow-on to r257345 to let the kernel
  support all valid SAM-5 LUN IDs. CAM_VERSION is bumped, as the CAM ABI
  (though not API) is changed. No behavior is changed relative to r257345
  except that LUNs with non-zero high 32 bits will no longer be ignored
  during device enumeration for SIMs that have set PIM_EXTLUNS.
  
  Reviewed by:	scottl

Modified:
  head/sys/cam/cam.h
  head/sys/cam/cam_ccb.h
  head/sys/cam/cam_compat.c
  head/sys/cam/cam_compat.h
  head/sys/cam/scsi/scsi_xpt.c

Modified: head/sys/cam/cam.h
==============================================================================
--- head/sys/cam/cam.h	Sat Dec 14 20:55:53 2013	(r259396)
+++ head/sys/cam/cam.h	Sat Dec 14 22:07:40 2013	(r259397)
@@ -39,16 +39,12 @@
 
 typedef u_int path_id_t;
 typedef u_int target_id_t;
-typedef u_int lun_id_t;
-typedef union {
-	u_int64_t	lun64;
-	u_int8_t	lun[8];
-} lun64_id_t;
+typedef u_int64_t lun_id_t;
 
 #define	CAM_XPT_PATH_ID	((path_id_t)~0)
 #define	CAM_BUS_WILDCARD ((path_id_t)~0)
 #define	CAM_TARGET_WILDCARD ((target_id_t)~0)
-#define	CAM_LUN_WILDCARD ((lun_id_t)~0)
+#define	CAM_LUN_WILDCARD (~(u_int)0)
 
 #define CAM_EXTLUN_BYTE_SWIZZLE(lun) (	\
 	((((u_int64_t)lun) & 0xffff000000000000L) >> 48) | \

Modified: head/sys/cam/cam_ccb.h
==============================================================================
--- head/sys/cam/cam_ccb.h	Sat Dec 14 20:55:53 2013	(r259396)
+++ head/sys/cam/cam_ccb.h	Sat Dec 14 22:07:40 2013	(r259397)
@@ -109,10 +109,6 @@ typedef enum {
 	CAM_UNLOCKED		= 0x80000000 /* Call callback without lock.   */
 } ccb_flags;
 
-typedef enum {
-	CAM_EXTLUN_VALID	= 0x00000001,/* 64bit lun field is valid      */
-} ccb_xflags;
-
 /* XPT Opcodes for xpt_action */
 typedef enum {
 /* Function code flags are bits greater than 0xff */
@@ -326,7 +322,6 @@ struct ccb_hdr {
 	path_id_t	path_id;	/* Path ID for the request */
 	target_id_t	target_id;	/* Target device ID */
 	lun_id_t	target_lun;	/* Target LUN number */
-	lun64_id_t	ext_lun;	/* 64bit extended/multi-level LUNs */
 	u_int32_t	flags;		/* ccb_flags */
 	u_int32_t	xflags;		/* Extended flags */
 	ccb_ppriv_area	periph_priv;
@@ -555,7 +550,7 @@ struct ccb_dev_match {
 /*
  * Definitions for the path inquiry CCB fields.
  */
-#define CAM_VERSION	0x18	/* Hex value for current version */
+#define CAM_VERSION	0x19	/* Hex value for current version */
 
 typedef enum {
 	PI_MDP_ABLE	= 0x80,	/* Supports MDP message */

Modified: head/sys/cam/cam_compat.c
==============================================================================
--- head/sys/cam/cam_compat.c	Sat Dec 14 20:55:53 2013	(r259396)
+++ head/sys/cam/cam_compat.c	Sat Dec 14 22:07:40 2013	(r259397)
@@ -46,6 +46,7 @@ __FBSDID("$FreeBSD$");
 #include <cam/cam_ccb.h>
 #include <cam/cam_xpt.h>
 #include <cam/cam_compat.h>
+#include <cam/cam_periph.h>
 
 #include <cam/scsi/scsi_pass.h>
 
@@ -53,6 +54,9 @@ __FBSDID("$FreeBSD$");
 
 static int cam_compat_handle_0x17(struct cdev *dev, u_long cmd, caddr_t addr,
     int flag, struct thread *td, d_ioctl_t *cbfnp);
+static int cam_compat_handle_0x18(struct cdev *dev, u_long cmd, caddr_t addr,
+    int flag, struct thread *td, d_ioctl_t *cbfnp);
+static int cam_compat_translate_dev_match_0x18(union ccb *ccb);
 
 int
 cam_compat_ioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flag,
@@ -63,28 +67,28 @@ cam_compat_ioctl(struct cdev *dev, u_lon
 	switch (cmd) {
 	case CAMIOCOMMAND_0x16:
 	{
-		union ccb *ccb;
+		struct ccb_hdr_0x17 *hdr17;
 
-		ccb = (union ccb *)addr;
-		if (ccb->ccb_h.flags & CAM_SG_LIST_PHYS_0x16) {
-			ccb->ccb_h.flags &= ~CAM_SG_LIST_PHYS_0x16;
-			ccb->ccb_h.flags |= CAM_DATA_SG_PADDR;
+		hdr17 = (struct ccb_hdr_0x17 *)addr;
+		if (hdr17->flags & CAM_SG_LIST_PHYS_0x16) {
+			hdr17->flags &= ~CAM_SG_LIST_PHYS_0x16;
+			hdr17->flags |= CAM_DATA_SG_PADDR;
 		}
-		if (ccb->ccb_h.flags & CAM_DATA_PHYS_0x16) {
-			ccb->ccb_h.flags &= ~CAM_DATA_PHYS_0x16;
-			ccb->ccb_h.flags |= CAM_DATA_PADDR;
+		if (hdr17->flags & CAM_DATA_PHYS_0x16) {
+			hdr17->flags &= ~CAM_DATA_PHYS_0x16;
+			hdr17->flags |= CAM_DATA_PADDR;
 		}
-		if (ccb->ccb_h.flags & CAM_SCATTER_VALID_0x16) {
-			ccb->ccb_h.flags &= CAM_SCATTER_VALID_0x16;
-			ccb->ccb_h.flags |= CAM_DATA_SG;
+		if (hdr17->flags & CAM_SCATTER_VALID_0x16) {
+			hdr17->flags &= CAM_SCATTER_VALID_0x16;
+			hdr17->flags |= CAM_DATA_SG;
 		}
 		cmd = CAMIOCOMMAND;
-		error = (cbfnp)(dev, cmd, addr, flag, td);
+		error = cam_compat_handle_0x17(dev, cmd, addr, flag, td, cbfnp);
 		break;
 	}
 	case CAMGETPASSTHRU_0x16:
 		cmd = CAMGETPASSTHRU;
-		error = (cbfnp)(dev, cmd, addr, flag, td);
+		error = cam_compat_handle_0x17(dev, cmd, addr, flag, td, cbfnp);
 		break;
 	case CAMIOCOMMAND_0x17:
 		cmd = CAMIOCOMMAND;
@@ -94,6 +98,14 @@ cam_compat_ioctl(struct cdev *dev, u_lon
 		cmd = CAMGETPASSTHRU;
 		error = cam_compat_handle_0x17(dev, cmd, addr, flag, td, cbfnp);
 		break;
+	case CAMIOCOMMAND_0x18:
+		cmd = CAMIOCOMMAND;
+		error = cam_compat_handle_0x18(dev, cmd, addr, flag, td, cbfnp);
+		break;
+	case CAMGETPASSTHRU_0x18:
+		cmd = CAMGETPASSTHRU;
+		error = cam_compat_handle_0x18(dev, cmd, addr, flag, td, cbfnp);
+		break;
 	default:
 		error = ENOTTY;
 	}
@@ -127,7 +139,6 @@ cam_compat_handle_0x17(struct cdev *dev,
 	hdr->path_id = hdr17->path_id;
 	hdr->target_id = hdr17->target_id;
 	hdr->target_lun = hdr17->target_lun;
-	hdr->ext_lun.lun64 = 0;
 	hdr->flags = hdr17->flags;
 	hdr->xflags = 0;
 	hdr->periph_priv = hdr17->periph_priv;
@@ -159,13 +170,11 @@ cam_compat_handle_0x17(struct cdev *dev,
 	hdr17->sim_priv = hdr->sim_priv;
 	hdr17->timeout = hdr->timeout;
 
-	/* The PATH_INQ only needs special handling on the way out */
-	if (ccb->ccb_h.func_code != XPT_PATH_INQ) {
-		bcopy(ccbb, ccbb17, CAM_0X17_DATA_LEN);
-	} else {
+	if (ccb->ccb_h.func_code == XPT_PATH_INQ) {
 		struct ccb_pathinq	*cpi;
 		struct ccb_pathinq_0x17 *cpi17;
 
+		/* The PATH_INQ only needs special handling on the way out */
 		cpi = &ccb->cpi;
 		cpi17 = (struct ccb_pathinq_0x17 *)hdr17;
 		cpi17->version_num = cpi->version_num;
@@ -196,9 +205,151 @@ cam_compat_handle_0x17(struct cdev *dev,
 		cpi17->hba_device = cpi->hba_device;
 		cpi17->hba_subvendor = cpi->hba_subvendor;
 		cpi17->hba_subdevice = cpi->hba_subdevice;
+	} else if (ccb->ccb_h.func_code == XPT_DEV_MATCH) {
+		/* Copy the rest of the header over */
+		bcopy(ccbb, ccbb17, CAM_0X17_DATA_LEN);
+
+		cam_compat_translate_dev_match_0x18(ccb);
+	} else {
+		bcopy(ccbb, ccbb17, CAM_0X17_DATA_LEN);
 	}
 
 	xpt_free_ccb(ccb);
 
 	return (error);
 }
+
+static int
+cam_compat_handle_0x18(struct cdev *dev, u_long cmd, caddr_t addr, int flag,
+    struct thread *td, d_ioctl_t *cbfnp)
+{
+	union ccb		*ccb;
+	struct ccb_hdr		*hdr;
+	struct ccb_hdr_0x18	*hdr18;
+	uint8_t			*ccbb, *ccbb18;
+	u_int			error;
+
+	hdr18 = (struct ccb_hdr_0x18 *)addr;
+	ccb = xpt_alloc_ccb();
+	hdr = &ccb->ccb_h;
+
+	hdr->pinfo = hdr18->pinfo;
+	hdr->xpt_links = hdr18->xpt_links;
+	hdr->sim_links = hdr18->sim_links;
+	hdr->periph_links = hdr18->periph_links;
+	hdr->retry_count = hdr18->retry_count;
+	hdr->cbfcnp = hdr18->cbfcnp;
+	hdr->func_code = hdr18->func_code;
+	hdr->status = hdr18->status;
+	hdr->path = hdr18->path;
+	hdr->path_id = hdr18->path_id;
+	hdr->target_id = hdr18->target_id;
+	hdr->target_lun = hdr18->target_lun;
+	if (hdr18->xflags & CAM_EXTLUN_VALID_0x18)
+		hdr->target_lun = hdr18->ext_lun;
+	hdr->flags = hdr18->flags;
+	hdr->xflags = hdr18->xflags;
+	hdr->periph_priv = hdr18->periph_priv;
+	hdr->sim_priv = hdr18->sim_priv;
+	hdr->timeout = hdr18->timeout;
+	hdr->softtimeout.tv_sec = 0;
+	hdr->softtimeout.tv_usec = 0;
+
+	ccbb = (uint8_t *)&hdr[1];
+	ccbb18 = (uint8_t *)&hdr18[1];
+	bcopy(ccbb18, ccbb, CAM_0X18_DATA_LEN);
+
+	error = (cbfnp)(dev, cmd, (caddr_t)ccb, flag, td);
+
+	hdr18->pinfo = hdr->pinfo;
+	hdr18->xpt_links = hdr->xpt_links;
+	hdr18->sim_links = hdr->sim_links;
+	hdr18->periph_links = hdr->periph_links;
+	hdr18->retry_count = hdr->retry_count;
+	hdr18->cbfcnp = hdr->cbfcnp;
+	hdr18->func_code = hdr->func_code;
+	hdr18->status = hdr->status;
+	hdr18->path = hdr->path;
+	hdr18->path_id = hdr->path_id;
+	hdr18->target_id = hdr->target_id;
+	hdr18->target_lun = hdr->target_lun;
+	hdr18->ext_lun = hdr->target_lun;
+	hdr18->flags = hdr->flags;
+	hdr18->xflags = hdr->xflags | CAM_EXTLUN_VALID_0x18;
+	hdr18->periph_priv = hdr->periph_priv;
+	hdr18->sim_priv = hdr->sim_priv;
+	hdr18->timeout = hdr->timeout;
+
+	bcopy(ccbb, ccbb18, CAM_0X18_DATA_LEN);
+
+	if (ccb->ccb_h.func_code == XPT_DEV_MATCH)
+		cam_compat_translate_dev_match_0x18(ccb);
+
+	xpt_free_ccb(ccb);
+
+	return (error);
+}
+
+static int
+cam_compat_translate_dev_match_0x18(union ccb *ccb)
+{
+	struct dev_match_result		*dm;
+	struct dev_match_result_0x18	*dm18;
+	struct cam_periph_map_info	mapinfo;
+	int i;
+
+	/* Remap the CCB into kernel address space */
+	bzero(&mapinfo, sizeof(mapinfo));
+	cam_periph_mapmem(ccb, &mapinfo);
+
+	dm = ccb->cdm.matches;
+	/* Translate in-place: old fields are smaller */
+	dm18 = (struct dev_match_result_0x18 *)(dm);
+	
+	for (i = 0; i < ccb->cdm.num_matches; i++) {
+		dm18[i].type = dm[i].type;
+		switch (dm[i].type) {
+		case DEV_MATCH_PERIPH:
+			memcpy(&dm18[i].result.periph_result.periph_name, 
+			    &dm[i].result.periph_result.periph_name,
+			    DEV_IDLEN);
+			dm18[i].result.periph_result.unit_number =
+			   dm[i].result.periph_result.unit_number;
+			dm18[i].result.periph_result.path_id =
+			   dm[i].result.periph_result.path_id;
+			dm18[i].result.periph_result.target_id =
+			   dm[i].result.periph_result.target_id;
+			dm18[i].result.periph_result.target_lun =
+			   dm[i].result.periph_result.target_lun;
+			break;
+		case DEV_MATCH_DEVICE:
+			dm18[i].result.device_result.path_id =
+			   dm[i].result.device_result.path_id;
+			dm18[i].result.device_result.target_id =
+			   dm[i].result.device_result.target_id;
+			dm18[i].result.device_result.target_lun =
+			   dm[i].result.device_result.target_lun;
+			dm18[i].result.device_result.protocol =
+			   dm[i].result.device_result.protocol;
+			memcpy(&dm18[i].result.device_result.inq_data, 
+			    &dm[i].result.device_result.inq_data,
+			    sizeof(struct scsi_inquiry_data));
+			memcpy(&dm18[i].result.device_result.ident_data,
+			    &dm[i].result.device_result.ident_data,
+			    sizeof(struct ata_params));
+			dm18[i].result.device_result.flags =
+			   dm[i].result.device_result.flags;
+			break;
+		case DEV_MATCH_BUS:
+			memcpy(&dm18[i].result.bus_result, 
+			    &dm[i].result.bus_result,
+			    sizeof(struct bus_match_result));
+			break;
+		}
+	}
+
+	cam_periph_unmapmem(ccb, &mapinfo);
+
+	return (0);
+}
+

Modified: head/sys/cam/cam_compat.h
==============================================================================
--- head/sys/cam/cam_compat.h	Sat Dec 14 20:55:53 2013	(r259396)
+++ head/sys/cam/cam_compat.h	Sat Dec 14 22:07:40 2013	(r259397)
@@ -65,7 +65,7 @@ struct ccb_hdr_0x17 {
 	struct		cam_path *path;	/* Compiled path for this ccb */
 	path_id_t	path_id;	/* Path ID for the request */
 	target_id_t	target_id;	/* Target device ID */
-	lun_id_t	target_lun;	/* Target LUN number */
+	u_int		target_lun;	/* Target LUN number */
 	u_int32_t	flags;		/* ccb_flags */
 	ccb_ppriv_area	periph_priv;
 	ccb_spriv_area	sim_priv;
@@ -116,5 +116,64 @@ struct ccb_pathinq_0x17 {
 #define	CAMIOCOMMAND_0x17	_IOC(IOC_INOUT, CAM_VERSION_0x17, 2, CAM_0X17_LEN)
 #define CAMGETPASSTHRU_0x17	_IOC(IOC_INOUT, CAM_VERSION_0x17, 3, CAM_0X17_LEN)
 
+/* Version 0x18 compatibility */
+#define CAM_VERSION_0x18	0x18
+
+struct ccb_hdr_0x18 {
+	cam_pinfo	pinfo;		/* Info for priority scheduling */
+	camq_entry	xpt_links;	/* For chaining in the XPT layer */	
+	camq_entry	sim_links;	/* For chaining in the SIM layer */	
+	camq_entry	periph_links;	/* For chaining in the type driver */
+	u_int32_t	retry_count;
+	void		(*cbfcnp)(struct cam_periph *, union ccb *);
+	xpt_opcode	func_code;	/* XPT function code */
+	u_int32_t	status;		/* Status returned by CAM subsystem */
+	struct		cam_path *path;	/* Compiled path for this ccb */
+	path_id_t	path_id;	/* Path ID for the request */
+	target_id_t	target_id;	/* Target device ID */
+	u_int		target_lun;	/* Target LUN number */
+	u_int64_t	ext_lun;	/* 64-bit LUN, more or less */
+	u_int32_t	flags;		/* ccb_flags */
+	u_int32_t	xflags;		/* extended ccb_flags */
+	ccb_ppriv_area	periph_priv;
+	ccb_spriv_area	sim_priv;
+	ccb_qos_area	qos;
+	u_int32_t	timeout;	/* Hard timeout value in seconds */
+	struct timeval	softtimeout;	/* Soft timeout value in sec + usec */
+};
+
+typedef enum {
+	CAM_EXTLUN_VALID_0x18	= 0x00000001,/* 64bit lun field is valid      */
+} ccb_xflags_0x18;
+
+struct dev_match_result_0x18 {
+        dev_match_type          type;
+        union {
+		struct {
+			char periph_name[DEV_IDLEN];
+			u_int32_t unit_number;
+			path_id_t path_id;
+			target_id_t target_id;
+			u_int target_lun;
+		} periph_result;
+		struct {
+			path_id_t	path_id;
+			target_id_t	target_id;
+			u_int		target_lun;
+			cam_proto	protocol;
+			struct scsi_inquiry_data inq_data;
+			struct ata_params ident_data;
+			dev_result_flags flags;
+		} device_result;
+		struct bus_match_result	bus_result;
+	} result;
+};
+
+#define CAM_0X18_LEN	(sizeof(union ccb) - sizeof(struct ccb_hdr) + sizeof(struct ccb_hdr_0x18))
+#define CAM_0X18_DATA_LEN (sizeof(union ccb) - sizeof(struct ccb_hdr_0x18))
+
+#define	CAMIOCOMMAND_0x18	_IOC(IOC_INOUT, CAM_VERSION_0x18, 2, CAM_0X18_LEN)
+#define CAMGETPASSTHRU_0x18	_IOC(IOC_INOUT, CAM_VERSION_0x18, 3, CAM_0X18_LEN)
+
 #endif
 #endif

Modified: head/sys/cam/scsi/scsi_xpt.c
==============================================================================
--- head/sys/cam/scsi/scsi_xpt.c	Sat Dec 14 20:55:53 2013	(r259396)
+++ head/sys/cam/scsi/scsi_xpt.c	Sat Dec 14 22:07:40 2013	(r259397)
@@ -101,10 +101,8 @@ SYSCTL_PROC(_kern_cam, OID_AUTO, cam_src
 		(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)
+	(lval) = scsi_8btou64((lp)->luns[(i)].lundata);			\
+	(lval) = CAM_EXTLUN_BYTE_SWIZZLE(lval);
 
 /*
  * If we're not quirked to search <= the first 8 luns
@@ -1766,8 +1764,6 @@ probe_purge_old(struct cam_path *path, s
 				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) {
@@ -2038,10 +2034,6 @@ scsi_scan_bus(struct cam_periph *periph,
 					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,


More information about the svn-src-head mailing list