aboutsummaryrefslogtreecommitdiff
path: root/sys/dev
diff options
context:
space:
mode:
authorColin Percival <cperciva@FreeBSD.org>2019-06-05 04:58:42 +0000
committerColin Percival <cperciva@FreeBSD.org>2019-06-05 04:58:42 +0000
commite0235fd34ab2a715fe4704807c37206c5e98010a (patch)
tree27c5f7d6d2b1c4eef39345e6e362e0c0dd8a5c36 /sys/dev
parent3ea05df092c05b8784b7c0df16dd81e838629862 (diff)
downloadsrc-e0235fd34ab2a715fe4704807c37206c5e98010a.tar.gz
src-e0235fd34ab2a715fe4704807c37206c5e98010a.zip
Only respond to the PCIe Attention Button if a device is already plugged in.
Prior to this commit, if PCIEM_SLOT_STA_ABP and PCIEM_SLOT_STA_PDC are asserted simultaneously, FreeBSD sets a 5 second "hardware going away" timer and then processes the "presence detect" change. In the (physically challenging) case that someone presses the "attention button" and inserts a new PCIe device at exactly the same moment, this results in FreeBSD recognizing that the device is present, attaching it, and then detaching it 5 seconds later. On EC2 "bare metal" hardware this is the precise sequence of events which takes place when a new EBS volume is attached; virtual machines have no difficulty effecting physically implausible simultaneity. This patch changes the handling of PCIEM_SLOT_STA_ABP to only detach a device if the presence of a device was detected *before* the interrupt which reports the Attention Button push. Reported by: Matt Wilson Reviewed by: jhb MFC after: 1 week Sponsored by: https://www.patreon.com/cperciva Differential Revision: https://reviews.freebsd.org/D20499
Notes
Notes: svn path=/head/; revision=348681
Diffstat (limited to 'sys/dev')
-rw-r--r--sys/dev/pci/pci_pci.c5
1 files changed, 4 insertions, 1 deletions
diff --git a/sys/dev/pci/pci_pci.c b/sys/dev/pci/pci_pci.c
index 2f71a1226615..f3233584096b 100644
--- a/sys/dev/pci/pci_pci.c
+++ b/sys/dev/pci/pci_pci.c
@@ -1170,9 +1170,11 @@ pcib_pcie_intr_hotplug(void *arg)
{
struct pcib_softc *sc;
device_t dev;
+ uint16_t old_slot_sta;
sc = arg;
dev = sc->dev;
+ old_slot_sta = sc->pcie_slot_sta;
sc->pcie_slot_sta = pcie_read_config(dev, PCIER_SLOT_STA, 2);
/* Clear the events just reported. */
@@ -1188,7 +1190,8 @@ pcib_pcie_intr_hotplug(void *arg)
"Attention Button Pressed: Detach Cancelled\n");
sc->flags &= ~PCIB_DETACH_PENDING;
callout_stop(&sc->pcie_ab_timer);
- } else {
+ } else if (old_slot_sta & PCIEM_SLOT_STA_PDS) {
+ /* Only initiate detach sequence if device present. */
device_printf(dev,
"Attention Button Pressed: Detaching in 5 seconds\n");
sc->flags |= PCIB_DETACH_PENDING;