drivers/pci/hotplug/acpiphp_glue.c
Source file repositories/reference/linux-study-clean/drivers/pci/hotplug/acpiphp_glue.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/pci/hotplug/acpiphp_glue.c- Extension
.c- Size
- 26721 bytes
- Lines
- 1069
- Domain
- Representative Device Path
- Bucket
- PCIe NVMe Storage Path
- Inferred role
- Representative Device Path: implementation source
- Status
- source implementation candidate
Why This File Exists
Part of the selected hardware vertical slice: PCI discovery, driver binding, NVMe queues, block requests, DMA, interrupts, and completion.
- Part of the selected hardware vertical slice: PCI discovery, driver binding, NVMe queues, block requests, DMA, interrupts, and completion.
- Uses kernel synchronization; read lock ordering, sleepability, and interrupt context assumptions before translating.
- Allocates kernel memory; connect allocation flags and lifetime to context constraints.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/module.hlinux/kernel.hlinux/pci.hlinux/pci_hotplug.hlinux/pci-acpi.hlinux/pm_runtime.hlinux/mutex.hlinux/slab.hlinux/acpi.h../pci.hacpiphp.h
Detected Declarations
function acpiphp_put_contextfunction get_bridgefunction put_bridgefunction acpiphp_let_context_gofunction free_bridgefunction list_for_each_entry_safefunction acpiphp_post_dock_fixupfunction acpiphp_add_contextfunction hotplugfunction cleanup_bridgefunction list_for_each_entryfunction acpiphp_max_busnrfunction list_for_each_entryfunction acpiphp_set_acpi_regionfunction list_for_each_entryfunction check_hotplug_bridgefunction list_for_each_entryfunction acpiphp_rescan_slotfunction list_for_each_entryfunction acpiphp_native_scan_bridgefunction enable_slotfunction for_each_pci_bridgefunction list_for_each_entryfunction disable_slotfunction slot_no_hotplugfunction list_for_each_entryfunction get_slot_statusfunction list_for_each_entryfunction device_status_validfunction trim_stale_devicesfunction acpiphp_check_bridgefunction list_for_each_entryfunction acpiphp_sanitize_busfunction list_for_each_entry_safe_reversefunction acpiphp_check_host_bridgefunction hotplug_eventfunction acpiphp_hotplug_notifyfunction acpiphp_enumerate_slotsfunction acpiphp_drop_bridgefunction acpiphp_remove_slotsfunction acpiphp_enable_slotfunction acpiphp_disable_and_eject_slotfunction list_for_each_entryfunction acpiphp_disable_slotfunction acpiphp_get_power_statusfunction acpiphp_get_latch_statusfunction acpiphp_get_adapter_status
Annotated Snippet
if (retval) {
slot->slot = NULL;
bridge->nr_slots--;
if (retval == -EBUSY)
pr_warn("Slot %llu already registered by another hotplug driver\n", sun);
else
pr_warn("acpiphp_register_hotplug_slot failed (err code = 0x%x)\n", retval);
}
/* Even if the slot registration fails, we can still use it. */
}
slot_found:
newfunc->slot = slot;
list_add_tail(&newfunc->sibling, &slot->funcs);
if (pci_bus_read_dev_vendor_id(pbus, PCI_DEVFN(device, function),
&val, 60*1000))
slot->flags |= SLOT_ENABLED;
return AE_OK;
}
static void cleanup_bridge(struct acpiphp_bridge *bridge)
{
struct acpiphp_slot *slot;
struct acpiphp_func *func;
list_for_each_entry(slot, &bridge->slots, node) {
list_for_each_entry(func, &slot->funcs, sibling) {
struct acpi_device *adev = func_to_acpi_device(func);
acpi_lock_hp_context();
adev->hp->notify = NULL;
adev->hp->fixup = NULL;
acpi_unlock_hp_context();
}
slot->flags |= SLOT_IS_GOING_AWAY;
if (slot->slot)
acpiphp_unregister_hotplug_slot(slot);
}
mutex_lock(&bridge_mutex);
list_del(&bridge->list);
mutex_unlock(&bridge_mutex);
acpi_lock_hp_context();
bridge->is_going_away = true;
acpi_unlock_hp_context();
}
/**
* acpiphp_max_busnr - return the highest reserved bus number under the given bus.
* @bus: bus to start search with
*/
static unsigned char acpiphp_max_busnr(struct pci_bus *bus)
{
struct pci_bus *tmp;
unsigned char max, n;
/*
* pci_bus_max_busnr will return the highest
* reserved busnr for all these children.
* that is equivalent to the bus->subordinate
* value. We don't want to use the parent's
* bus->subordinate value because it could have
* padding in it.
*/
max = bus->busn_res.start;
list_for_each_entry(tmp, &bus->children, node) {
n = pci_bus_max_busnr(tmp);
if (n > max)
max = n;
}
return max;
}
static void acpiphp_set_acpi_region(struct acpiphp_slot *slot)
{
struct acpiphp_func *func;
list_for_each_entry(func, &slot->funcs, sibling) {
/* _REG is optional, we don't care about if there is failure */
acpi_evaluate_reg(func_to_handle(func),
ACPI_ADR_SPACE_PCI_CONFIG,
ACPI_REG_CONNECT);
}
}
static void check_hotplug_bridge(struct acpiphp_slot *slot, struct pci_dev *dev)
Annotation
- Immediate include surface: `linux/module.h`, `linux/kernel.h`, `linux/pci.h`, `linux/pci_hotplug.h`, `linux/pci-acpi.h`, `linux/pm_runtime.h`, `linux/mutex.h`, `linux/slab.h`.
- Detected declarations: `function acpiphp_put_context`, `function get_bridge`, `function put_bridge`, `function acpiphp_let_context_go`, `function free_bridge`, `function list_for_each_entry_safe`, `function acpiphp_post_dock_fixup`, `function acpiphp_add_context`, `function hotplug`, `function cleanup_bridge`.
- Atlas domain: Representative Device Path / PCIe NVMe Storage Path.
- Implementation status: source implementation candidate.
- Synchronization appears in or near this file; preserve lock ordering, sleepability, and interrupt-context constraints.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.