RE: [PATCH 2/2] PCI: Versal CPM: Add support for Versal CPM Root Port driver

From: Bharat Kumar Gogada
Date: Fri Dec 27 2019 - 06:55:48 EST


> Subject: Re: [PATCH 2/2] PCI: Versal CPM: Add support for Versal CPM Root Port
> driver
>
> [+cc other drivers that use the broken "is link up" test in config access]
>
> On Fri, Dec 20, 2019 at 05:11:12PM +0530, Bharat Kumar Gogada wrote:
> > - Adding support for versal CPM as Root Port.
> > - The Versal ACAP devices include CCIX-PCIe Module (CPM). The integrated
> > block for CPM along with the integrated bridge can function
> > as PCIe Root Port.
> > - Versal CPM uses GICv3 ITS feature for assigning MSI/MSI-X
> > vectors and handling MSI/MSI-X interrupts.
> > - Bridge error and legacy interrupts in versal CPM are handled using
> > versal CPM specific MISC interrupt line.
>
> "Versal" appears to be a brand name and should be capitalized consistently.
>
> > +#define INTX_NUM 4
>
> Don't we have a generic PCI core definition for this?
Thanks Bjorn, will fix this with core definition.
>
> > +static inline bool cpm_pcie_link_is_up(struct xilinx_cpm_pcie_port
> > +*port)
>
> Please follow the example of other drivers and name this "cpm_pcie_link_up()".
Agreed, will change the name.
>
> > +{
> > + return (pcie_read(port, XILINX_CPM_PCIE_REG_PSCR) &
> > + XILINX_CPM_PCIE_REG_PSCR_LNKUP) ? 1 : 0; }
>
> > +/**
> > + * xilinx_cpm_pcie_valid_device - Check if a valid device is present
> > +on bus
> > + * @bus: PCI Bus structure
> > + * @devfn: device/function
> > + *
> > + * Return: 'true' on success and 'false' if invalid device is found
> > +*/ static bool xilinx_cpm_pcie_valid_device(struct pci_bus *bus,
> > + unsigned int devfn)
> > +{
> > + struct xilinx_cpm_pcie_port *port = bus->sysdata;
> > +
> > + /* Check if link is up when trying to access downstream ports */
> > + if (bus->number != port->root_busno)
> > + if (!cpm_pcie_link_is_up(port))
> > + return false;
>
> This check for the link being up is racy and should be removed. The link may go
> down after the check and before the config access.
>
> A config access to a device where the link is down is an error, but it's an error we
> expect to happen because of enumeration, surprise unplug, or electrical issue.
> It's impossible to avoid so we must be able to handle and recover from it.
>
> I know there are other drivers that do this (dwc, altera, xilinix-nwl, xilinx), and
> I've pointed this out many times in the past. This needs to be fixed.
Agreed, will fix this check.
>
> > +
> > + /* Only one device down on each root port */
> > + if (bus->number == port->root_busno && devfn > 0)
> > + return false;
> > +
> > + return true;
> > +}
>
> > +static irqreturn_t xilinx_cpm_pcie_intr_handler(int irq, void *data)
> > +{
> > + struct xilinx_cpm_pcie_port *port =
> > + (struct xilinx_cpm_pcie_port *)data;
>
> struct device *dev = port->dev;
>
> to reduce repetition of "port->dev" below.
Agreed, will fix this.

> > + u32 val, mask, status, bit;
> > + unsigned long intr_val;
> > +
> > + /* Read interrupt decode and mask registers */
> > + val = pcie_read(port, XILINX_CPM_PCIE_REG_IDR);
> > + mask = pcie_read(port, XILINX_CPM_PCIE_REG_IMR);
> > +
> > + status = val & mask;
> > + if (!status)
> > + return IRQ_NONE;
> > +
> > + if (status & XILINX_CPM_PCIE_INTR_LINK_DOWN)
> > + dev_warn(port->dev, "Link Down\n");
> > +
> > + if (status & XILINX_CPM_PCIE_INTR_HOT_RESET)
> > + dev_info(port->dev, "Hot reset\n");
> > ...