Loading drivers/pci/hotplug/acpiphp.h +10 −0 Original line number Diff line number Diff line Loading @@ -142,6 +142,16 @@ static inline acpi_handle func_to_handle(struct acpiphp_func *func) return func_to_acpi_device(func)->handle; } struct acpiphp_root_context { struct acpi_hotplug_context hp; struct acpiphp_bridge *root_bridge; }; static inline struct acpiphp_root_context *to_acpiphp_root_context(struct acpi_hotplug_context *hp) { return container_of(hp, struct acpiphp_root_context, hp); } /* * struct acpiphp_attention_info - device specific attention registration * Loading drivers/pci/hotplug/acpiphp_glue.c +42 −18 Original line number Diff line number Diff line Loading @@ -373,17 +373,13 @@ static acpi_status acpiphp_add_context(acpi_handle handle, u32 lvl, void *data, static struct acpiphp_bridge *acpiphp_dev_to_bridge(struct acpi_device *adev) { struct acpiphp_context *context; struct acpiphp_bridge *bridge = NULL; acpi_lock_hp_context(); context = acpiphp_get_context(adev); if (context) { bridge = context->bridge; if (adev->hp) { bridge = to_acpiphp_root_context(adev->hp)->root_bridge; if (bridge) get_bridge(bridge); acpiphp_put_context(context); } acpi_unlock_hp_context(); return bridge; Loading Loading @@ -881,7 +877,17 @@ void acpiphp_enumerate_slots(struct pci_bus *bus) */ get_device(&bus->dev); if (!pci_is_root_bus(bridge->pci_bus)) { acpi_lock_hp_context(); if (pci_is_root_bus(bridge->pci_bus)) { struct acpiphp_root_context *root_context; root_context = kzalloc(sizeof(*root_context), GFP_KERNEL); if (!root_context) goto err; root_context->root_bridge = bridge; acpi_set_hp_context(adev, &root_context->hp, NULL, NULL, NULL); } else { struct acpiphp_context *context; /* Loading @@ -890,21 +896,16 @@ void acpiphp_enumerate_slots(struct pci_bus *bus) * parent is going to be handled by pciehp, in which case this * bridge is not interesting to us either. */ acpi_lock_hp_context(); context = acpiphp_get_context(adev); if (!context) { acpi_unlock_hp_context(); put_device(&bus->dev); pci_dev_put(bridge->pci_dev); kfree(bridge); return; } if (!context) goto err; bridge->context = context; context->bridge = bridge; /* Get a reference to the parent bridge. */ get_bridge(context->func.parent); acpi_unlock_hp_context(); } acpi_unlock_hp_context(); /* Must be added to the list prior to calling acpiphp_add_context(). */ mutex_lock(&bridge_mutex); Loading @@ -919,6 +920,30 @@ void acpiphp_enumerate_slots(struct pci_bus *bus) cleanup_bridge(bridge); put_bridge(bridge); } return; err: acpi_unlock_hp_context(); put_device(&bus->dev); pci_dev_put(bridge->pci_dev); kfree(bridge); } void acpiphp_drop_bridge(struct acpiphp_bridge *bridge) { if (pci_is_root_bus(bridge->pci_bus)) { struct acpiphp_root_context *root_context; struct acpi_device *adev; acpi_lock_hp_context(); adev = ACPI_COMPANION(bridge->pci_bus->bridge); root_context = to_acpiphp_root_context(adev->hp); adev->hp = NULL; acpi_unlock_hp_context(); kfree(root_context); } cleanup_bridge(bridge); put_bridge(bridge); } /** Loading @@ -936,8 +961,7 @@ void acpiphp_remove_slots(struct pci_bus *bus) list_for_each_entry(bridge, &bridge_list, list) if (bridge->pci_bus == bus) { mutex_unlock(&bridge_mutex); cleanup_bridge(bridge); put_bridge(bridge); acpiphp_drop_bridge(bridge); return; } Loading Loading
drivers/pci/hotplug/acpiphp.h +10 −0 Original line number Diff line number Diff line Loading @@ -142,6 +142,16 @@ static inline acpi_handle func_to_handle(struct acpiphp_func *func) return func_to_acpi_device(func)->handle; } struct acpiphp_root_context { struct acpi_hotplug_context hp; struct acpiphp_bridge *root_bridge; }; static inline struct acpiphp_root_context *to_acpiphp_root_context(struct acpi_hotplug_context *hp) { return container_of(hp, struct acpiphp_root_context, hp); } /* * struct acpiphp_attention_info - device specific attention registration * Loading
drivers/pci/hotplug/acpiphp_glue.c +42 −18 Original line number Diff line number Diff line Loading @@ -373,17 +373,13 @@ static acpi_status acpiphp_add_context(acpi_handle handle, u32 lvl, void *data, static struct acpiphp_bridge *acpiphp_dev_to_bridge(struct acpi_device *adev) { struct acpiphp_context *context; struct acpiphp_bridge *bridge = NULL; acpi_lock_hp_context(); context = acpiphp_get_context(adev); if (context) { bridge = context->bridge; if (adev->hp) { bridge = to_acpiphp_root_context(adev->hp)->root_bridge; if (bridge) get_bridge(bridge); acpiphp_put_context(context); } acpi_unlock_hp_context(); return bridge; Loading Loading @@ -881,7 +877,17 @@ void acpiphp_enumerate_slots(struct pci_bus *bus) */ get_device(&bus->dev); if (!pci_is_root_bus(bridge->pci_bus)) { acpi_lock_hp_context(); if (pci_is_root_bus(bridge->pci_bus)) { struct acpiphp_root_context *root_context; root_context = kzalloc(sizeof(*root_context), GFP_KERNEL); if (!root_context) goto err; root_context->root_bridge = bridge; acpi_set_hp_context(adev, &root_context->hp, NULL, NULL, NULL); } else { struct acpiphp_context *context; /* Loading @@ -890,21 +896,16 @@ void acpiphp_enumerate_slots(struct pci_bus *bus) * parent is going to be handled by pciehp, in which case this * bridge is not interesting to us either. */ acpi_lock_hp_context(); context = acpiphp_get_context(adev); if (!context) { acpi_unlock_hp_context(); put_device(&bus->dev); pci_dev_put(bridge->pci_dev); kfree(bridge); return; } if (!context) goto err; bridge->context = context; context->bridge = bridge; /* Get a reference to the parent bridge. */ get_bridge(context->func.parent); acpi_unlock_hp_context(); } acpi_unlock_hp_context(); /* Must be added to the list prior to calling acpiphp_add_context(). */ mutex_lock(&bridge_mutex); Loading @@ -919,6 +920,30 @@ void acpiphp_enumerate_slots(struct pci_bus *bus) cleanup_bridge(bridge); put_bridge(bridge); } return; err: acpi_unlock_hp_context(); put_device(&bus->dev); pci_dev_put(bridge->pci_dev); kfree(bridge); } void acpiphp_drop_bridge(struct acpiphp_bridge *bridge) { if (pci_is_root_bus(bridge->pci_bus)) { struct acpiphp_root_context *root_context; struct acpi_device *adev; acpi_lock_hp_context(); adev = ACPI_COMPANION(bridge->pci_bus->bridge); root_context = to_acpiphp_root_context(adev->hp); adev->hp = NULL; acpi_unlock_hp_context(); kfree(root_context); } cleanup_bridge(bridge); put_bridge(bridge); } /** Loading @@ -936,8 +961,7 @@ void acpiphp_remove_slots(struct pci_bus *bus) list_for_each_entry(bridge, &bridge_list, list) if (bridge->pci_bus == bus) { mutex_unlock(&bridge_mutex); cleanup_bridge(bridge); put_bridge(bridge); acpiphp_drop_bridge(bridge); return; } Loading