diff options
author | Rongguang Wei <weirongguang@kylinos.cn> | 2023-05-12 05:15:18 +0300 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2023-07-19 17:21:35 +0300 |
commit | a982c13e11fbfd2d978ecafc00c10cfa91bb08cd (patch) | |
tree | 65ce92600af3edeee61f00c0585dd0f50dfb6fab | |
parent | 6c1b079e266bb70c699497548e3e4c8b57e5992e (diff) | |
download | linux-a982c13e11fbfd2d978ecafc00c10cfa91bb08cd.tar.xz |
PCI: pciehp: Cancel bringup sequence if card is not present
[ Upstream commit e8afd0d9fccc27c8ad263db5cf5952cfcf72d6fe ]
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/20230512021518.336460-1-clementwei90@163.com
Fixes: d331710ea78f ("PCI: pciehp: Become resilient to missed events")
Suggested-by: Lukas Wunner <lukas@wunner.de>
Signed-off-by: Rongguang Wei <weirongguang@kylinos.cn>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Reviewed-by: Lukas Wunner <lukas@wunner.de>
Signed-off-by: Sasha Levin <sashal@kernel.org>
-rw-r--r-- | drivers/pci/hotplug/pciehp_ctrl.c | 8 |
1 files changed, 8 insertions, 0 deletions
diff --git a/drivers/pci/hotplug/pciehp_ctrl.c b/drivers/pci/hotplug/pciehp_ctrl.c index 529c34808440..32baba1b7f13 100644 --- a/drivers/pci/hotplug/pciehp_ctrl.c +++ b/drivers/pci/hotplug/pciehp_ctrl.c @@ -256,6 +256,14 @@ void pciehp_handle_presence_or_link_change(struct controller *ctrl, u32 events) present = pciehp_card_present(ctrl); link_active = pciehp_check_link_active(ctrl); if (present <= 0 && link_active <= 0) { + if (ctrl->state == BLINKINGON_STATE) { + ctrl->state = OFF_STATE; + cancel_delayed_work(&ctrl->button_work); + pciehp_set_indicators(ctrl, PCI_EXP_SLTCTL_PWR_IND_OFF, + INDICATOR_NOOP); + ctrl_info(ctrl, "Slot(%s): Card not present\n", + slot_name(ctrl)); + } mutex_unlock(&ctrl->state_lock); return; } |