Make the exploring of all luns supported by an HBA more of a tunable.
authorPeter Avalos <pavalos@dragonflybsd.org>
Sat, 1 Dec 2007 22:49:49 +0000 (22:49 +0000)
committerPeter Avalos <pavalos@dragonflybsd.org>
Sat, 1 Dec 2007 22:49:49 +0000 (22:49 +0000)
If we're probing luns, and each probe succeeds, we keep going past
lun 7 if we're a SCSI3 or better device (until we fail to probe).

If we're probing luns, and a probe fails, we only keep going if
we're quirked *for* it (CAM_QUIRK_HILUNS), and if we're not quirked
*against* it (CAM_QUIRK_NOHILUNS), or we're a SCSI3 or better device
and the tunable (kern.cam.cam_srch_hi) is set non-zero.

Obtained-from: FreeBSD

sys/bus/cam/cam_xpt.c

index 1452b02..c47e1f0 100644 (file)
@@ -27,7 +27,7 @@
  * SUCH DAMAGE.
  *
  * $FreeBSD: src/sys/cam/cam_xpt.c,v 1.80.2.18 2002/12/09 17:31:55 gibbs Exp $
- * $DragonFly: src/sys/bus/cam/cam_xpt.c,v 1.54 2007/12/01 22:21:17 pavalos Exp $
+ * $DragonFly: src/sys/bus/cam/cam_xpt.c,v 1.55 2007/12/01 22:49:49 pavalos Exp $
  */
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -206,16 +206,31 @@ struct xpt_quirk_entry {
        u_int mintags;
        u_int maxtags;
 };
+
+static int cam_srch_hi = 0;
+TUNABLE_INT("kern.cam.cam_srch_hi", &cam_srch_hi);
+static int sysctl_cam_search_luns(SYSCTL_HANDLER_ARGS);
+SYSCTL_PROC(_kern_cam, OID_AUTO, cam_srch_hi, CTLTYPE_INT|CTLFLAG_RW, 0, 0,
+    sysctl_cam_search_luns, "I",
+    "allow search above LUN 7 for SCSI3 and greater devices");
+
 #define        CAM_SCSI2_MAXLUN        8
 /*
  * If we're not quirked to search <= the first 8 luns
  * and we are either quirked to search above lun 8,
- * or we're > SCSI-2, we can look for luns above lun 8.
+ * or we're > SCSI-2 and we've enabled hilun searching,
+ * or we're > SCSI-2 and the last lun was a success,
+ * we can look for luns above lun 8.
  */
-#define        CAN_SRCH_HI(dv)                                 \
+#define        CAN_SRCH_HI_SPARSE(dv)                          \
+  (((dv->quirk->quirks & CAM_QUIRK_NOHILUNS) == 0)     \
+  && ((dv->quirk->quirks & CAM_QUIRK_HILUNS)           \
+  || (SID_ANSI_REV(&dv->inq_data) > SCSI_REV_2 && cam_srch_hi)))
+
+#define        CAN_SRCH_HI_DENSE(dv)                           \
   (((dv->quirk->quirks & CAM_QUIRK_NOHILUNS) == 0)     \
   && ((dv->quirk->quirks & CAM_QUIRK_HILUNS)           \
-  || SID_ANSI_REV(&dv->inq_data) > SCSI_REV_2))
+  || (SID_ANSI_REV(&dv->inq_data) > SCSI_REV_2)))
 
 typedef enum {
        XPT_FLAG_OPEN           = 0x01
@@ -5144,7 +5159,7 @@ xpt_scan_bus(struct cam_periph *periph, union ccb *request_ccb)
                        crit_enter();
                        device = TAILQ_FIRST(&target->ed_entries);
                        if (device != NULL) {
-                               phl = CAN_SRCH_HI(device);
+                               phl = CAN_SRCH_HI_SPARSE(device);
                                if (device->lun_id == 0)
                                        device = TAILQ_NEXT(device, links);
                        }
@@ -5161,7 +5176,7 @@ xpt_scan_bus(struct cam_periph *periph, union ccb *request_ccb)
                        if ((device->quirk->quirks & CAM_QUIRK_NOLUNS) == 0) {
                                /* Try the next lun */
                                if (lun_id < (CAM_SCSI2_MAXLUN-1)
-                                 || CAN_SRCH_HI(device))
+                                 || CAN_SRCH_HI_DENSE(device))
                                        lun_id++;
                        }
                }
@@ -5895,6 +5910,23 @@ xpt_find_quirk(struct cam_ed *device)
        device->quirk = (struct xpt_quirk_entry *)match;
 }
 
+static int
+sysctl_cam_search_luns(SYSCTL_HANDLER_ARGS)
+{
+       int error, bool;
+
+       bool = cam_srch_hi;
+       error = sysctl_handle_int(oidp, &bool, sizeof(bool), req);
+       if (error != 0 || req->newptr == NULL)
+               return (error);
+       if (bool == 0 || bool == 1) {
+               cam_srch_hi = bool;
+               return (0);
+       } else {
+               return (EINVAL);
+       }
+}
+
 #ifdef CAM_NEW_TRAN_CODE
 
 static void