PERFORCE change 118702 for review
Scott Long
scottl at FreeBSD.org
Tue Apr 24 04:36:15 UTC 2007
http://perforce.freebsd.org/chv.cgi?CH=118702
Change 118702 by scottl at scottl-x64 on 2007/04/24 04:36:12
Move the bus and LUN scan code to scsi_xpt.c
Affected files ...
.. //depot/projects/scottl-camlock/src/sys/cam/cam_xpt.c#63 edit
.. //depot/projects/scottl-camlock/src/sys/cam/cam_xpt.h#10 edit
.. //depot/projects/scottl-camlock/src/sys/cam/scsi/scsi_xpt.c#2 edit
.. //depot/projects/scottl-camlock/src/sys/cam/scsi/scsi_xpt.h#2 edit
Differences ...
==== //depot/projects/scottl-camlock/src/sys/cam/cam_xpt.c#63 (text+ko) ====
@@ -100,31 +100,6 @@
#define CAM_MAX_HIGHPOWER 4
#endif
-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 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_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)))
-
typedef enum {
XPT_FLAG_OPEN = 0x01
} xpt_flags;
@@ -275,14 +250,6 @@
MODULE_VERSION(cam, 1);
-static cam_status xpt_compile_path(struct cam_path *new_path,
- struct cam_periph *perph,
- path_id_t path_id,
- target_id_t target_id,
- lun_id_t lun_id);
-
-static void xpt_release_path(struct cam_path *path);
-
static void xpt_async_bcast(struct async_list *async_head,
u_int32_t async_code,
struct cam_path *path,
@@ -319,11 +286,6 @@
xpt_find_target(struct cam_eb *bus, target_id_t target_id);
static struct cam_ed*
xpt_find_device(struct cam_et *target, lun_id_t lun_id);
-static void xpt_scan_bus(struct cam_periph *periph, union ccb *ccb);
-static void xpt_scan_lun(struct cam_periph *periph,
- struct cam_path *path, cam_flags flags,
- union ccb *ccb);
-static void xptscandone(struct cam_periph *periph, union ccb *done_ccb);
static xpt_busfunc_t xptconfigbuscountfunc;
static xpt_busfunc_t xptconfigfunc;
static void xpt_config(void *arg);
@@ -3492,7 +3454,7 @@
return (status);
}
-static cam_status
+cam_status
xpt_compile_path(struct cam_path *new_path, struct cam_periph *perph,
path_id_t path_id, target_id_t target_id, lun_id_t lun_id)
{
@@ -3563,7 +3525,7 @@
return (status);
}
-static void
+void
xpt_release_path(struct cam_path *path)
{
CAM_DEBUG(path, CAM_DEBUG_TRACE, ("xpt_release_path\n"));
@@ -4677,386 +4639,6 @@
return (device);
}
-typedef struct {
- union ccb *request_ccb;
- struct ccb_pathinq *cpi;
- int counter;
-} xpt_scan_bus_info;
-
-/*
- * To start a scan, request_ccb is an XPT_SCAN_BUS ccb.
- * As the scan progresses, xpt_scan_bus is used as the
- * callback on completion function.
- */
-static void
-xpt_scan_bus(struct cam_periph *periph, union ccb *request_ccb)
-{
- CAM_DEBUG(request_ccb->ccb_h.path, CAM_DEBUG_TRACE,
- ("xpt_scan_bus\n"));
- switch (request_ccb->ccb_h.func_code) {
- case XPT_SCAN_BUS:
- {
- xpt_scan_bus_info *scan_info;
- union ccb *work_ccb;
- struct cam_path *path;
- u_int i;
- u_int max_target;
- u_int initiator_id;
-
- /* Find out the characteristics of the bus */
- work_ccb = xpt_alloc_ccb_nowait();
- if (work_ccb == NULL) {
- request_ccb->ccb_h.status = CAM_RESRC_UNAVAIL;
- xpt_done(request_ccb);
- return;
- }
- xpt_setup_ccb(&work_ccb->ccb_h, request_ccb->ccb_h.path,
- request_ccb->ccb_h.pinfo.priority);
- work_ccb->ccb_h.func_code = XPT_PATH_INQ;
- xpt_action(work_ccb);
- if (work_ccb->ccb_h.status != CAM_REQ_CMP) {
- request_ccb->ccb_h.status = work_ccb->ccb_h.status;
- xpt_free_ccb(work_ccb);
- xpt_done(request_ccb);
- return;
- }
-
- if ((work_ccb->cpi.hba_misc & PIM_NOINITIATOR) != 0) {
- /*
- * Can't scan the bus on an adapter that
- * cannot perform the initiator role.
- */
- request_ccb->ccb_h.status = CAM_REQ_CMP;
- xpt_free_ccb(work_ccb);
- xpt_done(request_ccb);
- return;
- }
-
- /* Save some state for use while we probe for devices */
- scan_info = (xpt_scan_bus_info *)
- malloc(sizeof(xpt_scan_bus_info), M_TEMP, M_NOWAIT);
- scan_info->request_ccb = request_ccb;
- scan_info->cpi = &work_ccb->cpi;
-
- /* Cache on our stack so we can work asynchronously */
- max_target = scan_info->cpi->max_target;
- initiator_id = scan_info->cpi->initiator_id;
-
-
- /*
- * We can scan all targets in parallel, or do it sequentially.
- */
- if (scan_info->cpi->hba_misc & PIM_SEQSCAN) {
- max_target = 0;
- scan_info->counter = 0;
- } else {
- scan_info->counter = scan_info->cpi->max_target + 1;
- if (scan_info->cpi->initiator_id < scan_info->counter) {
- scan_info->counter--;
- }
- }
-
- for (i = 0; i <= max_target; i++) {
- cam_status status;
- if (i == initiator_id)
- continue;
-
- status = xpt_create_path(&path, xpt_periph,
- request_ccb->ccb_h.path_id,
- i, 0);
- if (status != CAM_REQ_CMP) {
- printf("xpt_scan_bus: xpt_create_path failed"
- " with status %#x, bus scan halted\n",
- status);
- free(scan_info, M_TEMP);
- request_ccb->ccb_h.status = status;
- xpt_free_ccb(work_ccb);
- xpt_done(request_ccb);
- break;
- }
- work_ccb = xpt_alloc_ccb_nowait();
- if (work_ccb == NULL) {
- free(scan_info, M_TEMP);
- xpt_free_path(path);
- request_ccb->ccb_h.status = CAM_RESRC_UNAVAIL;
- xpt_done(request_ccb);
- break;
- }
- xpt_setup_ccb(&work_ccb->ccb_h, path,
- request_ccb->ccb_h.pinfo.priority);
- work_ccb->ccb_h.func_code = XPT_SCAN_LUN;
- work_ccb->ccb_h.cbfcnp = xpt_scan_bus;
- work_ccb->ccb_h.ppriv_ptr0 = scan_info;
- work_ccb->crcn.flags = request_ccb->crcn.flags;
- xpt_action(work_ccb);
- }
- break;
- }
- case XPT_SCAN_LUN:
- {
- cam_status status;
- struct cam_path *path;
- xpt_scan_bus_info *scan_info;
- path_id_t path_id;
- target_id_t target_id;
- lun_id_t lun_id;
-
- /* Reuse the same CCB to query if a device was really found */
- scan_info = (xpt_scan_bus_info *)request_ccb->ccb_h.ppriv_ptr0;
- xpt_setup_ccb(&request_ccb->ccb_h, request_ccb->ccb_h.path,
- request_ccb->ccb_h.pinfo.priority);
- request_ccb->ccb_h.func_code = XPT_GDEV_TYPE;
-
- path_id = request_ccb->ccb_h.path_id;
- target_id = request_ccb->ccb_h.target_id;
- lun_id = request_ccb->ccb_h.target_lun;
- xpt_action(request_ccb);
-
- if (request_ccb->ccb_h.status != CAM_REQ_CMP) {
- struct cam_ed *device;
- struct cam_et *target;
- int phl;
-
- /*
- * If we already probed lun 0 successfully, or
- * we have additional configured luns on this
- * target that might have "gone away", go onto
- * the next lun.
- */
- target = request_ccb->ccb_h.path->target;
- /*
- * We may touch devices that we don't
- * hold references too, so ensure they
- * don't disappear out from under us.
- * The target above is referenced by the
- * path in the request ccb.
- */
- phl = 0;
- device = TAILQ_FIRST(&target->ed_entries);
- if (device != NULL) {
- phl = CAN_SRCH_HI_SPARSE(device);
- if (device->lun_id == 0)
- device = TAILQ_NEXT(device, links);
- }
- if ((lun_id != 0) || (device != NULL)) {
- if (lun_id < (CAM_SCSI2_MAXLUN-1) || phl)
- lun_id++;
- }
- } else {
- struct cam_ed *device;
-
- device = request_ccb->ccb_h.path->device;
-
- if ((device->quirk->quirks & CAM_QUIRK_NOLUNS) == 0) {
- /* Try the next lun */
- if (lun_id < (CAM_SCSI2_MAXLUN-1)
- || CAN_SRCH_HI_DENSE(device))
- lun_id++;
- }
- }
-
- /*
- * Free the current request path- we're done with it.
- */
- xpt_free_path(request_ccb->ccb_h.path);
-
- /*
- * Check to see if we scan any further luns.
- */
- if (lun_id == request_ccb->ccb_h.target_lun
- || lun_id > scan_info->cpi->max_lun) {
- int done;
-
- hop_again:
- done = 0;
- if (scan_info->cpi->hba_misc & PIM_SEQSCAN) {
- scan_info->counter++;
- if (scan_info->counter ==
- scan_info->cpi->initiator_id) {
- scan_info->counter++;
- }
- if (scan_info->counter >=
- scan_info->cpi->max_target+1) {
- done = 1;
- }
- } else {
- scan_info->counter--;
- if (scan_info->counter == 0) {
- done = 1;
- }
- }
- if (done) {
- xpt_free_ccb(request_ccb);
- xpt_free_ccb((union ccb *)scan_info->cpi);
- request_ccb = scan_info->request_ccb;
- free(scan_info, M_TEMP);
- request_ccb->ccb_h.status = CAM_REQ_CMP;
- xpt_done(request_ccb);
- break;
- }
-
- if ((scan_info->cpi->hba_misc & PIM_SEQSCAN) == 0) {
- break;
- }
- status = xpt_create_path(&path, xpt_periph,
- scan_info->request_ccb->ccb_h.path_id,
- scan_info->counter, 0);
- if (status != CAM_REQ_CMP) {
- printf("xpt_scan_bus: xpt_create_path failed"
- " with status %#x, bus scan halted\n",
- status);
- xpt_free_ccb(request_ccb);
- xpt_free_ccb((union ccb *)scan_info->cpi);
- request_ccb = scan_info->request_ccb;
- free(scan_info, M_TEMP);
- request_ccb->ccb_h.status = status;
- xpt_done(request_ccb);
- break;
- }
- xpt_setup_ccb(&request_ccb->ccb_h, path,
- request_ccb->ccb_h.pinfo.priority);
- request_ccb->ccb_h.func_code = XPT_SCAN_LUN;
- request_ccb->ccb_h.cbfcnp = xpt_scan_bus;
- request_ccb->ccb_h.ppriv_ptr0 = scan_info;
- request_ccb->crcn.flags =
- scan_info->request_ccb->crcn.flags;
- } else {
- status = xpt_create_path(&path, xpt_periph,
- path_id, target_id, lun_id);
- if (status != CAM_REQ_CMP) {
- printf("xpt_scan_bus: xpt_create_path failed "
- "with status %#x, halting LUN scan\n",
- status);
- goto hop_again;
- }
- xpt_setup_ccb(&request_ccb->ccb_h, path,
- request_ccb->ccb_h.pinfo.priority);
- request_ccb->ccb_h.func_code = XPT_SCAN_LUN;
- request_ccb->ccb_h.cbfcnp = xpt_scan_bus;
- request_ccb->ccb_h.ppriv_ptr0 = scan_info;
- request_ccb->crcn.flags =
- scan_info->request_ccb->crcn.flags;
- }
- xpt_action(request_ccb);
- break;
- }
- default:
- break;
- }
-}
-
-static void
-xpt_scan_lun(struct cam_periph *periph, struct cam_path *path,
- cam_flags flags, union ccb *request_ccb)
-{
- struct ccb_pathinq cpi;
- cam_status status;
- struct cam_path *new_path;
- struct cam_periph *old_periph;
-
- CAM_DEBUG(request_ccb->ccb_h.path, CAM_DEBUG_TRACE,
- ("xpt_scan_lun\n"));
-
- xpt_setup_ccb(&cpi.ccb_h, path, /*priority*/1);
- cpi.ccb_h.func_code = XPT_PATH_INQ;
- xpt_action((union ccb *)&cpi);
-
- if (cpi.ccb_h.status != CAM_REQ_CMP) {
- if (request_ccb != NULL) {
- request_ccb->ccb_h.status = cpi.ccb_h.status;
- xpt_done(request_ccb);
- }
- return;
- }
-
- if ((cpi.hba_misc & PIM_NOINITIATOR) != 0) {
- /*
- * Can't scan the bus on an adapter that
- * cannot perform the initiator role.
- */
- if (request_ccb != NULL) {
- request_ccb->ccb_h.status = CAM_REQ_CMP;
- xpt_done(request_ccb);
- }
- return;
- }
-
- if (request_ccb == NULL) {
- request_ccb = malloc(sizeof(union ccb), M_TEMP, M_NOWAIT);
- if (request_ccb == NULL) {
- xpt_print(path, "xpt_scan_lun: can't allocate CCB, "
- "can't continue\n");
- return;
- }
- new_path = malloc(sizeof(*new_path), M_TEMP, M_NOWAIT);
- if (new_path == NULL) {
- xpt_print(path, "xpt_scan_lun: can't allocate path, "
- "can't continue\n");
- free(request_ccb, M_TEMP);
- return;
- }
- status = xpt_compile_path(new_path, xpt_periph,
- path->bus->path_id,
- path->target->target_id,
- path->device->lun_id);
-
- if (status != CAM_REQ_CMP) {
- xpt_print(path, "xpt_scan_lun: can't compile path, "
- "can't continue\n");
- free(request_ccb, M_TEMP);
- free(new_path, M_TEMP);
- return;
- }
- xpt_setup_ccb(&request_ccb->ccb_h, new_path, /*priority*/ 1);
- request_ccb->ccb_h.cbfcnp = xptscandone;
- request_ccb->ccb_h.func_code = XPT_SCAN_LUN;
- request_ccb->crcn.flags = flags;
- }
-
- if ((old_periph = cam_periph_find(path, "probe")) != NULL) {
- probe_insert_ccbq(old_periph, &request_ccb->ccb_h);
- } else {
- status = cam_periph_alloc(proberegister, NULL, probecleanup,
- probestart, "probe",
- CAM_PERIPH_BIO,
- request_ccb->ccb_h.path, NULL, 0,
- request_ccb);
-
- if (status != CAM_REQ_CMP) {
- xpt_print(path, "xpt_scan_lun: cam_alloc_periph "
- "returned an error, can't continue probe\n");
- request_ccb->ccb_h.status = status;
- xpt_done(request_ccb);
- }
- }
-}
-
-static void
-xptscandone(struct cam_periph *periph, union ccb *done_ccb)
-{
- xpt_release_path(done_ccb->ccb_h.path);
- free(done_ccb->ccb_h.path, M_TEMP);
- free(done_ccb, M_TEMP);
-}
-
-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);
- }
-}
-
-
void
xpt_devise_transport(struct cam_path *path)
{
==== //depot/projects/scottl-camlock/src/sys/cam/cam_xpt.h#10 (text+ko) ====
@@ -80,6 +80,14 @@
void xpt_rescan(union ccb *ccb);
void xpt_lock_buses(void);
void xpt_unlock_buses(void);
+cam_status xpt_compile_path(struct cam_path *new_path,
+ struct cam_periph *perph,
+ path_id_t path_id,
+ target_id_t target_id,
+ lun_id_t lun_id);
+
+void xpt_release_path(struct cam_path *path);
+
#endif /* _KERNEL */
#endif /* _CAM_CAM_XPT_H */
==== //depot/projects/scottl-camlock/src/sys/cam/scsi/scsi_xpt.c#2 (text+ko) ====
@@ -64,6 +64,7 @@
#include <cam/scsi/scsi_message.h>
#include <cam/scsi/scsi_pass.h>
#include <cam/scsi/scsi_xpt.h>
+#include <cam/scsi/scsi_probe.h>
#include <machine/stdarg.h> /* for xpt_print below */
#include "opt_cam.h"
@@ -431,6 +432,31 @@
struct xpt_quirk_entry *xpt_default_quirk =
&xpt_quirk_table[(sizeof(xpt_quirk_table) / sizeof(*xpt_quirk_table)) - 1];
+#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 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_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)))
+
+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");
+
void
xpt_find_quirk(struct cam_ed *device)
@@ -448,3 +474,381 @@
device->quirk = (struct xpt_quirk_entry *)match;
}
+typedef struct {
+ union ccb *request_ccb;
+ struct ccb_pathinq *cpi;
+ int counter;
+} xpt_scan_bus_info;
+
+/*
+ * To start a scan, request_ccb is an XPT_SCAN_BUS ccb.
+ * As the scan progresses, xpt_scan_bus is used as the
+ * callback on completion function.
+ */
+void
+xpt_scan_bus(struct cam_periph *periph, union ccb *request_ccb)
+{
+ CAM_DEBUG(request_ccb->ccb_h.path, CAM_DEBUG_TRACE,
+ ("xpt_scan_bus\n"));
+ switch (request_ccb->ccb_h.func_code) {
+ case XPT_SCAN_BUS:
+ {
+ xpt_scan_bus_info *scan_info;
+ union ccb *work_ccb;
+ struct cam_path *path;
+ u_int i;
+ u_int max_target;
+ u_int initiator_id;
+
+ /* Find out the characteristics of the bus */
+ work_ccb = xpt_alloc_ccb_nowait();
+ if (work_ccb == NULL) {
+ request_ccb->ccb_h.status = CAM_RESRC_UNAVAIL;
+ xpt_done(request_ccb);
+ return;
+ }
+ xpt_setup_ccb(&work_ccb->ccb_h, request_ccb->ccb_h.path,
+ request_ccb->ccb_h.pinfo.priority);
+ work_ccb->ccb_h.func_code = XPT_PATH_INQ;
+ xpt_action(work_ccb);
+ if (work_ccb->ccb_h.status != CAM_REQ_CMP) {
+ request_ccb->ccb_h.status = work_ccb->ccb_h.status;
+ xpt_free_ccb(work_ccb);
+ xpt_done(request_ccb);
+ return;
+ }
+
+ if ((work_ccb->cpi.hba_misc & PIM_NOINITIATOR) != 0) {
+ /*
+ * Can't scan the bus on an adapter that
+ * cannot perform the initiator role.
+ */
+ request_ccb->ccb_h.status = CAM_REQ_CMP;
+ xpt_free_ccb(work_ccb);
+ xpt_done(request_ccb);
+ return;
+ }
+
+ /* Save some state for use while we probe for devices */
+ scan_info = (xpt_scan_bus_info *)
+ malloc(sizeof(xpt_scan_bus_info), M_TEMP, M_NOWAIT);
+ scan_info->request_ccb = request_ccb;
+ scan_info->cpi = &work_ccb->cpi;
+
+ /* Cache on our stack so we can work asynchronously */
+ max_target = scan_info->cpi->max_target;
+ initiator_id = scan_info->cpi->initiator_id;
+
+
+ /*
+ * We can scan all targets in parallel, or do it sequentially.
+ */
+ if (scan_info->cpi->hba_misc & PIM_SEQSCAN) {
+ max_target = 0;
+ scan_info->counter = 0;
+ } else {
+ scan_info->counter = scan_info->cpi->max_target + 1;
+ if (scan_info->cpi->initiator_id < scan_info->counter) {
+ scan_info->counter--;
+ }
+ }
+
+ for (i = 0; i <= max_target; i++) {
+ cam_status status;
+ if (i == initiator_id)
+ continue;
+
+ status = xpt_create_path(&path, xpt_periph,
+ request_ccb->ccb_h.path_id,
+ i, 0);
+ if (status != CAM_REQ_CMP) {
+ printf("xpt_scan_bus: xpt_create_path failed"
+ " with status %#x, bus scan halted\n",
+ status);
+ free(scan_info, M_TEMP);
+ request_ccb->ccb_h.status = status;
+ xpt_free_ccb(work_ccb);
+ xpt_done(request_ccb);
+ break;
+ }
+ work_ccb = xpt_alloc_ccb_nowait();
+ if (work_ccb == NULL) {
+ free(scan_info, M_TEMP);
+ xpt_free_path(path);
+ request_ccb->ccb_h.status = CAM_RESRC_UNAVAIL;
+ xpt_done(request_ccb);
+ break;
+ }
+ xpt_setup_ccb(&work_ccb->ccb_h, path,
+ request_ccb->ccb_h.pinfo.priority);
+ work_ccb->ccb_h.func_code = XPT_SCAN_LUN;
+ work_ccb->ccb_h.cbfcnp = xpt_scan_bus;
+ work_ccb->ccb_h.ppriv_ptr0 = scan_info;
+ work_ccb->crcn.flags = request_ccb->crcn.flags;
+ xpt_action(work_ccb);
+ }
+ break;
+ }
+ case XPT_SCAN_LUN:
+ {
+ cam_status status;
+ struct cam_path *path;
+ xpt_scan_bus_info *scan_info;
+ path_id_t path_id;
+ target_id_t target_id;
+ lun_id_t lun_id;
+
+ /* Reuse the same CCB to query if a device was really found */
+ scan_info = (xpt_scan_bus_info *)request_ccb->ccb_h.ppriv_ptr0;
+ xpt_setup_ccb(&request_ccb->ccb_h, request_ccb->ccb_h.path,
+ request_ccb->ccb_h.pinfo.priority);
+ request_ccb->ccb_h.func_code = XPT_GDEV_TYPE;
+
+ path_id = request_ccb->ccb_h.path_id;
+ target_id = request_ccb->ccb_h.target_id;
+ lun_id = request_ccb->ccb_h.target_lun;
+ xpt_action(request_ccb);
+
+ if (request_ccb->ccb_h.status != CAM_REQ_CMP) {
+ struct cam_ed *device;
+ struct cam_et *target;
+ int phl;
+
+ /*
+ * If we already probed lun 0 successfully, or
+ * we have additional configured luns on this
+ * target that might have "gone away", go onto
+ * the next lun.
+ */
+ target = request_ccb->ccb_h.path->target;
+ /*
+ * We may touch devices that we don't
+ * hold references too, so ensure they
+ * don't disappear out from under us.
+ * The target above is referenced by the
+ * path in the request ccb.
+ */
+ phl = 0;
+ device = TAILQ_FIRST(&target->ed_entries);
+ if (device != NULL) {
+ phl = CAN_SRCH_HI_SPARSE(device);
+ if (device->lun_id == 0)
+ device = TAILQ_NEXT(device, links);
+ }
+ if ((lun_id != 0) || (device != NULL)) {
+ if (lun_id < (CAM_SCSI2_MAXLUN-1) || phl)
+ lun_id++;
+ }
+ } else {
+ struct cam_ed *device;
+
+ device = request_ccb->ccb_h.path->device;
+
+ if ((device->quirk->quirks & CAM_QUIRK_NOLUNS) == 0) {
+ /* Try the next lun */
+ if (lun_id < (CAM_SCSI2_MAXLUN-1)
+ || CAN_SRCH_HI_DENSE(device))
+ lun_id++;
+ }
+ }
+
+ /*
+ * Free the current request path- we're done with it.
+ */
+ xpt_free_path(request_ccb->ccb_h.path);
+
+ /*
+ * Check to see if we scan any further luns.
+ */
+ if (lun_id == request_ccb->ccb_h.target_lun
+ || lun_id > scan_info->cpi->max_lun) {
+ int done;
+
+ hop_again:
+ done = 0;
+ if (scan_info->cpi->hba_misc & PIM_SEQSCAN) {
+ scan_info->counter++;
+ if (scan_info->counter ==
+ scan_info->cpi->initiator_id) {
+ scan_info->counter++;
+ }
+ if (scan_info->counter >=
+ scan_info->cpi->max_target+1) {
+ done = 1;
+ }
+ } else {
+ scan_info->counter--;
+ if (scan_info->counter == 0) {
+ done = 1;
+ }
+ }
+ if (done) {
+ xpt_free_ccb(request_ccb);
+ xpt_free_ccb((union ccb *)scan_info->cpi);
+ request_ccb = scan_info->request_ccb;
+ free(scan_info, M_TEMP);
+ request_ccb->ccb_h.status = CAM_REQ_CMP;
+ xpt_done(request_ccb);
+ break;
+ }
+
+ if ((scan_info->cpi->hba_misc & PIM_SEQSCAN) == 0) {
+ break;
+ }
+ status = xpt_create_path(&path, xpt_periph,
+ scan_info->request_ccb->ccb_h.path_id,
+ scan_info->counter, 0);
+ if (status != CAM_REQ_CMP) {
+ printf("xpt_scan_bus: xpt_create_path failed"
+ " with status %#x, bus scan halted\n",
+ status);
+ xpt_free_ccb(request_ccb);
+ xpt_free_ccb((union ccb *)scan_info->cpi);
+ request_ccb = scan_info->request_ccb;
+ free(scan_info, M_TEMP);
+ request_ccb->ccb_h.status = status;
+ xpt_done(request_ccb);
+ break;
+ }
+ xpt_setup_ccb(&request_ccb->ccb_h, path,
+ request_ccb->ccb_h.pinfo.priority);
+ request_ccb->ccb_h.func_code = XPT_SCAN_LUN;
+ request_ccb->ccb_h.cbfcnp = xpt_scan_bus;
+ request_ccb->ccb_h.ppriv_ptr0 = scan_info;
+ request_ccb->crcn.flags =
+ scan_info->request_ccb->crcn.flags;
+ } else {
+ status = xpt_create_path(&path, xpt_periph,
+ path_id, target_id, lun_id);
+ if (status != CAM_REQ_CMP) {
+ printf("xpt_scan_bus: xpt_create_path failed "
+ "with status %#x, halting LUN scan\n",
+ status);
+ goto hop_again;
+ }
+ xpt_setup_ccb(&request_ccb->ccb_h, path,
+ request_ccb->ccb_h.pinfo.priority);
+ request_ccb->ccb_h.func_code = XPT_SCAN_LUN;
+ request_ccb->ccb_h.cbfcnp = xpt_scan_bus;
+ request_ccb->ccb_h.ppriv_ptr0 = scan_info;
+ request_ccb->crcn.flags =
+ scan_info->request_ccb->crcn.flags;
+ }
+ xpt_action(request_ccb);
+ break;
+ }
+ default:
+ break;
+ }
+}
+
+void
+xpt_scan_lun(struct cam_periph *periph, struct cam_path *path,
+ cam_flags flags, union ccb *request_ccb)
+{
+ struct ccb_pathinq cpi;
+ cam_status status;
+ struct cam_path *new_path;
+ struct cam_periph *old_periph;
+
+ CAM_DEBUG(request_ccb->ccb_h.path, CAM_DEBUG_TRACE,
+ ("xpt_scan_lun\n"));
+
+ xpt_setup_ccb(&cpi.ccb_h, path, /*priority*/1);
+ cpi.ccb_h.func_code = XPT_PATH_INQ;
+ xpt_action((union ccb *)&cpi);
+
+ if (cpi.ccb_h.status != CAM_REQ_CMP) {
+ if (request_ccb != NULL) {
+ request_ccb->ccb_h.status = cpi.ccb_h.status;
+ xpt_done(request_ccb);
+ }
+ return;
+ }
+
+ if ((cpi.hba_misc & PIM_NOINITIATOR) != 0) {
+ /*
+ * Can't scan the bus on an adapter that
+ * cannot perform the initiator role.
+ */
+ if (request_ccb != NULL) {
+ request_ccb->ccb_h.status = CAM_REQ_CMP;
+ xpt_done(request_ccb);
+ }
+ return;
+ }
+
+ if (request_ccb == NULL) {
+ request_ccb = malloc(sizeof(union ccb), M_TEMP, M_NOWAIT);
+ if (request_ccb == NULL) {
+ xpt_print(path, "xpt_scan_lun: can't allocate CCB, "
+ "can't continue\n");
+ return;
+ }
+ new_path = malloc(sizeof(*new_path), M_TEMP, M_NOWAIT);
+ if (new_path == NULL) {
+ xpt_print(path, "xpt_scan_lun: can't allocate path, "
+ "can't continue\n");
+ free(request_ccb, M_TEMP);
+ return;
+ }
+ status = xpt_compile_path(new_path, xpt_periph,
+ path->bus->path_id,
+ path->target->target_id,
+ path->device->lun_id);
+
+ if (status != CAM_REQ_CMP) {
+ xpt_print(path, "xpt_scan_lun: can't compile path, "
+ "can't continue\n");
+ free(request_ccb, M_TEMP);
+ free(new_path, M_TEMP);
+ return;
+ }
+ xpt_setup_ccb(&request_ccb->ccb_h, new_path, /*priority*/ 1);
+ request_ccb->ccb_h.cbfcnp = xptscandone;
+ request_ccb->ccb_h.func_code = XPT_SCAN_LUN;
+ request_ccb->crcn.flags = flags;
+ }
+
+ if ((old_periph = cam_periph_find(path, "probe")) != NULL) {
+ probe_insert_ccbq(old_periph, &request_ccb->ccb_h);
+ } else {
+ status = cam_periph_alloc(proberegister, NULL, probecleanup,
+ probestart, "probe",
+ CAM_PERIPH_BIO,
+ request_ccb->ccb_h.path, NULL, 0,
+ request_ccb);
+
+ if (status != CAM_REQ_CMP) {
+ xpt_print(path, "xpt_scan_lun: cam_alloc_periph "
+ "returned an error, can't continue probe\n");
+ request_ccb->ccb_h.status = status;
+ xpt_done(request_ccb);
+ }
+ }
+}
+
+void
+xptscandone(struct cam_periph *periph, union ccb *done_ccb)
+{
+ xpt_release_path(done_ccb->ccb_h.path);
+ free(done_ccb->ccb_h.path, M_TEMP);
+ free(done_ccb, M_TEMP);
+}
+
+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);
+ }
+}
==== //depot/projects/scottl-camlock/src/sys/cam/scsi/scsi_xpt.h#2 (text+ko) ====
@@ -115,5 +115,9 @@
};
void xpt_find_quirk(struct cam_ed *device);
+void xpt_scan_bus(struct cam_periph *periph, union ccb *ccb);
+void xpt_scan_lun(struct cam_periph *periph, struct cam_path *path,
+ cam_flags flags, union ccb *ccb);
+void xptscandone(struct cam_periph *periph, union ccb *done_ccb);
extern struct xpt_quirk_entry *xpt_default_quirk;
More information about the p4-projects
mailing list