What follows is a list of requirements for an I/O framework
to be used for most (all?) CERN drivers.
Digital and analog, input and output. All the 4 combinations.
TDC and DTC devices. The former (time to digital converter) is
pure timestamp input, stamping a pulse. The latter (digital to
converter) is outputting a pulse at a specified time. In most use
cases, the time is known to the peripheral device but not to the
One-shot, burst, and streaming support (streaming being the
least interesting). We need to set a value in a DAC but also
send a stream of samples, to generate some waveform. Similarly,
acquisition may be immediately (at read time) or fired by
Layered structure. Most cards have arrays of identical channels,
the framework must support grouping them and acting on them all at
same time. Input and output on the channels is synchronized, and
framework must support this concept.
No hard limits on the number of bits or channels. Our systems
very complex, like hundreds of devices and/or channels. We don't
hundreds of PCI boards, but I/O device may be remote over a
network, so the host system may really to handle hundreds of them.
High-data rate, little storage overhead. On of the first devices
need to support is a 4-channel ADC, 100Msamples per second, and
figures may only increase in the upcoming years. Our devices have
internal RAM, so the data is retrieved at a later time (no need
continuous streaming of such data rates). However, we can't afford
per-sample storage overhead.
Easy and general configuration. Although there will surely be
device-specific I/O applications, generic application should be
to make sense of the I/O zoo handled by each host system. We need
udev support, autodetection and all such features -- remember: we
have up to hundreds of such things in a single host.
Offset, gain, number of bits, ... . Most common attributes
be supported out of the box, with consistent naming for all devices.
Extensibility. New attributes may be needed in specific cases,
a new attribute may need to be promoted to be "common". The
must support special cases and the rare core extension with a
effort from the programmer.
Little code overhead. Configuration should fit naturally in
device drivers, requiring just a few lines of code (mainly, data
structures). We can't afford long sysfs-specific code within each
Centralized semaphores. Low-level drivers should not deal with
semaphores, as much as possible. All the complexity must be dealt
by the framework. The low-level driver should ideally only code
specifics of the hardware.
Flexible buffer management. The framework must support both
standard kmalloc or circular buffers, to be used in simple
and custom buffers. A fast ADC, for example, will need DMA-aware
buffering techniques, and support zero-copy acquisition to user
Device-driven data transfers. Data input or output may be
by data values (like a scope does), external pulses or whatever.
input and output operations may be fired by hardware, and the
framework must support this concept -- in addition to controlling
trasfers at software level.
Hardware time stamps. We need to either timestamp each sample,
or a whole batch of samples. In either case the time bits may be
provided by hardware, and the framework must make no assumption
on the format. The typical constraints (using timespec or a
count) are not acceptable.