addition of an XPT_SCAN_TGT code
Matthew Jacob
mj at feral.com
Sat May 15 01:15:36 UTC 2010
Sometimes, particularly in relation to a hotplug event, you just want to
scan a target id, not the whole bus. It's lighter weight.
The attached patch adds this with a relatively light touch. I'm not
super happy with it, but it does make rescanning on a target basis doable.
Comments?
-------------- next part --------------
diff -r 85c0fa25a2fc sys/cam/ata/ata_xpt.c
--- a/sys/cam/ata/ata_xpt.c Fri May 14 15:55:34 2010 -0700
+++ b/sys/cam/ata/ata_xpt.c Fri May 14 18:14:46 2010 -0700
@@ -1189,6 +1189,7 @@
("xpt_scan_bus\n"));
switch (request_ccb->ccb_h.func_code) {
case XPT_SCAN_BUS:
+ case XPT_SCAN_TGT:
/* Find out the characteristics of the bus */
work_ccb = xpt_alloc_ccb_nowait();
if (work_ccb == NULL) {
@@ -1530,6 +1531,7 @@
break;
}
case XPT_SCAN_BUS:
+ case XPT_SCAN_TGT:
ata_scan_bus(start_ccb->ccb_h.path->periph, start_ccb);
break;
case XPT_SCAN_LUN:
diff -r 85c0fa25a2fc sys/cam/cam_ccb.h
--- a/sys/cam/cam_ccb.h Fri May 14 15:55:34 2010 -0700
+++ b/sys/cam/cam_ccb.h Fri May 14 18:14:46 2010 -0700
@@ -207,6 +207,10 @@
/* Notify Host Target driver of event */
XPT_NOTIFY_ACKNOWLEDGE = 0x37 | XPT_FC_QUEUED | XPT_FC_USER_CCB,
/* Acknowledgement of event */
+/* overflow commands: 0x40 ->0x4F */
+ XPT_SCAN_TGT = 0x40 | XPT_FC_QUEUED | XPT_FC_USER_CCB
+ | XPT_FC_XPT_ONLY,
+ /* (Re)Scan the SCSI Bus */
/* Vendor Unique codes: 0x80->0x8F */
XPT_VUNIQUE = 0x80
diff -r 85c0fa25a2fc sys/cam/cam_xpt.c
--- a/sys/cam/cam_xpt.c Fri May 14 15:55:34 2010 -0700
+++ b/sys/cam/cam_xpt.c Fri May 14 18:14:46 2010 -0700
@@ -463,6 +463,13 @@
case XPT_PATH_INQ:
case XPT_ENG_INQ:
case XPT_SCAN_LUN:
+ case XPT_SCAN_TGT:
+ if (inccb->ccb_h.func_code == XPT_SCAN_TGT &&
+ (inccb->ccb_h.target_id == CAM_TARGET_WILDCARD ||
+ (inccb->ccb_h.target_lun != CAM_LUN_WILDCARD))) {
+ error = EINVAL;
+ break;
+ }
ccb = xpt_alloc_ccb();
@@ -839,11 +846,21 @@
struct ccb_hdr *hdr;
/* Prepare request */
- if (ccb->ccb_h.path->target->target_id == CAM_TARGET_WILDCARD ||
+ if (ccb->ccb_h.path->target->target_id == CAM_TARGET_WILDCARD &&
ccb->ccb_h.path->device->lun_id == CAM_LUN_WILDCARD)
ccb->ccb_h.func_code = XPT_SCAN_BUS;
- else
+ else if (ccb->ccb_h.path->target->target_id != CAM_TARGET_WILDCARD &&
+ ccb->ccb_h.path->device->lun_id == CAM_LUN_WILDCARD)
+ ccb->ccb_h.func_code = XPT_SCAN_TGT;
+ else if (ccb->ccb_h.path->target->target_id != CAM_TARGET_WILDCARD &&
+ ccb->ccb_h.path->device->lun_id != CAM_LUN_WILDCARD)
ccb->ccb_h.func_code = XPT_SCAN_LUN;
+ else {
+ xpt_print(ccb->ccb_h.path, "illegal scan path\n");
+ xpt_free_path(ccb->ccb_h.path);
+ xpt_free_ccb(ccb);
+ return;
+ }
ccb->ccb_h.ppriv_ptr1 = ccb->ccb_h.cbfcnp;
ccb->ccb_h.cbfcnp = xpt_rescan_done;
xpt_setup_ccb(&ccb->ccb_h, ccb->ccb_h.path, CAM_PRIORITY_XPT);
diff -r 85c0fa25a2fc sys/cam/scsi/scsi_xpt.c
--- a/sys/cam/scsi/scsi_xpt.c Fri May 14 15:55:34 2010 -0700
+++ b/sys/cam/scsi/scsi_xpt.c Fri May 14 18:14:46 2010 -0700
@@ -1487,12 +1487,13 @@
("scsi_scan_bus\n"));
switch (request_ccb->ccb_h.func_code) {
case XPT_SCAN_BUS:
+ case XPT_SCAN_TGT:
{
scsi_scan_bus_info *scan_info;
union ccb *work_ccb, *reset_ccb;
struct cam_path *path;
u_int i;
- u_int max_target;
+ u_int low_target, max_target;
u_int initiator_id;
/* Find out the characteristics of the bus */
@@ -1557,13 +1558,18 @@
/* Cache on our stack so we can work asynchronously */
max_target = scan_info->cpi->max_target;
+ low_target = 0;
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) {
+
+ if (request_ccb->ccb_h.func_code == XPT_SCAN_TGT) {
+ max_target = low_target = request_ccb->ccb_h.target_id;
+ scan_info->counter = 0;
+ } else if (scan_info->cpi->hba_misc & PIM_SEQSCAN) {
max_target = 0;
scan_info->counter = 0;
} else {
@@ -1573,7 +1579,7 @@
}
}
- for (i = 0; i <= max_target; i++) {
+ for (i = low_target; i <= max_target; i++) {
cam_status status;
if (i == initiator_id)
continue;
@@ -1688,7 +1694,9 @@
hop_again:
done = 0;
- if (scan_info->cpi->hba_misc & PIM_SEQSCAN) {
+ if (request_ccb->ccb_h.func_code == XPT_SCAN_TGT) {
+ done = 1;
+ } else if (scan_info->cpi->hba_misc & PIM_SEQSCAN) {
scan_info->counter++;
if (scan_info->counter ==
scan_info->cpi->initiator_id) {
@@ -2009,6 +2017,7 @@
break;
}
case XPT_SCAN_BUS:
+ case XPT_SCAN_TGT:
scsi_scan_bus(start_ccb->ccb_h.path->periph, start_ccb);
break;
case XPT_SCAN_LUN:
diff -r 85c0fa25a2fc sys/dev/isp/isp_freebsd.c
--- a/sys/dev/isp/isp_freebsd.c Fri May 14 15:55:34 2010 -0700
+++ b/sys/dev/isp/isp_freebsd.c Fri May 14 18:14:46 2010 -0700
@@ -3898,7 +3898,7 @@
* Scan the whole bus instead of target, which will then
* force a scan of all luns.
*/
- if (xpt_create_path(&ccb->ccb_h.path, xpt_periph, cam_sim_path(fc->sim), CAM_TARGET_WILDCARD, CAM_LUN_WILDCARD) != CAM_REQ_CMP) {
+ if (xpt_create_path(&ccb->ccb_h.path, xpt_periph, cam_sim_path(fc->sim), tgt, CAM_LUN_WILDCARD) != CAM_REQ_CMP) {
isp_prt(isp, ISP_LOGWARN, "unable to create path for rescan");
xpt_free_ccb(ccb);
return;
More information about the freebsd-scsi
mailing list