aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorLinas Vepstas <linas@austin.ibm.com>2006-02-03 17:52:42 -0500
committer <jejb@mulgrave.il.steeleye.com>2006-02-27 23:55:05 -0500
commitf8a88b19b9d4f59bd625b4852c1b1138a5cf89f3 (patch)
treeb57dab8bea1b8575da4e2922f798815b2ac979b5 /drivers
parent4f8d98abaf957691f9543b9b1b610d49aa0f662b (diff)
[SCSI] PCI Error Recovery: IPR SCSI device driver
Various PCI bus errors can be signaled by newer PCI controllers. This patch adds the PCI error recovery callbacks to the IPR SCSI device driver. The patch has been tested, and appears to work well. Signed-off-by: Linas Vepstas <linas@linas.org> Signed-off-by: Brian King <brking@us.ibm.com> Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/scsi/ipr.c109
1 files changed, 109 insertions, 0 deletions
diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c
index 2bba5e55d7bc..5890e5f92d82 100644
--- a/drivers/scsi/ipr.c
+++ b/drivers/scsi/ipr.c
@@ -5831,6 +5831,109 @@ static void ipr_initiate_ioa_reset(struct ipr_ioa_cfg *ioa_cfg,
5831} 5831}
5832 5832
5833/** 5833/**
5834 * ipr_reset_freeze - Hold off all I/O activity
5835 * @ipr_cmd: ipr command struct
5836 *
5837 * Description: If the PCI slot is frozen, hold off all I/O
5838 * activity; then, as soon as the slot is available again,
5839 * initiate an adapter reset.
5840 */
5841static int ipr_reset_freeze(struct ipr_cmnd *ipr_cmd)
5842{
5843 /* Disallow new interrupts, avoid loop */
5844 ipr_cmd->ioa_cfg->allow_interrupts = 0;
5845 list_add_tail(&ipr_cmd->queue, &ipr_cmd->ioa_cfg->pending_q);
5846 ipr_cmd->done = ipr_reset_ioa_job;
5847 return IPR_RC_JOB_RETURN;
5848}
5849
5850/**
5851 * ipr_pci_frozen - Called when slot has experienced a PCI bus error.
5852 * @pdev: PCI device struct
5853 *
5854 * Description: This routine is called to tell us that the PCI bus
5855 * is down. Can't do anything here, except put the device driver
5856 * into a holding pattern, waiting for the PCI bus to come back.
5857 */
5858static void ipr_pci_frozen(struct pci_dev *pdev)
5859{
5860 unsigned long flags = 0;
5861 struct ipr_ioa_cfg *ioa_cfg = pci_get_drvdata(pdev);
5862
5863 spin_lock_irqsave(ioa_cfg->host->host_lock, flags);
5864 _ipr_initiate_ioa_reset(ioa_cfg, ipr_reset_freeze, IPR_SHUTDOWN_NONE);
5865 spin_unlock_irqrestore(ioa_cfg->host->host_lock, flags);
5866}
5867
5868/**
5869 * ipr_pci_slot_reset - Called when PCI slot has been reset.
5870 * @pdev: PCI device struct
5871 *
5872 * Description: This routine is called by the pci error recovery
5873 * code after the PCI slot has been reset, just before we
5874 * should resume normal operations.
5875 */
5876static pci_ers_result_t ipr_pci_slot_reset(struct pci_dev *pdev)
5877{
5878 unsigned long flags = 0;
5879 struct ipr_ioa_cfg *ioa_cfg = pci_get_drvdata(pdev);
5880
5881 spin_lock_irqsave(ioa_cfg->host->host_lock, flags);
5882 _ipr_initiate_ioa_reset(ioa_cfg, ipr_reset_restore_cfg_space,
5883 IPR_SHUTDOWN_NONE);
5884 spin_unlock_irqrestore(ioa_cfg->host->host_lock, flags);
5885 return PCI_ERS_RESULT_RECOVERED;
5886}
5887
5888/**
5889 * ipr_pci_perm_failure - Called when PCI slot is dead for good.
5890 * @pdev: PCI device struct
5891 *
5892 * Description: This routine is called when the PCI bus has
5893 * permanently failed.
5894 */
5895static void ipr_pci_perm_failure(struct pci_dev *pdev)
5896{
5897 unsigned long flags = 0;
5898 struct ipr_ioa_cfg *ioa_cfg = pci_get_drvdata(pdev);
5899
5900 spin_lock_irqsave(ioa_cfg->host->host_lock, flags);
5901 if (ioa_cfg->sdt_state == WAIT_FOR_DUMP)
5902 ioa_cfg->sdt_state = ABORT_DUMP;
5903 ioa_cfg->reset_retries = IPR_NUM_RESET_RELOAD_RETRIES;
5904 ioa_cfg->in_ioa_bringdown = 1;
5905 ipr_initiate_ioa_reset(ioa_cfg, IPR_SHUTDOWN_NONE);
5906 spin_unlock_irqrestore(ioa_cfg->host->host_lock, flags);
5907}
5908
5909/**
5910 * ipr_pci_error_detected - Called when a PCI error is detected.
5911 * @pdev: PCI device struct
5912 * @state: PCI channel state
5913 *
5914 * Description: Called when a PCI error is detected.
5915 *
5916 * Return value:
5917 * PCI_ERS_RESULT_NEED_RESET or PCI_ERS_RESULT_DISCONNECT
5918 */
5919static pci_ers_result_t ipr_pci_error_detected(struct pci_dev *pdev,
5920 pci_channel_state_t state)
5921{
5922 switch (state) {
5923 case pci_channel_io_frozen:
5924 ipr_pci_frozen(pdev);
5925 return PCI_ERS_RESULT_NEED_RESET;
5926 case pci_channel_io_perm_failure:
5927 ipr_pci_perm_failure(pdev);
5928 return PCI_ERS_RESULT_DISCONNECT;
5929 break;
5930 default:
5931 break;
5932 }
5933 return PCI_ERS_RESULT_NEED_RESET;
5934}
5935
5936/**
5834 * ipr_probe_ioa_part2 - Initializes IOAs found in ipr_probe_ioa(..) 5937 * ipr_probe_ioa_part2 - Initializes IOAs found in ipr_probe_ioa(..)
5835 * @ioa_cfg: ioa cfg struct 5938 * @ioa_cfg: ioa cfg struct
5836 * 5939 *
@@ -6601,12 +6704,18 @@ static struct pci_device_id ipr_pci_table[] __devinitdata = {
6601}; 6704};
6602MODULE_DEVICE_TABLE(pci, ipr_pci_table); 6705MODULE_DEVICE_TABLE(pci, ipr_pci_table);
6603 6706
6707static struct pci_error_handlers ipr_err_handler = {
6708 .error_detected = ipr_pci_error_detected,
6709 .slot_reset = ipr_pci_slot_reset,
6710};
6711
6604static struct pci_driver ipr_driver = { 6712static struct pci_driver ipr_driver = {
6605 .name = IPR_NAME, 6713 .name = IPR_NAME,
6606 .id_table = ipr_pci_table, 6714 .id_table = ipr_pci_table,
6607 .probe = ipr_probe, 6715 .probe = ipr_probe,
6608 .remove = ipr_remove, 6716 .remove = ipr_remove,
6609 .shutdown = ipr_shutdown, 6717 .shutdown = ipr_shutdown,
6718 .err_handler = &ipr_err_handler,
6610}; 6719};
6611 6720
6612/** 6721/**