diff options
Diffstat (limited to 'drivers/scsi')
-rw-r--r-- | drivers/scsi/hpsa.c | 40 |
1 files changed, 16 insertions, 24 deletions
diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c index 7915dc45a37c..a92653a18bd2 100644 --- a/drivers/scsi/hpsa.c +++ b/drivers/scsi/hpsa.c | |||
@@ -4149,25 +4149,14 @@ static int hpsa_scsi_queue_command(struct Scsi_Host *sh, struct scsi_cmnd *cmd) | |||
4149 | return hpsa_ciss_submit(h, c, cmd, scsi3addr); | 4149 | return hpsa_ciss_submit(h, c, cmd, scsi3addr); |
4150 | } | 4150 | } |
4151 | 4151 | ||
4152 | static int do_not_scan_if_controller_locked_up(struct ctlr_info *h) | 4152 | static void hpsa_scan_complete(struct ctlr_info *h) |
4153 | { | 4153 | { |
4154 | unsigned long flags; | 4154 | unsigned long flags; |
4155 | 4155 | ||
4156 | /* | 4156 | spin_lock_irqsave(&h->scan_lock, flags); |
4157 | * Don't let rescans be initiated on a controller known | 4157 | h->scan_finished = 1; |
4158 | * to be locked up. If the controller locks up *during* | 4158 | wake_up_all(&h->scan_wait_queue); |
4159 | * a rescan, that thread is probably hosed, but at least | 4159 | spin_unlock_irqrestore(&h->scan_lock, flags); |
4160 | * we can prevent new rescan threads from piling up on a | ||
4161 | * locked up controller. | ||
4162 | */ | ||
4163 | if (unlikely(lockup_detected(h))) { | ||
4164 | spin_lock_irqsave(&h->scan_lock, flags); | ||
4165 | h->scan_finished = 1; | ||
4166 | wake_up_all(&h->scan_wait_queue); | ||
4167 | spin_unlock_irqrestore(&h->scan_lock, flags); | ||
4168 | return 1; | ||
4169 | } | ||
4170 | return 0; | ||
4171 | } | 4160 | } |
4172 | 4161 | ||
4173 | static void hpsa_scan_start(struct Scsi_Host *sh) | 4162 | static void hpsa_scan_start(struct Scsi_Host *sh) |
@@ -4175,8 +4164,14 @@ static void hpsa_scan_start(struct Scsi_Host *sh) | |||
4175 | struct ctlr_info *h = shost_to_hba(sh); | 4164 | struct ctlr_info *h = shost_to_hba(sh); |
4176 | unsigned long flags; | 4165 | unsigned long flags; |
4177 | 4166 | ||
4178 | if (do_not_scan_if_controller_locked_up(h)) | 4167 | /* |
4179 | return; | 4168 | * Don't let rescans be initiated on a controller known to be locked |
4169 | * up. If the controller locks up *during* a rescan, that thread is | ||
4170 | * probably hosed, but at least we can prevent new rescan threads from | ||
4171 | * piling up on a locked up controller. | ||
4172 | */ | ||
4173 | if (unlikely(lockup_detected(h))) | ||
4174 | return hpsa_scan_complete(h); | ||
4180 | 4175 | ||
4181 | /* wait until any scan already in progress is finished. */ | 4176 | /* wait until any scan already in progress is finished. */ |
4182 | while (1) { | 4177 | while (1) { |
@@ -4194,15 +4189,12 @@ static void hpsa_scan_start(struct Scsi_Host *sh) | |||
4194 | h->scan_finished = 0; /* mark scan as in progress */ | 4189 | h->scan_finished = 0; /* mark scan as in progress */ |
4195 | spin_unlock_irqrestore(&h->scan_lock, flags); | 4190 | spin_unlock_irqrestore(&h->scan_lock, flags); |
4196 | 4191 | ||
4197 | if (do_not_scan_if_controller_locked_up(h)) | 4192 | if (unlikely(lockup_detected(h))) |
4198 | return; | 4193 | return hpsa_scan_complete(h); |
4199 | 4194 | ||
4200 | hpsa_update_scsi_devices(h, h->scsi_host->host_no); | 4195 | hpsa_update_scsi_devices(h, h->scsi_host->host_no); |
4201 | 4196 | ||
4202 | spin_lock_irqsave(&h->scan_lock, flags); | 4197 | hpsa_scan_complete(h); |
4203 | h->scan_finished = 1; /* mark scan as finished. */ | ||
4204 | wake_up_all(&h->scan_wait_queue); | ||
4205 | spin_unlock_irqrestore(&h->scan_lock, flags); | ||
4206 | } | 4198 | } |
4207 | 4199 | ||
4208 | static int hpsa_change_queue_depth(struct scsi_device *sdev, int qdepth) | 4200 | static int hpsa_change_queue_depth(struct scsi_device *sdev, int qdepth) |