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-all
mailing list