diff options
author | ken <ken@FreeBSD.org> | 2009-09-15 00:15:24 +0000 |
---|---|---|
committer | ken <ken@FreeBSD.org> | 2009-09-15 00:15:24 +0000 |
commit | f2066f0140b87790e588ec3ea9e07817b7f04bd2 (patch) | |
tree | 8817cc33d150514e8915f5ba99c2be02a50fc6b6 | |
parent | f70487e83490cabe03cf0cec48256cc039fd1107 (diff) | |
download | FreeBSD-src-f2066f0140b87790e588ec3ea9e07817b7f04bd2.zip FreeBSD-src-f2066f0140b87790e588ec3ea9e07817b7f04bd2.tar.gz |
Fix some instances where CAM rescans get hung up or take a long time to
complete.
Also, allow xpt_rescan() to rescan a LUN instead of a full bus.
MFC after: 3 days
Sponsored by: Copan Systems, Inc.
-rw-r--r-- | sys/cam/cam_xpt.c | 13 |
1 files changed, 9 insertions, 4 deletions
diff --git a/sys/cam/cam_xpt.c b/sys/cam/cam_xpt.c index b506481..39b25df 100644 --- a/sys/cam/cam_xpt.c +++ b/sys/cam/cam_xpt.c @@ -794,8 +794,9 @@ xpt_scanner_thread(void *dummy) * processed. */ xpt_lock_buses(); - msleep(&xsoftc.ccb_scanq, &xsoftc.xpt_topo_lock, PRIBIO, - "ccb_scanq", 0); + if (TAILQ_EMPTY(&xsoftc.ccb_scanq)) + msleep(&xsoftc.ccb_scanq, &xsoftc.xpt_topo_lock, PRIBIO, + "ccb_scanq", 0); TAILQ_INIT(&queue); TAILQ_CONCAT(&queue, &xsoftc.ccb_scanq, sim_links.tqe); xpt_unlock_buses(); @@ -806,9 +807,12 @@ xpt_scanner_thread(void *dummy) sim = ccb->ccb_h.path->bus->sim; CAM_SIM_LOCK(sim); - ccb->ccb_h.func_code = XPT_SCAN_BUS; + if( ccb->ccb_h.path->target->target_id == CAM_TARGET_WILDCARD ) + ccb->ccb_h.func_code = XPT_SCAN_BUS; + else + ccb->ccb_h.func_code = XPT_SCAN_LUN; ccb->ccb_h.cbfcnp = xptdone; - xpt_setup_ccb(&ccb->ccb_h, ccb->ccb_h.path, 5); + xpt_setup_ccb(&ccb->ccb_h, ccb->ccb_h.path, 1); cam_periph_runccb(ccb, NULL, 0, 0, NULL); xpt_free_path(ccb->ccb_h.path); xpt_free_ccb(ccb); @@ -828,6 +832,7 @@ xpt_rescan(union ccb *ccb) xpt_lock_buses(); TAILQ_FOREACH(hdr, &xsoftc.ccb_scanq, sim_links.tqe) { if (xpt_path_comp(hdr->path, ccb->ccb_h.path) == 0) { + wakeup(&xsoftc.ccb_scanq); xpt_unlock_buses(); xpt_print(ccb->ccb_h.path, "rescan already queued\n"); xpt_free_path(ccb->ccb_h.path); |