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
This commit is contained in:
parent
522c90a143
commit
0e85f214e3
@ -1185,6 +1185,7 @@ ata_scan_bus(struct cam_periph *periph, union ccb *request_ccb)
|
||||
("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) {
|
||||
@ -1526,6 +1527,7 @@ ata_action(union ccb *start_ccb)
|
||||
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:
|
||||
|
@ -184,6 +184,11 @@ typedef enum {
|
||||
/*
|
||||
* Set SIM specific knob values.
|
||||
*/
|
||||
|
||||
XPT_SCAN_TGT = 0x1E | XPT_FC_QUEUED | XPT_FC_USER_CCB
|
||||
| XPT_FC_XPT_ONLY,
|
||||
/* Scan Target */
|
||||
|
||||
/* HBA engine commands 0x20->0x2F */
|
||||
XPT_ENG_INQ = 0x20 | XPT_FC_XPT_ONLY,
|
||||
/* HBA engine feature inquiry */
|
||||
|
@ -446,23 +446,36 @@ xptioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flag, struct thread *td
|
||||
inccb = (union ccb *)addr;
|
||||
|
||||
bus = xpt_find_bus(inccb->ccb_h.path_id);
|
||||
if (bus == NULL) {
|
||||
error = EINVAL;
|
||||
if (bus == NULL)
|
||||
return (EINVAL);
|
||||
|
||||
switch (inccb->ccb_h.func_code) {
|
||||
case XPT_SCAN_BUS:
|
||||
case XPT_RESET_BUS:
|
||||
if (inccb->ccb_h.target_id != CAM_TARGET_WILDCARD ||
|
||||
inccb->ccb_h.target_lun != CAM_LUN_WILDCARD) {
|
||||
xpt_release_bus(bus);
|
||||
return (EINVAL);
|
||||
}
|
||||
break;
|
||||
case XPT_SCAN_TGT:
|
||||
if (inccb->ccb_h.target_id == CAM_TARGET_WILDCARD ||
|
||||
inccb->ccb_h.target_lun != CAM_LUN_WILDCARD) {
|
||||
xpt_release_bus(bus);
|
||||
return (EINVAL);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
switch(inccb->ccb_h.func_code) {
|
||||
case XPT_SCAN_BUS:
|
||||
case XPT_RESET_BUS:
|
||||
if ((inccb->ccb_h.target_id != CAM_TARGET_WILDCARD)
|
||||
|| (inccb->ccb_h.target_lun != CAM_LUN_WILDCARD)) {
|
||||
error = EINVAL;
|
||||
break;
|
||||
}
|
||||
/* FALLTHROUGH */
|
||||
case XPT_PATH_INQ:
|
||||
case XPT_ENG_INQ:
|
||||
case XPT_SCAN_LUN:
|
||||
case XPT_SCAN_TGT:
|
||||
|
||||
ccb = xpt_alloc_ccb();
|
||||
|
||||
@ -839,11 +852,21 @@ xpt_rescan(union ccb *ccb)
|
||||
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);
|
||||
|
@ -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:
|
||||
|
@ -3893,19 +3893,14 @@ isp_make_here(ispsoftc_t *isp, int chan, int tgt)
|
||||
}
|
||||
|
||||
/*
|
||||
* Allocate a CCB, create a wildcard path for this bus/target and schedule a rescan.
|
||||
* Allocate a CCB, create a wildcard path for this target and schedule a rescan.
|
||||
*/
|
||||
ccb = xpt_alloc_ccb_nowait();
|
||||
if (ccb == NULL) {
|
||||
isp_prt(isp, ISP_LOGWARN, "Chan %d unable to alloc CCB for rescan", chan);
|
||||
return;
|
||||
}
|
||||
/*
|
||||
* xpt_rescan only honors wildcard in the target field.
|
||||
* 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;
|
||||
|
Loading…
x
Reference in New Issue
Block a user