aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/block/cciss.c
diff options
context:
space:
mode:
authorStephen M. Cameron <scameron@beardog.cce.hp.com>2009-11-12 13:49:19 -0500
committerJens Axboe <jens.axboe@oracle.com>2009-11-13 02:45:53 -0500
commitfd8489cff419d216479655b8041b8574ed89f806 (patch)
treee09263fd1b593a4033ce79e6e5152b46105bf0ec /drivers/block/cciss.c
parent8ba95c69fe6eb65ff36b64136ae24844ddba16a1 (diff)
cciss: Fix problem with remove_from_scan_list on driver unload
cciss: Fix problem with remove_from_scan_list that on driver unload it doesn't remove the controller from the scan list correctly if the controller is currently being scanned for new devices. Signed-off-by: Stephen M. Cameron <scameron@beardog.cce.hp.com> Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
Diffstat (limited to 'drivers/block/cciss.c')
-rw-r--r--drivers/block/cciss.c21
1 files changed, 13 insertions, 8 deletions
diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c
index 92b126394fa..81c21875eb7 100644
--- a/drivers/block/cciss.c
+++ b/drivers/block/cciss.c
@@ -3513,28 +3513,33 @@ static int add_to_scan_list(struct ctlr_info *h)
3513 * @h: Pointer to the controller. 3513 * @h: Pointer to the controller.
3514 * 3514 *
3515 * Removes the controller from the rescan queue if present. Blocks if 3515 * Removes the controller from the rescan queue if present. Blocks if
3516 * the controller is currently conducting a rescan. 3516 * the controller is currently conducting a rescan. The controller
3517 * can be in one of three states:
3518 * 1. Doesn't need a scan
3519 * 2. On the scan list, but not scanning yet (we remove it)
3520 * 3. Busy scanning (and not on the list). In this case we want to wait for
3521 * the scan to complete to make sure the scanning thread for this
3522 * controller is completely idle.
3517 **/ 3523 **/
3518static void remove_from_scan_list(struct ctlr_info *h) 3524static void remove_from_scan_list(struct ctlr_info *h)
3519{ 3525{
3520 struct ctlr_info *test_h, *tmp_h; 3526 struct ctlr_info *test_h, *tmp_h;
3521 int scanning = 0;
3522 3527
3523 mutex_lock(&scan_mutex); 3528 mutex_lock(&scan_mutex);
3524 list_for_each_entry_safe(test_h, tmp_h, &scan_q, scan_list) { 3529 list_for_each_entry_safe(test_h, tmp_h, &scan_q, scan_list) {
3525 if (test_h == h) { 3530 if (test_h == h) { /* state 2. */
3526 list_del(&h->scan_list); 3531 list_del(&h->scan_list);
3527 complete_all(&h->scan_wait); 3532 complete_all(&h->scan_wait);
3528 mutex_unlock(&scan_mutex); 3533 mutex_unlock(&scan_mutex);
3529 return; 3534 return;
3530 } 3535 }
3531 } 3536 }
3532 if (&h->busy_scanning) 3537 if (h->busy_scanning) { /* state 3. */
3533 scanning = 0; 3538 mutex_unlock(&scan_mutex);
3534 mutex_unlock(&scan_mutex);
3535
3536 if (scanning)
3537 wait_for_completion(&h->scan_wait); 3539 wait_for_completion(&h->scan_wait);
3540 } else { /* state 1, nothing to do. */
3541 mutex_unlock(&scan_mutex);
3542 }
3538} 3543}
3539 3544
3540/** 3545/**