summaryrefslogtreecommitdiffstats
path: root/sys/cam/scsi
diff options
context:
space:
mode:
authormjacob <mjacob@FreeBSD.org>2010-05-26 22:49:42 +0000
committermjacob <mjacob@FreeBSD.org>2010-05-26 22:49:42 +0000
commit39b696507f1a5623910a10e31faedf7281e3cc41 (patch)
tree814f54bc94bcdd3b953da0eada061521fa6b750d /sys/cam/scsi
parent7201725878b6cb600187de6a38ff7c846c85ba0b (diff)
downloadFreeBSD-src-39b696507f1a5623910a10e31faedf7281e3cc41.zip
FreeBSD-src-39b696507f1a5623910a10e31faedf7281e3cc41.tar.gz
Add a new primitive, XPT_SCAN_TGT, to cover the range between scanning a
whole bus (XPT_SCAN_BUS) and a single lun on that bus (XPT_SCAN_LUN). It's less resource comsumptive than scanning a whole bus when the caller knows only one target has changes. Reviewed by: scsi@ Sponsored by: Panasas MFC after: 1 month
Diffstat (limited to 'sys/cam/scsi')
-rw-r--r--sys/cam/scsi/scsi_xpt.c17
1 files changed, 13 insertions, 4 deletions
diff --git a/sys/cam/scsi/scsi_xpt.c b/sys/cam/scsi/scsi_xpt.c
index 6e61cb8..c4043ad 100644
--- a/sys/cam/scsi/scsi_xpt.c
+++ b/sys/cam/scsi/scsi_xpt.c
@@ -1494,12 +1494,13 @@ scsi_scan_bus(struct cam_periph *periph, union ccb *request_ccb)
("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 */
@@ -1564,13 +1565,18 @@ scsi_scan_bus(struct cam_periph *periph, union ccb *request_ccb)
/* 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 {
@@ -1580,7 +1586,7 @@ scsi_scan_bus(struct cam_periph *periph, union ccb *request_ccb)
}
}
- for (i = 0; i <= max_target; i++) {
+ for (i = low_target; i <= max_target; i++) {
cam_status status;
if (i == initiator_id)
continue;
@@ -1695,7 +1701,9 @@ scsi_scan_bus(struct cam_periph *periph, union ccb *request_ccb)
hop_again:
done = 0;
- if (scan_info->cpi->hba_misc & PIM_SEQSCAN) {
+ if (scan_info->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) {
@@ -2016,6 +2024,7 @@ scsi_action(union ccb *start_ccb)
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:
OpenPOWER on IntegriCloud