STRUCT COMEDI_DEVICE(9)

πŸ“¦ version 7.3.1, in nixpkgs unstable

πŸ’– struct comedi_device(9) β€” the Kernel API Manual moment πŸ’–

okay so bestie, gather round, because today we're talking about struct comedi_device β€” which is described in the Kernel API Manual, and it's literally the working data for a COMEDI device. main character struct energy, no cap. πŸŽ€


✨ NAME ✨

struct comedi_device β€” the working data for a COMEDI device. that's it, that's the vibe. πŸ¦‹


🌸 SYNOPSIS 🌸

here's the whole glow-up, copy it exactly bestie, every single member matters:

struct comedi_device {
    int use_count;
    struct comedi_driver *driver;
    struct comedi_8254 *pacer;
    void *private;
    struct device *class_dev;
    int minor;
    unsigned int detach_count;
    struct device *hw_dev;
    const char *board_name;
    const void *board_ptr;
    unsigned int attached:1;
    unsigned int ioenabled:1;
    spinlock_t spinlock;
    struct mutex mutex;
    struct rw_semaphore attach_lock;
    struct kref refcount;
    int n_subdevices;
    struct comedi_subdevice *subdevices;
    void __iomem *mmio;
    unsigned long iobase;
    unsigned long iolen;
    unsigned int irq;
    struct comedi_subdevice *read_subdev;
    struct comedi_subdevice *write_subdev;
    struct fasync_struct *async_queue;
    int (*open)(struct comedi_device *dev);
    void (*close)(struct comedi_device *dev);
    int (*insn_device_config)(struct comedi_device *dev, struct
comedi_insn *insn, unsigned int *data);
    unsigned int (*get_valid_routes)(struct comedi_device *dev, unsigned
int n_pairs, unsigned int *pair_data);
 };

yes the wrapping on those last two function pointers is exactly like that in the original, don't come for me πŸ’…


🧩 Members 🧩

okay this is the part where we go member by member, like a group chat roll call. every single one gets its moment. πŸ‘‘

  • use_count β€” the number of open file objects. that's the whole job. counting the opens. πŸ“
  • driver β€” the low-level COMEDI driver attached to this COMEDI device. your ride-or-die.
  • pacer β€” an optional pointer to a dynamically allocated acquisition pacer control. it gets freed automatically after the COMEDI device is detached from the low-level driver, so like… don't stress about the cleanup, it handles itself. 🧚
  • private β€” an optional pointer to private data allocated by the low-level driver. same deal: freed automatically after the COMEDI device is detached from the low-level driver. self-cleaning icon.
  • class_dev β€” the sysfs comediX device. hi bestie, you're in sysfs now.
  • minor β€” the minor device number of the COMEDI char device (0-47). yes, 0 through 47, those are the numbers, memorize them.
  • detach_count β€” a counter, incremented every time the COMEDI device is detached. it's used for checking that a previous attachment is still valid. like a receipt for your last breakup, lowkey.
  • hw_dev β€” an optional pointer to the low-level hardware struct device. and now the important part, bestie, read carefully: it's required for automatically configured COMEDI devices, and optional for COMEDI devices configured by the COMEDI_DEVCONFIG ioctl β€” although the bus-specific COMEDI functions only work if it is set correctly. it's also passed to dma_alloc_coherent for COMEDI subdevices that have their 'async_dma_dir' member set to something other than DMA_NONE. so many jobs, one pointer, fr fr.
  • board_name β€” a pointer to a COMEDI board name or a COMEDI driver name. the deets: when the low-level driver's "attach" handler is called by the handler for the COMEDI_DEVCONFIG ioctl, it either points to a matched board name string if the 'num_names' member of the struct comedi_driver is non-zero, otherwise it points to the low-level driver name string. when the low-lever driver's "auto_attach" handler is called for an automatically configured COMEDI device, it points to the low-level driver name string. the low-level driver is free to change it in its "attach" or "auto_attach" handler if it wishes. (yes, "low-lever" β€” that's a typo that lives in the original, I'm not fixing it, I'm not that kind of girl πŸ’€)
  • board_ptr β€” an optional pointer to private, read-only board type information in the low-level driver. if the 'num_names' member of the struct comedi_driver is non-zero, the handler for the COMEDI_DEVCONFIG ioctl will point it to a pointer to a matched board name string within the driver's private array of static, read-only board type information when calling the driver's "attach" handler. the low-level driver is free to change it. so much freedom, honestly iconic. πŸ¦‹
  • attached β€” a flag indicating that the COMEDI device is attached to a low-level driver. are we attached? yes we are.
  • ioenabled β€” a flag used to indicate that a PCI device has been enabled and its regions requested. slay, get those regions.
  • spinlock β€” a generic spin-lock for use by the low-level driver. spin spin spin. πŸ”₯
  • mutex β€” a generic mutex for use by the COMEDI core module. mutual exclusion, mutual respect.
  • attach_lock β€” a struct rw_semaphore used to guard against the COMEDI device being detached while an operation is in progress. the down_write operation is only allowed while mutex is held, and is used when changing attached and detach_count and calling the low-level driver's "detach" handler. the down_read operation is generally used without holding mutex. that's the rule bestie, boundaries are healthy.
  • refcount β€” a struct kref reference counter for freeing the COMEDI device. it's giving responsible memory management.
  • n_subdevices β€” the number of COMEDI subdevices allocated by the low-level driver for this device. count them.
  • subdevices β€” a dynamically allocated array of COMEDI subdevices. the whole squad, allocated. 🫢
  • mmio β€” an optional pointer to a remapped MMIO region, set by the low-level driver. πŸŽ€
  • iobase β€” an optional base of an I/O port region requested by the low-level driver.
  • iolen β€” the length of the I/O port region requested at iobase. they're a package deal, iykyk.
  • irq β€” an optional IRQ number requested by the low-level driver.
  • read_subdev β€” an optional pointer to a default COMEDI subdevice operated on by the read file operation. set by the low-level driver. the reader. the main character of read(). πŸ‘‘
  • write_subdev β€” an optional pointer to a default COMEDI subdevice operated on by the write file operation. set by the low-level driver. the writer. equally iconic.
  • async_queue β€” storage for fasync_helper. just storage. humble. holding it down.
  • open β€” an optional pointer to a function set by the low-level driver, called when use_count changes from 0 to 1. the "hi we're here" moment.
  • close β€” an optional pointer to a function set by the low-level driver, called when use_count changed from 1 to 0. the "ok bye ily" moment. 😭
  • insn_device_config β€” an optional pointer to a handler for all sub-instructions except INSN_DEVICE_CONFIG_GET_ROUTES of the INSN_DEVICE_CONFIG instruction. if this is not initialized by the low-level driver, a default handler will be set during post-configuration. the core has your back, bestie.
  • get_valid_routes β€” an optional pointer to a handler for the INSN_DEVICE_CONFIG_GET_ROUTES sub-instruction of the INSN_DEVICE_CONFIG instruction set. if this is not initialized by the low-level driver, a default handler that copies zero routes back to the user will be used. zero routes. none. empty. πŸ™ˆ

🌈 Description 🌈

so here's the tea: this is the main control data structure for a COMEDI device (as far as the COMEDI core is concerned). like, the core's whole understanding of the device lives here. πŸ’…

there are two groups of COMEDI devices, and you need to know both, okay?

  1. "legacy" devices β€” configured by the handler for the COMEDI_DEVCONFIG ioctl. these are allocated during module initialization if the "comedi_num_legacy_minors" module parameter is non-zero, and they use minor device numbers from 0 to comedi_num_legacy_minors minus one.
  2. automatically configured devices β€” resulting from a call to comedi_auto_config as a result of a bus driver probe in a low-level COMEDI driver. these are allocated on demand and use minor device numbers from comedi_num_legacy_minors to 47.

so: legacy = allocated at module init, minor numbers 0 to comedi_num_legacy_minors minus one. auto = allocated on demand, minor numbers comedi_num_legacy_minors to 47. both groups, both ranges, memorized. periodt. ⭐


πŸ¦‹ SEE ALSO πŸ¦‹

the whole friend group, every single one tagged, no one left out:


ngl bestie, if you got all the way here you officially understand struct comedi_device better than most people. go drink some water. πŸ“

and that's a wrap! this came from ./include/linux/comedi, dated October 2026, and yes, the page name is struct comedi_device(9) β€” mwah, bye, ily, slay πŸ’–βœ¨πŸŽ€

πŸ“¦ where this page comes from