drivers/comedi/kcomedilib/kcomedilib_main.c
Source file repositories/reference/linux-study-clean/drivers/comedi/kcomedilib/kcomedilib_main.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/comedi/kcomedilib/kcomedilib_main.c- Extension
.c- Size
- 8416 bytes
- Lines
- 354
- Domain
- Driver Families
- Bucket
- drivers/comedi
- 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.
- 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.hlinux/fcntl.hlinux/mm.hlinux/io.hlinux/bitmap.hlinux/comedi.hlinux/comedi/comedidev.hlinux/comedi/comedilib.h
Detected Declarations
function kcomedilib_set_link_from_tofunction kcomedilib_clear_link_from_tofunction comedi_open_fromfunction comedi_close_fromfunction comedi_do_insnfunction comedi_dio_get_configfunction comedi_dio_configfunction comedi_dio_bitfield2function comedi_find_subdevice_by_typefunction comedi_get_n_channelsexport comedi_open_fromexport comedi_close_fromexport comedi_dio_get_configexport comedi_dio_configexport comedi_dio_bitfield2export comedi_find_subdevice_by_typeexport comedi_get_n_channels
Annotated Snippet
if (test_bit(to, destinations[cur])) {
/* Loop detected. */
okay = false;
break;
}
/* Create next set of destinations. */
bitmap_zero(destinations[next], COMEDI_NUM_BOARD_MINORS);
while ((t = find_next_bit(destinations[cur],
COMEDI_NUM_BOARD_MINORS,
t)) < COMEDI_NUM_BOARD_MINORS) {
unsigned int f;
for (f = 0; f < COMEDI_NUM_BOARD_MINORS; f++) {
if (kcomedilib_to_from[t][f])
set_bit(f, destinations[next]);
}
t++;
}
cur = next;
} while (!bitmap_empty(destinations[cur], COMEDI_NUM_BOARD_MINORS));
if (okay) {
/* Allow a maximum of 255 links from "from" to "to". */
if (kcomedilib_to_from[to][from] < 255)
kcomedilib_to_from[to][from]++;
else
okay = false;
}
mutex_unlock(&kcomedilib_to_from_lock);
return okay;
}
static void kcomedilib_clear_link_from_to(unsigned int from, unsigned int to)
{
if (to < COMEDI_NUM_BOARD_MINORS && from < COMEDI_NUM_BOARD_MINORS) {
mutex_lock(&kcomedilib_to_from_lock);
if (kcomedilib_to_from[to][from])
kcomedilib_to_from[to][from]--;
mutex_unlock(&kcomedilib_to_from_lock);
}
}
/**
* comedi_open_from() - Open a COMEDI device from the kernel with loop checks
* @filename: Fake pathname of the form "/dev/comediN".
* @from: Device number it is being opened from (if in range).
*
* Converts @filename to a COMEDI device number and "opens" it if it exists
* and is attached to a low-level COMEDI driver.
*
* If @from is in range, refuse to open the device if doing so would form a
* loop of devices opening each other. There is also a limit of 255 on the
* number of concurrent opens from one device to another.
*
* Return: A pointer to the COMEDI device on success.
* Return %NULL on failure.
*/
struct comedi_device *comedi_open_from(const char *filename, int from)
{
struct comedi_device *dev, *retval = NULL;
unsigned int minor;
if (strncmp(filename, "/dev/comedi", 11) != 0)
return NULL;
if (kstrtouint(filename + 11, 0, &minor))
return NULL;
if (minor >= COMEDI_NUM_BOARD_MINORS)
return NULL;
dev = comedi_dev_get_from_minor(minor);
if (!dev)
return NULL;
down_read(&dev->attach_lock);
if (dev->attached && kcomedilib_set_link_from_to(from, minor))
retval = dev;
else
retval = NULL;
up_read(&dev->attach_lock);
if (!retval)
comedi_dev_put(dev);
return retval;
}
EXPORT_SYMBOL_GPL(comedi_open_from);
/**
* comedi_close_from() - Close a COMEDI device from the kernel with loop checks
Annotation
- Immediate include surface: `linux/module.h`, `linux/errno.h`, `linux/kernel.h`, `linux/sched.h`, `linux/fcntl.h`, `linux/mm.h`, `linux/io.h`, `linux/bitmap.h`.
- Detected declarations: `function kcomedilib_set_link_from_to`, `function kcomedilib_clear_link_from_to`, `function comedi_open_from`, `function comedi_close_from`, `function comedi_do_insn`, `function comedi_dio_get_config`, `function comedi_dio_config`, `function comedi_dio_bitfield2`, `function comedi_find_subdevice_by_type`, `function comedi_get_n_channels`.
- Atlas domain: Driver Families / drivers/comedi.
- 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.