On Tue, Mar 05, 2019 at 06:31:22PM +0100, Stefan Mätje wrote: > Due to an erratum in some Pericom PCIe-to-PCI bridges in reverse mode the > retrain link bit needs to be cleared again manually to allow the link > training to complete successfully. > > If it is not cleared manually the link training is continuously restarted > and all devices below the PCI-to-PCIe bridge can't be accessed any more. > That means drivers for devices below the bridge will be loaded but won't > work or even crash because the driver is only reading 0xffff. > > See the Pericom Errata Sheet PI7C9X111SLB_errata_rev1.2_102711.pdf for > details. > > Devices known as affected so far are: PI7C9X110, PI7C9X111SL, PI7C9X130 > > The patch introduces a new flag clear_retrain_link in the struct pci_dev. This > flag is set in quirk_enable_clear_retrain_link() for the affected devices in > the pci_fixup_header in quirks.c > > The link retraining code is moved to pcie_retrain_link(). This function now > applies the work around to clear the PCI_EXP_LNKCTL_RL bit again if > clear_retrain_link bit is set in the pci_dev structure of the link parent > device. > + /* Wait for link training end. Break out after waiting for timeout */ > + start_jiffies = jiffies; > + for (;;) { > + pcie_capability_read_word(parent, PCI_EXP_LNKSTA, ®16); > + if (!(reg16 & PCI_EXP_LNKSTA_LT)) > + break; > + if (time_after(jiffies, start_jiffies + LINK_RETRAIN_TIMEOUT)) > + break; > + msleep(1); > + } I see this is existing code, though two comments (perhaps for future clean up): - msleep(1) is not guaranteed to be 1 ms at all (in some cases it might be less) - better to use do {} while (time_before()) loop > +static void quirk_enable_clear_retrain_link(struct pci_dev *dev) > +{ > + dev->clear_retrain_link = 1; > + pci_info(dev, "Enable Pericom link retrain quirk\n"); If some other device would appear with same issue, but from another vendor this becomes misleading. I would recommend to refer to an issue the quirk is about, and not the vendor. > +} -- With Best Regards, Andy Shevchenko