mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git
synced 2025-01-07 22:42:04 +00:00
PCI: acpiphp: Re-enumerate devices when host bridge receives Bus Check
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=nBgKNew@mail.gmail.com
Reference: https://bugzilla.kernel.org/show_bug.cgi?id=57961
Reported-by: Gavin Guo <tuffkidtt@gmail.com>
Tested-by: Gavin Guo <tuffkidtt@gmail.com>
Signed-off-by: Yinghai Lu <yinghai@kernel.org>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Reviewed-by: Jiang Liu <jiang.liu@huawei.com>
Acked-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
CC: stable@vger.kernel.org # v3.9+
This commit is contained in:
parent
f722406faa
commit
3f327e39b4
@ -641,7 +641,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;
|
||||
|
@ -950,6 +950,20 @@ 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);
|
||||
put_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;
|
||||
|
@ -60,11 +60,13 @@ static inline void acpi_pci_slot_remove(struct pci_bus *bus) { }
|
||||
void acpiphp_init(void);
|
||||
void acpiphp_enumerate_slots(struct pci_bus *bus, acpi_handle handle);
|
||||
void acpiphp_remove_slots(struct pci_bus *bus);
|
||||
void acpiphp_check_host_bridge(acpi_handle handle);
|
||||
#else
|
||||
static inline void acpiphp_init(void) { }
|
||||
static inline void acpiphp_enumerate_slots(struct pci_bus *bus,
|
||||
acpi_handle handle) { }
|
||||
static inline void acpiphp_remove_slots(struct pci_bus *bus) { }
|
||||
static inline void acpiphp_check_host_bridge(acpi_handle handle) { }
|
||||
#endif
|
||||
|
||||
#else /* CONFIG_ACPI */
|
||||
|
Loading…
Reference in New Issue
Block a user