Here is how I would prefer to rework ipr. 

Thanks,

Brian

-- 
Brian King
Linux on Power Virtualization
IBM Linux Technology Center



The PCI config space blocking API has changed to better
allow for multiple users. Update ipr to use the new API.

Signed-off-by: Brian King <[email protected]>
---

 drivers/scsi/ipr.c |   66 +++++++++++++++++++++++++++++++++++++++++++++++------
 drivers/scsi/ipr.h |    1 
 2 files changed, 60 insertions(+), 7 deletions(-)

diff -puN drivers/scsi/ipr.c~ipr_new_pci_block drivers/scsi/ipr.c
--- linux-2.6/drivers/scsi/ipr.c~ipr_new_pci_block      2011-09-06 
16:52:47.000000000 -0500
+++ linux-2.6-bjking1/drivers/scsi/ipr.c        2011-09-07 08:34:54.000000000 
-0500
@@ -7639,8 +7639,12 @@ static int ipr_reset_restore_cfg_space(s
  **/
 static int ipr_reset_bist_done(struct ipr_cmnd *ipr_cmd)
 {
+       struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg;
+
        ENTER;
-       pci_unblock_user_cfg_access(ipr_cmd->ioa_cfg->pdev);
+       if (ioa_cfg->ucfg_blocked)
+               pci_unblock_cfg_access(ioa_cfg->pdev);
+       ioa_cfg->ucfg_blocked = 0;
        ipr_cmd->job_step = ipr_reset_restore_cfg_space;
        LEAVE;
        return IPR_RC_JOB_CONTINUE;
@@ -7661,8 +7665,6 @@ static int ipr_reset_start_bist(struct i
        int rc = PCIBIOS_SUCCESSFUL;
 
        ENTER;
-       pci_block_user_cfg_access(ioa_cfg->pdev);
-
        if (ioa_cfg->ipr_chip->bist_method == IPR_MMIO)
                writel(IPR_UPROCI_SIS64_START_BIST,
                       ioa_cfg->regs.set_uproc_interrupt_reg32);
@@ -7674,7 +7676,9 @@ static int ipr_reset_start_bist(struct i
                ipr_reset_start_timer(ipr_cmd, IPR_WAIT_FOR_BIST_TIMEOUT);
                rc = IPR_RC_JOB_RETURN;
        } else {
-               pci_unblock_user_cfg_access(ipr_cmd->ioa_cfg->pdev);
+               if (ioa_cfg->ucfg_blocked)
+                       pci_unblock_cfg_access(ipr_cmd->ioa_cfg->pdev);
+               ioa_cfg->ucfg_blocked = 0;
                ipr_cmd->s.ioasa.hdr.ioasc = 
cpu_to_be32(IPR_IOASC_PCI_ACCESS_ERROR);
                rc = IPR_RC_JOB_CONTINUE;
        }
@@ -7717,7 +7721,6 @@ static int ipr_reset_slot_reset(struct i
        struct pci_dev *pdev = ioa_cfg->pdev;
 
        ENTER;
-       pci_block_user_cfg_access(pdev);
        pci_set_pcie_reset_state(pdev, pcie_warm_reset);
        ipr_cmd->job_step = ipr_reset_slot_reset_done;
        ipr_reset_start_timer(ipr_cmd, IPR_PCI_RESET_TIMEOUT);
@@ -7726,6 +7729,55 @@ static int ipr_reset_slot_reset(struct i
 }
 
 /**
+ * ipr_reset_block_config_access_wait - Wait for permission to block config 
access
+ * @ipr_cmd:   ipr command struct
+ *
+ * Description: This attempts to block config access to the IOA.
+ *
+ * Return value:
+ *     IPR_RC_JOB_CONTINUE / IPR_RC_JOB_RETURN
+ **/
+static int ipr_reset_block_config_access_wait(struct ipr_cmnd *ipr_cmd)
+{
+       struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg;
+       int rc = IPR_RC_JOB_CONTINUE;
+
+       if (pci_block_cfg_access_in_atomic(ioa_cfg->pdev)) {
+               if (ipr_cmd->u.time_left) {
+                       rc = IPR_RC_JOB_RETURN;
+                       ipr_cmd->u.time_left -= IPR_CHECK_FOR_RESET_TIMEOUT;
+                       ipr_reset_start_timer(ipr_cmd, 
IPR_CHECK_FOR_RESET_TIMEOUT);
+               } else {
+                       ipr_cmd->job_step = ioa_cfg->reset;
+                       dev_err(&ioa_cfg->pdev->dev,
+                               "Timed out waiting to block config access. 
Resetting anyway.\n");
+               }
+       } else {
+               ioa_cfg->ucfg_blocked = 1;
+               ipr_cmd->job_step = ioa_cfg->reset;
+       }
+
+       return rc;
+}
+
+/**
+ * ipr_reset_block_config_access - Block config access to the IOA
+ * @ipr_cmd:   ipr command struct
+ *
+ * Description: This attempts to block config access to the IOA
+ *
+ * Return value:
+ *     IPR_RC_JOB_CONTINUE
+ **/
+static int ipr_reset_block_config_access(struct ipr_cmnd *ipr_cmd)
+{
+       ipr_cmd->ioa_cfg->ucfg_blocked = 0;
+       ipr_cmd->job_step = ipr_reset_block_config_access_wait;
+       ipr_cmd->u.time_left = IPR_WAIT_FOR_RESET_TIMEOUT;
+       return IPR_RC_JOB_CONTINUE;
+}
+
+/**
  * ipr_reset_allowed - Query whether or not IOA can be reset
  * @ioa_cfg:   ioa config struct
  *
@@ -7764,7 +7816,7 @@ static int ipr_reset_wait_to_start_bist(
                ipr_cmd->u.time_left -= IPR_CHECK_FOR_RESET_TIMEOUT;
                ipr_reset_start_timer(ipr_cmd, IPR_CHECK_FOR_RESET_TIMEOUT);
        } else {
-               ipr_cmd->job_step = ioa_cfg->reset;
+               ipr_cmd->job_step = ipr_reset_block_config_access;
                rc = IPR_RC_JOB_CONTINUE;
        }
 
@@ -7797,7 +7849,7 @@ static int ipr_reset_alert(struct ipr_cm
                writel(IPR_UPROCI_RESET_ALERT, 
ioa_cfg->regs.set_uproc_interrupt_reg32);
                ipr_cmd->job_step = ipr_reset_wait_to_start_bist;
        } else {
-               ipr_cmd->job_step = ioa_cfg->reset;
+               ipr_cmd->job_step = ipr_reset_block_config_access;
        }
 
        ipr_cmd->u.time_left = IPR_WAIT_FOR_RESET_TIMEOUT;
diff -puN drivers/scsi/ipr.h~ipr_new_pci_block drivers/scsi/ipr.h
--- linux-2.6/drivers/scsi/ipr.h~ipr_new_pci_block      2011-09-07 
07:29:20.000000000 -0500
+++ linux-2.6-bjking1/drivers/scsi/ipr.h        2011-09-07 08:10:29.000000000 
-0500
@@ -1384,6 +1384,7 @@ struct ipr_ioa_cfg {
        u8 needs_warm_reset:1;
        u8 msi_received:1;
        u8 sis64:1;
+       u8 ucfg_blocked:1;
 
        u8 revid;
 
_
--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to