On Sun, May 26, 2013 at 08:54:10AM +0900, [email protected] wrote:
> 
> The patch below does not apply to the 3.9-stable tree.
> If someone wants it applied there, or to any other stable or longterm
> tree, then please email the backport, including the original git commit
> id to <[email protected]>.

Here's the v3.9 backport:


PCI: acpiphp: Re-enumerate devices when host bridge receives Bus Check

From: Yinghai Lu <[email protected]>

Backport of 3f327e39b4 to v3.9 by Bjorn Helgaas <[email protected]>

When a PCI host bridge device receives a Bus Check notification, we
must re-enumerate starting with the bridge to discover changes (devices
that have been added or removed).

Prior to 668192b678 ("PCI: acpiphp: Move host bridge hotplug to
pci_root.c"), this happened in _handle_hotplug_event_bridge().  After that
commit, _handle_hotplug_event_bridge() is not installed for host bridges,
and the host bridge notify handler, _handle_hotplug_event_root() did not
re-enumerate.

This patch adds re-enumeration to _handle_hotplug_event_root().

This fixes cases where we don't notice the addition or removal of
PCI devices, e.g., the PCI-to-USB ExpressCard in the bugzilla below.

[bhelgaas: changelog, references]
Reference: 
https://lkml.kernel.org/r/CAAh6nkmbKR3HTqm5ommevsBwhL_u0N8Rk7Wsms_LfP=nbgk...@mail.gmail.com
Reference: https://bugzilla.kernel.org/show_bug.cgi?id=57961
Reported-by: Gavin Guo <[email protected]>
Tested-by: Gavin Guo <[email protected]>
Signed-off-by: Yinghai Lu <[email protected]>
Signed-off-by: Bjorn Helgaas <[email protected]>
Acked-by: Rafael J. Wysocki <[email protected]>
CC: [email protected]      # v3.9+
---
 drivers/acpi/pci_root.c            |    4 +++-
 drivers/pci/hotplug/acpiphp_glue.c |   12 ++++++++++++
 include/linux/pci-acpi.h           |    6 ++++++
 3 files changed, 21 insertions(+), 1 deletion(-)

diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c
index 6ae5e44..99748eb 100644
--- a/drivers/acpi/pci_root.c
+++ b/drivers/acpi/pci_root.c
@@ -687,7 +687,9 @@ static void _handle_hotplug_event_root(struct work_struct 
*work)
                /* bus enumerate */
                printk(KERN_DEBUG "%s: Bus check notify on %s\n", __func__,
                                 (char *)buffer.pointer);
-               if (!root)
+               if (root)
+                       acpiphp_check_host_bridge(handle);
+               else
                        handle_root_bridge_insertion(handle);
 
                break;
diff --git a/drivers/pci/hotplug/acpiphp_glue.c 
b/drivers/pci/hotplug/acpiphp_glue.c
index 270fdba..3f3f2cd 100644
--- a/drivers/pci/hotplug/acpiphp_glue.c
+++ b/drivers/pci/hotplug/acpiphp_glue.c
@@ -1122,6 +1122,18 @@ check_sub_bridges(acpi_handle handle, u32 lvl, void 
*context, void **rv)
        return AE_OK ;
 }
 
+void acpiphp_check_host_bridge(acpi_handle handle)
+{
+       struct acpiphp_bridge *bridge;
+
+       bridge = acpiphp_handle_to_bridge(handle);
+       if (bridge)
+               acpiphp_check_bridge(bridge);
+
+       acpi_walk_namespace(ACPI_TYPE_DEVICE, handle,
+               ACPI_UINT32_MAX, check_sub_bridges, NULL, NULL, NULL);
+}
+
 static void _handle_hotplug_event_bridge(struct work_struct *work)
 {
        struct acpiphp_bridge *bridge;
diff --git a/include/linux/pci-acpi.h b/include/linux/pci-acpi.h
index 9a22b5e..09512b2 100644
--- a/include/linux/pci-acpi.h
+++ b/include/linux/pci-acpi.h
@@ -43,6 +43,12 @@ static inline acpi_handle acpi_pci_get_bridge_handle(struct 
pci_bus *pbus)
 }
 #endif
 
+#ifdef CONFIG_HOTPLUG_PCI_ACPI
+void acpiphp_check_host_bridge(acpi_handle handle);
+#else
+static inline void acpiphp_check_host_bridge(acpi_handle handle) { }
+#endif
+
 #ifdef CONFIG_ACPI_APEI
 extern bool aer_acpi_firmware_first(void);
 #else
--
To unsubscribe from this list: send the line "unsubscribe stable" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to