diff options
Diffstat (limited to 'drivers/scsi/mpt2sas/mpt2sas_scsih.c')
-rw-r--r-- | drivers/scsi/mpt2sas/mpt2sas_scsih.c | 64 |
1 files changed, 52 insertions, 12 deletions
diff --git a/drivers/scsi/mpt2sas/mpt2sas_scsih.c b/drivers/scsi/mpt2sas/mpt2sas_scsih.c index 16e99b686354..794d927f70c1 100644 --- a/drivers/scsi/mpt2sas/mpt2sas_scsih.c +++ b/drivers/scsi/mpt2sas/mpt2sas_scsih.c | |||
@@ -819,7 +819,7 @@ _scsih_is_end_device(u32 device_info) | |||
819 | } | 819 | } |
820 | 820 | ||
821 | /** | 821 | /** |
822 | * mptscsih_get_scsi_lookup - returns scmd entry | 822 | * _scsih_scsi_lookup_get - returns scmd entry |
823 | * @ioc: per adapter object | 823 | * @ioc: per adapter object |
824 | * @smid: system request message index | 824 | * @smid: system request message index |
825 | * | 825 | * |
@@ -832,6 +832,28 @@ _scsih_scsi_lookup_get(struct MPT2SAS_ADAPTER *ioc, u16 smid) | |||
832 | } | 832 | } |
833 | 833 | ||
834 | /** | 834 | /** |
835 | * _scsih_scsi_lookup_get_clear - returns scmd entry | ||
836 | * @ioc: per adapter object | ||
837 | * @smid: system request message index | ||
838 | * | ||
839 | * Returns the smid stored scmd pointer. | ||
840 | * Then will derefrence the stored scmd pointer. | ||
841 | */ | ||
842 | static inline struct scsi_cmnd * | ||
843 | _scsih_scsi_lookup_get_clear(struct MPT2SAS_ADAPTER *ioc, u16 smid) | ||
844 | { | ||
845 | unsigned long flags; | ||
846 | struct scsi_cmnd *scmd; | ||
847 | |||
848 | spin_lock_irqsave(&ioc->scsi_lookup_lock, flags); | ||
849 | scmd = ioc->scsi_lookup[smid - 1].scmd; | ||
850 | ioc->scsi_lookup[smid - 1].scmd = NULL; | ||
851 | spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags); | ||
852 | |||
853 | return scmd; | ||
854 | } | ||
855 | |||
856 | /** | ||
835 | * _scsih_scsi_lookup_find_by_scmd - scmd lookup | 857 | * _scsih_scsi_lookup_find_by_scmd - scmd lookup |
836 | * @ioc: per adapter object | 858 | * @ioc: per adapter object |
837 | * @smid: system request message index | 859 | * @smid: system request message index |
@@ -2957,9 +2979,6 @@ _scsih_check_topo_delete_events(struct MPT2SAS_ADAPTER *ioc, | |||
2957 | u16 handle; | 2979 | u16 handle; |
2958 | 2980 | ||
2959 | for (i = 0 ; i < event_data->NumEntries; i++) { | 2981 | for (i = 0 ; i < event_data->NumEntries; i++) { |
2960 | if (event_data->PHY[i].PhyStatus & | ||
2961 | MPI2_EVENT_SAS_TOPO_PHYSTATUS_VACANT) | ||
2962 | continue; | ||
2963 | handle = le16_to_cpu(event_data->PHY[i].AttachedDevHandle); | 2982 | handle = le16_to_cpu(event_data->PHY[i].AttachedDevHandle); |
2964 | if (!handle) | 2983 | if (!handle) |
2965 | continue; | 2984 | continue; |
@@ -3186,7 +3205,7 @@ _scsih_flush_running_cmds(struct MPT2SAS_ADAPTER *ioc) | |||
3186 | u16 count = 0; | 3205 | u16 count = 0; |
3187 | 3206 | ||
3188 | for (smid = 1; smid <= ioc->scsiio_depth; smid++) { | 3207 | for (smid = 1; smid <= ioc->scsiio_depth; smid++) { |
3189 | scmd = _scsih_scsi_lookup_get(ioc, smid); | 3208 | scmd = _scsih_scsi_lookup_get_clear(ioc, smid); |
3190 | if (!scmd) | 3209 | if (!scmd) |
3191 | continue; | 3210 | continue; |
3192 | count++; | 3211 | count++; |
@@ -3778,7 +3797,7 @@ _scsih_io_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index, u32 reply) | |||
3778 | u32 response_code = 0; | 3797 | u32 response_code = 0; |
3779 | 3798 | ||
3780 | mpi_reply = mpt2sas_base_get_reply_virt_addr(ioc, reply); | 3799 | mpi_reply = mpt2sas_base_get_reply_virt_addr(ioc, reply); |
3781 | scmd = _scsih_scsi_lookup_get(ioc, smid); | 3800 | scmd = _scsih_scsi_lookup_get_clear(ioc, smid); |
3782 | if (scmd == NULL) | 3801 | if (scmd == NULL) |
3783 | return 1; | 3802 | return 1; |
3784 | 3803 | ||
@@ -4940,6 +4959,12 @@ _scsih_sas_device_status_change_event(struct MPT2SAS_ADAPTER *ioc, | |||
4940 | event_data); | 4959 | event_data); |
4941 | #endif | 4960 | #endif |
4942 | 4961 | ||
4962 | /* In MPI Revision K (0xC), the internal device reset complete was | ||
4963 | * implemented, so avoid setting tm_busy flag for older firmware. | ||
4964 | */ | ||
4965 | if ((ioc->facts.HeaderVersion >> 8) < 0xC) | ||
4966 | return; | ||
4967 | |||
4943 | if (event_data->ReasonCode != | 4968 | if (event_data->ReasonCode != |
4944 | MPI2_EVENT_SAS_DEV_STAT_RC_INTERNAL_DEVICE_RESET && | 4969 | MPI2_EVENT_SAS_DEV_STAT_RC_INTERNAL_DEVICE_RESET && |
4945 | event_data->ReasonCode != | 4970 | event_data->ReasonCode != |
@@ -5034,6 +5059,7 @@ _scsih_sas_broadcast_primative_event(struct MPT2SAS_ADAPTER *ioc, | |||
5034 | struct fw_event_work *fw_event) | 5059 | struct fw_event_work *fw_event) |
5035 | { | 5060 | { |
5036 | struct scsi_cmnd *scmd; | 5061 | struct scsi_cmnd *scmd; |
5062 | struct scsi_device *sdev; | ||
5037 | u16 smid, handle; | 5063 | u16 smid, handle; |
5038 | u32 lun; | 5064 | u32 lun; |
5039 | struct MPT2SAS_DEVICE *sas_device_priv_data; | 5065 | struct MPT2SAS_DEVICE *sas_device_priv_data; |
@@ -5044,12 +5070,17 @@ _scsih_sas_broadcast_primative_event(struct MPT2SAS_ADAPTER *ioc, | |||
5044 | Mpi2EventDataSasBroadcastPrimitive_t *event_data = fw_event->event_data; | 5070 | Mpi2EventDataSasBroadcastPrimitive_t *event_data = fw_event->event_data; |
5045 | #endif | 5071 | #endif |
5046 | u16 ioc_status; | 5072 | u16 ioc_status; |
5073 | unsigned long flags; | ||
5074 | int r; | ||
5075 | |||
5047 | dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "broadcast primative: " | 5076 | dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "broadcast primative: " |
5048 | "phy number(%d), width(%d)\n", ioc->name, event_data->PhyNum, | 5077 | "phy number(%d), width(%d)\n", ioc->name, event_data->PhyNum, |
5049 | event_data->PortWidth)); | 5078 | event_data->PortWidth)); |
5050 | dtmprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: enter\n", ioc->name, | 5079 | dtmprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: enter\n", ioc->name, |
5051 | __func__)); | 5080 | __func__)); |
5052 | 5081 | ||
5082 | spin_lock_irqsave(&ioc->scsi_lookup_lock, flags); | ||
5083 | ioc->broadcast_aen_busy = 0; | ||
5053 | termination_count = 0; | 5084 | termination_count = 0; |
5054 | query_count = 0; | 5085 | query_count = 0; |
5055 | mpi_reply = ioc->tm_cmds.reply; | 5086 | mpi_reply = ioc->tm_cmds.reply; |
@@ -5057,7 +5088,8 @@ _scsih_sas_broadcast_primative_event(struct MPT2SAS_ADAPTER *ioc, | |||
5057 | scmd = _scsih_scsi_lookup_get(ioc, smid); | 5088 | scmd = _scsih_scsi_lookup_get(ioc, smid); |
5058 | if (!scmd) | 5089 | if (!scmd) |
5059 | continue; | 5090 | continue; |
5060 | sas_device_priv_data = scmd->device->hostdata; | 5091 | sdev = scmd->device; |
5092 | sas_device_priv_data = sdev->hostdata; | ||
5061 | if (!sas_device_priv_data || !sas_device_priv_data->sas_target) | 5093 | if (!sas_device_priv_data || !sas_device_priv_data->sas_target) |
5062 | continue; | 5094 | continue; |
5063 | /* skip hidden raid components */ | 5095 | /* skip hidden raid components */ |
@@ -5073,6 +5105,7 @@ _scsih_sas_broadcast_primative_event(struct MPT2SAS_ADAPTER *ioc, | |||
5073 | lun = sas_device_priv_data->lun; | 5105 | lun = sas_device_priv_data->lun; |
5074 | query_count++; | 5106 | query_count++; |
5075 | 5107 | ||
5108 | spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags); | ||
5076 | mpt2sas_scsih_issue_tm(ioc, handle, 0, 0, lun, | 5109 | mpt2sas_scsih_issue_tm(ioc, handle, 0, 0, lun, |
5077 | MPI2_SCSITASKMGMT_TASKTYPE_QUERY_TASK, smid, 30, NULL); | 5110 | MPI2_SCSITASKMGMT_TASKTYPE_QUERY_TASK, smid, 30, NULL); |
5078 | ioc->tm_cmds.status = MPT2_CMD_NOT_USED; | 5111 | ioc->tm_cmds.status = MPT2_CMD_NOT_USED; |
@@ -5082,14 +5115,20 @@ _scsih_sas_broadcast_primative_event(struct MPT2SAS_ADAPTER *ioc, | |||
5082 | (mpi_reply->ResponseCode == | 5115 | (mpi_reply->ResponseCode == |
5083 | MPI2_SCSITASKMGMT_RSP_TM_SUCCEEDED || | 5116 | MPI2_SCSITASKMGMT_RSP_TM_SUCCEEDED || |
5084 | mpi_reply->ResponseCode == | 5117 | mpi_reply->ResponseCode == |
5085 | MPI2_SCSITASKMGMT_RSP_IO_QUEUED_ON_IOC)) | 5118 | MPI2_SCSITASKMGMT_RSP_IO_QUEUED_ON_IOC)) { |
5119 | spin_lock_irqsave(&ioc->scsi_lookup_lock, flags); | ||
5086 | continue; | 5120 | continue; |
5087 | 5121 | } | |
5088 | mpt2sas_scsih_issue_tm(ioc, handle, 0, 0, lun, | 5122 | r = mpt2sas_scsih_issue_tm(ioc, handle, sdev->channel, sdev->id, |
5089 | MPI2_SCSITASKMGMT_TASKTYPE_ABRT_TASK_SET, 0, 30, NULL); | 5123 | sdev->lun, MPI2_SCSITASKMGMT_TASKTYPE_ABORT_TASK, smid, 30, |
5124 | scmd); | ||
5125 | if (r == FAILED) | ||
5126 | sdev_printk(KERN_WARNING, sdev, "task abort: FAILED " | ||
5127 | "scmd(%p)\n", scmd); | ||
5090 | termination_count += le32_to_cpu(mpi_reply->TerminationCount); | 5128 | termination_count += le32_to_cpu(mpi_reply->TerminationCount); |
5129 | spin_lock_irqsave(&ioc->scsi_lookup_lock, flags); | ||
5091 | } | 5130 | } |
5092 | ioc->broadcast_aen_busy = 0; | 5131 | spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags); |
5093 | 5132 | ||
5094 | dtmprintk(ioc, printk(MPT2SAS_INFO_FMT | 5133 | dtmprintk(ioc, printk(MPT2SAS_INFO_FMT |
5095 | "%s - exit, query_count = %d termination_count = %d\n", | 5134 | "%s - exit, query_count = %d termination_count = %d\n", |
@@ -6685,6 +6724,7 @@ _scsih_remove(struct pci_dev *pdev) | |||
6685 | destroy_workqueue(wq); | 6724 | destroy_workqueue(wq); |
6686 | 6725 | ||
6687 | /* release all the volumes */ | 6726 | /* release all the volumes */ |
6727 | _scsih_ir_shutdown(ioc); | ||
6688 | list_for_each_entry_safe(raid_device, next, &ioc->raid_device_list, | 6728 | list_for_each_entry_safe(raid_device, next, &ioc->raid_device_list, |
6689 | list) { | 6729 | list) { |
6690 | if (raid_device->starget) { | 6730 | if (raid_device->starget) { |