Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F159925712
D53920.id167337.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
12 KB
Referenced Files
None
Subscribers
None
D53920.id167337.diff
View Options
diff --git a/sys/cam/cam_ccb.h b/sys/cam/cam_ccb.h
--- a/sys/cam/cam_ccb.h
+++ b/sys/cam/cam_ccb.h
@@ -614,6 +614,7 @@
} pi_tmflag;
typedef enum {
+ PIM_WLUNS = 0x400,/* Well known LUNs supported */
PIM_ATA_EXT = 0x200,/* ATA requests can understand ata_ext requests */
PIM_EXTLUNS = 0x100,/* 64bit extended LUNs supported */
PIM_SCANHILO = 0x80, /* Bus scans from high ID to low ID */
diff --git a/sys/cam/cam_xpt.c b/sys/cam/cam_xpt.c
--- a/sys/cam/cam_xpt.c
+++ b/sys/cam/cam_xpt.c
@@ -4682,6 +4682,7 @@
target->refcount = 1;
target->generation = 0;
target->luns = NULL;
+ target->wluns = NULL;
mtx_init(&target->luns_mtx, "CAM LUNs lock", NULL, MTX_DEF);
timevalclear(&target->last_reset);
/*
diff --git a/sys/cam/cam_xpt_internal.h b/sys/cam/cam_xpt_internal.h
--- a/sys/cam/cam_xpt_internal.h
+++ b/sys/cam/cam_xpt_internal.h
@@ -169,6 +169,7 @@
struct timeval last_reset;
u_int rpl_size;
struct scsi_report_luns_data *luns;
+ struct scsi_report_luns_data *wluns;
struct mtx luns_mtx; /* Protection for luns field. */
};
diff --git a/sys/cam/scsi/scsi_all.h b/sys/cam/scsi/scsi_all.h
--- a/sys/cam/scsi/scsi_all.h
+++ b/sys/cam/scsi/scsi_all.h
@@ -3057,7 +3057,7 @@
uint8_t length[4]; /* length of LUN inventory, in bytes */
uint8_t reserved[4]; /* unused */
/*
- * LUN inventory- we only support the type zero form for now.
+ * LUN inventory- we only support type zero and extended (well-known) formats.
*/
struct scsi_report_luns_lundata luns[0];
};
diff --git a/sys/cam/scsi/scsi_xpt.c b/sys/cam/scsi/scsi_xpt.c
--- a/sys/cam/scsi/scsi_xpt.c
+++ b/sys/cam/scsi/scsi_xpt.c
@@ -130,6 +130,7 @@
PROBE_TUR,
PROBE_INQUIRY, /* this counts as DV0 for Basic Domain Validation */
PROBE_FULL_INQUIRY,
+ PROBE_REPORT_WLUNS,
PROBE_REPORT_LUNS,
PROBE_MODE_SENSE,
PROBE_SUPPORTED_VPD_LIST,
@@ -148,6 +149,7 @@
"PROBE_TUR",
"PROBE_INQUIRY",
"PROBE_FULL_INQUIRY",
+ "PROBE_REPORT_WLUNS",
"PROBE_REPORT_LUNS",
"PROBE_MODE_SENSE",
"PROBE_SUPPORTED_VPD_LIST",
@@ -567,7 +569,7 @@
static void probedone(struct cam_periph *periph, union ccb *done_ccb);
static void probe_purge_old(struct cam_path *path,
struct scsi_report_luns_data *new,
- probe_flags flags);
+ probe_flags flags, bool is_wlun);
static void probecleanup(struct cam_periph *periph);
static void scsi_find_quirk(struct cam_ed *device);
static void scsi_scan_bus(struct cam_periph *periph, union ccb *ccb);
@@ -817,6 +819,23 @@
/*timeout*/60 * 1000);
break;
}
+ case PROBE_REPORT_WLUNS:
+ {
+ void *rp;
+
+ rp = malloc(periph->path->target->rpl_size,
+ M_CAMXPT, M_NOWAIT | M_ZERO);
+ if (rp == NULL) {
+ xpt_print(periph->path,
+ "Unable to alloc report wluns storage\n");
+ PROBE_SET_ACTION(softc, PROBE_REPORT_LUNS);
+ goto again;
+ }
+ scsi_report_luns(csio, 5, probedone, MSG_SIMPLE_Q_TAG,
+ RPL_REPORT_WELLKNOWN, rp, periph->path->target->rpl_size,
+ SSD_FULL_SIZE, 60000);
+ break;
+ }
case PROBE_REPORT_LUNS:
{
void *rp;
@@ -1162,6 +1181,7 @@
struct cam_path *path;
struct scsi_inquiry_data *inq_buf;
uint32_t priority;
+ struct ccb_pathinq cpi;
CAM_DEBUG(done_ccb->ccb_h.path, CAM_DEBUG_TRACE, ("probedone\n"));
@@ -1169,6 +1189,7 @@
path = done_ccb->ccb_h.path;
priority = done_ccb->ccb_h.pinfo.priority;
cam_periph_assert(periph, MA_OWNED);
+ xpt_path_inq(&cpi, path);
switch (softc->action) {
case PROBE_TUR:
@@ -1235,8 +1256,10 @@
SID_ANSI_REV(inq_buf) > SCSI_REV_SPC2 &&
(SCSI_QUIRK(path->device)->quirks &
CAM_QUIRK_NORPTLUNS) == 0) {
- PROBE_SET_ACTION(softc,
- PROBE_REPORT_LUNS);
+ if (cpi.hba_misc & PIM_WLUNS)
+ PROBE_SET_ACTION(softc, PROBE_REPORT_WLUNS);
+ else
+ PROBE_SET_ACTION(softc, PROBE_REPORT_LUNS);
/*
* Start with room for *one* lun.
*/
@@ -1259,7 +1282,10 @@
SID_ANSI_REV(inq_buf) >= SCSI_REV_SPC2 &&
(SCSI_QUIRK(path->device)->quirks &
CAM_QUIRK_NORPTLUNS) == 0) {
- PROBE_SET_ACTION(softc, PROBE_REPORT_LUNS);
+ if (cpi.hba_misc & PIM_WLUNS)
+ PROBE_SET_ACTION(softc, PROBE_REPORT_WLUNS);
+ else
+ PROBE_SET_ACTION(softc, PROBE_REPORT_LUNS);
periph->path->target->rpl_size = 16;
xpt_release_ccb(done_ccb);
xpt_schedule(periph, priority);
@@ -1296,11 +1322,13 @@
xpt_release_ccb(done_ccb);
break;
}
+ case PROBE_REPORT_WLUNS:
case PROBE_REPORT_LUNS:
{
struct ccb_scsiio *csio;
struct scsi_report_luns_data *lp;
u_int nlun, maxlun;
+ bool is_wlun = softc->action == PROBE_REPORT_WLUNS;
csio = &done_ccb->csio;
@@ -1377,7 +1405,7 @@
* This function will also install the new list
* in the target structure.
*/
- probe_purge_old(path, lp, softc->flags);
+ probe_purge_old(path, lp, softc->flags, is_wlun);
lp = NULL;
}
/* The processing above should either exit via a `goto
@@ -1390,7 +1418,9 @@
if (path->device->flags & CAM_DEV_INQUIRY_DATA_VALID &&
(SID_QUAL(inq_buf) == SID_QUAL_LU_CONNECTED ||
SID_QUAL(inq_buf) == SID_QUAL_LU_OFFLINE)) {
- if (INQ_DATA_TQ_ENABLED(inq_buf))
+ if (is_wlun)
+ PROBE_SET_ACTION(softc, PROBE_REPORT_LUNS);
+ else if (INQ_DATA_TQ_ENABLED(inq_buf))
PROBE_SET_ACTION(softc, PROBE_MODE_SENSE);
else
PROBE_SET_ACTION(softc,
@@ -1815,20 +1845,22 @@
static void
probe_purge_old(struct cam_path *path, struct scsi_report_luns_data *new,
- probe_flags flags)
+ probe_flags flags, bool is_wlun)
{
struct cam_path *tp;
- struct scsi_report_luns_data *old;
+ struct scsi_report_luns_data **luns_data, *old;
u_int idx1, idx2, nlun_old, nlun_new;
lun_id_t this_lun;
uint8_t *ol, *nl;
+ luns_data = is_wlun ? &path->target->wluns : &path->target->luns;
+
if (path->target == NULL) {
return;
}
mtx_lock(&path->target->luns_mtx);
- old = path->target->luns;
- path->target->luns = new;
+ old = *luns_data;
+ *luns_data = new;
mtx_unlock(&path->target->luns_mtx);
if (old == NULL)
return;
@@ -1908,11 +1940,16 @@
device->maxtags = quirk->maxtags;
}
+typedef struct {
+ int lun;
+ int wlun;
+} lun_pair;
+
typedef struct {
union ccb *request_ccb;
struct ccb_pathinq *cpi;
int counter;
- int lunindex[0];
+ lun_pair lunindex[0];
} scsi_scan_bus_info;
static void
@@ -1995,7 +2032,8 @@
/* Save some state for use while we probe for devices */
scan_info = (scsi_scan_bus_info *) malloc(sizeof(scsi_scan_bus_info) +
- (work_ccb->cpi.max_target * sizeof (u_int)), M_CAMXPT, M_ZERO|M_NOWAIT);
+ (work_ccb->cpi.max_target * sizeof(lun_pair)),
+ M_CAMXPT, M_ZERO|M_NOWAIT);
if (scan_info == NULL) {
request_ccb->ccb_h.status = CAM_RESRC_UNAVAIL;
xpt_free_ccb(work_ccb);
@@ -2080,6 +2118,8 @@
path_id_t path_id;
target_id_t target_id;
lun_id_t lun_id;
+ u_int nwluns;
+ bool need_wlun_scan = false;
oldpath = request_ccb->ccb_h.path;
@@ -2093,89 +2133,124 @@
mtx = xpt_path_mtx(scan_info->request_ccb->ccb_h.path);
mtx_lock(mtx);
- mtx_lock(&target->luns_mtx);
- if (target->luns) {
- lun_id_t first;
- u_int nluns = scsi_4btoul(target->luns->length) / 8;
- /*
- * Make sure we skip over lun 0 if it's the first member
- * of the list as we've actually just finished probing
- * it.
- */
- CAM_GET_LUN(target->luns, 0, first);
- if (first == 0 && scan_info->lunindex[target_id] == 0) {
- scan_info->lunindex[target_id]++;
- }
-
- /*
- * Skip any LUNs that the HBA can't deal with.
- */
- while (scan_info->lunindex[target_id] < nluns) {
- if (scan_info->cpi->hba_misc & PIM_EXTLUNS) {
- CAM_GET_LUN(target->luns,
- scan_info->lunindex[target_id],
- lun_id);
- break;
- }
+ if (scan_info->cpi->hba_misc & PIM_WLUNS) {
+ /* Scan Well known logical units */
+ mtx_lock(&target->luns_mtx);
- if (CAM_CAN_GET_SIMPLE_LUN(target->luns,
- scan_info->lunindex[target_id])) {
- CAM_GET_SIMPLE_LUN(target->luns,
- scan_info->lunindex[target_id],
- lun_id);
- break;
- }
-
- scan_info->lunindex[target_id]++;
+ if (target->wluns) {
+ nwluns = scsi_4btoul(target->wluns->length) / 8;
+ if (scan_info->lunindex[target_id].wlun < nwluns)
+ need_wlun_scan = true;
}
- if (scan_info->lunindex[target_id] < nluns) {
+ if (need_wlun_scan) {
+ /*
+ * WLUN uses the Extended WLUN address format, so we can handle all of
+ * them.
+ */
+ CAM_GET_LUN(target->wluns, scan_info->lunindex[target_id].wlun, lun_id);
+
mtx_unlock(&target->luns_mtx);
next_target = 0;
CAM_DEBUG(request_ccb->ccb_h.path,
- CAM_DEBUG_PROBE,
- ("next lun to try at index %u is %jx\n",
- scan_info->lunindex[target_id],
- (uintmax_t)lun_id));
- scan_info->lunindex[target_id]++;
+ CAM_DEBUG_PROBE,
+ ("next wlun to try at index %u is %jx\n",
+ scan_info->lunindex[target_id].wlun,
+ (uintmax_t)lun_id));
+ scan_info->lunindex[target_id].wlun++;
} else {
mtx_unlock(&target->luns_mtx);
- /* We're done with scanning all luns. */
+ /* We're done with scanning all wluns. */
}
- } else {
- mtx_unlock(&target->luns_mtx);
- device = request_ccb->ccb_h.path->device;
- /* Continue sequential LUN scan if: */
- /* -- we have more LUNs that need recheck */
- mtx_lock(&target->bus->eb_mtx);
- nextdev = device;
- while ((nextdev = TAILQ_NEXT(nextdev, links)) != NULL)
- if ((nextdev->flags & CAM_DEV_UNCONFIGURED) == 0)
- break;
- mtx_unlock(&target->bus->eb_mtx);
- if (nextdev != NULL) {
- next_target = 0;
- /* -- stop if CAM_QUIRK_NOLUNS is set. */
- } else if (SCSI_QUIRK(device)->quirks & CAM_QUIRK_NOLUNS) {
- next_target = 1;
- /* -- this LUN is connected and its SCSI version
- * allows more LUNs. */
- } else if ((device->flags & CAM_DEV_UNCONFIGURED) == 0) {
- if (lun_id < (CAM_SCSI2_MAXLUN-1) ||
- CAN_SRCH_HI_DENSE(device))
+ }
+
+ if (!need_wlun_scan) {
+ /* Scan logical units */
+ mtx_lock(&target->luns_mtx);
+ if (target->luns) {
+ lun_id_t first;
+ u_int nluns = scsi_4btoul(target->luns->length) / 8;
+
+ /*
+ * Make sure we skip over lun 0 if it's the first member
+ * of the list as we've actually just finished probing
+ * it.
+ */
+ CAM_GET_LUN(target->luns, 0, first);
+ if (first == 0 && scan_info->lunindex[target_id].lun == 0) {
+ scan_info->lunindex[target_id].lun++;
+ }
+
+ /*
+ * Skip any LUNs that the HBA can't deal with.
+ */
+ while (scan_info->lunindex[target_id].lun < nluns) {
+ if (scan_info->cpi->hba_misc & PIM_EXTLUNS) {
+ CAM_GET_LUN(target->luns,
+ scan_info->lunindex[target_id].lun,
+ lun_id);
+ break;
+ }
+
+ if (CAM_CAN_GET_SIMPLE_LUN(target->luns,
+ scan_info->lunindex[target_id].lun)) {
+ CAM_GET_SIMPLE_LUN(target->luns,
+ scan_info->lunindex[target_id].lun,
+ lun_id);
+ break;
+ }
+
+ scan_info->lunindex[target_id].lun++;
+ }
+
+ if (scan_info->lunindex[target_id].lun < nluns) {
+ mtx_unlock(&target->luns_mtx);
next_target = 0;
- /* -- this LUN is disconnected, its SCSI version
- * allows more LUNs and we guess they may be. */
- } else if ((device->flags & CAM_DEV_INQUIRY_DATA_VALID) != 0) {
- if (lun_id < (CAM_SCSI2_MAXLUN-1) ||
- CAN_SRCH_HI_SPARSE(device))
+ CAM_DEBUG(request_ccb->ccb_h.path,
+ CAM_DEBUG_PROBE,
+ ("next lun to try at index %u is %jx\n",
+ scan_info->lunindex[target_id].lun,
+ (uintmax_t)lun_id));
+ scan_info->lunindex[target_id].lun++;
+ } else {
+ mtx_unlock(&target->luns_mtx);
+ /* We're done with scanning all luns. */
+ }
+ } else {
+ mtx_unlock(&target->luns_mtx);
+ device = request_ccb->ccb_h.path->device;
+ /* Continue sequential LUN scan if: */
+ /* -- we have more LUNs that need recheck */
+ mtx_lock(&target->bus->eb_mtx);
+ nextdev = device;
+ while ((nextdev = TAILQ_NEXT(nextdev, links)) != NULL)
+ if ((nextdev->flags & CAM_DEV_UNCONFIGURED) == 0)
+ break;
+ mtx_unlock(&target->bus->eb_mtx);
+ if (nextdev != NULL) {
next_target = 0;
- }
- if (next_target == 0) {
- lun_id++;
- if (lun_id > scan_info->cpi->max_lun)
+ /* -- stop if CAM_QUIRK_NOLUNS is set. */
+ } else if (SCSI_QUIRK(device)->quirks & CAM_QUIRK_NOLUNS) {
next_target = 1;
+ /* -- this LUN is connected and its SCSI version
+ * allows more LUNs. */
+ } else if ((device->flags & CAM_DEV_UNCONFIGURED) == 0) {
+ if (lun_id < (CAM_SCSI2_MAXLUN-1) ||
+ CAN_SRCH_HI_DENSE(device))
+ next_target = 0;
+ /* -- this LUN is disconnected, its SCSI version
+ * allows more LUNs and we guess they may be. */
+ } else if ((device->flags & CAM_DEV_INQUIRY_DATA_VALID) != 0) {
+ if (lun_id < (CAM_SCSI2_MAXLUN-1) ||
+ CAN_SRCH_HI_SPARSE(device))
+ next_target = 0;
+ }
+ if (next_target == 0) {
+ lun_id++;
+ if (lun_id > scan_info->cpi->max_lun)
+ next_target = 1;
+ }
}
}
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sat, Jun 20, 2:59 PM (14 h, 40 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
34120018
Default Alt Text
D53920.id167337.diff (12 KB)
Attached To
Mode
D53920: cam/scsi: Support well known logical unit
Attached
Detach File
Event Timeline
Log In to Comment