[PATCH 3/5] PCI: Separate PCI-E FLR function into pcie_flr()

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Signed-off-by: Sheng Yang <sheng@xxxxxxxxxxxxxxx>
---
 drivers/pci/pci.c |   49 ++++++++++++++++++++++++++++++++-----------------
 1 files changed, 32 insertions(+), 17 deletions(-)

diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index 28af496..9adf1ad 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -1751,6 +1751,37 @@ int pci_set_dma_seg_boundary(struct pci_dev *dev, unsigned long mask)
 EXPORT_SYMBOL(pci_set_dma_seg_boundary);
 #endif
 
+static int __pcie_flr(struct pci_dev *dev)
+{
+	int exppos = pci_find_capability(dev, PCI_CAP_ID_EXP);
+	u16 status;
+	u32 cap;
+
+	if (!exppos)
+		return -ENOTTY;
+	pci_read_config_dword(dev, exppos + PCI_EXP_DEVCAP, &cap);
+	if (!(cap & PCI_EXP_DEVCAP_FLR))
+		return -ENOTTY;
+
+	/* Wait for Transaction Pending bit clean */
+	msleep(100);
+	pci_read_config_word(dev, exppos + PCI_EXP_DEVSTA, &status);
+	if (status & PCI_EXP_DEVSTA_TRPND) {
+		dev_info(&dev->dev, "Busy after 100ms while trying to reset; "
+			"sleeping for 1 second\n");
+		ssleep(1);
+		pci_read_config_word(dev, exppos + PCI_EXP_DEVSTA, &status);
+		if (status & PCI_EXP_DEVSTA_TRPND)
+			dev_info(&dev->dev, "Still busy after 1s; "
+				"proceeding with reset anyway\n");
+	}
+
+	pci_write_config_word(dev, exppos + PCI_EXP_DEVCTL,
+				PCI_EXP_DEVCTL_BCR_FLR);
+	mdelay(100);
+	return 0;
+}
+
 /**
  * pci_execute_reset_function() - Reset a PCI device function
  * @dev: Device function to reset
@@ -1770,7 +1801,6 @@ EXPORT_SYMBOL(pci_set_dma_seg_boundary);
  */
 int pci_execute_reset_function(struct pci_dev *dev)
 {
-	u16 status;
 	u32 cap;
 	int exppos = pci_find_capability(dev, PCI_CAP_ID_EXP);
 
@@ -1782,22 +1812,7 @@ int pci_execute_reset_function(struct pci_dev *dev)
 
 	pci_block_user_cfg_access(dev);
 
-	/* Wait for Transaction Pending bit clean */
-	msleep(100);
-	pci_read_config_word(dev, exppos + PCI_EXP_DEVSTA, &status);
-	if (status & PCI_EXP_DEVSTA_TRPND) {
-		dev_info(&dev->dev, "Busy after 100ms while trying to reset; "
-			"sleeping for 1 second\n");
-		ssleep(1);
-		pci_read_config_word(dev, exppos + PCI_EXP_DEVSTA, &status);
-		if (status & PCI_EXP_DEVSTA_TRPND)
-			dev_info(&dev->dev, "Still busy after 1s; "
-				"proceeding with reset anyway\n");
-	}
-
-	pci_write_config_word(dev, exppos + PCI_EXP_DEVCTL,
-				PCI_EXP_DEVCTL_BCR_FLR);
-	mdelay(100);
+	__pcie_flr(dev);
 
 	pci_unblock_user_cfg_access(dev);
 	return 0;
-- 
1.5.4.5

--
To unsubscribe from this list: send the line "unsubscribe linux-pci" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [DMA Engine]     [Linux Coverity]     [Linux USB]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Greybus]

  Powered by Linux