diff options
author | Jeremy Erickson <jerickso@cs.unc.edu> | 2014-04-18 17:06:00 -0400 |
---|---|---|
committer | Jeremy Erickson <jerickso@cs.unc.edu> | 2014-04-18 17:06:00 -0400 |
commit | a215aa7b9ab3759c047201199fba64d3042d7f13 (patch) | |
tree | bca37493d9b2233450e6d3ffced1261d0e4f71fe /drivers/scsi/mpt2sas | |
parent | d31199a77ef606f1d06894385f1852181ba6136b (diff) |
Update 2.6.36 to 2.6.36.4wip-dissipation2-jerickso
Diffstat (limited to 'drivers/scsi/mpt2sas')
-rw-r--r-- | drivers/scsi/mpt2sas/mpt2sas_base.c | 24 | ||||
-rw-r--r-- | drivers/scsi/mpt2sas/mpt2sas_scsih.c | 64 |
2 files changed, 71 insertions, 17 deletions
diff --git a/drivers/scsi/mpt2sas/mpt2sas_base.c b/drivers/scsi/mpt2sas/mpt2sas_base.c index 57bcd5c9dcff..9e590265a020 100644 --- a/drivers/scsi/mpt2sas/mpt2sas_base.c +++ b/drivers/scsi/mpt2sas/mpt2sas_base.c | |||
@@ -2057,9 +2057,9 @@ _base_allocate_memory_pools(struct MPT2SAS_ADAPTER *ioc, int sleep_flag) | |||
2057 | /* adjust hba_queue_depth, reply_free_queue_depth, | 2057 | /* adjust hba_queue_depth, reply_free_queue_depth, |
2058 | * and queue_size | 2058 | * and queue_size |
2059 | */ | 2059 | */ |
2060 | ioc->hba_queue_depth -= queue_diff; | 2060 | ioc->hba_queue_depth -= (queue_diff / 2); |
2061 | ioc->reply_free_queue_depth -= queue_diff; | 2061 | ioc->reply_free_queue_depth -= (queue_diff / 2); |
2062 | queue_size -= queue_diff; | 2062 | queue_size = facts->MaxReplyDescriptorPostQueueDepth; |
2063 | } | 2063 | } |
2064 | ioc->reply_post_queue_depth = queue_size; | 2064 | ioc->reply_post_queue_depth = queue_size; |
2065 | 2065 | ||
@@ -3662,6 +3662,11 @@ mpt2sas_base_attach(struct MPT2SAS_ADAPTER *ioc) | |||
3662 | ioc->scsih_cmds.status = MPT2_CMD_NOT_USED; | 3662 | ioc->scsih_cmds.status = MPT2_CMD_NOT_USED; |
3663 | mutex_init(&ioc->scsih_cmds.mutex); | 3663 | mutex_init(&ioc->scsih_cmds.mutex); |
3664 | 3664 | ||
3665 | /* scsih internal command bits */ | ||
3666 | ioc->scsih_cmds.reply = kzalloc(ioc->reply_sz, GFP_KERNEL); | ||
3667 | ioc->scsih_cmds.status = MPT2_CMD_NOT_USED; | ||
3668 | mutex_init(&ioc->scsih_cmds.mutex); | ||
3669 | |||
3665 | /* task management internal command bits */ | 3670 | /* task management internal command bits */ |
3666 | ioc->tm_cmds.reply = kzalloc(ioc->reply_sz, GFP_KERNEL); | 3671 | ioc->tm_cmds.reply = kzalloc(ioc->reply_sz, GFP_KERNEL); |
3667 | ioc->tm_cmds.status = MPT2_CMD_NOT_USED; | 3672 | ioc->tm_cmds.status = MPT2_CMD_NOT_USED; |
@@ -3786,6 +3791,8 @@ mpt2sas_base_detach(struct MPT2SAS_ADAPTER *ioc) | |||
3786 | static void | 3791 | static void |
3787 | _base_reset_handler(struct MPT2SAS_ADAPTER *ioc, int reset_phase) | 3792 | _base_reset_handler(struct MPT2SAS_ADAPTER *ioc, int reset_phase) |
3788 | { | 3793 | { |
3794 | mpt2sas_scsih_reset_handler(ioc, reset_phase); | ||
3795 | mpt2sas_ctl_reset_handler(ioc, reset_phase); | ||
3789 | switch (reset_phase) { | 3796 | switch (reset_phase) { |
3790 | case MPT2_IOC_PRE_RESET: | 3797 | case MPT2_IOC_PRE_RESET: |
3791 | dtmprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: " | 3798 | dtmprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: " |
@@ -3816,8 +3823,6 @@ _base_reset_handler(struct MPT2SAS_ADAPTER *ioc, int reset_phase) | |||
3816 | "MPT2_IOC_DONE_RESET\n", ioc->name, __func__)); | 3823 | "MPT2_IOC_DONE_RESET\n", ioc->name, __func__)); |
3817 | break; | 3824 | break; |
3818 | } | 3825 | } |
3819 | mpt2sas_scsih_reset_handler(ioc, reset_phase); | ||
3820 | mpt2sas_ctl_reset_handler(ioc, reset_phase); | ||
3821 | } | 3826 | } |
3822 | 3827 | ||
3823 | /** | 3828 | /** |
@@ -3871,6 +3876,7 @@ mpt2sas_base_hard_reset_handler(struct MPT2SAS_ADAPTER *ioc, int sleep_flag, | |||
3871 | { | 3876 | { |
3872 | int r; | 3877 | int r; |
3873 | unsigned long flags; | 3878 | unsigned long flags; |
3879 | u8 pe_complete = ioc->wait_for_port_enable_to_complete; | ||
3874 | 3880 | ||
3875 | dtmprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: enter\n", ioc->name, | 3881 | dtmprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: enter\n", ioc->name, |
3876 | __func__)); | 3882 | __func__)); |
@@ -3913,6 +3919,14 @@ mpt2sas_base_hard_reset_handler(struct MPT2SAS_ADAPTER *ioc, int sleep_flag, | |||
3913 | if (r) | 3919 | if (r) |
3914 | goto out; | 3920 | goto out; |
3915 | _base_reset_handler(ioc, MPT2_IOC_AFTER_RESET); | 3921 | _base_reset_handler(ioc, MPT2_IOC_AFTER_RESET); |
3922 | |||
3923 | /* If this hard reset is called while port enable is active, then | ||
3924 | * there is no reason to call make_ioc_operational | ||
3925 | */ | ||
3926 | if (pe_complete) { | ||
3927 | r = -EFAULT; | ||
3928 | goto out; | ||
3929 | } | ||
3916 | r = _base_make_ioc_operational(ioc, sleep_flag); | 3930 | r = _base_make_ioc_operational(ioc, sleep_flag); |
3917 | if (!r) | 3931 | if (!r) |
3918 | _base_reset_handler(ioc, MPT2_IOC_DONE_RESET); | 3932 | _base_reset_handler(ioc, MPT2_IOC_DONE_RESET); |
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) { |