diff options
author | Stephen M. Cameron <scameron@beardog.cce.hp.com> | 2014-02-18 20:55:48 +0100 |
---|---|---|
committer | James Bottomley <JBottomley@Parallels.com> | 2014-03-15 18:19:04 +0100 |
commit | 5f389360559bcb99f1efd4fef772d3755c97d24f (patch) | |
tree | fda0689d25390b31beed9f40cbd3917ad275d2f7 /drivers/scsi/hpsa.c | |
parent | [SCSI] hpsa: poll controller to detect device change event (diff) | |
download | linux-5f389360559bcb99f1efd4fef772d3755c97d24f.tar.xz linux-5f389360559bcb99f1efd4fef772d3755c97d24f.zip |
[SCSI] hpsa: do not rescan controllers known to be locked up
* Do not check event bits on locked up controllers to
see if they need to be rescanned.
* Do not initiate any device rescans on controllers
which are known to be locked up.
Signed-off-by: Stephen M. Cameron <scameron@beardog.cce.hp.com>
Signed-off-by: James Bottomley <JBottomley@Parallels.com>
Diffstat (limited to '')
-rw-r--r-- | drivers/scsi/hpsa.c | 30 |
1 files changed, 30 insertions, 0 deletions
diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c index ee17556058c2..67e059cd9e57 100644 --- a/drivers/scsi/hpsa.c +++ b/drivers/scsi/hpsa.c @@ -2868,11 +2868,38 @@ static int hpsa_scsi_queue_command_lck(struct scsi_cmnd *cmd, static DEF_SCSI_QCMD(hpsa_scsi_queue_command) +static int do_not_scan_if_controller_locked_up(struct ctlr_info *h) +{ + unsigned long flags; + + /* + * Don't let rescans be initiated on a controller known + * to be locked up. If the controller locks up *during* + * a rescan, that thread is probably hosed, but at least + * we can prevent new rescan threads from piling up on a + * locked up controller. + */ + spin_lock_irqsave(&h->lock, flags); + if (unlikely(h->lockup_detected)) { + spin_unlock_irqrestore(&h->lock, flags); + spin_lock_irqsave(&h->scan_lock, flags); + h->scan_finished = 1; + wake_up_all(&h->scan_wait_queue); + spin_unlock_irqrestore(&h->scan_lock, flags); + return 1; + } + spin_unlock_irqrestore(&h->lock, flags); + return 0; +} + static void hpsa_scan_start(struct Scsi_Host *sh) { struct ctlr_info *h = shost_to_hba(sh); unsigned long flags; + if (do_not_scan_if_controller_locked_up(h)) + return; + /* wait until any scan already in progress is finished. */ while (1) { spin_lock_irqsave(&h->scan_lock, flags); @@ -2889,6 +2916,9 @@ static void hpsa_scan_start(struct Scsi_Host *sh) h->scan_finished = 0; /* mark scan as in progress */ spin_unlock_irqrestore(&h->scan_lock, flags); + if (do_not_scan_if_controller_locked_up(h)) + return; + hpsa_update_scsi_devices(h, h->scsi_host->host_no); spin_lock_irqsave(&h->scan_lock, flags); |