aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBrian King <brking@linux.vnet.ibm.com>2015-03-26 12:23:52 -0400
committerJames Bottomley <JBottomley@Odin.com>2015-04-09 16:43:14 -0400
commit2796ca5e51737ed0be8ebb6cf73fd56af05da0a7 (patch)
tree6b6ae274bf930a91025b0b1e18200b8a73ecf310
parent4fdd7c7aabbec3aa9e5dc41c129bc9f6aed7e615 (diff)
ipr: Reset in task context
The pci_set_pcie_reset_state has changed semantics to not be callable from interrupt context, so change ipr's usage of the API to comply with this change by ensuring this occurs from a workqueue. Signed-off-by: Brian King <brking@linux.vnet.ibm.com> Reviewed-by: Wen Xiong <wenxiong@linux.vnet.ibm.com> Reviewed-by: Daniel Kreling <kreling@linux.vnet.ibm.com> Signed-off-by: James Bottomley <JBottomley@Odin.com>
-rw-r--r--drivers/scsi/ipr.c91
-rw-r--r--drivers/scsi/ipr.h2
2 files changed, 67 insertions, 26 deletions
diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c
index 190d0ae0193f..200110caae17 100644
--- a/drivers/scsi/ipr.c
+++ b/drivers/scsi/ipr.c
@@ -8319,7 +8319,6 @@ static int ipr_reset_start_bist(struct ipr_cmnd *ipr_cmd)
8319static int ipr_reset_slot_reset_done(struct ipr_cmnd *ipr_cmd) 8319static int ipr_reset_slot_reset_done(struct ipr_cmnd *ipr_cmd)
8320{ 8320{
8321 ENTER; 8321 ENTER;
8322 pci_set_pcie_reset_state(ipr_cmd->ioa_cfg->pdev, pcie_deassert_reset);
8323 ipr_cmd->job_step = ipr_reset_bist_done; 8322 ipr_cmd->job_step = ipr_reset_bist_done;
8324 ipr_reset_start_timer(ipr_cmd, IPR_WAIT_FOR_BIST_TIMEOUT); 8323 ipr_reset_start_timer(ipr_cmd, IPR_WAIT_FOR_BIST_TIMEOUT);
8325 LEAVE; 8324 LEAVE;
@@ -8327,6 +8326,32 @@ static int ipr_reset_slot_reset_done(struct ipr_cmnd *ipr_cmd)
8327} 8326}
8328 8327
8329/** 8328/**
8329 * ipr_reset_reset_work - Pulse a PCIe fundamental reset
8330 * @work: work struct
8331 *
8332 * Description: This pulses warm reset to a slot.
8333 *
8334 **/
8335static void ipr_reset_reset_work(struct work_struct *work)
8336{
8337 struct ipr_cmnd *ipr_cmd = container_of(work, struct ipr_cmnd, work);
8338 struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg;
8339 struct pci_dev *pdev = ioa_cfg->pdev;
8340 unsigned long lock_flags = 0;
8341
8342 ENTER;
8343 pci_set_pcie_reset_state(pdev, pcie_warm_reset);
8344 msleep(jiffies_to_msecs(IPR_PCI_RESET_TIMEOUT));
8345 pci_set_pcie_reset_state(pdev, pcie_deassert_reset);
8346
8347 spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags);
8348 if (ioa_cfg->reset_cmd == ipr_cmd)
8349 ipr_reset_ioa_job(ipr_cmd);
8350 spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags);
8351 LEAVE;
8352}
8353
8354/**
8330 * ipr_reset_slot_reset - Reset the PCI slot of the adapter. 8355 * ipr_reset_slot_reset - Reset the PCI slot of the adapter.
8331 * @ipr_cmd: ipr command struct 8356 * @ipr_cmd: ipr command struct
8332 * 8357 *
@@ -8338,12 +8363,11 @@ static int ipr_reset_slot_reset_done(struct ipr_cmnd *ipr_cmd)
8338static int ipr_reset_slot_reset(struct ipr_cmnd *ipr_cmd) 8363static int ipr_reset_slot_reset(struct ipr_cmnd *ipr_cmd)
8339{ 8364{
8340 struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg; 8365 struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg;
8341 struct pci_dev *pdev = ioa_cfg->pdev;
8342 8366
8343 ENTER; 8367 ENTER;
8344 pci_set_pcie_reset_state(pdev, pcie_warm_reset); 8368 INIT_WORK(&ipr_cmd->work, ipr_reset_reset_work);
8369 queue_work(ioa_cfg->reset_work_q, &ipr_cmd->work);
8345 ipr_cmd->job_step = ipr_reset_slot_reset_done; 8370 ipr_cmd->job_step = ipr_reset_slot_reset_done;
8346 ipr_reset_start_timer(ipr_cmd, IPR_PCI_RESET_TIMEOUT);
8347 LEAVE; 8371 LEAVE;
8348 return IPR_RC_JOB_RETURN; 8372 return IPR_RC_JOB_RETURN;
8349} 8373}
@@ -9092,26 +9116,25 @@ static void ipr_free_mem(struct ipr_ioa_cfg *ioa_cfg)
9092} 9116}
9093 9117
9094/** 9118/**
9095 * ipr_free_all_resources - Free all allocated resources for an adapter. 9119 * ipr_free_irqs - Free all allocated IRQs for the adapter.
9096 * @ipr_cmd: ipr command struct 9120 * @ioa_cfg: ipr cfg struct
9097 * 9121 *
9098 * This function frees all allocated resources for the 9122 * This function frees all allocated IRQs for the
9099 * specified adapter. 9123 * specified adapter.
9100 * 9124 *
9101 * Return value: 9125 * Return value:
9102 * none 9126 * none
9103 **/ 9127 **/
9104static void ipr_free_all_resources(struct ipr_ioa_cfg *ioa_cfg) 9128static void ipr_free_irqs(struct ipr_ioa_cfg *ioa_cfg)
9105{ 9129{
9106 struct pci_dev *pdev = ioa_cfg->pdev; 9130 struct pci_dev *pdev = ioa_cfg->pdev;
9107 9131
9108 ENTER;
9109 if (ioa_cfg->intr_flag == IPR_USE_MSI || 9132 if (ioa_cfg->intr_flag == IPR_USE_MSI ||
9110 ioa_cfg->intr_flag == IPR_USE_MSIX) { 9133 ioa_cfg->intr_flag == IPR_USE_MSIX) {
9111 int i; 9134 int i;
9112 for (i = 0; i < ioa_cfg->nvectors; i++) 9135 for (i = 0; i < ioa_cfg->nvectors; i++)
9113 free_irq(ioa_cfg->vectors_info[i].vec, 9136 free_irq(ioa_cfg->vectors_info[i].vec,
9114 &ioa_cfg->hrrq[i]); 9137 &ioa_cfg->hrrq[i]);
9115 } else 9138 } else
9116 free_irq(pdev->irq, &ioa_cfg->hrrq[0]); 9139 free_irq(pdev->irq, &ioa_cfg->hrrq[0]);
9117 9140
@@ -9122,7 +9145,26 @@ static void ipr_free_all_resources(struct ipr_ioa_cfg *ioa_cfg)
9122 pci_disable_msix(pdev); 9145 pci_disable_msix(pdev);
9123 ioa_cfg->intr_flag &= ~IPR_USE_MSIX; 9146 ioa_cfg->intr_flag &= ~IPR_USE_MSIX;
9124 } 9147 }
9148}
9149
9150/**
9151 * ipr_free_all_resources - Free all allocated resources for an adapter.
9152 * @ipr_cmd: ipr command struct
9153 *
9154 * This function frees all allocated resources for the
9155 * specified adapter.
9156 *
9157 * Return value:
9158 * none
9159 **/
9160static void ipr_free_all_resources(struct ipr_ioa_cfg *ioa_cfg)
9161{
9162 struct pci_dev *pdev = ioa_cfg->pdev;
9125 9163
9164 ENTER;
9165 ipr_free_irqs(ioa_cfg);
9166 if (ioa_cfg->reset_work_q)
9167 destroy_workqueue(ioa_cfg->reset_work_q);
9126 iounmap(ioa_cfg->hdw_dma_regs); 9168 iounmap(ioa_cfg->hdw_dma_regs);
9127 pci_release_regions(pdev); 9169 pci_release_regions(pdev);
9128 ipr_free_mem(ioa_cfg); 9170 ipr_free_mem(ioa_cfg);
@@ -9942,6 +9984,14 @@ static int ipr_probe_ioa(struct pci_dev *pdev,
9942 (dev_id->device == PCI_DEVICE_ID_IBM_OBSIDIAN_E && !ioa_cfg->revid)) { 9984 (dev_id->device == PCI_DEVICE_ID_IBM_OBSIDIAN_E && !ioa_cfg->revid)) {
9943 ioa_cfg->needs_warm_reset = 1; 9985 ioa_cfg->needs_warm_reset = 1;
9944 ioa_cfg->reset = ipr_reset_slot_reset; 9986 ioa_cfg->reset = ipr_reset_slot_reset;
9987
9988 ioa_cfg->reset_work_q = alloc_ordered_workqueue("ipr_reset_%d",
9989 WQ_MEM_RECLAIM, host->host_no);
9990
9991 if (!ioa_cfg->reset_work_q) {
9992 dev_err(&pdev->dev, "Couldn't register reset workqueue\n");
9993 goto out_free_irq;
9994 }
9945 } else 9995 } else
9946 ioa_cfg->reset = ipr_reset_start_bist; 9996 ioa_cfg->reset = ipr_reset_start_bist;
9947 9997
@@ -9953,6 +10003,8 @@ static int ipr_probe_ioa(struct pci_dev *pdev,
9953out: 10003out:
9954 return rc; 10004 return rc;
9955 10005
10006out_free_irq:
10007 ipr_free_irqs(ioa_cfg);
9956cleanup_nolog: 10008cleanup_nolog:
9957 ipr_free_mem(ioa_cfg); 10009 ipr_free_mem(ioa_cfg);
9958out_msi_disable: 10010out_msi_disable:
@@ -10033,6 +10085,8 @@ static void __ipr_remove(struct pci_dev *pdev)
10033 spin_unlock_irqrestore(ioa_cfg->host->host_lock, host_lock_flags); 10085 spin_unlock_irqrestore(ioa_cfg->host->host_lock, host_lock_flags);
10034 wait_event(ioa_cfg->reset_wait_q, !ioa_cfg->in_reset_reload); 10086 wait_event(ioa_cfg->reset_wait_q, !ioa_cfg->in_reset_reload);
10035 flush_work(&ioa_cfg->work_q); 10087 flush_work(&ioa_cfg->work_q);
10088 if (ioa_cfg->reset_work_q)
10089 flush_workqueue(ioa_cfg->reset_work_q);
10036 INIT_LIST_HEAD(&ioa_cfg->used_res_q); 10090 INIT_LIST_HEAD(&ioa_cfg->used_res_q);
10037 spin_lock_irqsave(ioa_cfg->host->host_lock, host_lock_flags); 10091 spin_lock_irqsave(ioa_cfg->host->host_lock, host_lock_flags);
10038 10092
@@ -10178,22 +10232,7 @@ static void ipr_shutdown(struct pci_dev *pdev)
10178 spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); 10232 spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags);
10179 wait_event(ioa_cfg->reset_wait_q, !ioa_cfg->in_reset_reload); 10233 wait_event(ioa_cfg->reset_wait_q, !ioa_cfg->in_reset_reload);
10180 if (ipr_fast_reboot && system_state == SYSTEM_RESTART && ioa_cfg->sis64) { 10234 if (ipr_fast_reboot && system_state == SYSTEM_RESTART && ioa_cfg->sis64) {
10181 if (ioa_cfg->intr_flag == IPR_USE_MSI || 10235 ipr_free_irqs(ioa_cfg);
10182 ioa_cfg->intr_flag == IPR_USE_MSIX) {
10183 int i;
10184 for (i = 0; i < ioa_cfg->nvectors; i++)
10185 free_irq(ioa_cfg->vectors_info[i].vec,
10186 &ioa_cfg->hrrq[i]);
10187 }
10188
10189 if (ioa_cfg->intr_flag == IPR_USE_MSI) {
10190 pci_disable_msi(ioa_cfg->pdev);
10191 ioa_cfg->intr_flag &= ~IPR_USE_MSI;
10192 } else if (ioa_cfg->intr_flag == IPR_USE_MSIX) {
10193 pci_disable_msix(ioa_cfg->pdev);
10194 ioa_cfg->intr_flag &= ~IPR_USE_MSIX;
10195 }
10196
10197 pci_disable_device(ioa_cfg->pdev); 10236 pci_disable_device(ioa_cfg->pdev);
10198 } 10237 }
10199} 10238}
diff --git a/drivers/scsi/ipr.h b/drivers/scsi/ipr.h
index 34eec5bcdce0..f7d0e375e4f6 100644
--- a/drivers/scsi/ipr.h
+++ b/drivers/scsi/ipr.h
@@ -1540,6 +1540,7 @@ struct ipr_ioa_cfg {
1540 u8 saved_mode_page_len; 1540 u8 saved_mode_page_len;
1541 1541
1542 struct work_struct work_q; 1542 struct work_struct work_q;
1543 struct workqueue_struct *reset_work_q;
1543 1544
1544 wait_queue_head_t reset_wait_q; 1545 wait_queue_head_t reset_wait_q;
1545 wait_queue_head_t msi_wait_q; 1546 wait_queue_head_t msi_wait_q;
@@ -1591,6 +1592,7 @@ struct ipr_cmnd {
1591 struct ata_queued_cmd *qc; 1592 struct ata_queued_cmd *qc;
1592 struct completion completion; 1593 struct completion completion;
1593 struct timer_list timer; 1594 struct timer_list timer;
1595 struct work_struct work;
1594 void (*fast_done) (struct ipr_cmnd *); 1596 void (*fast_done) (struct ipr_cmnd *);
1595 void (*done) (struct ipr_cmnd *); 1597 void (*done) (struct ipr_cmnd *);
1596 int (*job_step) (struct ipr_cmnd *); 1598 int (*job_step) (struct ipr_cmnd *);