Make the exploring of all luns supported by an HBA more of a

tunable (until we get REPORT LUNS in place).

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.

Reviewed by:	nate@rootlabs.org, gibbs@scsiguy.com, ken@kdm.com, scottl@samsco.org
MFC after:	1 week
This commit is contained in:
mjacob 2005-09-16 01:26:17 +00:00
parent 2d4ad1cc44
commit 638e44e0fe

View File

@ -45,6 +45,7 @@ __FBSDID("$FreeBSD$");
#include <sys/lock.h>
#include <sys/mutex.h>
#include <sys/sysctl.h>
#ifdef PC98
#include <pc98/pc98/pc98_machdep.h> /* geometry translation */
@ -208,16 +209,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))
|| (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)))
typedef enum {
XPT_FLAG_OPEN = 0x01
@ -5334,7 +5350,7 @@ xpt_scan_bus(struct cam_periph *periph, union ccb *request_ccb)
s = splcam();
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);
}
@ -5351,7 +5367,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++;
}
}
@ -6115,6 +6131,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