[PATCH 4/5] PCI: Introduce __pci_check_reset_function_cap()

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

 



There are various way to do function granularity reset. PCI-e and PCI
Advanced Feature have Function Level Reset(FLR) support. Introduce
__pci_check_reset_function_cap() to find out which method device supported
to reset the function.

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

diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index 9adf1ad..ad89c74 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -1751,6 +1751,22 @@ int pci_set_dma_seg_boundary(struct pci_dev *dev, unsigned long mask)
 EXPORT_SYMBOL(pci_set_dma_seg_boundary);
 #endif
 
+#define PCI_RESET_FUNC_CAP_PCIE_FLR	    0
+static int __pci_check_reset_function_cap(struct pci_dev *dev)
+{
+	int cappos;
+	u32 cap;
+
+	cappos = pci_find_capability(dev, PCI_CAP_ID_EXP);
+	if (cappos) {
+		pci_read_config_dword(dev, cappos + PCI_EXP_DEVCAP, &cap);
+		if (cap & PCI_EXP_DEVCAP_FLR)
+			return PCI_RESET_FUNC_CAP_PCIE_FLR;
+	}
+
+	return -ENOTTY;
+}
+
 static int __pcie_flr(struct pci_dev *dev)
 {
 	int exppos = pci_find_capability(dev, PCI_CAP_ID_EXP);
@@ -1801,21 +1817,23 @@ static int __pcie_flr(struct pci_dev *dev)
  */
 int pci_execute_reset_function(struct pci_dev *dev)
 {
-	u32 cap;
-	int exppos = pci_find_capability(dev, PCI_CAP_ID_EXP);
+	int reset_cap;
+	int r;
 
-	if (!exppos)
-		return -ENOTTY;
-	pci_read_config_dword(dev, exppos + PCI_EXP_DEVCAP, &cap);
-	if (!(cap & PCI_EXP_DEVCAP_FLR))
-		return -ENOTTY;
+	reset_cap = __pci_check_reset_function_cap(dev);
+	if (reset_cap < 0)
+		return reset_cap;
 
+	r = 0;
 	pci_block_user_cfg_access(dev);
 
-	__pcie_flr(dev);
+	if (reset_cap == PCI_RESET_FUNC_CAP_PCIE_FLR)
+		r = __pcie_flr(dev);
+	else
+		r = -ENOTTY;
 
 	pci_unblock_user_cfg_access(dev);
-	return 0;
+	return r;
 }
 EXPORT_SYMBOL_GPL(pci_execute_reset_function);
 
@@ -1837,15 +1855,11 @@ EXPORT_SYMBOL_GPL(pci_execute_reset_function);
  */
 int pci_reset_function(struct pci_dev *dev)
 {
-	u32 cap;
-	int exppos = pci_find_capability(dev, PCI_CAP_ID_EXP);
 	int r;
 
-	if (!exppos)
-		return -ENOTTY;
-	pci_read_config_dword(dev, exppos + PCI_EXP_DEVCAP, &cap);
-	if (!(cap & PCI_EXP_DEVCAP_FLR))
-		return -ENOTTY;
+	r = __pci_check_reset_function_cap(dev);
+	if (r < 0)
+		return r;
 
 	if (!dev->msi_enabled && !dev->msix_enabled && dev->irq != 0)
 		disable_irq(dev->irq);
-- 
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