diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-10-02 22:01:32 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-10-02 22:01:32 -0400 |
commit | 3151367f8778a1789d6f6e6f6c642681b6cd6d64 (patch) | |
tree | 1869d5429a25abd994ae94079808b8db060ec6f3 /drivers/scsi/isci | |
parent | 16642a2e7be23bbda013fc32d8f6c68982eab603 (diff) | |
parent | fe709ed827d370e6b0c0a9f9456da1c22bdcd118 (diff) |
Merge tag 'scsi-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi
Pull first round of SCSI updates from James Bottomley:
"This is a large set of updates, mostly for drivers (qla2xxx [including
support for new 83xx based card], qla4xxx, mpt2sas, bfa, zfcp, hpsa,
be2iscsi, isci, lpfc, ipr, ibmvfc, ibmvscsi, megaraid_sas).
There's also a rework for tape adding virtually unlimited numbers of
tape drives plus a set of dif fixes for sd and a fix for a live lock
on hot remove of SCSI devices.
This round includes a signed tag pull of isci-for-3.6
Signed-off-by: James Bottomley <JBottomley@Parallels.com>"
Fix up trivial conflict in drivers/scsi/qla2xxx/qla_nx.c due to new PCI
helper function use in a function that was removed by this pull.
* tag 'scsi-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi: (198 commits)
[SCSI] st: remove st_mutex
[SCSI] sd: Ensure we correctly disable devices with unknown protection type
[SCSI] hpsa: gen8plus Smart Array IDs
[SCSI] qla4xxx: Update driver version to 5.03.00-k1
[SCSI] qla4xxx: Disable generating pause frames for ISP83XX
[SCSI] qla4xxx: Fix double clearing of risc_intr for ISP83XX
[SCSI] qla4xxx: IDC implementation for Loopback
[SCSI] qla4xxx: update copyrights in LICENSE.qla4xxx
[SCSI] qla4xxx: Fix panic while rmmod
[SCSI] qla4xxx: Fail probe_adapter if IRQ allocation fails
[SCSI] qla4xxx: Prevent MSI/MSI-X falling back to INTx for ISP82XX
[SCSI] qla4xxx: Update idc reg in case of PCI AER
[SCSI] qla4xxx: Fix double IDC locking in qla4_8xxx_error_recovery
[SCSI] qla4xxx: Clear interrupt while unloading driver for ISP83XX
[SCSI] qla4xxx: Print correct IDC version
[SCSI] qla4xxx: Added new mbox cmd to pass driver version to FW
[SCSI] scsi_dh_alua: Enable STPG for unavailable ports
[SCSI] scsi_remove_target: fix softlockup regression on hot remove
[SCSI] ibmvscsi: Fix host config length field overflow
[SCSI] ibmvscsi: Remove backend abstraction
...
Diffstat (limited to 'drivers/scsi/isci')
-rw-r--r-- | drivers/scsi/isci/host.c | 24 | ||||
-rw-r--r-- | drivers/scsi/isci/host.h | 2 | ||||
-rw-r--r-- | drivers/scsi/isci/init.c | 59 | ||||
-rw-r--r-- | drivers/scsi/isci/phy.c | 4 | ||||
-rw-r--r-- | drivers/scsi/isci/probe_roms.c | 1 | ||||
-rw-r--r-- | drivers/scsi/isci/remote_node_context.h | 2 |
6 files changed, 78 insertions, 14 deletions
diff --git a/drivers/scsi/isci/host.c b/drivers/scsi/isci/host.c index b334fdc1726..609dafd661d 100644 --- a/drivers/scsi/isci/host.c +++ b/drivers/scsi/isci/host.c | |||
@@ -1044,7 +1044,7 @@ static enum sci_status sci_controller_start(struct isci_host *ihost, | |||
1044 | return SCI_SUCCESS; | 1044 | return SCI_SUCCESS; |
1045 | } | 1045 | } |
1046 | 1046 | ||
1047 | void isci_host_scan_start(struct Scsi_Host *shost) | 1047 | void isci_host_start(struct Scsi_Host *shost) |
1048 | { | 1048 | { |
1049 | struct isci_host *ihost = SHOST_TO_SAS_HA(shost)->lldd_ha; | 1049 | struct isci_host *ihost = SHOST_TO_SAS_HA(shost)->lldd_ha; |
1050 | unsigned long tmo = sci_controller_get_suggested_start_timeout(ihost); | 1050 | unsigned long tmo = sci_controller_get_suggested_start_timeout(ihost); |
@@ -1079,7 +1079,6 @@ static void sci_controller_completion_handler(struct isci_host *ihost) | |||
1079 | 1079 | ||
1080 | void ireq_done(struct isci_host *ihost, struct isci_request *ireq, struct sas_task *task) | 1080 | void ireq_done(struct isci_host *ihost, struct isci_request *ireq, struct sas_task *task) |
1081 | { | 1081 | { |
1082 | task->lldd_task = NULL; | ||
1083 | if (!test_bit(IREQ_ABORT_PATH_ACTIVE, &ireq->flags) && | 1082 | if (!test_bit(IREQ_ABORT_PATH_ACTIVE, &ireq->flags) && |
1084 | !(task->task_state_flags & SAS_TASK_STATE_ABORTED)) { | 1083 | !(task->task_state_flags & SAS_TASK_STATE_ABORTED)) { |
1085 | if (test_bit(IREQ_COMPLETE_IN_TARGET, &ireq->flags)) { | 1084 | if (test_bit(IREQ_COMPLETE_IN_TARGET, &ireq->flags)) { |
@@ -1087,16 +1086,19 @@ void ireq_done(struct isci_host *ihost, struct isci_request *ireq, struct sas_ta | |||
1087 | dev_dbg(&ihost->pdev->dev, | 1086 | dev_dbg(&ihost->pdev->dev, |
1088 | "%s: Normal - ireq/task = %p/%p\n", | 1087 | "%s: Normal - ireq/task = %p/%p\n", |
1089 | __func__, ireq, task); | 1088 | __func__, ireq, task); |
1090 | 1089 | task->lldd_task = NULL; | |
1091 | task->task_done(task); | 1090 | task->task_done(task); |
1092 | } else { | 1091 | } else { |
1093 | dev_dbg(&ihost->pdev->dev, | 1092 | dev_dbg(&ihost->pdev->dev, |
1094 | "%s: Error - ireq/task = %p/%p\n", | 1093 | "%s: Error - ireq/task = %p/%p\n", |
1095 | __func__, ireq, task); | 1094 | __func__, ireq, task); |
1096 | 1095 | if (sas_protocol_ata(task->task_proto)) | |
1096 | task->lldd_task = NULL; | ||
1097 | sas_task_abort(task); | 1097 | sas_task_abort(task); |
1098 | } | 1098 | } |
1099 | } | 1099 | } else |
1100 | task->lldd_task = NULL; | ||
1101 | |||
1100 | if (test_and_clear_bit(IREQ_ABORT_PATH_ACTIVE, &ireq->flags)) | 1102 | if (test_and_clear_bit(IREQ_ABORT_PATH_ACTIVE, &ireq->flags)) |
1101 | wake_up_all(&ihost->eventq); | 1103 | wake_up_all(&ihost->eventq); |
1102 | 1104 | ||
@@ -1120,10 +1122,16 @@ void isci_host_completion_routine(unsigned long data) | |||
1120 | sci_controller_completion_handler(ihost); | 1122 | sci_controller_completion_handler(ihost); |
1121 | spin_unlock_irq(&ihost->scic_lock); | 1123 | spin_unlock_irq(&ihost->scic_lock); |
1122 | 1124 | ||
1123 | /* the coalesence timeout doubles at each encoding step, so | 1125 | /* |
1126 | * we subtract SCI_MAX_PORTS to account for the number of dummy TCs | ||
1127 | * issued for hardware issue workaround | ||
1128 | */ | ||
1129 | active = isci_tci_active(ihost) - SCI_MAX_PORTS; | ||
1130 | |||
1131 | /* | ||
1132 | * the coalesence timeout doubles at each encoding step, so | ||
1124 | * update it based on the ilog2 value of the outstanding requests | 1133 | * update it based on the ilog2 value of the outstanding requests |
1125 | */ | 1134 | */ |
1126 | active = isci_tci_active(ihost); | ||
1127 | writel(SMU_ICC_GEN_VAL(NUMBER, active) | | 1135 | writel(SMU_ICC_GEN_VAL(NUMBER, active) | |
1128 | SMU_ICC_GEN_VAL(TIMER, ISCI_COALESCE_BASE + ilog2(active)), | 1136 | SMU_ICC_GEN_VAL(TIMER, ISCI_COALESCE_BASE + ilog2(active)), |
1129 | &ihost->smu_registers->interrupt_coalesce_control); | 1137 | &ihost->smu_registers->interrupt_coalesce_control); |
@@ -1973,7 +1981,7 @@ static void sci_controller_afe_initialization(struct isci_host *ihost) | |||
1973 | } | 1981 | } |
1974 | 1982 | ||
1975 | for (phy_id = 0; phy_id < SCI_MAX_PHYS; phy_id++) { | 1983 | for (phy_id = 0; phy_id < SCI_MAX_PHYS; phy_id++) { |
1976 | struct scu_afe_transceiver *xcvr = &afe->scu_afe_xcvr[phy_id]; | 1984 | struct scu_afe_transceiver __iomem *xcvr = &afe->scu_afe_xcvr[phy_id]; |
1977 | const struct sci_phy_oem_params *oem_phy = &oem->phys[phy_id]; | 1985 | const struct sci_phy_oem_params *oem_phy = &oem->phys[phy_id]; |
1978 | int cable_length_long = | 1986 | int cable_length_long = |
1979 | is_long_cable(phy_id, cable_selection_mask); | 1987 | is_long_cable(phy_id, cable_selection_mask); |
diff --git a/drivers/scsi/isci/host.h b/drivers/scsi/isci/host.h index 9ab58e0540e..4911310a38f 100644 --- a/drivers/scsi/isci/host.h +++ b/drivers/scsi/isci/host.h | |||
@@ -473,7 +473,7 @@ void sci_controller_remote_device_stopped(struct isci_host *ihost, | |||
473 | 473 | ||
474 | enum sci_status sci_controller_continue_io(struct isci_request *ireq); | 474 | enum sci_status sci_controller_continue_io(struct isci_request *ireq); |
475 | int isci_host_scan_finished(struct Scsi_Host *, unsigned long); | 475 | int isci_host_scan_finished(struct Scsi_Host *, unsigned long); |
476 | void isci_host_scan_start(struct Scsi_Host *); | 476 | void isci_host_start(struct Scsi_Host *); |
477 | u16 isci_alloc_tag(struct isci_host *ihost); | 477 | u16 isci_alloc_tag(struct isci_host *ihost); |
478 | enum sci_status isci_free_tag(struct isci_host *ihost, u16 io_tag); | 478 | enum sci_status isci_free_tag(struct isci_host *ihost, u16 io_tag); |
479 | void isci_tci_free(struct isci_host *ihost, u16 tci); | 479 | void isci_tci_free(struct isci_host *ihost, u16 tci); |
diff --git a/drivers/scsi/isci/init.c b/drivers/scsi/isci/init.c index 9be45a2b223..b74050b95d6 100644 --- a/drivers/scsi/isci/init.c +++ b/drivers/scsi/isci/init.c | |||
@@ -156,7 +156,7 @@ static struct scsi_host_template isci_sht = { | |||
156 | .target_alloc = sas_target_alloc, | 156 | .target_alloc = sas_target_alloc, |
157 | .slave_configure = sas_slave_configure, | 157 | .slave_configure = sas_slave_configure, |
158 | .scan_finished = isci_host_scan_finished, | 158 | .scan_finished = isci_host_scan_finished, |
159 | .scan_start = isci_host_scan_start, | 159 | .scan_start = isci_host_start, |
160 | .change_queue_depth = sas_change_queue_depth, | 160 | .change_queue_depth = sas_change_queue_depth, |
161 | .change_queue_type = sas_change_queue_type, | 161 | .change_queue_type = sas_change_queue_type, |
162 | .bios_param = sas_bios_param, | 162 | .bios_param = sas_bios_param, |
@@ -644,7 +644,6 @@ static int __devinit isci_pci_probe(struct pci_dev *pdev, const struct pci_devic | |||
644 | orom->hdr.version)) { | 644 | orom->hdr.version)) { |
645 | dev_warn(&pdev->dev, | 645 | dev_warn(&pdev->dev, |
646 | "[%d]: invalid oem parameters detected, falling back to firmware\n", i); | 646 | "[%d]: invalid oem parameters detected, falling back to firmware\n", i); |
647 | devm_kfree(&pdev->dev, orom); | ||
648 | orom = NULL; | 647 | orom = NULL; |
649 | break; | 648 | break; |
650 | } | 649 | } |
@@ -722,11 +721,67 @@ static void __devexit isci_pci_remove(struct pci_dev *pdev) | |||
722 | } | 721 | } |
723 | } | 722 | } |
724 | 723 | ||
724 | #ifdef CONFIG_PM | ||
725 | static int isci_suspend(struct device *dev) | ||
726 | { | ||
727 | struct pci_dev *pdev = to_pci_dev(dev); | ||
728 | struct isci_host *ihost; | ||
729 | int i; | ||
730 | |||
731 | for_each_isci_host(i, ihost, pdev) { | ||
732 | sas_suspend_ha(&ihost->sas_ha); | ||
733 | isci_host_deinit(ihost); | ||
734 | } | ||
735 | |||
736 | pci_save_state(pdev); | ||
737 | pci_disable_device(pdev); | ||
738 | pci_set_power_state(pdev, PCI_D3hot); | ||
739 | |||
740 | return 0; | ||
741 | } | ||
742 | |||
743 | static int isci_resume(struct device *dev) | ||
744 | { | ||
745 | struct pci_dev *pdev = to_pci_dev(dev); | ||
746 | struct isci_host *ihost; | ||
747 | int rc, i; | ||
748 | |||
749 | pci_set_power_state(pdev, PCI_D0); | ||
750 | pci_restore_state(pdev); | ||
751 | |||
752 | rc = pcim_enable_device(pdev); | ||
753 | if (rc) { | ||
754 | dev_err(&pdev->dev, | ||
755 | "enabling device failure after resume(%d)\n", rc); | ||
756 | return rc; | ||
757 | } | ||
758 | |||
759 | pci_set_master(pdev); | ||
760 | |||
761 | for_each_isci_host(i, ihost, pdev) { | ||
762 | sas_prep_resume_ha(&ihost->sas_ha); | ||
763 | |||
764 | isci_host_init(ihost); | ||
765 | isci_host_start(ihost->sas_ha.core.shost); | ||
766 | wait_for_start(ihost); | ||
767 | |||
768 | sas_resume_ha(&ihost->sas_ha); | ||
769 | } | ||
770 | |||
771 | return 0; | ||
772 | } | ||
773 | |||
774 | static SIMPLE_DEV_PM_OPS(isci_pm_ops, isci_suspend, isci_resume); | ||
775 | #endif | ||
776 | |||
725 | static struct pci_driver isci_pci_driver = { | 777 | static struct pci_driver isci_pci_driver = { |
726 | .name = DRV_NAME, | 778 | .name = DRV_NAME, |
727 | .id_table = isci_id_table, | 779 | .id_table = isci_id_table, |
728 | .probe = isci_pci_probe, | 780 | .probe = isci_pci_probe, |
729 | .remove = __devexit_p(isci_pci_remove), | 781 | .remove = __devexit_p(isci_pci_remove), |
782 | #ifdef CONFIG_PM | ||
783 | .driver.pm = &isci_pm_ops, | ||
784 | #endif | ||
730 | }; | 785 | }; |
731 | 786 | ||
732 | static __init int isci_init(void) | 787 | static __init int isci_init(void) |
diff --git a/drivers/scsi/isci/phy.c b/drivers/scsi/isci/phy.c index 18f43d4c30b..cb87b2ef7c9 100644 --- a/drivers/scsi/isci/phy.c +++ b/drivers/scsi/isci/phy.c | |||
@@ -169,7 +169,7 @@ sci_phy_link_layer_initialization(struct isci_phy *iphy, | |||
169 | phy_cap.gen1_no_ssc = 1; | 169 | phy_cap.gen1_no_ssc = 1; |
170 | if (ihost->oem_parameters.controller.do_enable_ssc) { | 170 | if (ihost->oem_parameters.controller.do_enable_ssc) { |
171 | struct scu_afe_registers __iomem *afe = &ihost->scu_registers->afe; | 171 | struct scu_afe_registers __iomem *afe = &ihost->scu_registers->afe; |
172 | struct scu_afe_transceiver *xcvr = &afe->scu_afe_xcvr[phy_idx]; | 172 | struct scu_afe_transceiver __iomem *xcvr = &afe->scu_afe_xcvr[phy_idx]; |
173 | struct isci_pci_info *pci_info = to_pci_info(ihost->pdev); | 173 | struct isci_pci_info *pci_info = to_pci_info(ihost->pdev); |
174 | bool en_sas = false; | 174 | bool en_sas = false; |
175 | bool en_sata = false; | 175 | bool en_sata = false; |
@@ -1205,6 +1205,7 @@ static void scu_link_layer_start_oob(struct isci_phy *iphy) | |||
1205 | /** Reset OOB sequence - start */ | 1205 | /** Reset OOB sequence - start */ |
1206 | val = readl(&ll->phy_configuration); | 1206 | val = readl(&ll->phy_configuration); |
1207 | val &= ~(SCU_SAS_PCFG_GEN_BIT(OOB_RESET) | | 1207 | val &= ~(SCU_SAS_PCFG_GEN_BIT(OOB_RESET) | |
1208 | SCU_SAS_PCFG_GEN_BIT(OOB_ENABLE) | | ||
1208 | SCU_SAS_PCFG_GEN_BIT(HARD_RESET)); | 1209 | SCU_SAS_PCFG_GEN_BIT(HARD_RESET)); |
1209 | writel(val, &ll->phy_configuration); | 1210 | writel(val, &ll->phy_configuration); |
1210 | readl(&ll->phy_configuration); /* flush */ | 1211 | readl(&ll->phy_configuration); /* flush */ |
@@ -1236,6 +1237,7 @@ static void scu_link_layer_tx_hard_reset( | |||
1236 | * to the starting state. */ | 1237 | * to the starting state. */ |
1237 | phy_configuration_value = | 1238 | phy_configuration_value = |
1238 | readl(&iphy->link_layer_registers->phy_configuration); | 1239 | readl(&iphy->link_layer_registers->phy_configuration); |
1240 | phy_configuration_value &= ~(SCU_SAS_PCFG_GEN_BIT(OOB_ENABLE)); | ||
1239 | phy_configuration_value |= | 1241 | phy_configuration_value |= |
1240 | (SCU_SAS_PCFG_GEN_BIT(HARD_RESET) | | 1242 | (SCU_SAS_PCFG_GEN_BIT(HARD_RESET) | |
1241 | SCU_SAS_PCFG_GEN_BIT(OOB_RESET)); | 1243 | SCU_SAS_PCFG_GEN_BIT(OOB_RESET)); |
diff --git a/drivers/scsi/isci/probe_roms.c b/drivers/scsi/isci/probe_roms.c index 4d95654c3fd..8ac646e5edd 100644 --- a/drivers/scsi/isci/probe_roms.c +++ b/drivers/scsi/isci/probe_roms.c | |||
@@ -104,7 +104,6 @@ struct isci_orom *isci_request_oprom(struct pci_dev *pdev) | |||
104 | 104 | ||
105 | if (i >= len) { | 105 | if (i >= len) { |
106 | dev_err(&pdev->dev, "oprom parse error\n"); | 106 | dev_err(&pdev->dev, "oprom parse error\n"); |
107 | devm_kfree(&pdev->dev, rom); | ||
108 | rom = NULL; | 107 | rom = NULL; |
109 | } | 108 | } |
110 | pci_unmap_biosrom(oprom); | 109 | pci_unmap_biosrom(oprom); |
diff --git a/drivers/scsi/isci/remote_node_context.h b/drivers/scsi/isci/remote_node_context.h index a703b9ce0c2..c7ee81d0112 100644 --- a/drivers/scsi/isci/remote_node_context.h +++ b/drivers/scsi/isci/remote_node_context.h | |||
@@ -212,7 +212,7 @@ enum sci_status sci_remote_node_context_destruct(struct sci_remote_node_context | |||
212 | scics_sds_remote_node_context_callback callback, | 212 | scics_sds_remote_node_context_callback callback, |
213 | void *callback_parameter); | 213 | void *callback_parameter); |
214 | enum sci_status sci_remote_node_context_suspend(struct sci_remote_node_context *sci_rnc, | 214 | enum sci_status sci_remote_node_context_suspend(struct sci_remote_node_context *sci_rnc, |
215 | u32 suspend_type, | 215 | enum sci_remote_node_suspension_reasons reason, |
216 | u32 suspension_code); | 216 | u32 suspension_code); |
217 | enum sci_status sci_remote_node_context_resume(struct sci_remote_node_context *sci_rnc, | 217 | enum sci_status sci_remote_node_context_resume(struct sci_remote_node_context *sci_rnc, |
218 | scics_sds_remote_node_context_callback cb_fn, | 218 | scics_sds_remote_node_context_callback cb_fn, |