On Tue, Mar 10, 2020 at 01:21:00PM -0500, Stuart Hayes wrote: > When a pciehp slot is powered down via /sys/bus/pci/slots/<slot>/power, > and then the card is physically removed, the kernel will sometimes try to > enable the slot as the card is removed, which results in an error in the > kernel log. > > This can happen if the presence detect and link active bits don't go down > at the exact same time. When the card is disabled via /sys/.../power, the > card is placed in OFF_STATE, but the presence detect and link active bits > can still be up. Then, when, say, presence detect goes down, an interrupt > reports that the presence detect has changed, and the code in > pciehp_handle_presence_or_link_change() will see that the link is up > (because it hasn't gone down yet), and it will try to enable the slot. > > This patch modifies that code so it won't try to enable a slot in OFF_STATE > unless it sees the presence detect changed bit with presence detect active, > or the link status changed bit with an active link. This will prevent the > unwanted attempts to enable a card that's being removed, but will still > allow the slot to come up if the slot is re-enabled by writing to > /sys/.../power, or if a new card is added to the slot. Looking for a reviewed-by from Lukas for this. > Signed-off-by: Stuart Hayes <stuart.w.hayes@xxxxxxxxx> > --- > drivers/pci/hotplug/pciehp_ctrl.c | 24 ++++++++++++++---------- > 1 file changed, 14 insertions(+), 10 deletions(-) > > diff --git a/drivers/pci/hotplug/pciehp_ctrl.c b/drivers/pci/hotplug/pciehp_ctrl.c > index 6503d15effbb..f6cbf21711e0 100644 > --- a/drivers/pci/hotplug/pciehp_ctrl.c > +++ b/drivers/pci/hotplug/pciehp_ctrl.c > @@ -267,16 +267,20 @@ void pciehp_handle_presence_or_link_change(struct controller *ctrl, u32 events) > cancel_delayed_work(&ctrl->button_work); > /* fall through */ > case OFF_STATE: > - ctrl->state = POWERON_STATE; > - mutex_unlock(&ctrl->state_lock); > - if (present) > - ctrl_info(ctrl, "Slot(%s): Card present\n", > - slot_name(ctrl)); > - if (link_active) > - ctrl_info(ctrl, "Slot(%s): Link Up\n", > - slot_name(ctrl)); > - ctrl->request_result = pciehp_enable_slot(ctrl); > - break; > + if ((events & PCI_EXP_SLTSTA_PDC && present) || > + (events & PCI_EXP_SLTSTA_DLLSC && link_active)) { > + ctrl->state = POWERON_STATE; > + mutex_unlock(&ctrl->state_lock); > + if (present) > + ctrl_info(ctrl, "Slot(%s): Card present\n", > + slot_name(ctrl)); > + if (link_active) > + ctrl_info(ctrl, "Slot(%s): Link Up\n", > + slot_name(ctrl)); > + ctrl->request_result = pciehp_enable_slot(ctrl); > + break; > + } > + /* fall through */ > default: > mutex_unlock(&ctrl->state_lock); > break; > -- > 2.18.1 >