PCI: Add pci_wait_for_pending_transaction()
authorCasey Leedom <leedom@chelsio.com>
Tue, 6 Aug 2013 10:18:36 +0000 (15:48 +0530)
committerBjorn Helgaas <bhelgaas@google.com>
Mon, 12 Aug 2013 19:47:09 +0000 (13:47 -0600)
New routine to avoid duplication of code to wait for pending PCI
transactions to complete.

Signed-off-by: Casey Leedom <leedom@chelsio.com>
Signed-off-by: Vipul Pandya <vipul@chelsio.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
drivers/pci/pci.c
include/linux/pci.h

index e37fea6e178d2dab00d3334848d231117d525013..10ab64e8878e1d0fd30ac3443303f15683f8b7fa 100644 (file)
@@ -3098,19 +3098,17 @@ int pci_set_dma_seg_boundary(struct pci_dev *dev, unsigned long mask)
 }
 EXPORT_SYMBOL(pci_set_dma_seg_boundary);
 
-static int pcie_flr(struct pci_dev *dev, int probe)
+/**
+ * pci_wait_for_pending_transaction - waits for pending transaction
+ * @dev: the PCI device to operate on
+ *
+ * Return 0 if transaction is pending 1 otherwise.
+ */
+int pci_wait_for_pending_transaction(struct pci_dev *dev)
 {
        int i;
-       u32 cap;
        u16 status;
 
-       pcie_capability_read_dword(dev, PCI_EXP_DEVCAP, &cap);
-       if (!(cap & PCI_EXP_DEVCAP_FLR))
-               return -ENOTTY;
-
-       if (probe)
-               return 0;
-
        /* Wait for Transaction Pending bit clean */
        for (i = 0; i < 4; i++) {
                if (i)
@@ -3118,13 +3116,27 @@ static int pcie_flr(struct pci_dev *dev, int probe)
 
                pcie_capability_read_word(dev, PCI_EXP_DEVSTA, &status);
                if (!(status & PCI_EXP_DEVSTA_TRPND))
-                       goto clear;
+                       return 1;
        }
 
-       dev_err(&dev->dev, "transaction is not cleared; "
-                       "proceeding with reset anyway\n");
+       return 0;
+}
+EXPORT_SYMBOL(pci_wait_for_pending_transaction);
+
+static int pcie_flr(struct pci_dev *dev, int probe)
+{
+       u32 cap;
+
+       pcie_capability_read_dword(dev, PCI_EXP_DEVCAP, &cap);
+       if (!(cap & PCI_EXP_DEVCAP_FLR))
+               return -ENOTTY;
+
+       if (probe)
+               return 0;
+
+       if (!pci_wait_for_pending_transaction(dev))
+               dev_err(&dev->dev, "transaction is not cleared; proceeding with reset anyway\n");
 
-clear:
        pcie_capability_set_word(dev, PCI_EXP_DEVCTL, PCI_EXP_DEVCTL_BCR_FLR);
 
        msleep(100);
index 0fd1f1582fa1cdf359b33f3cddeaa60026f492ac..e6470016c718b73fe6b4f82d083496b311da15db 100644 (file)
@@ -914,6 +914,7 @@ bool pci_check_and_unmask_intx(struct pci_dev *dev);
 void pci_msi_off(struct pci_dev *dev);
 int pci_set_dma_max_seg_size(struct pci_dev *dev, unsigned int size);
 int pci_set_dma_seg_boundary(struct pci_dev *dev, unsigned long mask);
+int pci_wait_for_pending_transaction(struct pci_dev *dev);
 int pcix_get_max_mmrbc(struct pci_dev *dev);
 int pcix_get_mmrbc(struct pci_dev *dev);
 int pcix_set_mmrbc(struct pci_dev *dev, int mmrbc);
This page took 0.02849 seconds and 5 git commands to generate.