drivers/dma/acpi-dma.c
Source file repositories/reference/linux-study-clean/drivers/dma/acpi-dma.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/dma/acpi-dma.c- Extension
.c- Size
- 13091 bytes
- Lines
- 463
- Domain
- Driver Families
- Bucket
- drivers/dma
- Inferred role
- Driver Families: exported/initcall integration point
- Status
- integration 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.
- Exports symbols or registers init work; inspect boot/module ordering and who consumes the exported contract.
- 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/acpi.hlinux/acpi_dma.hlinux/device.hlinux/dma-mapping.hlinux/err.hlinux/errno.hlinux/export.hlinux/ioport.hlinux/kernel.hlinux/list.hlinux/mutex.hlinux/property.hlinux/slab.hlinux/string.hlinux/types.h
Detected Declarations
struct acpi_dma_parser_datafunction acpi_dma_parse_resource_groupfunction list_for_each_entryfunction acpi_dma_parse_csrtfunction acpi_dma_controller_freefunction acpi_dma_controller_registerfunction list_for_each_entryfunction devm_acpi_dma_freefunction acpi_dma_controller_registerfunction acpi_dma_update_dma_specfunction acpi_dma_parse_fixed_dmafunction list_for_each_entryexport acpi_dma_controller_registerexport acpi_dma_controller_freeexport devm_acpi_dma_controller_registerexport acpi_dma_request_slave_chan_by_indexexport acpi_dma_request_slave_chan_by_nameexport acpi_dma_simple_xlate
Annotated Snippet
struct acpi_dma_parser_data {
struct acpi_dma_spec dma_spec;
size_t index;
size_t n;
};
/**
* acpi_dma_parse_fixed_dma - Parse FixedDMA ACPI resources to a DMA specifier
* @res: struct acpi_resource to get FixedDMA resources from
* @data: pointer to a helper struct acpi_dma_parser_data
*/
static int acpi_dma_parse_fixed_dma(struct acpi_resource *res, void *data)
{
struct acpi_dma_parser_data *pdata = data;
if (res->type == ACPI_RESOURCE_TYPE_FIXED_DMA) {
struct acpi_resource_fixed_dma *dma = &res->data.fixed_dma;
if (pdata->n++ == pdata->index) {
pdata->dma_spec.chan_id = dma->channels;
pdata->dma_spec.slave_id = dma->request_lines;
}
}
/* Tell the ACPI core to skip this resource */
return 1;
}
/**
* acpi_dma_request_slave_chan_by_index - Get the DMA slave channel
* @dev: struct device to get DMA request from
* @index: index of FixedDMA descriptor for @dev
*
* Return:
* Pointer to appropriate dma channel on success or an error pointer.
*/
struct dma_chan *acpi_dma_request_slave_chan_by_index(struct device *dev,
size_t index)
{
struct acpi_dma_parser_data pdata;
struct acpi_dma_spec *dma_spec = &pdata.dma_spec;
struct acpi_device *adev = ACPI_COMPANION(dev);
struct list_head resource_list;
struct acpi_dma *adma;
struct dma_chan *chan = NULL;
int found;
int ret;
memset(&pdata, 0, sizeof(pdata));
pdata.index = index;
/* Initial values for the request line and channel */
dma_spec->chan_id = -1;
dma_spec->slave_id = -1;
INIT_LIST_HEAD(&resource_list);
ret = acpi_dev_get_resources(adev, &resource_list,
acpi_dma_parse_fixed_dma, &pdata);
acpi_dev_free_resource_list(&resource_list);
if (ret < 0)
return ERR_PTR(ret);
if (dma_spec->slave_id < 0 || dma_spec->chan_id < 0)
return ERR_PTR(-ENODEV);
mutex_lock(&acpi_dma_lock);
list_for_each_entry(adma, &acpi_dma_list, dma_controllers) {
/*
* We are not going to call translation function if slave_id
* doesn't fall to the request range.
*/
found = acpi_dma_update_dma_spec(adma, dma_spec);
if (found < 0)
continue;
chan = adma->acpi_dma_xlate(dma_spec, adma);
/*
* Try to get a channel only from the DMA controller that
* matches the slave_id. See acpi_dma_update_dma_spec()
* description for the details.
*/
if (found > 0 || chan)
break;
}
mutex_unlock(&acpi_dma_lock);
return chan ? chan : ERR_PTR(-EPROBE_DEFER);
}
EXPORT_SYMBOL_GPL(acpi_dma_request_slave_chan_by_index);
Annotation
- Immediate include surface: `linux/acpi.h`, `linux/acpi_dma.h`, `linux/device.h`, `linux/dma-mapping.h`, `linux/err.h`, `linux/errno.h`, `linux/export.h`, `linux/ioport.h`.
- Detected declarations: `struct acpi_dma_parser_data`, `function acpi_dma_parse_resource_group`, `function list_for_each_entry`, `function acpi_dma_parse_csrt`, `function acpi_dma_controller_free`, `function acpi_dma_controller_register`, `function list_for_each_entry`, `function devm_acpi_dma_free`, `function acpi_dma_controller_register`, `function acpi_dma_update_dma_spec`.
- Atlas domain: Driver Families / drivers/dma.
- Implementation status: integration 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.