On Tue, Feb 19, 2019 at 07:20:28PM -0600, Alexandru Gagniuc wrote: > @@ -213,6 +213,21 @@ void pciehp_handle_disable_request(struct controller *ctrl) > ctrl->request_result = pciehp_disable_slot(ctrl, SAFE_REMOVAL); > } > > +static bool is_delayed_presence_up_event(struct controller *ctrl, u32 events) > +{ > + bool present, link_active; > + > + if (!ctrl->inband_presence_disabled) > + return false; > + > + present = pciehp_card_present(ctrl); > + link_active = pciehp_check_link_active(ctrl); > + > + if (!present || !link_active || events & PCI_EXP_SLTSTA_DLLSC) > + return false; > + > + return true; > +} > void pciehp_handle_presence_or_link_change(struct controller *ctrl, u32 events) Newline please after the closing curly brace. > @@ -220,13 +235,22 @@ void pciehp_handle_presence_or_link_change(struct controller *ctrl, u32 events) > /* > * If the slot is on and presence or link has changed, turn it off. > * Even if it's occupied again, we cannot assume the card is the same. > + * When the card is swapped, we also expect a change in link state, > + * without which, it's likely presence became high after link-active. > */ Maybe it's just me but I find the code comment difficult to understand. How about something along the lines of: /* * If the slot is on and presence or link has changed, turn it off. * Even if it's occupied again, we cannot assume the card is the same. + * + * An exception is a delayed "Card present" after a "Link Up". + * This can happen on controllers with in-band presence disabled, + * PCIe r5.0 sec X.Y.Z. */ > mutex_lock(&ctrl->state_lock); > + present = pciehp_card_present(ctrl); > + link_active = pciehp_check_link_active(ctrl); > switch (ctrl->state) { These two assignments appear to be superfluous as you're also performing them in pciehp_check_link_active(). Thanks, Lukas