summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Miroshnichenko <s.miroshnichenko@yadro.com>2019-03-12 15:05:48 +0300
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2019-04-17 09:39:53 +0300
commit8af91139a0a8297557375f08320a89c7d2c87310 (patch)
tree5a480513b9ed465fea375c185b6a06f550a3b056
parent9b63917c6a4c5576e5fc84aaf0a3d8915035cf95 (diff)
downloadlinux-8af91139a0a8297557375f08320a89c7d2c87310.tar.xz
PCI: pciehp: Ignore Link State Changes after powering off a slot
commit 3943af9d01e94330d0cfac6fccdbc829aad50c92 upstream. During a safe hot remove, the OS powers off the slot, which may cause a Data Link Layer State Changed event. The slot has already been set to OFF_STATE, so that event results in re-enabling the device, making it impossible to safely remove it. Clear out the Presence Detect Changed and Data Link Layer State Changed events when the disabled slot has settled down. It is still possible to re-enable the device if it remains in the slot after pressing the Attention Button by pressing it again. Fixes the problem that Micah reported below: an NVMe drive power button may not actually turn off the drive. Link: https://bugzilla.kernel.org/show_bug.cgi?id=203237 Reported-by: Micah Parrish <micah.parrish@hpe.com> Tested-by: Micah Parrish <micah.parrish@hpe.com> Signed-off-by: Sergey Miroshnichenko <s.miroshnichenko@yadro.com> [bhelgaas: changelog, add bugzilla URL] Signed-off-by: Bjorn Helgaas <bhelgaas@google.com> Reviewed-by: Lukas Wunner <lukas@wunner.de> Cc: stable@vger.kernel.org # v4.19+ Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--drivers/pci/hotplug/pciehp_ctrl.c4
1 files changed, 4 insertions, 0 deletions
diff --git a/drivers/pci/hotplug/pciehp_ctrl.c b/drivers/pci/hotplug/pciehp_ctrl.c
index 3f3df4c29f6e..905282a8ddaa 100644
--- a/drivers/pci/hotplug/pciehp_ctrl.c
+++ b/drivers/pci/hotplug/pciehp_ctrl.c
@@ -115,6 +115,10 @@ static void remove_board(struct controller *ctrl, bool safe_removal)
* removed from the slot/adapter.
*/
msleep(1000);
+
+ /* Ignore link or presence changes caused by power off */
+ atomic_and(~(PCI_EXP_SLTSTA_DLLSC | PCI_EXP_SLTSTA_PDC),
+ &ctrl->pending_events);
}
/* turn off Green LED */