drivers/dma/idma64.c
Source file repositories/reference/linux-study-clean/drivers/dma/idma64.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/dma/idma64.c- Extension
.c- Size
- 18205 bytes
- Lines
- 709
- Domain
- Driver Families
- Bucket
- drivers/dma
- 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.
- 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/bitops.hlinux/delay.hlinux/dmaengine.hlinux/dma-mapping.hlinux/dmapool.hlinux/init.hlinux/module.hlinux/platform_device.hlinux/slab.hlinux/dma/idma64.hidma64.h
Detected Declarations
function Copyrightfunction idma64_offfunction idma64_onfunction idma64_chan_initfunction idma64_chan_stopfunction idma64_chan_startfunction idma64_stop_transferfunction idma64_start_transferfunction idma64_chan_irqfunction idma64_irqfunction idma64_desc_freefunction idma64_vdesc_freefunction idma64_hw_desc_fillfunction idma64_desc_fillfunction for_each_sgfunction idma64_issue_pendingfunction idma64_active_desc_sizefunction idma64_tx_statusfunction convert_burstfunction idma64_slave_configfunction idma64_chan_deactivatefunction idma64_chan_activatefunction idma64_pausefunction idma64_resumefunction idma64_terminate_allfunction idma64_synchronizefunction idma64_alloc_chan_resourcesfunction idma64_free_chan_resourcesfunction idma64_probefunction idma64_removefunction idma64_platform_probefunction idma64_platform_removefunction idma64_pm_suspendfunction idma64_pm_resume
Annotated Snippet
if (status_err & (1 << c)) {
dma_writel(idma64, CLEAR(ERROR), idma64c->mask);
desc->status = DMA_ERROR;
} else if (status_xfer & (1 << c)) {
dma_writel(idma64, CLEAR(XFER), idma64c->mask);
desc->status = DMA_COMPLETE;
vchan_cookie_complete(&desc->vdesc);
stat->bytes_transferred += desc->length;
idma64_start_transfer(idma64c);
}
/* idma64_start_transfer() updates idma64c->desc */
if (idma64c->desc == NULL || desc->status == DMA_ERROR)
idma64_stop_transfer(idma64c);
}
spin_unlock(&idma64c->vchan.lock);
}
static irqreturn_t idma64_irq(int irq, void *dev)
{
struct idma64 *idma64 = dev;
u32 status = dma_readl(idma64, STATUS_INT);
u32 status_xfer;
u32 status_err;
unsigned short i;
/* Since IRQ may be shared, check if DMA controller is powered on */
if (status == GENMASK(31, 0))
return IRQ_NONE;
dev_vdbg(idma64->dma.dev, "%s: status=%#x\n", __func__, status);
/* Check if we have any interrupt from the DMA controller */
if (!status)
return IRQ_NONE;
status_xfer = dma_readl(idma64, RAW(XFER));
status_err = dma_readl(idma64, RAW(ERROR));
for (i = 0; i < idma64->dma.chancnt; i++)
idma64_chan_irq(idma64, i, status_err, status_xfer);
return IRQ_HANDLED;
}
/* ---------------------------------------------------------------------- */
static struct idma64_desc *idma64_alloc_desc(unsigned int ndesc)
{
struct idma64_desc *desc;
desc = kzalloc_obj(*desc, GFP_NOWAIT);
if (!desc)
return NULL;
desc->hw = kzalloc_objs(*desc->hw, ndesc, GFP_NOWAIT);
if (!desc->hw) {
kfree(desc);
return NULL;
}
return desc;
}
static void idma64_desc_free(struct idma64_chan *idma64c,
struct idma64_desc *desc)
{
struct idma64_hw_desc *hw;
if (desc->ndesc) {
unsigned int i = desc->ndesc;
do {
hw = &desc->hw[--i];
dma_pool_free(idma64c->pool, hw->lli, hw->llp);
} while (i);
}
kfree(desc->hw);
kfree(desc);
}
static void idma64_vdesc_free(struct virt_dma_desc *vdesc)
{
struct idma64_chan *idma64c = to_idma64_chan(vdesc->tx.chan);
idma64_desc_free(idma64c, to_idma64_desc(vdesc));
}
static void idma64_hw_desc_fill(struct idma64_hw_desc *hw,
Annotation
- Immediate include surface: `linux/bitops.h`, `linux/delay.h`, `linux/dmaengine.h`, `linux/dma-mapping.h`, `linux/dmapool.h`, `linux/init.h`, `linux/module.h`, `linux/platform_device.h`.
- Detected declarations: `function Copyright`, `function idma64_off`, `function idma64_on`, `function idma64_chan_init`, `function idma64_chan_stop`, `function idma64_chan_start`, `function idma64_stop_transfer`, `function idma64_start_transfer`, `function idma64_chan_irq`, `function idma64_irq`.
- Atlas domain: Driver Families / drivers/dma.
- Implementation status: source 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.