aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/mpt2sas/mpt2sas_scsih.c
diff options
context:
space:
mode:
authorKashyap, Desai <kashyap.desai@lsi.com>2009-08-20 03:52:00 -0400
committerJames Bottomley <James.Bottomley@suse.de>2009-09-05 10:34:49 -0400
commit155dd4c763694222c125e65438d823f58ea653bc (patch)
tree0db7b5b8d41c165222357ac8dee45482f1425faa /drivers/scsi/mpt2sas/mpt2sas_scsih.c
parentcd4e12e8ad246ec5bc23ab04d0da0e6985025620 (diff)
[SCSI] mpt2sas: Prevent sending command to FW while Host Reset
This patch renames the flag for indicating host reset from ioc_reset_in_progress to shost_recovery. It also removes the spin locks surrounding the setting of this flag, which are unnecessary. Sanity checks on the shost_recovery flag were added thru out the code so as to prevent sending firmware commands during host reset. Also, the setting of the shost state to SHOST_RECOVERY was removed to prevent deadlocks, this is actually better handled by the shost_recovery flag. Signed-off-by: Kashyap Desai <kashyap.desai@lsi.com> Reviewed-by: Eric Moore <Eric.moore@lsi.com> Cc: Stable Tree <stable@kernel.org> Signed-off-by: James Bottomley <James.Bottomley@suse.de>
Diffstat (limited to 'drivers/scsi/mpt2sas/mpt2sas_scsih.c')
-rw-r--r--drivers/scsi/mpt2sas/mpt2sas_scsih.c40
1 files changed, 24 insertions, 16 deletions
diff --git a/drivers/scsi/mpt2sas/mpt2sas_scsih.c b/drivers/scsi/mpt2sas/mpt2sas_scsih.c
index 471c3b604596..195f5e5aabf1 100644
--- a/drivers/scsi/mpt2sas/mpt2sas_scsih.c
+++ b/drivers/scsi/mpt2sas/mpt2sas_scsih.c
@@ -1785,17 +1785,18 @@ mpt2sas_scsih_issue_tm(struct MPT2SAS_ADAPTER *ioc, u16 handle, uint lun,
1785 u32 ioc_state; 1785 u32 ioc_state;
1786 unsigned long timeleft; 1786 unsigned long timeleft;
1787 u8 VF_ID = 0; 1787 u8 VF_ID = 0;
1788 unsigned long flags;
1789 1788
1790 spin_lock_irqsave(&ioc->ioc_reset_in_progress_lock, flags); 1789 if (ioc->tm_cmds.status != MPT2_CMD_NOT_USED) {
1791 if (ioc->tm_cmds.status != MPT2_CMD_NOT_USED || 1790 printk(MPT2SAS_INFO_FMT "%s: tm_cmd busy!!!\n",
1792 ioc->shost_recovery) { 1791 __func__, ioc->name);
1793 spin_unlock_irqrestore(&ioc->ioc_reset_in_progress_lock, flags); 1792 return;
1793 }
1794
1795 if (ioc->shost_recovery) {
1794 printk(MPT2SAS_INFO_FMT "%s: host reset in progress!\n", 1796 printk(MPT2SAS_INFO_FMT "%s: host reset in progress!\n",
1795 __func__, ioc->name); 1797 __func__, ioc->name);
1796 return; 1798 return;
1797 } 1799 }
1798 spin_unlock_irqrestore(&ioc->ioc_reset_in_progress_lock, flags);
1799 1800
1800 ioc_state = mpt2sas_base_get_iocstate(ioc, 0); 1801 ioc_state = mpt2sas_base_get_iocstate(ioc, 0);
1801 if (ioc_state & MPI2_DOORBELL_USED) { 1802 if (ioc_state & MPI2_DOORBELL_USED) {
@@ -2553,7 +2554,6 @@ _scsih_qcmd(struct scsi_cmnd *scmd, void (*done)(struct scsi_cmnd *))
2553 Mpi2SCSIIORequest_t *mpi_request; 2554 Mpi2SCSIIORequest_t *mpi_request;
2554 u32 mpi_control; 2555 u32 mpi_control;
2555 u16 smid; 2556 u16 smid;
2556 unsigned long flags;
2557 2557
2558 scmd->scsi_done = done; 2558 scmd->scsi_done = done;
2559 sas_device_priv_data = scmd->device->hostdata; 2559 sas_device_priv_data = scmd->device->hostdata;
@@ -2572,13 +2572,10 @@ _scsih_qcmd(struct scsi_cmnd *scmd, void (*done)(struct scsi_cmnd *))
2572 } 2572 }
2573 2573
2574 /* see if we are busy with task managment stuff */ 2574 /* see if we are busy with task managment stuff */
2575 spin_lock_irqsave(&ioc->ioc_reset_in_progress_lock, flags); 2575 if (sas_target_priv_data->tm_busy)
2576 if (sas_target_priv_data->tm_busy || 2576 return SCSI_MLQUEUE_DEVICE_BUSY;
2577 ioc->shost_recovery || ioc->ioc_link_reset_in_progress) { 2577 else if (ioc->shost_recovery || ioc->ioc_link_reset_in_progress)
2578 spin_unlock_irqrestore(&ioc->ioc_reset_in_progress_lock, flags);
2579 return SCSI_MLQUEUE_HOST_BUSY; 2578 return SCSI_MLQUEUE_HOST_BUSY;
2580 }
2581 spin_unlock_irqrestore(&ioc->ioc_reset_in_progress_lock, flags);
2582 2579
2583 if (scmd->sc_data_direction == DMA_FROM_DEVICE) 2580 if (scmd->sc_data_direction == DMA_FROM_DEVICE)
2584 mpi_control = MPI2_SCSIIO_CONTROL_READ; 2581 mpi_control = MPI2_SCSIIO_CONTROL_READ;
@@ -3374,6 +3371,9 @@ _scsih_expander_add(struct MPT2SAS_ADAPTER *ioc, u16 handle)
3374 if (!handle) 3371 if (!handle)
3375 return -1; 3372 return -1;
3376 3373
3374 if (ioc->shost_recovery)
3375 return -1;
3376
3377 if ((mpt2sas_config_get_expander_pg0(ioc, &mpi_reply, &expander_pg0, 3377 if ((mpt2sas_config_get_expander_pg0(ioc, &mpi_reply, &expander_pg0,
3378 MPI2_SAS_EXPAND_PGAD_FORM_HNDL, handle))) { 3378 MPI2_SAS_EXPAND_PGAD_FORM_HNDL, handle))) {
3379 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n", 3379 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
@@ -3510,6 +3510,9 @@ _scsih_expander_remove(struct MPT2SAS_ADAPTER *ioc, u16 handle)
3510 struct _sas_node *sas_expander; 3510 struct _sas_node *sas_expander;
3511 unsigned long flags; 3511 unsigned long flags;
3512 3512
3513 if (ioc->shost_recovery)
3514 return;
3515
3513 spin_lock_irqsave(&ioc->sas_node_lock, flags); 3516 spin_lock_irqsave(&ioc->sas_node_lock, flags);
3514 sas_expander = mpt2sas_scsih_expander_find_by_handle(ioc, handle); 3517 sas_expander = mpt2sas_scsih_expander_find_by_handle(ioc, handle);
3515 spin_unlock_irqrestore(&ioc->sas_node_lock, flags); 3518 spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
@@ -3681,6 +3684,8 @@ _scsih_remove_device(struct MPT2SAS_ADAPTER *ioc, u16 handle)
3681 mutex_unlock(&ioc->tm_cmds.mutex); 3684 mutex_unlock(&ioc->tm_cmds.mutex);
3682 dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "issue target reset " 3685 dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "issue target reset "
3683 "done: handle(0x%04x)\n", ioc->name, device_handle)); 3686 "done: handle(0x%04x)\n", ioc->name, device_handle));
3687 if (ioc->shost_recovery)
3688 goto out;
3684 } 3689 }
3685 3690
3686 /* SAS_IO_UNIT_CNTR - send REMOVE_DEVICE */ 3691 /* SAS_IO_UNIT_CNTR - send REMOVE_DEVICE */
@@ -3846,6 +3851,8 @@ _scsih_sas_topology_change_event(struct MPT2SAS_ADAPTER *ioc, u8 VF_ID,
3846 "expander event\n", ioc->name)); 3851 "expander event\n", ioc->name));
3847 return; 3852 return;
3848 } 3853 }
3854 if (ioc->shost_recovery)
3855 return;
3849 if (event_data->PHY[i].PhyStatus & 3856 if (event_data->PHY[i].PhyStatus &
3850 MPI2_EVENT_SAS_TOPO_PHYSTATUS_VACANT) 3857 MPI2_EVENT_SAS_TOPO_PHYSTATUS_VACANT)
3851 continue; 3858 continue;
@@ -5217,13 +5224,10 @@ _firmware_event_work(struct work_struct *work)
5217 } 5224 }
5218 spin_unlock_irqrestore(&ioc->fw_event_lock, flags); 5225 spin_unlock_irqrestore(&ioc->fw_event_lock, flags);
5219 5226
5220 spin_lock_irqsave(&ioc->ioc_reset_in_progress_lock, flags);
5221 if (ioc->shost_recovery) { 5227 if (ioc->shost_recovery) {
5222 spin_unlock_irqrestore(&ioc->ioc_reset_in_progress_lock, flags);
5223 _scsih_fw_event_requeue(ioc, fw_event, 1000); 5228 _scsih_fw_event_requeue(ioc, fw_event, 1000);
5224 return; 5229 return;
5225 } 5230 }
5226 spin_unlock_irqrestore(&ioc->ioc_reset_in_progress_lock, flags);
5227 5231
5228 switch (fw_event->event) { 5232 switch (fw_event->event) {
5229 case MPI2_EVENT_SAS_TOPOLOGY_CHANGE_LIST: 5233 case MPI2_EVENT_SAS_TOPOLOGY_CHANGE_LIST:
@@ -5425,6 +5429,8 @@ _scsih_expander_node_remove(struct MPT2SAS_ADAPTER *ioc,
5425 if (!sas_device) 5429 if (!sas_device)
5426 continue; 5430 continue;
5427 _scsih_remove_device(ioc, sas_device->handle); 5431 _scsih_remove_device(ioc, sas_device->handle);
5432 if (ioc->shost_recovery)
5433 return;
5428 goto retry_device_search; 5434 goto retry_device_search;
5429 } 5435 }
5430 } 5436 }
@@ -5446,6 +5452,8 @@ _scsih_expander_node_remove(struct MPT2SAS_ADAPTER *ioc,
5446 if (!expander_sibling) 5452 if (!expander_sibling)
5447 continue; 5453 continue;
5448 _scsih_expander_remove(ioc, expander_sibling->handle); 5454 _scsih_expander_remove(ioc, expander_sibling->handle);
5455 if (ioc->shost_recovery)
5456 return;
5449 goto retry_expander_search; 5457 goto retry_expander_search;
5450 } 5458 }
5451 } 5459 }