Page MenuHomeFreeBSD

D32932.id98335.diff
No OneTemporary

D32932.id98335.diff

diff --git a/sys/dev/pci/pci_pci.c b/sys/dev/pci/pci_pci.c
--- a/sys/dev/pci/pci_pci.c
+++ b/sys/dev/pci/pci_pci.c
@@ -148,6 +148,10 @@
SYSCTL_INT(_hw_pci, OID_AUTO, clear_pcib, CTLFLAG_RDTUN, &pci_clear_pcib, 0,
"Clear firmware-assigned resources for PCI-PCI bridge I/O windows.");
+static int pci_dll_timeout = 1;
+SYSCTL_INT(_hw_pci, OID_AUTO, dll_link_timeout, CTLFLAG_RWTUN, &pci_dll_timeout,
+ 0, "Timeout in seconds for DLL active");
+
/*
* Is a resource from a child device sub-allocated from one of our
* resource managers?
@@ -1046,11 +1050,14 @@
{
/* Pretend the card isn't present if a detach is forced. */
- if (sc->flags & PCIB_DETACHING)
+ if (sc->state == PCIB_STATE_DETACHING)
return (false);
- /* Card must be present in the slot. */
- if ((sc->pcie_slot_sta & PCIEM_SLOT_STA_PDS) == 0)
+ /* XXX RL seems the starship/matisse bridge can report link active and
+ * no presence detect when a device comes up on the link */
+ /* Card must be present in the slot, or the link must be active. */
+ if ((sc->pcie_slot_sta & PCIEM_SLOT_STA_PDS) == 0 &&
+ (sc->pcie_link_sta & PCIEM_LINK_STA_DL_ACTIVE) == 0)
return (false);
/* XXX KDM Viking AMD chassis keeps returning power fault */
@@ -1091,10 +1098,13 @@
{
bool card_inserted, ei_engaged = false;
- /* Clear DETACHING if Presence Detect has cleared. */
+ /* Transition to DETACHED if Presence Detect has cleared and we were
+ detaching. */
if ((sc->pcie_slot_sta & (PCIEM_SLOT_STA_PDC | PCIEM_SLOT_STA_PDS)) ==
- PCIEM_SLOT_STA_PDC)
- sc->flags &= ~PCIB_DETACHING;
+ PCIEM_SLOT_STA_PDC) {
+ sc->state = PCIB_STATE_DETACHED;
+ goto task_schedule;
+ }
card_inserted = pcib_hotplug_inserted(sc);
@@ -1103,7 +1113,7 @@
mask |= PCIEM_SLOT_CTL_PIC;
if (card_inserted)
val |= PCIEM_SLOT_CTL_PI_ON;
- else if (sc->flags & PCIB_DETACH_PENDING)
+ else if (sc->state == PCIB_STATE_DETACH_PENDING)
val |= PCIEM_SLOT_CTL_PI_BLINK;
else
val |= PCIEM_SLOT_CTL_PI_OFF;
@@ -1146,13 +1156,16 @@
device_printf(sc->dev,
"Data Link Layer inactive\n");
else
- callout_reset(&sc->pcie_dll_timer, hz,
+ callout_reset(&sc->pcie_dll_timer, pci_dll_timeout * hz,
pcib_pcie_dll_timeout, sc);
- } else if (sc->pcie_link_sta & PCIEM_LINK_STA_DL_ACTIVE)
+ } else if (sc->pcie_link_sta & PCIEM_LINK_STA_DL_ACTIVE) {
callout_stop(&sc->pcie_dll_timer);
+ sc->state = PCIB_STATE_ATTACHED;
+ }
pcib_pcie_hotplug_command(sc, val, mask);
+task_schedule:
/*
* During attach the child "pci" device is added synchronously;
* otherwise, the task is scheduled to manage the child
@@ -1185,16 +1198,16 @@
if ((sc->pcie_slot_sta & PCIEM_SLOT_STA_ABP) &&
(pci_enable_attn != 0)) {
- if (sc->flags & PCIB_DETACH_PENDING) {
+ if (sc->state == PCIB_STATE_DETACH_PENDING) {
device_printf(dev,
"Attention Button Pressed: Detach Cancelled\n");
- sc->flags &= ~PCIB_DETACH_PENDING;
+ sc->state = PCIB_STATE_ATTACHED;
callout_stop(&sc->pcie_ab_timer);
} 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;
+ sc->state = PCIB_STATE_DETACH_PENDING;
callout_reset(&sc->pcie_ab_timer, 5 * hz,
pcib_pcie_ab_timeout, sc);
}
@@ -1257,9 +1270,8 @@
sc = arg;
PCIB_HP_LOCK_ASSERT(sc);
- if (sc->flags & PCIB_DETACH_PENDING) {
- sc->flags |= PCIB_DETACHING;
- sc->flags &= ~PCIB_DETACH_PENDING;
+ if (sc->state == PCIB_STATE_DETACH_PENDING) {
+ sc->state = PCIB_STATE_DETACHING;
pcib_pcie_hotplug_update(sc, 0, 0, true);
}
}
@@ -1299,7 +1311,8 @@
if (!(sta & PCIEM_LINK_STA_DL_ACTIVE)) {
device_printf(dev,
"Timed out waiting for Data Link Layer Active\n");
- sc->flags |= PCIB_DETACHING;
+ if (sc->state == PCIB_STATE_DETACH_PENDING)
+ sc->state = PCIB_STATE_DETACHING;
pcib_pcie_hotplug_update(sc, 0, 0, true);
} else if (sta != sc->pcie_link_sta) {
device_printf(dev,
@@ -1430,11 +1443,10 @@
int error;
/* Disable the card in the slot and force it to detach. */
- if (sc->flags & PCIB_DETACH_PENDING) {
- sc->flags &= ~PCIB_DETACH_PENDING;
+ if (sc->state == PCIB_STATE_DETACH_PENDING) {
callout_stop(&sc->pcie_ab_timer);
}
- sc->flags |= PCIB_DETACHING;
+ sc->state = PCIB_STATE_DETACHING;
if (sc->flags & PCIB_HOTPLUG_CMD_PENDING) {
callout_stop(&sc->pcie_cc_timer);
diff --git a/sys/dev/pci/pcib_private.h b/sys/dev/pci/pcib_private.h
--- a/sys/dev/pci/pcib_private.h
+++ b/sys/dev/pci/pcib_private.h
@@ -114,8 +114,11 @@
#define PCIB_ENABLE_ARI 0x8
#define PCIB_HOTPLUG 0x10
#define PCIB_HOTPLUG_CMD_PENDING 0x20
-#define PCIB_DETACH_PENDING 0x40
-#define PCIB_DETACHING 0x80
+ uint32_t state;
+#define PCIB_STATE_DETACHED 0
+#define PCIB_STATE_ATTACHED 1
+#define PCIB_STATE_DETACH_PENDING 2
+#define PCIB_STATE_DETACHING 3
u_int domain; /* domain number */
u_int pribus; /* primary bus number */
struct pcib_secbus bus; /* secondary bus numbers */

File Metadata

Mime Type
text/plain
Expires
Thu, Jul 16, 8:16 PM (7 h, 48 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
35148077
Default Alt Text
D32932.id98335.diff (4 KB)

Event Timeline