drivers/xen/xen-pciback/conf_space.c
Source file repositories/reference/linux-study-clean/drivers/xen/xen-pciback/conf_space.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/xen/xen-pciback/conf_space.c- Extension
.c- Size
- 11735 bytes
- Lines
- 472
- 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.
- 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/kernel.hlinux/moduleparam.hlinux/pci.hpciback.hconf_space.hconf_space_quirks.h
Detected Declarations
function conf_space_readfunction conf_space_writefunction get_maskfunction valid_requestfunction merge_valuefunction xen_pcibios_err_to_errnofunction xen_pcibk_config_readfunction list_for_each_entryfunction xen_pcibk_config_writefunction list_for_each_entryfunction xen_pcibk_get_interrupt_typefunction xen_pcibk_config_free_dyn_fieldsfunction list_for_each_entry_safefunction xen_pcibk_config_reset_devfunction list_for_each_entryfunction xen_pcibk_config_free_devfunction list_for_each_entry_safefunction xen_pcibk_config_add_field_offsetfunction registersfunction xen_pcibk_config_init
Annotated Snippet
if (offset + size > field_start && field_end > offset) {
err = conf_space_read(dev, cfg_entry, field_start,
&tmp_val);
if (err)
goto out;
value = merge_value(value, tmp_val,
get_mask(field->size),
field_start - offset);
}
}
out:
dev_dbg(&dev->dev, "read %d bytes at 0x%x = %x\n", size, offset, value);
*ret_val = value;
return xen_pcibios_err_to_errno(err);
}
int xen_pcibk_config_write(struct pci_dev *dev, int offset, int size, u32 value)
{
int err = 0, handled = 0;
struct xen_pcibk_dev_data *dev_data = pci_get_drvdata(dev);
const struct config_field_entry *cfg_entry;
const struct config_field *field;
u32 tmp_val;
int field_start, field_end;
dev_dbg(&dev->dev, "write request %d bytes at 0x%x = %x\n",
size, offset, value);
if (!valid_request(offset, size))
return XEN_PCI_ERR_invalid_offset;
list_for_each_entry(cfg_entry, &dev_data->config_fields, list) {
field = cfg_entry->field;
field_start = OFFSET(cfg_entry);
field_end = OFFSET(cfg_entry) + field->size;
if (offset + size > field_start && field_end > offset) {
err = conf_space_read(dev, cfg_entry, field_start,
&tmp_val);
if (err)
break;
tmp_val = merge_value(tmp_val, value, get_mask(size),
offset - field_start);
err = conf_space_write(dev, cfg_entry, field_start,
tmp_val);
/* handled is set true here, but not every byte
* may have been written! Properly detecting if
* every byte is handled is unnecessary as the
* flag is used to detect devices that need
* special helpers to work correctly.
*/
handled = 1;
}
}
if (!handled && !err) {
/* By default, anything not specificially handled above is
* read-only. The permissive flag changes this behavior so
* that anything not specifically handled above is writable.
* This means that some fields may still be read-only because
* they have entries in the config_field list that intercept
* the write and do nothing. */
if (dev_data->permissive || xen_pcibk_permissive) {
switch (size) {
case 1:
err = pci_write_config_byte(dev, offset,
(u8) value);
break;
case 2:
err = pci_write_config_word(dev, offset,
(u16) value);
break;
case 4:
err = pci_write_config_dword(dev, offset,
(u32) value);
break;
}
} else if (!dev_data->warned_on_write) {
dev_data->warned_on_write = 1;
dev_warn(&dev->dev, "Driver tried to write to a "
"read-only configuration space field at offset"
" 0x%x, size %d. This may be harmless, but if "
"you have problems with your device:\n"
Annotation
- Immediate include surface: `linux/kernel.h`, `linux/moduleparam.h`, `linux/pci.h`, `pciback.h`, `conf_space.h`, `conf_space_quirks.h`.
- Detected declarations: `function conf_space_read`, `function conf_space_write`, `function get_mask`, `function valid_request`, `function merge_value`, `function xen_pcibios_err_to_errno`, `function xen_pcibk_config_read`, `function list_for_each_entry`, `function xen_pcibk_config_write`, `function list_for_each_entry`.
- Atlas domain: Driver Families / drivers/xen.
- Implementation status: source 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.