Re: [PATCH] PCI: altera: Check TLP completion status

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

 



please ignore this letter


On 2017年02月17日 08:19, Yadi Hu wrote:
From: Ley Foon Tan <lftan@xxxxxxxxxx>

Check TLP packet successful completion status.  This fix the issue when
accessing multi-function devices in enumeration process, TLP will return
error when accessing non-exist function number.  Returns PCI error code
instead of generic errno.

Tested on Ethernet adapter card with multi-functions.

[bhelgaas: simplify completion status checking code]
Signed-off-by: Ley Foon Tan <lftan@xxxxxxxxxx>
Signed-off-by: Bjorn Helgaas <bhelgaas@xxxxxxxxxx>
---
  drivers/pci/host/pcie-altera.c | 12 ++++++++++--
  1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/drivers/pci/host/pcie-altera.c b/drivers/pci/host/pcie-altera.c
index ed736a9..072255d 100644
--- a/drivers/pci/host/pcie-altera.c
+++ b/drivers/pci/host/pcie-altera.c
@@ -55,6 +55,7 @@
  #define TLP_CFG_DW2(bus, devfn, offset)	\
  				(((bus) << 24) | ((devfn) << 16) | (offset))
  #define TLP_REQ_ID(bus, devfn)		(((bus) << 8) | (devfn))
+#define TLP_COMP_STATUS(s)		(((s) >> 12) & 7)
  #define TLP_HDR_SIZE			3
  #define TLP_LOOP			500
  #define RP_DEVFN			0
@@ -171,6 +172,7 @@ static int tlp_read_packet(struct altera_pcie *pcie, u32 *value)
  	bool sop = 0;
  	u32 ctrl;
  	u32 reg0, reg1;
+	u32 comp_status = 1;
/*
  	 * Minimum 2 loops to read TLP headers and 1 loop to read data
@@ -182,19 +184,25 @@ static int tlp_read_packet(struct altera_pcie *pcie, u32 *value)
  			reg0 = cra_readl(pcie, RP_RXCPL_REG0);
  			reg1 = cra_readl(pcie, RP_RXCPL_REG1);
- if (ctrl & RP_RXCPL_SOP)
+			if (ctrl & RP_RXCPL_SOP) {
  				sop = true;
+				comp_status = TLP_COMP_STATUS(reg1);
+			}
if (ctrl & RP_RXCPL_EOP) {
+				if (comp_status)
+					return PCIBIOS_DEVICE_NOT_FOUND;
+
  				if (value)
  					*value = reg0;
+
  				return PCIBIOS_SUCCESSFUL;
  			}
  		}
  		udelay(5);
  	}
- return -ENOENT;
+	return PCIBIOS_DEVICE_NOT_FOUND;
  }
static void tlp_write_packet(struct altera_pcie *pcie, u32 *headers,




[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