#define LINK_MAX_RETRIES 10
#define LINK_WAIT_TIMEOUT 100000
-#define CFG_RD_UR_VAL 0xFFFFFFFF
#define CFG_RD_CRS_VAL 0xFFFF0001
/**
* pcie_advk_check_pio_status() - Validate PIO status and get the read result
*
* @pcie: Pointer to the PCI bus
- * @read: Read from or write to configuration space - true(read) false(write)
- * @read_val: Pointer to the read result, only valid when read is true
+ * @allow_crs: Only for read requests, if CRS response is allowed
+ * @read_val: Pointer to the read result
*
*/
static int pcie_advk_check_pio_status(struct pcie_advk *pcie,
- bool read,
+ bool allow_crs,
uint *read_val)
{
uint reg;
break;
}
/* Get the read result */
- if (read)
+ if (read_val)
*read_val = advk_readl(pcie, PIO_RD_DATA);
/* No error */
strcomp_status = NULL;
break;
case PIO_COMPLETION_STATUS_UR:
- if (read) {
- /* For reading, UR is not an error status. */
- *read_val = CFG_RD_UR_VAL;
- strcomp_status = NULL;
- } else {
- strcomp_status = "UR";
- }
+ strcomp_status = "UR";
break;
case PIO_COMPLETION_STATUS_CRS:
- if (read) {
+ if (allow_crs && read_val) {
/* For reading, CRS is not an error status. */
*read_val = CFG_RD_CRS_VAL;
strcomp_status = NULL;
enum pci_size_t size)
{
struct pcie_advk *pcie = dev_get_priv(bus);
+ bool allow_crs;
uint reg;
int ret;
return 0;
}
+ allow_crs = (offset == PCI_VENDOR_ID) && (size == 4);
+
if (advk_readl(pcie, PIO_START)) {
dev_err(pcie->dev,
"Previous PIO read/write transfer is still running\n");
- if (offset != PCI_VENDOR_ID)
- return -EINVAL;
- *valuep = CFG_RD_CRS_VAL;
- return 0;
+ if (allow_crs) {
+ *valuep = CFG_RD_CRS_VAL;
+ return 0;
+ }
+ *valuep = pci_get_ff(size);
+ return -EINVAL;
}
/* Program the control register */
advk_writel(pcie, 1, PIO_START);
if (!pcie_advk_wait_pio(pcie)) {
- if (offset != PCI_VENDOR_ID)
- return -EINVAL;
- *valuep = CFG_RD_CRS_VAL;
- return 0;
+ if (allow_crs) {
+ *valuep = CFG_RD_CRS_VAL;
+ return 0;
+ }
+ *valuep = pci_get_ff(size);
+ return -EINVAL;
}
/* Check PIO status and get the read result */
- ret = pcie_advk_check_pio_status(pcie, true, ®);
- if (ret)
+ ret = pcie_advk_check_pio_status(pcie, allow_crs, ®);
+ if (ret) {
+ *valuep = pci_get_ff(size);
return ret;
+ }
dev_dbg(pcie->dev, "(addr,size,val)=(0x%04x, %d, 0x%08x)\n",
offset, size, reg);
}
/* Check PIO status */
- pcie_advk_check_pio_status(pcie, false, ®);
-
- return 0;
+ return pcie_advk_check_pio_status(pcie, false, NULL);
}
/**