drivers/comedi/comedi_fops.c
Source file repositories/reference/linux-study-clean/drivers/comedi/comedi_fops.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/comedi/comedi_fops.c- Extension
.c- Size
- 89195 bytes
- Lines
- 3704
- Domain
- Driver Families
- Bucket
- drivers/comedi
- Inferred role
- Driver Families: operation-table or driver-model contract
- Status
- pattern 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.
- Defines an operation table; this is where Linux turns generic core objects into subsystem-specific behavior.
- 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.
- 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/module.hlinux/errno.hlinux/kernel.hlinux/sched/signal.hlinux/fcntl.hlinux/delay.hlinux/mm.hlinux/slab.hlinux/poll.hlinux/device.hlinux/fs.hlinux/comedi/comedidev.hlinux/cdev.hlinux/io.hlinux/uaccess.hlinux/compat.hcomedi_internal.h
Detected Declarations
struct comedi_filestruct comedi32_chaninfo_structstruct comedi32_rangeinfo_structstruct comedi32_cmd_structstruct comedi32_insn_structstruct comedi32_insnlist_structfunction comedi_device_initfunction comedi_dev_kref_releasefunction comedi_dev_putfunction comedi_device_cleanupfunction comedi_clear_board_devfunction comedi_subdevice_from_minorfunction comedi_dev_get_from_subdevice_minorfunction comedi_dev_get_from_minorfunction comedi_read_subdevicefunction comedi_write_subdevicefunction comedi_file_resetfunction comedi_file_checkfunction resize_async_bufferfunction max_read_buffer_kb_showfunction max_read_buffer_kb_storefunction read_buffer_kb_showfunction read_buffer_kb_storefunction max_write_buffer_kb_showfunction max_write_buffer_kb_storefunction write_buffer_kb_showfunction write_buffer_kb_storefunction comedi_free_board_devfunction __comedi_clear_subdevice_runflagsfunction __comedi_set_subdevice_runflagsfunction comedi_update_subdevice_runflagsfunction __comedi_get_subdevice_runflagsfunction comedi_get_subdevice_runflagsfunction comedi_is_runflags_runningfunction comedi_is_runflags_in_errorfunction comedi_is_runflags_busyfunction comedi_is_subdevice_runningfunction __comedi_is_subdevice_runningfunction comedi_get_is_subdevice_runningfunction comedi_put_is_subdevice_runningfunction comedi_can_auto_free_sprivfunction comedi_set_spriv_auto_freefunction do_become_nonbusyfunction do_cancelfunction comedi_device_cancel_allfunction is_device_busyfunction attachesfunction do_bufconfig_ioctl
Annotated Snippet
static const struct file_operations comedi_fops = {
.owner = THIS_MODULE,
.unlocked_ioctl = comedi_unlocked_ioctl,
.compat_ioctl = comedi_compat_ioctl,
.open = comedi_open,
.release = comedi_close,
.read = comedi_read,
.write = comedi_write,
.mmap = comedi_mmap,
.poll = comedi_poll,
.fasync = comedi_fasync,
.llseek = noop_llseek,
};
void _comedi_event(struct comedi_device *dev, struct comedi_subdevice *s)
{
struct comedi_async *async = s->async;
unsigned int events;
int si_code = 0;
unsigned long flags;
spin_lock_irqsave(&s->spin_lock, flags);
events = async->events;
async->events = 0;
if (!__comedi_is_subdevice_running(s)) {
spin_unlock_irqrestore(&s->spin_lock, flags);
return;
}
if (events & COMEDI_CB_CANCEL_MASK)
__comedi_clear_subdevice_runflags(s, COMEDI_SRF_RUNNING);
/*
* Remember if an error event has occurred, so an error can be
* returned the next time the user does a read() or write().
*/
if (events & COMEDI_CB_ERROR_MASK)
__comedi_set_subdevice_runflags(s, COMEDI_SRF_ERROR);
if (async->cb_mask & events) {
wake_up_interruptible(&async->wait_head);
si_code = async->cmd.flags & CMDF_WRITE ? POLL_OUT : POLL_IN;
}
spin_unlock_irqrestore(&s->spin_lock, flags);
if (si_code)
kill_fasync(&dev->async_queue, SIGIO, si_code);
}
/**
* comedi_event() - Handle events for asynchronous COMEDI command
* @dev: COMEDI device.
* @s: COMEDI subdevice.
* Context: in_interrupt() (usually), @s->spin_lock spin-lock not held.
*
* If an asynchronous COMEDI command is active on the subdevice, process
* any %COMEDI_CB_... event flags that have been set, usually by an
* interrupt handler. These may change the run state of the asynchronous
* command, wake a task, and/or send a %SIGIO signal.
*/
void comedi_event(struct comedi_device *dev, struct comedi_subdevice *s)
{
if (comedi_get_is_subdevice_running(s)) {
comedi_event(dev, s);
comedi_put_is_subdevice_running(s);
}
}
EXPORT_SYMBOL_GPL(comedi_event);
/* Note: the ->mutex is pre-locked on successful return */
struct comedi_device *comedi_alloc_board_minor(struct device *hardware_device)
{
struct comedi_device *dev;
struct device *csdev;
unsigned int i;
dev = kzalloc_obj(*dev);
if (!dev)
return ERR_PTR(-ENOMEM);
comedi_device_init(dev);
comedi_set_hw_dev(dev, hardware_device);
mutex_lock(&dev->mutex);
mutex_lock(&comedi_board_minor_table_lock);
for (i = hardware_device ? comedi_num_legacy_minors : 0;
i < COMEDI_NUM_BOARD_MINORS; ++i) {
if (!comedi_board_minor_table[i]) {
comedi_board_minor_table[i] = dev;
break;
Annotation
- Immediate include surface: `linux/module.h`, `linux/errno.h`, `linux/kernel.h`, `linux/sched/signal.h`, `linux/fcntl.h`, `linux/delay.h`, `linux/mm.h`, `linux/slab.h`.
- Detected declarations: `struct comedi_file`, `struct comedi32_chaninfo_struct`, `struct comedi32_rangeinfo_struct`, `struct comedi32_cmd_struct`, `struct comedi32_insn_struct`, `struct comedi32_insnlist_struct`, `function comedi_device_init`, `function comedi_dev_kref_release`, `function comedi_dev_put`, `function comedi_device_cleanup`.
- Atlas domain: Driver Families / drivers/comedi.
- Implementation status: pattern 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.
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.