drivers/pci/pci-driver.c
Source file repositories/reference/linux-study-clean/drivers/pci/pci-driver.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/pci/pci-driver.c- Extension
.c- Size
- 45692 bytes
- Lines
- 1772
- Domain
- Representative Device Path
- Bucket
- PCIe NVMe Storage Path
- Inferred role
- Representative Device Path: operation-table or driver-model contract
- Status
- pattern 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.
- Defines an operation table; this is where Linux turns generic core objects into subsystem-specific behavior.
- Uses kernel synchronization; read lock ordering, sleepability, and interrupt context assumptions before translating.
- Touches IRQ or DMA behavior; this matters for the representative real-device path.
- 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/pci.hlinux/module.hlinux/init.hlinux/device.hlinux/mempolicy.hlinux/string.hlinux/slab.hlinux/sched.hlinux/sched/isolation.hlinux/cpu.hlinux/pm_runtime.hlinux/suspend.hlinux/kexec.hlinux/of_device.hlinux/acpi.hlinux/dma-map-ops.hlinux/iommu.hpci.hpcie/portdrv.h
Detected Declarations
struct pci_dynidstruct drv_dev_and_idstruct pci_probe_argfunction pci_add_dynidfunction pci_free_dynidsfunction _pci_free_devicefunction new_id_storefunction remove_id_storefunction local_pci_probefunction local_pci_probe_callbackfunction pci_physfn_is_probedfunction pci_call_probefunction work_on_cpufunction pci_probe_flush_workqueuefunction __pci_device_probefunction pci_device_can_probefunction pci_device_can_probefunction pci_device_probefunction pci_device_removefunction pci_device_shutdownfunction pci_restore_standard_configfunction pci_pm_default_resumefunction pci_pm_default_resume_earlyfunction pci_pm_bridge_power_up_actionsfunction allfunction allfunction pci_legacy_suspendfunction pci_legacy_suspend_latefunction pci_legacy_resumefunction pci_pm_default_suspendfunction pci_has_legacy_pm_supportfunction pci_pm_preparefunction pci_pm_completefunction pcie_pme_root_status_cleanupfunction pci_pm_suspendfunction pci_pm_suspend_latefunction pci_pm_suspend_noirqfunction pci_pm_resume_noirqfunction pci_pm_resume_earlyfunction pci_pm_resumefunction pci_pm_freezefunction pci_pm_freeze_noirqfunction pci_pm_thaw_noirqfunction pci_pm_thawfunction pci_pm_powerofffunction pci_pm_poweroff_latefunction pci_pm_poweroff_noirqfunction pci_pm_restore_noirq
Annotated Snippet
int pci_add_dynid(struct pci_driver *drv,
unsigned int vendor, unsigned int device,
unsigned int subvendor, unsigned int subdevice,
unsigned int class, unsigned int class_mask,
unsigned long driver_data)
{
struct pci_dynid *dynid;
dynid = kzalloc_obj(*dynid);
if (!dynid)
return -ENOMEM;
dynid->id.vendor = vendor;
dynid->id.device = device;
dynid->id.subvendor = subvendor;
dynid->id.subdevice = subdevice;
dynid->id.class = class;
dynid->id.class_mask = class_mask;
dynid->id.driver_data = driver_data;
spin_lock(&drv->dynids.lock);
list_add_tail(&dynid->node, &drv->dynids.list);
spin_unlock(&drv->dynids.lock);
return driver_attach(&drv->driver);
}
EXPORT_SYMBOL_GPL(pci_add_dynid);
static void pci_free_dynids(struct pci_driver *drv)
{
struct pci_dynid *dynid, *n;
spin_lock(&drv->dynids.lock);
list_for_each_entry_safe(dynid, n, &drv->dynids.list, node) {
list_del(&dynid->node);
kfree(dynid);
}
spin_unlock(&drv->dynids.lock);
}
/**
* pci_match_id - See if a PCI device matches a given pci_id table
* @ids: array of PCI device ID structures to search in
* @dev: the PCI device structure to match against.
*
* Used by a driver to check whether a PCI device is in its list of
* supported devices. Returns the matching pci_device_id structure or
* %NULL if there is no match.
*
* Deprecated; don't use this as it will not catch any dynamic IDs
* that a driver might want to check for.
*/
const struct pci_device_id *pci_match_id(const struct pci_device_id *ids,
struct pci_dev *dev)
{
if (ids) {
while (ids->vendor || ids->subvendor || ids->class_mask) {
if (pci_match_one_device(ids, dev))
return ids;
ids++;
}
}
return NULL;
}
EXPORT_SYMBOL(pci_match_id);
static const struct pci_device_id pci_device_id_any = {
.vendor = PCI_ANY_ID,
.device = PCI_ANY_ID,
.subvendor = PCI_ANY_ID,
.subdevice = PCI_ANY_ID,
};
/**
* pci_match_device - See if a device matches a driver's list of IDs
* @drv: the PCI driver to match against
* @dev: the PCI device structure to match against
*
* Used by a driver to check whether a PCI device is in its list of
* supported devices or in the dynids list, which may have been augmented
* via the sysfs "new_id" file. Returns the matching pci_device_id
* structure or %NULL if there is no match.
*/
static const struct pci_device_id *pci_match_device(struct pci_driver *drv,
struct pci_dev *dev)
{
struct pci_dynid *dynid;
const struct pci_device_id *found_id = NULL, *ids;
int ret;
Annotation
- Immediate include surface: `linux/pci.h`, `linux/module.h`, `linux/init.h`, `linux/device.h`, `linux/mempolicy.h`, `linux/string.h`, `linux/slab.h`, `linux/sched.h`.
- Detected declarations: `struct pci_dynid`, `struct drv_dev_and_id`, `struct pci_probe_arg`, `function pci_add_dynid`, `function pci_free_dynids`, `function _pci_free_device`, `function new_id_store`, `function remove_id_store`, `function local_pci_probe`, `function local_pci_probe_callback`.
- Atlas domain: Representative Device Path / PCIe NVMe Storage Path.
- Implementation status: pattern implementation candidate.
- Synchronization appears in or near this file; preserve lock ordering, sleepability, and interrupt-context constraints.
- IRQ or DMA behavior appears here, which is relevant to the selected PCIe/NVMe device path.
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.