drivers/pci/msi/api.c
Source file repositories/reference/linux-study-clean/drivers/pci/msi/api.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/pci/msi/api.c- Extension
.c- Size
- 13260 bytes
- Lines
- 412
- Domain
- Representative Device Path
- Bucket
- PCIe NVMe Storage Path
- Inferred role
- Representative Device Path: exported/initcall integration point
- Status
- integration 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.
- Exports symbols or registers init work; inspect boot/module ordering and who consumes the exported contract.
- Touches IRQ or DMA behavior; this matters for the representative real-device path.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/export.hlinux/irq.hmsi.h
Detected Declarations
function Copyrightfunction pci_disable_msifunction pci_msix_vec_countfunction pci_enable_msix_rangefunction pci_msix_can_alloc_dynfunction pci_msix_alloc_irq_atfunction pci_msix_free_irqfunction pci_disable_msixfunction pci_alloc_irq_vectorsfunction pci_alloc_irq_vectors_affinityfunction pci_irq_vectorfunction MSIfunction pci_free_irq_vectorsfunction pci_restore_msi_statefunction pci_msi_enabledexport pci_enable_msiexport pci_disable_msiexport pci_msix_vec_countexport pci_enable_msix_rangeexport pci_msix_can_alloc_dynexport pci_msix_alloc_irq_atexport pci_msix_free_irqexport pci_disable_msixexport pci_alloc_irq_vectorsexport pci_alloc_irq_vectors_affinityexport pci_irq_vectorexport pci_irq_get_affinityexport pci_free_irq_vectorsexport pci_restore_msi_stateexport pci_msi_enabled
Annotated Snippet
if (min_vecs == 1 && dev->irq) {
/*
* Invoke the affinity spreading logic to ensure that
* the device driver can adjust queue configuration
* for the single interrupt case.
*/
if (affd)
irq_create_affinity_masks(1, affd);
pci_intx(dev, 1);
return 1;
}
}
return nvecs;
}
EXPORT_SYMBOL(pci_alloc_irq_vectors_affinity);
/**
* pci_irq_vector() - Get Linux IRQ number of a device interrupt vector
* @dev: the PCI device to operate on
* @nr: device-relative interrupt vector index (0-based); has different
* meanings, depending on interrupt mode:
*
* * MSI-X the index in the MSI-X vector table
* * MSI the index of the enabled MSI vectors
* * INTx must be 0
*
* Return: the Linux IRQ number, or -EINVAL if @nr is out of range
*/
int pci_irq_vector(struct pci_dev *dev, unsigned int nr)
{
unsigned int irq;
if (!dev->msi_enabled && !dev->msix_enabled)
return !nr ? dev->irq : -EINVAL;
irq = msi_get_virq(&dev->dev, nr);
return irq ? irq : -EINVAL;
}
EXPORT_SYMBOL(pci_irq_vector);
/**
* pci_irq_get_affinity() - Get a device interrupt vector affinity
* @dev: the PCI device to operate on
* @nr: device-relative interrupt vector index (0-based); has different
* meanings, depending on interrupt mode:
*
* * MSI-X the index in the MSI-X vector table
* * MSI the index of the enabled MSI vectors
* * INTx must be 0
*
* Return: MSI/MSI-X vector affinity, NULL if @nr is out of range or if
* the MSI(-X) vector was allocated without explicit affinity
* requirements (e.g., by pci_enable_msi(), pci_enable_msix_range(), or
* pci_alloc_irq_vectors() without the %PCI_IRQ_AFFINITY flag). Return a
* generic set of CPU IDs representing all possible CPUs available
* during system boot if the device is in legacy INTx mode.
*/
const struct cpumask *pci_irq_get_affinity(struct pci_dev *dev, int nr)
{
int idx, irq = pci_irq_vector(dev, nr);
struct msi_desc *desc;
if (WARN_ON_ONCE(irq <= 0))
return NULL;
desc = irq_get_msi_desc(irq);
/* Non-MSI does not have the information handy */
if (!desc)
return cpu_possible_mask;
/* MSI[X] interrupts can be allocated without affinity descriptor */
if (!desc->affinity)
return NULL;
/*
* MSI has a mask array in the descriptor.
* MSI-X has a single mask.
*/
idx = dev->msi_enabled ? nr : 0;
return &desc->affinity[idx].mask;
}
EXPORT_SYMBOL(pci_irq_get_affinity);
/**
* pci_free_irq_vectors() - Free previously allocated IRQs for a device
* @dev: the PCI device to operate on
*
* Undo the interrupt vector allocations and possible device MSI/MSI-X
* enablement earlier done through pci_alloc_irq_vectors_affinity() or
Annotation
- Immediate include surface: `linux/export.h`, `linux/irq.h`, `msi.h`.
- Detected declarations: `function Copyright`, `function pci_disable_msi`, `function pci_msix_vec_count`, `function pci_enable_msix_range`, `function pci_msix_can_alloc_dyn`, `function pci_msix_alloc_irq_at`, `function pci_msix_free_irq`, `function pci_disable_msix`, `function pci_alloc_irq_vectors`, `function pci_alloc_irq_vectors_affinity`.
- Atlas domain: Representative Device Path / PCIe NVMe Storage Path.
- Implementation status: integration implementation candidate.
- 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.