drivers/xen/xen-pciback/vpci.c
Source file repositories/reference/linux-study-clean/drivers/xen/xen-pciback/vpci.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/xen/xen-pciback/vpci.c- Extension
.c- Size
- 6315 bytes
- Lines
- 269
- Domain
- Driver Families
- Bucket
- drivers/xen
- Inferred role
- Driver Families: implementation source
- Status
- source implementation candidate
Why This File Exists
Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- 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/list.hlinux/slab.hlinux/pci.hlinux/mutex.hpciback.h
Detected Declarations
struct vpci_dev_datafunction list_for_each_entryfunction match_slotfunction __xen_pcibk_add_pci_devfunction __xen_pcibk_release_pci_devfunction list_for_each_entryfunction __xen_pcibk_init_devicesfunction __xen_pcibk_publish_pci_rootsfunction __xen_pcibk_release_devicesfunction list_for_each_entry_safefunction __xen_pcibk_get_pcifront_devfunction list_for_each_entry
Annotated Snippet
struct vpci_dev_data {
/* Access to dev_list must be protected by lock */
struct list_head dev_list[PCI_SLOT_MAX];
struct mutex lock;
};
static inline struct list_head *list_first(struct list_head *head)
{
return head->next;
}
static struct pci_dev *__xen_pcibk_get_pci_dev(struct xen_pcibk_device *pdev,
unsigned int domain,
unsigned int bus,
unsigned int devfn)
{
struct pci_dev_entry *entry;
struct pci_dev *dev = NULL;
struct vpci_dev_data *vpci_dev = pdev->pci_dev_data;
if (domain != 0 || bus != 0)
return NULL;
if (PCI_SLOT(devfn) < PCI_SLOT_MAX) {
mutex_lock(&vpci_dev->lock);
list_for_each_entry(entry,
&vpci_dev->dev_list[PCI_SLOT(devfn)],
list) {
if (PCI_FUNC(entry->dev->devfn) == PCI_FUNC(devfn)) {
dev = entry->dev;
break;
}
}
mutex_unlock(&vpci_dev->lock);
}
return dev;
}
static inline int match_slot(struct pci_dev *l, struct pci_dev *r)
{
if (pci_domain_nr(l->bus) == pci_domain_nr(r->bus)
&& l->bus == r->bus && PCI_SLOT(l->devfn) == PCI_SLOT(r->devfn))
return 1;
return 0;
}
static int __xen_pcibk_add_pci_dev(struct xen_pcibk_device *pdev,
struct pci_dev *dev, int devid,
publish_pci_dev_cb publish_cb)
{
int err = 0, slot, func = PCI_FUNC(dev->devfn);
struct pci_dev_entry *t, *dev_entry;
struct vpci_dev_data *vpci_dev = pdev->pci_dev_data;
if ((dev->class >> 24) == PCI_BASE_CLASS_BRIDGE) {
err = -EFAULT;
xenbus_dev_fatal(pdev->xdev, err,
"Can't export bridges on the virtual PCI bus");
goto out;
}
dev_entry = kmalloc_obj(*dev_entry);
if (!dev_entry) {
err = -ENOMEM;
xenbus_dev_fatal(pdev->xdev, err,
"Error adding entry to virtual PCI bus");
goto out;
}
dev_entry->dev = dev;
mutex_lock(&vpci_dev->lock);
/*
* Keep multi-function devices together on the virtual PCI bus, except
* that we want to keep virtual functions at func 0 on their own. They
* aren't multi-function devices and hence their presence at func 0
* may cause guests to not scan the other functions.
*/
if (!dev->is_virtfn || func) {
for (slot = 0; slot < PCI_SLOT_MAX; slot++) {
if (list_empty(&vpci_dev->dev_list[slot]))
continue;
t = list_entry(list_first(&vpci_dev->dev_list[slot]),
struct pci_dev_entry, list);
if (t->dev->is_virtfn && !PCI_FUNC(t->dev->devfn))
Annotation
- Immediate include surface: `linux/list.h`, `linux/slab.h`, `linux/pci.h`, `linux/mutex.h`, `pciback.h`.
- Detected declarations: `struct vpci_dev_data`, `function list_for_each_entry`, `function match_slot`, `function __xen_pcibk_add_pci_dev`, `function __xen_pcibk_release_pci_dev`, `function list_for_each_entry`, `function __xen_pcibk_init_devices`, `function __xen_pcibk_publish_pci_roots`, `function __xen_pcibk_release_devices`, `function list_for_each_entry_safe`.
- Atlas domain: Driver Families / drivers/xen.
- 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.