• Lukas Wunner's avatar
    PCI: pciehp: Tolerate initially unstable link · 6c35a1ac
    Lukas Wunner authored
    When a device is hotplugged, Presence Detect and Link Up events often do
    not occur simultaneously, but with a lag of a few milliseconds.  Only
    the first event received is relevant, the other one can be disregarded.
    
    Moreover, Stefan Roese reports that on certain platforms, Link State and
    Presence Detect may flap for up to 100 ms before stabilizing, suggesting
    that such events should be disregarded for at least this long:
    https://lkml.kernel.org/r/20180130084121.18653-1-sr@denx.de
    
    On slot enablement, pciehp_check_link_status() waits for 100 ms per
    PCIe r4.0, sec 6.7.3.3, then probes the hotplugged device's vendor
    register for up to 1 second.
    
    If this succeeds, the link is definitely up, so ignore any Presence
    Detect or Link State events that occurred up to this point.
    
    pciehp_check_link_status() then checks the Link Training bit in the
    Link Status register.  This is the final opportunity to detect
    inaccessibility of the device and abort slot enablement.  Any link
    or presence change that occurs afterwards will cause the slot to be
    disabled again immediately after attempting to enable it.
    
    The astute reviewer may appreciate that achieving this behavior would be
    more complicated had pciehp not just been converted to enable/disable
    the slot exclusively from the IRQ thread:  When the slot is enabled via
    sysfs, each link or presence flap would otherwise cause the IRQ thread
    to run and it would have to sense that those events are belonging to a
    concurrent slot enablement operation and disregard them.  It would be
    much more difficult than this mere 3 line change.
    Signed-off-by: default avatarLukas Wunner <lukas@wunner.de>
    Signed-off-by: default avatarBjorn Helgaas <bhelgaas@google.com>
    Cc: Stefan Roese <sr@denx.de>
    6c35a1ac
pciehp_hpc.c 23.8 KB