aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/pci/pci.c38
-rw-r--r--include/linux/pci.h1
2 files changed, 26 insertions, 13 deletions
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index e37fea6e178d..10ab64e8878e 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -3098,19 +3098,17 @@ int pci_set_dma_seg_boundary(struct pci_dev *dev, unsigned long mask)
3098} 3098}
3099EXPORT_SYMBOL(pci_set_dma_seg_boundary); 3099EXPORT_SYMBOL(pci_set_dma_seg_boundary);
3100 3100
3101static int pcie_flr(struct pci_dev *dev, int probe) 3101/**
3102 * pci_wait_for_pending_transaction - waits for pending transaction
3103 * @dev: the PCI device to operate on
3104 *
3105 * Return 0 if transaction is pending 1 otherwise.
3106 */
3107int pci_wait_for_pending_transaction(struct pci_dev *dev)
3102{ 3108{
3103 int i; 3109 int i;
3104 u32 cap;
3105 u16 status; 3110 u16 status;
3106 3111
3107 pcie_capability_read_dword(dev, PCI_EXP_DEVCAP, &cap);
3108 if (!(cap & PCI_EXP_DEVCAP_FLR))
3109 return -ENOTTY;
3110
3111 if (probe)
3112 return 0;
3113
3114 /* Wait for Transaction Pending bit clean */ 3112 /* Wait for Transaction Pending bit clean */
3115 for (i = 0; i < 4; i++) { 3113 for (i = 0; i < 4; i++) {
3116 if (i) 3114 if (i)
@@ -3118,13 +3116,27 @@ static int pcie_flr(struct pci_dev *dev, int probe)
3118 3116
3119 pcie_capability_read_word(dev, PCI_EXP_DEVSTA, &status); 3117 pcie_capability_read_word(dev, PCI_EXP_DEVSTA, &status);
3120 if (!(status & PCI_EXP_DEVSTA_TRPND)) 3118 if (!(status & PCI_EXP_DEVSTA_TRPND))
3121 goto clear; 3119 return 1;
3122 } 3120 }
3123 3121
3124 dev_err(&dev->dev, "transaction is not cleared; " 3122 return 0;
3125 "proceeding with reset anyway\n"); 3123}
3124EXPORT_SYMBOL(pci_wait_for_pending_transaction);
3125
3126static int pcie_flr(struct pci_dev *dev, int probe)
3127{
3128 u32 cap;
3129
3130 pcie_capability_read_dword(dev, PCI_EXP_DEVCAP, &cap);
3131 if (!(cap & PCI_EXP_DEVCAP_FLR))
3132 return -ENOTTY;
3133
3134 if (probe)
3135 return 0;
3136
3137 if (!pci_wait_for_pending_transaction(dev))
3138 dev_err(&dev->dev, "transaction is not cleared; proceeding with reset anyway\n");
3126 3139
3127clear:
3128 pcie_capability_set_word(dev, PCI_EXP_DEVCTL, PCI_EXP_DEVCTL_BCR_FLR); 3140 pcie_capability_set_word(dev, PCI_EXP_DEVCTL, PCI_EXP_DEVCTL_BCR_FLR);
3129 3141
3130 msleep(100); 3142 msleep(100);
diff --git a/include/linux/pci.h b/include/linux/pci.h
index 0fd1f1582fa1..e6470016c718 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -914,6 +914,7 @@ bool pci_check_and_unmask_intx(struct pci_dev *dev);
914void pci_msi_off(struct pci_dev *dev); 914void pci_msi_off(struct pci_dev *dev);
915int pci_set_dma_max_seg_size(struct pci_dev *dev, unsigned int size); 915int pci_set_dma_max_seg_size(struct pci_dev *dev, unsigned int size);
916int pci_set_dma_seg_boundary(struct pci_dev *dev, unsigned long mask); 916int pci_set_dma_seg_boundary(struct pci_dev *dev, unsigned long mask);
917int pci_wait_for_pending_transaction(struct pci_dev *dev);
917int pcix_get_max_mmrbc(struct pci_dev *dev); 918int pcix_get_max_mmrbc(struct pci_dev *dev);
918int pcix_get_mmrbc(struct pci_dev *dev); 919int pcix_get_mmrbc(struct pci_dev *dev);
919int pcix_set_mmrbc(struct pci_dev *dev, int mmrbc); 920int pcix_set_mmrbc(struct pci_dev *dev, int mmrbc);