aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/ipr.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/ipr.c')
-rw-r--r--drivers/scsi/ipr.c67
1 files changed, 60 insertions, 7 deletions
diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c
index fd860d952b2..67b169b7a5b 100644
--- a/drivers/scsi/ipr.c
+++ b/drivers/scsi/ipr.c
@@ -7638,8 +7638,12 @@ static int ipr_reset_restore_cfg_space(struct ipr_cmnd *ipr_cmd)
7638 **/ 7638 **/
7639static int ipr_reset_bist_done(struct ipr_cmnd *ipr_cmd) 7639static int ipr_reset_bist_done(struct ipr_cmnd *ipr_cmd)
7640{ 7640{
7641 struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg;
7642
7641 ENTER; 7643 ENTER;
7642 pci_unblock_user_cfg_access(ipr_cmd->ioa_cfg->pdev); 7644 if (ioa_cfg->cfg_locked)
7645 pci_cfg_access_unlock(ioa_cfg->pdev);
7646 ioa_cfg->cfg_locked = 0;
7643 ipr_cmd->job_step = ipr_reset_restore_cfg_space; 7647 ipr_cmd->job_step = ipr_reset_restore_cfg_space;
7644 LEAVE; 7648 LEAVE;
7645 return IPR_RC_JOB_CONTINUE; 7649 return IPR_RC_JOB_CONTINUE;
@@ -7660,8 +7664,6 @@ static int ipr_reset_start_bist(struct ipr_cmnd *ipr_cmd)
7660 int rc = PCIBIOS_SUCCESSFUL; 7664 int rc = PCIBIOS_SUCCESSFUL;
7661 7665
7662 ENTER; 7666 ENTER;
7663 pci_block_user_cfg_access(ioa_cfg->pdev);
7664
7665 if (ioa_cfg->ipr_chip->bist_method == IPR_MMIO) 7667 if (ioa_cfg->ipr_chip->bist_method == IPR_MMIO)
7666 writel(IPR_UPROCI_SIS64_START_BIST, 7668 writel(IPR_UPROCI_SIS64_START_BIST,
7667 ioa_cfg->regs.set_uproc_interrupt_reg32); 7669 ioa_cfg->regs.set_uproc_interrupt_reg32);
@@ -7673,7 +7675,9 @@ static int ipr_reset_start_bist(struct ipr_cmnd *ipr_cmd)
7673 ipr_reset_start_timer(ipr_cmd, IPR_WAIT_FOR_BIST_TIMEOUT); 7675 ipr_reset_start_timer(ipr_cmd, IPR_WAIT_FOR_BIST_TIMEOUT);
7674 rc = IPR_RC_JOB_RETURN; 7676 rc = IPR_RC_JOB_RETURN;
7675 } else { 7677 } else {
7676 pci_unblock_user_cfg_access(ipr_cmd->ioa_cfg->pdev); 7678 if (ioa_cfg->cfg_locked)
7679 pci_cfg_access_unlock(ipr_cmd->ioa_cfg->pdev);
7680 ioa_cfg->cfg_locked = 0;
7677 ipr_cmd->s.ioasa.hdr.ioasc = cpu_to_be32(IPR_IOASC_PCI_ACCESS_ERROR); 7681 ipr_cmd->s.ioasa.hdr.ioasc = cpu_to_be32(IPR_IOASC_PCI_ACCESS_ERROR);
7678 rc = IPR_RC_JOB_CONTINUE; 7682 rc = IPR_RC_JOB_CONTINUE;
7679 } 7683 }
@@ -7716,7 +7720,6 @@ static int ipr_reset_slot_reset(struct ipr_cmnd *ipr_cmd)
7716 struct pci_dev *pdev = ioa_cfg->pdev; 7720 struct pci_dev *pdev = ioa_cfg->pdev;
7717 7721
7718 ENTER; 7722 ENTER;
7719 pci_block_user_cfg_access(pdev);
7720 pci_set_pcie_reset_state(pdev, pcie_warm_reset); 7723 pci_set_pcie_reset_state(pdev, pcie_warm_reset);
7721 ipr_cmd->job_step = ipr_reset_slot_reset_done; 7724 ipr_cmd->job_step = ipr_reset_slot_reset_done;
7722 ipr_reset_start_timer(ipr_cmd, IPR_PCI_RESET_TIMEOUT); 7725 ipr_reset_start_timer(ipr_cmd, IPR_PCI_RESET_TIMEOUT);
@@ -7725,6 +7728,56 @@ static int ipr_reset_slot_reset(struct ipr_cmnd *ipr_cmd)
7725} 7728}
7726 7729
7727/** 7730/**
7731 * ipr_reset_block_config_access_wait - Wait for permission to block config access
7732 * @ipr_cmd: ipr command struct
7733 *
7734 * Description: This attempts to block config access to the IOA.
7735 *
7736 * Return value:
7737 * IPR_RC_JOB_CONTINUE / IPR_RC_JOB_RETURN
7738 **/
7739static int ipr_reset_block_config_access_wait(struct ipr_cmnd *ipr_cmd)
7740{
7741 struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg;
7742 int rc = IPR_RC_JOB_CONTINUE;
7743
7744 if (pci_cfg_access_trylock(ioa_cfg->pdev)) {
7745 ioa_cfg->cfg_locked = 1;
7746 ipr_cmd->job_step = ioa_cfg->reset;
7747 } else {
7748 if (ipr_cmd->u.time_left) {
7749 rc = IPR_RC_JOB_RETURN;
7750 ipr_cmd->u.time_left -= IPR_CHECK_FOR_RESET_TIMEOUT;
7751 ipr_reset_start_timer(ipr_cmd,
7752 IPR_CHECK_FOR_RESET_TIMEOUT);
7753 } else {
7754 ipr_cmd->job_step = ioa_cfg->reset;
7755 dev_err(&ioa_cfg->pdev->dev,
7756 "Timed out waiting to lock config access. Resetting anyway.\n");
7757 }
7758 }
7759
7760 return rc;
7761}
7762
7763/**
7764 * ipr_reset_block_config_access - Block config access to the IOA
7765 * @ipr_cmd: ipr command struct
7766 *
7767 * Description: This attempts to block config access to the IOA
7768 *
7769 * Return value:
7770 * IPR_RC_JOB_CONTINUE
7771 **/
7772static int ipr_reset_block_config_access(struct ipr_cmnd *ipr_cmd)
7773{
7774 ipr_cmd->ioa_cfg->cfg_locked = 0;
7775 ipr_cmd->job_step = ipr_reset_block_config_access_wait;
7776 ipr_cmd->u.time_left = IPR_WAIT_FOR_RESET_TIMEOUT;
7777 return IPR_RC_JOB_CONTINUE;
7778}
7779
7780/**
7728 * ipr_reset_allowed - Query whether or not IOA can be reset 7781 * ipr_reset_allowed - Query whether or not IOA can be reset
7729 * @ioa_cfg: ioa config struct 7782 * @ioa_cfg: ioa config struct
7730 * 7783 *
@@ -7763,7 +7816,7 @@ static int ipr_reset_wait_to_start_bist(struct ipr_cmnd *ipr_cmd)
7763 ipr_cmd->u.time_left -= IPR_CHECK_FOR_RESET_TIMEOUT; 7816 ipr_cmd->u.time_left -= IPR_CHECK_FOR_RESET_TIMEOUT;
7764 ipr_reset_start_timer(ipr_cmd, IPR_CHECK_FOR_RESET_TIMEOUT); 7817 ipr_reset_start_timer(ipr_cmd, IPR_CHECK_FOR_RESET_TIMEOUT);
7765 } else { 7818 } else {
7766 ipr_cmd->job_step = ioa_cfg->reset; 7819 ipr_cmd->job_step = ipr_reset_block_config_access;
7767 rc = IPR_RC_JOB_CONTINUE; 7820 rc = IPR_RC_JOB_CONTINUE;
7768 } 7821 }
7769 7822
@@ -7796,7 +7849,7 @@ static int ipr_reset_alert(struct ipr_cmnd *ipr_cmd)
7796 writel(IPR_UPROCI_RESET_ALERT, ioa_cfg->regs.set_uproc_interrupt_reg32); 7849 writel(IPR_UPROCI_RESET_ALERT, ioa_cfg->regs.set_uproc_interrupt_reg32);
7797 ipr_cmd->job_step = ipr_reset_wait_to_start_bist; 7850 ipr_cmd->job_step = ipr_reset_wait_to_start_bist;
7798 } else { 7851 } else {
7799 ipr_cmd->job_step = ioa_cfg->reset; 7852 ipr_cmd->job_step = ipr_reset_block_config_access;
7800 } 7853 }
7801 7854
7802 ipr_cmd->u.time_left = IPR_WAIT_FOR_RESET_TIMEOUT; 7855 ipr_cmd->u.time_left = IPR_WAIT_FOR_RESET_TIMEOUT;