aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pci/hotplug/pciehp.h
diff options
context:
space:
mode:
authorLukas Wunner <lukas@wunner.de>2018-07-31 01:50:37 -0400
committerBjorn Helgaas <bhelgaas@google.com>2018-09-17 17:34:35 -0400
commit11e87702be65780be92fb1f0a5b7b293954185f7 (patch)
treeaef305785ff65cbad47c5323f97645b6fcd3e51e /drivers/pci/hotplug/pciehp.h
parenta50ac6bfd6042b16e0de4ac3264c407e678c9b10 (diff)
PCI: pciehp: Differentiate between surprise and safe removal
When removing PCI devices below a hotplug bridge, pciehp marks them as disconnected if the card is no longer present in the slot or it quiesces them if the card is still present (by disabling INTx interrupts, bus mastering and SERR# reporting). To detect whether the card is still present, pciehp checks the Presence Detect State bit in the Slot Status register. The problem with this approach is that even if the card is present, the link to it may be down, and it that case it would be better to mark the devices as disconnected instead of trying to quiesce them. Moreover, if the card in the slot was quickly replaced by another one, the Presence Detect State bit would be set, yet trying to quiesce the new card's devices would be wrong and the correct thing to do is to mark the previous card's devices as disconnected. Instead of looking at the Presence Detect State bit, it is better to differentiate whether the card was surprise removed versus safely removed (via sysfs or an Attention Button press). On surprise removal, the devices should be marked as disconnected, whereas on safe removal it is correct to quiesce the devices. The knowledge whether a surprise removal or a safe removal is at hand does exist further up in the call stack: A surprise removal is initiated by pciehp_handle_presence_or_link_change(), a safe removal by pciehp_handle_disable_request(). Pass that information down to pciehp_unconfigure_device() and use it in lieu of the Presence Detect State bit. While there, add kernel-doc to pciehp_unconfigure_device() and pciehp_configure_device(). Tested-by: Alexandru Gagniuc <mr.nuke.me@gmail.com> Signed-off-by: Lukas Wunner <lukas@wunner.de> Signed-off-by: Bjorn Helgaas <bhelgaas@google.com> Cc: Keith Busch <keith.busch@intel.com>
Diffstat (limited to 'drivers/pci/hotplug/pciehp.h')
-rw-r--r--drivers/pci/hotplug/pciehp.h2
1 files changed, 1 insertions, 1 deletions
diff --git a/drivers/pci/hotplug/pciehp.h b/drivers/pci/hotplug/pciehp.h
index 811cf83f956d..39c9c8815a35 100644
--- a/drivers/pci/hotplug/pciehp.h
+++ b/drivers/pci/hotplug/pciehp.h
@@ -181,7 +181,7 @@ void pciehp_handle_button_press(struct slot *slot);
181void pciehp_handle_disable_request(struct slot *slot); 181void pciehp_handle_disable_request(struct slot *slot);
182void pciehp_handle_presence_or_link_change(struct slot *slot, u32 events); 182void pciehp_handle_presence_or_link_change(struct slot *slot, u32 events);
183int pciehp_configure_device(struct slot *p_slot); 183int pciehp_configure_device(struct slot *p_slot);
184void pciehp_unconfigure_device(struct slot *p_slot); 184void pciehp_unconfigure_device(struct slot *p_slot, bool presence);
185void pciehp_queue_pushbutton_work(struct work_struct *work); 185void pciehp_queue_pushbutton_work(struct work_struct *work);
186struct controller *pcie_init(struct pcie_device *dev); 186struct controller *pcie_init(struct pcie_device *dev);
187int pcie_init_notification(struct controller *ctrl); 187int pcie_init_notification(struct controller *ctrl);