aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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 2bba5e55d7b..5890e5f92d8 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/**