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,
_______________________________________________
svn-src-head@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to