diff options
author | Kashyap, Desai <kashyap.desai@lsi.com> | 2009-08-20 03:52:00 -0400 |
---|---|---|
committer | James Bottomley <James.Bottomley@suse.de> | 2009-09-05 10:34:49 -0400 |
commit | 155dd4c763694222c125e65438d823f58ea653bc (patch) | |
tree | 0db7b5b8d41c165222357ac8dee45482f1425faa /drivers/scsi/mpt2sas/mpt2sas_scsih.c | |
parent | cd4e12e8ad246ec5bc23ab04d0da0e6985025620 (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.c | 40 |
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 | } |