drivers/iio/buffer/industrialio-buffer-dma.c
Source file repositories/reference/linux-study-clean/drivers/iio/buffer/industrialio-buffer-dma.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/iio/buffer/industrialio-buffer-dma.c- Extension
.c- Size
- 26377 bytes
- Lines
- 876
- Domain
- Driver Families
- Bucket
- drivers/iio
- 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.
- Touches user memory; correctness depends on fault-safe copying and privilege boundary handling.
- 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/atomic.hlinux/cleanup.hlinux/lockdep.hlinux/slab.hlinux/kernel.hlinux/module.hlinux/device.hlinux/workqueue.hlinux/mutex.hlinux/sched.hlinux/poll.hlinux/iio/buffer_impl.hlinux/iio/buffer-dma.hlinux/dma-buf.hlinux/dma-fence.hlinux/dma-mapping.hlinux/sizes.h
Detected Declarations
function submitfunction iio_buffer_block_getfunction iio_buffer_block_putfunction iio_dma_buffer_cleanup_workerfunction iio_buffer_block_release_atomicfunction iio_buffer_block_putfunction iio_dma_buffer_alloc_blockfunction _iio_dma_buffer_block_donefunction iio_dma_buffer_queue_wakefunction iio_dma_buffer_block_donefunction iio_dma_buffer_block_list_abortfunction scoped_guardfunction iio_dma_block_reusablefunction iio_dma_buffer_can_use_fileiofunction iio_dma_buffer_request_updatefunction scoped_guardfunction iio_dma_buffer_enablefunction iio_dma_buffer_fileio_freefunction scoped_guardfunction iio_dma_buffer_submit_blockfunction iio_dma_buffer_enablefunction iio_dma_buffer_disablefunction iio_dma_buffer_enqueuefunction iio_dma_buffer_dequeuefunction iio_dma_buffer_iofunction iio_dma_buffer_readfunction iio_dma_buffer_writefunction iio_dma_buffer_usagefunction iio_dma_buffer_attach_dmabuffunction iio_dma_buffer_detach_dmabuffunction iio_dma_can_enqueue_blockfunction iio_dma_buffer_enqueue_dmabuffunction iio_dma_buffer_lock_queuefunction iio_dma_buffer_unlock_queuefunction iio_dma_buffer_set_bytes_per_datumfunction iio_dma_buffer_set_lengthfunction iio_dma_buffer_initfunction iio_dma_buffer_exitfunction iio_dma_buffer_release
Annotated Snippet
list_for_each_entry_safe(block, _block, list, head) {
list_del(&block->head);
block->bytes_used = 0;
_iio_dma_buffer_block_done(block);
if (!block->fileio)
iio_buffer_signal_dmabuf_done(block->fence,
-EINTR);
iio_buffer_block_put_atomic(block);
}
}
if (queue->fileio.enabled)
queue->fileio.enabled = false;
iio_dma_buffer_queue_wake(queue);
dma_fence_end_signalling(cookie);
}
EXPORT_SYMBOL_NS_GPL(iio_dma_buffer_block_list_abort, "IIO_DMA_BUFFER");
static bool iio_dma_block_reusable(struct iio_dma_buffer_block *block)
{
/*
* If the core owns the block it can be re-used. This should be the
* default case when enabling the buffer, unless the DMA controller does
* not support abort and has not given back the block yet.
*/
switch (block->state) {
case IIO_BLOCK_STATE_QUEUED:
case IIO_BLOCK_STATE_DONE:
return true;
default:
return false;
}
}
static bool iio_dma_buffer_can_use_fileio(struct iio_dma_buffer_queue *queue)
{
/*
* Note that queue->num_dmabufs cannot increase while the queue is
* locked, it can only decrease, so it does not race against
* iio_dma_buffer_alloc_block().
*/
return queue->fileio.enabled || !atomic_read(&queue->num_dmabufs);
}
/**
* iio_dma_buffer_request_update() - DMA buffer request_update callback
* @buffer: The buffer which to request an update
*
* Should be used as the iio_dma_buffer_request_update() callback for
* iio_buffer_access_ops struct for DMA buffers.
*/
int iio_dma_buffer_request_update(struct iio_buffer *buffer)
{
struct iio_dma_buffer_queue *queue = iio_buffer_to_queue(buffer);
struct iio_dma_buffer_block *block;
bool try_reuse = false;
size_t size;
int i;
/*
* Split the buffer into two even parts. This is used as a double
* buffering scheme with usually one block at a time being used by the
* DMA and the other one by the application.
*/
size = DIV_ROUND_UP(queue->buffer.bytes_per_datum *
queue->buffer.length, 2);
guard(mutex)(&queue->lock);
queue->fileio.enabled = iio_dma_buffer_can_use_fileio(queue);
/* If DMABUFs were created, disable fileio interface */
if (!queue->fileio.enabled)
return 0;
/* Allocations are page aligned */
if (PAGE_ALIGN(queue->fileio.block_size) == PAGE_ALIGN(size))
try_reuse = true;
queue->fileio.block_size = size;
queue->fileio.active_block = NULL;
scoped_guard(spinlock_irq, &queue->list_lock) {
for (i = 0; i < ARRAY_SIZE(queue->fileio.blocks); i++) {
block = queue->fileio.blocks[i];
/* If we can't re-use it free it */
if (block && (!iio_dma_block_reusable(block) || !try_reuse))
Annotation
- Immediate include surface: `linux/atomic.h`, `linux/cleanup.h`, `linux/lockdep.h`, `linux/slab.h`, `linux/kernel.h`, `linux/module.h`, `linux/device.h`, `linux/workqueue.h`.
- Detected declarations: `function submit`, `function iio_buffer_block_get`, `function iio_buffer_block_put`, `function iio_dma_buffer_cleanup_worker`, `function iio_buffer_block_release_atomic`, `function iio_buffer_block_put`, `function iio_dma_buffer_alloc_block`, `function _iio_dma_buffer_block_done`, `function iio_dma_buffer_queue_wake`, `function iio_dma_buffer_block_done`.
- Atlas domain: Driver Families / drivers/iio.
- Implementation status: integration implementation candidate.
- This snippet crosses the user/kernel memory boundary; validate fault handling and access checks before translating the pattern.
- 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.