aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/mpt2sas/mpt2sas_base.c
diff options
context:
space:
mode:
authorKashyap, Desai <kashyap.desai@lsi.com>2010-06-17 03:58:55 -0400
committerJames Bottomley <James.Bottomley@suse.de>2010-07-27 13:02:06 -0400
commitd274213a1ae59e8abde8d43e1e3a478fe9f28794 (patch)
treea13dcb559d8a444c862fd57bf0c114dd7425018a /drivers/scsi/mpt2sas/mpt2sas_base.c
parentab6ce92541ea24c6a92be8498d7d1b26c14ec62d (diff)
[SCSI] mpt2sas: Hold Controller reset when another reset is in progress
Driver should not allow multiple host reset when already host reset is in progress. It is possible that host reset was sent by scsi mid layer while there was already an host reset active, either issued via IOCTL interface or internaly, like a config page timeout. Since there was a host reset active, the driver would return a FAILED response to the scsi mid layer. The solution is make sure pending host resets will wait for the active host reset to complete before returning control back up the call stack. Signed-off-by: Kashyap Desai <kashyap.desai@lsi.com> Signed-off-by: James Bottomley <James.Bottomley@suse.de>
Diffstat (limited to 'drivers/scsi/mpt2sas/mpt2sas_base.c')
-rw-r--r--drivers/scsi/mpt2sas/mpt2sas_base.c29
1 files changed, 22 insertions, 7 deletions
diff --git a/drivers/scsi/mpt2sas/mpt2sas_base.c b/drivers/scsi/mpt2sas/mpt2sas_base.c
index 0ec1ed389c20..f0c0df4278d7 100644
--- a/drivers/scsi/mpt2sas/mpt2sas_base.c
+++ b/drivers/scsi/mpt2sas/mpt2sas_base.c
@@ -3804,7 +3804,7 @@ _wait_for_commands_to_complete(struct MPT2SAS_ADAPTER *ioc, int sleep_flag)
3804 return; 3804 return;
3805 3805
3806 /* wait for pending commands to complete */ 3806 /* wait for pending commands to complete */
3807 wait_event_timeout(ioc->reset_wq, ioc->pending_io_count == 0, 3 * HZ); 3807 wait_event_timeout(ioc->reset_wq, ioc->pending_io_count == 0, 10 * HZ);
3808} 3808}
3809 3809
3810/** 3810/**
@@ -3828,13 +3828,24 @@ mpt2sas_base_hard_reset_handler(struct MPT2SAS_ADAPTER *ioc, int sleep_flag,
3828 if (mpt2sas_fwfault_debug) 3828 if (mpt2sas_fwfault_debug)
3829 mpt2sas_halt_firmware(ioc); 3829 mpt2sas_halt_firmware(ioc);
3830 3830
3831 spin_lock_irqsave(&ioc->ioc_reset_in_progress_lock, flags); 3831 /* TODO - What we really should be doing is pulling
3832 if (ioc->shost_recovery) { 3832 * out all the code associated with NO_SLEEP; its never used.
3833 spin_unlock_irqrestore(&ioc->ioc_reset_in_progress_lock, flags); 3833 * That is legacy code from mpt fusion driver, ported over.
3834 printk(MPT2SAS_ERR_FMT "%s: busy\n", 3834 * I will leave this BUG_ON here for now till its been resolved.
3835 ioc->name, __func__); 3835 */
3836 return -EBUSY; 3836 BUG_ON(sleep_flag == NO_SLEEP);
3837
3838 /* wait for an active reset in progress to complete */
3839 if (!mutex_trylock(&ioc->reset_in_progress_mutex)) {
3840 do {
3841 ssleep(1);
3842 } while (ioc->shost_recovery == 1);
3843 dtmprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s: exit\n", ioc->name,
3844 __func__));
3845 return ioc->ioc_reset_in_progress_status;
3837 } 3846 }
3847
3848 spin_lock_irqsave(&ioc->ioc_reset_in_progress_lock, flags);
3838 ioc->shost_recovery = 1; 3849 ioc->shost_recovery = 1;
3839 spin_unlock_irqrestore(&ioc->ioc_reset_in_progress_lock, flags); 3850 spin_unlock_irqrestore(&ioc->ioc_reset_in_progress_lock, flags);
3840 3851
@@ -3853,9 +3864,13 @@ mpt2sas_base_hard_reset_handler(struct MPT2SAS_ADAPTER *ioc, int sleep_flag,
3853 ioc->name, __func__, ((r == 0) ? "SUCCESS" : "FAILED"))); 3864 ioc->name, __func__, ((r == 0) ? "SUCCESS" : "FAILED")));
3854 3865
3855 spin_lock_irqsave(&ioc->ioc_reset_in_progress_lock, flags); 3866 spin_lock_irqsave(&ioc->ioc_reset_in_progress_lock, flags);
3867 ioc->ioc_reset_in_progress_status = r;
3856 ioc->shost_recovery = 0; 3868 ioc->shost_recovery = 0;
3857 complete(&ioc->shost_recovery_done); 3869 complete(&ioc->shost_recovery_done);
3858 spin_unlock_irqrestore(&ioc->ioc_reset_in_progress_lock, flags); 3870 spin_unlock_irqrestore(&ioc->ioc_reset_in_progress_lock, flags);
3871 mutex_unlock(&ioc->reset_in_progress_mutex);
3859 3872
3873 dtmprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s: exit\n", ioc->name,
3874 __func__));
3860 return r; 3875 return r;
3861} 3876}