Skip to content

Commit e8afd0d

Browse files
Rongguang Weibjorn-helgaas
authored andcommitted
PCI: pciehp: Cancel bringup sequence if card is not present
If a PCIe hotplug slot has an Attention Button, the normal hot-add flow is: - Slot is empty and slot power is off - User inserts card in slot and presses Attention Button - OS blinks Power Indicator for 5 seconds - After 5 seconds, OS turns on Power Indicator, turns on slot power, and enumerates the device Previously, if a user pressed the Attention Button on an *empty* slot, pciehp logged the following messages and blinked the Power Indicator until a second button press: [0.000] pciehp: Button press: will power on in 5 sec [0.001] # Power Indicator starts blinking [5.001] # 5 second timeout; slot is empty, so we should cancel the request to power on and turn off Power Indicator [7.000] # Power Indicator still blinking [8.000] # possible card insertion [9.000] pciehp: Button press: canceling request to power on The first button press incorrectly left the slot in BLINKINGON_STATE, so the second was interpreted as a "cancel power on" event regardless of whether a card was present. If the slot is empty, turn off the Power Indicator and return from BLINKINGON_STATE to OFF_STATE after 5 seconds, effectively canceling the request to power on. Putting the slot in OFF_STATE also means the second button press will correctly request a slot power on if the slot is occupied. [bhelgaas: commit log] Link: https://lore.kernel.org/r/[email protected] Fixes: d331710 ("PCI: pciehp: Become resilient to missed events") Suggested-by: Lukas Wunner <[email protected]> Signed-off-by: Rongguang Wei <[email protected]> Signed-off-by: Bjorn Helgaas <[email protected]> Reviewed-by: Lukas Wunner <[email protected]>
1 parent 5054133 commit e8afd0d

File tree

1 file changed

+8
-0
lines changed

1 file changed

+8
-0
lines changed

drivers/pci/hotplug/pciehp_ctrl.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -257,6 +257,14 @@ void pciehp_handle_presence_or_link_change(struct controller *ctrl, u32 events)
257257
present = pciehp_card_present(ctrl);
258258
link_active = pciehp_check_link_active(ctrl);
259259
if (present <= 0 && link_active <= 0) {
260+
if (ctrl->state == BLINKINGON_STATE) {
261+
ctrl->state = OFF_STATE;
262+
cancel_delayed_work(&ctrl->button_work);
263+
pciehp_set_indicators(ctrl, PCI_EXP_SLTCTL_PWR_IND_OFF,
264+
INDICATOR_NOOP);
265+
ctrl_info(ctrl, "Slot(%s): Card not present\n",
266+
slot_name(ctrl));
267+
}
260268
mutex_unlock(&ctrl->state_lock);
261269
return;
262270
}

0 commit comments

Comments
 (0)