Skip to contentSkip to conversation

Introducing ZIO, a new I/O framework

RFC PATCH In review Alessandro Rubini 7 participants 25 messages Nov 26, 2011 – Dec 6, 2011

Subsystems (2)
lore
Share & tools
lore
#0 lore raw

cover Introducing ZIO, a new I/O framework

This RFC patch-set introduces the ZIO framework for input/output, which will be used in the new series of drivers by the BE-CO-HT group at CERN.

The use-case it is meant to cover is very fast I/O with hardware-provided timestamps. The first production driver we will support is a 100Ms/s 4-channel 14-bit ADC (developed on ohwr: see
http://www.ohwr.org/projects/fmc-adc-100m14b4cha ). We need similar bandwidth on output.

The synchronization engine of that FMC card and other ones is going to be White Rabbit (http://www.ohwr.org/projects/white-rabbit).

Currently, the patch-set includes one example driver (zio-zero) that behaves like /dev/zero and /dev/urandom. Other drivers will come soon, both demo and real hardware.

Slides for a tutorial on the design ideas are online here:
http://www.ohwr.org/attachments/881/zio-111123.pdf

A list of pending issues and development plans is online at:
http://www.ohwr.org/projects/zio/wiki/Todo

/alessandro

Alessandro Rubini (5):
Documentation: add docs for drivers/zio include/linux: add headers for drivers/zio drivers/zio: add triggers and buffers drivers/zio: add user-space tool zio-dump
zio: insert in Kbuild so it is actually compiled

Federico Vaga (2):
drivers/zio: core files for the ZIO input/output framework drivers/zio: add the zio-zero device driver

 Documentation/zio/00-INDEX            |   10 +
 Documentation/zio/buffer.txt          |  114 +++
 Documentation/zio/device.txt          |   69 ++
 Documentation/zio/modules.txt         |   45 +
 Documentation/zio/trigger.txt         |  128 +++
 drivers/Kconfig                       |    2 +
 drivers/Makefile                      |    1 +
 drivers/zio/Kconfig                   |   12 +
 drivers/zio/Makefile                  |   10 +
 drivers/zio/README                    |  105 +++
 drivers/zio/buffers/Makefile          |    1 +
 drivers/zio/buffers/zio-buf-kmalloc.c |  273 +++++++
 drivers/zio/drivers/Makefile          |    1 +
 drivers/zio/drivers/zio-zero.c        |   87 ++
 drivers/zio/triggers/Makefile         |    2 +
 drivers/zio/triggers/zio-trig-irq.c   |  203 +++++
 drivers/zio/triggers/zio-trig-timer.c |  193 +++++
 drivers/zio/zio-cdev.c                |  498 ++++++++++++
 drivers/zio/zio-dump.c                |  196 +++++
 drivers/zio/zio-sys.c                 | 1423 +++++++++++++++++++++++++++++++++
 include/linux/zio-buffer.h            |  246 ++++++
 include/linux/zio-sysfs.h             |  122 +++
 include/linux/zio-trigger.h           |   99 +++
 include/linux/zio.h                   |  244 ++++++
 24 files changed, 4084 insertions(+), 0 deletions(-)
 create mode 100644 Documentation/zio/00-INDEX
 create mode 100644 Documentation/zio/buffer.txt
 create mode 100644 Documentation/zio/device.txt
 create mode 100644 Documentation/zio/modules.txt
 create mode 100644 Documentation/zio/trigger.txt
 create mode 100644 drivers/zio/Kconfig
 create mode 100644 drivers/zio/Makefile
 create mode 100644 drivers/zio/README
 create mode 100644 drivers/zio/buffers/Makefile
 create mode 100644 drivers/zio/buffers/zio-buf-kmalloc.c
 create mode 100644 drivers/zio/drivers/Makefile
 create mode 100644 drivers/zio/drivers/zio-zero.c
 create mode 100644 drivers/zio/triggers/Makefile
 create mode 100644 drivers/zio/triggers/zio-trig-irq.c
 create mode 100644 drivers/zio/triggers/zio-trig-timer.c
 create mode 100644 drivers/zio/zio-cdev.c
 create mode 100644 drivers/zio/zio-dump.c
 create mode 100644 drivers/zio/zio-sys.c
 create mode 100644 include/linux/zio-buffer.h
 create mode 100644 include/linux/zio-sysfs.h
 create mode 100644 include/linux/zio-trigger.h
 create mode 100644 include/linux/zio.h
Signature · 1 line
1.7.7.2
#1 lore raw

RFC PATCH 1/7 Documentation: add docs for drivers/zio

This is documentation for the beta3 release of zio. The files match commit 7d37663 in git://ohwr.org/misc/zio.git .

We are aware the "modules.txt" file is not correct as it lists files that are not ready. We decided to avoid fixing it for this RFC submission, which won't go upstream anyways.

---
 Documentation/zio/00-INDEX    |   10 +++
 Documentation/zio/buffer.txt  |  114 ++++++++++++++++++++++++++++++++++++
 Documentation/zio/device.txt  |   69 ++++++++++++++++++++++
 Documentation/zio/modules.txt |   45 ++++++++++++++
 Documentation/zio/trigger.txt |  128 +++++++++++++++++++++++++++++++++++++++++
 drivers/zio/README            |  105 +++++++++++++++++++++++++++++++++
 6 files changed, 471 insertions(+), 0 deletions(-)
 create mode 100644 Documentation/zio/00-INDEX
 create mode 100644 Documentation/zio/buffer.txt
 create mode 100644 Documentation/zio/device.txt
 create mode 100644 Documentation/zio/modules.txt
 create mode 100644 Documentation/zio/trigger.txt
 create mode 100644 drivers/zio/README
Documentation/zio/00-INDEX new file +10 -0
new file mode 100644
index 0000000..093d9fb
@@ -0,0 +1,10 @@
+00-INDEX
+	- this file
+device.txt
+	- description of what ZIO devices (and csets and channels) are.
+buffer.txt
+	- description of the buffer, it's methods and how it is used.
+trigger.txt
+	- what is a trigger and what's its role in ZIO.
+modules.txt
+	- list of modules (and description) found in the first ZIO package
Documentation/zio/buffer.txt new file +114 -0

114 lines not on this page · raw message

Documentation/zio/device.txt new file +69 -0

69 lines not on this page · raw message

Documentation/zio/modules.txt new file +45 -0

45 lines not on this page · raw message

Documentation/zio/trigger.txt new file +128 -0

128 lines not on this page · raw message

drivers/zio/README new file +105 -0

105 lines not on this page · raw message

Signature · 1 line
1.7.7.2
#2 lore raw

Re: [RFC PATCH 1/7] Documentation: add docs for drivers/zio

Quoted 6 lines · Alessandro Rubini

This is documentation for the beta3 release of zio. The files match commit 7d37663 in git://ohwr.org/misc/zio.git .

We are aware the "modules.txt" file is not correct as it lists files that are not ready. We decided to avoid fixing it for this RFC submission, which won't go upstream anyways.

I think you are using sysfs files here, yet I don't see any Documentation/ABI files describing those sysfs files and how they are to be used. Could you please include them?

thanks,

greg k-h

#3 lore raw

Re: [RFC PATCH 1/7] Documentation: add docs for drivers/zio

In data sabato 26 novembre 2011 12:00:12, Greg KH ha scritto:

Quoted 11 lines · Alessandro Rubini
Quoted 6 lines

This is documentation for the beta3 release of zio. The files match commit 7d37663 in git://ohwr.org/misc/zio.git .

We are aware the "modules.txt" file is not correct as it lists files that are not ready. We decided to avoid fixing it for this RFC submission, which won't go upstream anyways.

I think you are using sysfs files here, yet I don't see any Documentation/ABI files describing those sysfs files and how they are to be used. Could you please include them?

Sure, we'll do for the next release.

Quoted 3 lines

thanks,

greg k-h

Signature · 1 line
Federico Vaga
maintainer
#4 lore raw

Re: [RFC PATCH 1/7] Documentation: add docs for drivers/zio

In reply to Alessandro Rubini
Quoted 524 lines · Alessandro Rubini

This is documentation for the beta3 release of zio. The files match commit 7d37663 in git://ohwr.org/misc/zio.git .

We are aware the "modules.txt" file is not correct as it lists files that are not ready. We decided to avoid fixing it for this RFC submission, which won't go upstream anyways.

---
 Documentation/zio/00-INDEX    |   10 +++
 Documentation/zio/buffer.txt  |  114 ++++++++++++++++++++++++++++++++++++
 Documentation/zio/device.txt  |   69 ++++++++++++++++++++++
 Documentation/zio/modules.txt |   45 ++++++++++++++
 Documentation/zio/trigger.txt |  128 +++++++++++++++++++++++++++++++++++++++++
 drivers/zio/README            |  105 +++++++++++++++++++++++++++++++++
 6 files changed, 471 insertions(+), 0 deletions(-)
 create mode 100644 Documentation/zio/00-INDEX
 create mode 100644 Documentation/zio/buffer.txt
 create mode 100644 Documentation/zio/device.txt
 create mode 100644 Documentation/zio/modules.txt
 create mode 100644 Documentation/zio/trigger.txt
 create mode 100644 drivers/zio/README
Documentation/zio/00-INDEX new file +10 -0
new file mode 100644
index 0000000..093d9fb
@@ -0,0 +1,10 @@
+00-INDEX
+	- this file
+device.txt
+	- description of what ZIO devices (and csets and channels) are.
+buffer.txt
+	- description of the buffer, it's methods and how it is used.
+trigger.txt
+	- what is a trigger and what's its role in ZIO.
+modules.txt
+	- list of modules (and description) found in the first ZIO package
Documentation/zio/buffer.txt new file +114 -0
new file mode 100644
index 0000000..f80e63a
@@ -0,0 +1,114 @@
+
+ZIO defines a "buffer" object type, so each device can exploit any
+features it may offer to speed up data transfers.
+
+Each cset in a device can use a different buffer, which is specified
+as an attribute of the cset.  One instance of the buffer type exists
+for each channel, and the char devices (control and data: see
+device.txt) refer to the buffer.
+
+Please read <linux/zio-buffer.h> together with this file.
+
+	Buffer Types
+	============
+
+Buffers may be device-specific or generic. A generic buffer called
+"kmalloc" is provided within zio-core; it uses kmalloc for allocation
+data blocks.  Such buffer is activated by default on all new csets
+being registered but is not special in any other way, you can write
+your own generic buffer (and if it's better than ours, we may use it
+as default buffer in future releases).
+
+A device-specific buffer declares to be such within its attributes.  A
+device-specific buffer can only be used by csets that declare its name
+as preferred buffer type.  When such csets are registered, if the
+buffer is already known to ZIO, it will be activated by default instead
+of "kmalloc".
+
+Sometimes people write drivers for a set of similar devices, with
+similar DMA capabilities. In this case, all of them may refer to the
+same device-specific buffer type; the buffer type may be registered
+as a standalone kernel module.
+
+The ZIO buffer data structures includes two sets of operations:
+file_operations and buffer_operations.
+
+
+	Buffer Operations
+	=================
+
+Each buffer type must provide the following buffer operations. All
+of them are implemented in zio-buf-kmalloc.c, which may be used as
+reference to better understand the role of each method:
+
+	struct zio_bi *(*create)(struct zio_buffer_type *zbuf,
+				 struct zio_channel *ch,
+				 fmode_t f_flags);
+	void (*destroy)(struct zio_bi *bi);
+
+The create() operation allocates and initializes an instance of the
+buffer type. It is called by ZIO when a channel is opened for the
+first time. The operation return a zio buffer instance (zio_bi),
+which is the generic descriptor of a buffer instance. ZIO handles
+only zio_bi, so complex buffer structures must contain the zio_bi
+structure and use container_of() to access the private enclosing
+structure.
+
+Destroy() deallocates a buffer instance. ZIO calls destroy when the
+channel is unregistered from ZIO or when the user assigns a different
+buffer type to the channel.
+
+When the control/data devices are closed, ZIO doesn't call destroy, so
+incoming data can queue up while the application leaves it closed
+(e.g., a shell script).  Actually, the release file operation is not
+handled by ZIO, so it couldn't call destroy on close even if it wanted
+to.
+
+	struct zio_block *(*alloc_block)(struct zio_bi *bi,
+					 struct zio_control *ctrl,
+					 size_t datalen, gfp_t gfp);
+	void (*free_block)(struct zio_bi *bi, struct zio_block *block);
+
+For input channels, a block is allocated before the trigger fires, and
+it is freed when the user has read or explicitly ignored it. For
+output, allocation happens on user write and free is called by the
+trigger when it is done. Thus, the functions are sometimes called by
+buffer code itself, and sometimes by the trigger. The generic
+structure hosting a block is zio_block which contain both data
+(samples) and control informations.  If needed, buffers may use a more
+complex structure, which will include zio_block, which is the only
+structure that ZIO handles; by using container_of you can retrieve the
+enclosing complex structure used in your buffer
+
+	int (*store_block)(struct zio_bi *bi, struct zio_block *block);
+	struct zio_block (*retr_block) (struct zio_bi *bi);
+
+For input the trigger calls store_block() and the read system call issues
+retr_block().  For output, the write system call runs store_block()
+and the trigger may call retr_block() (although the buffer pushes to
+the trigger when it receives the first data block).
+
+
+	File Operations
+	===============
+
+This field hosts the file_operations used by the char devices (control and
+data) for every channel using this buffer type.  When char devices are
+initially opened, the open method being run is within zio-code;
+it  kmallocs f->private_data before calling the buffer-specific open
+method. The private data being used is:
+
+	struct zio_f_priv {
+		struct zio_channel *chan;
+		enum zio_cdev_type type;
+	};
+
+All buffer file operations can thus refer to the current channel (and
+its buffer and its trigger), and know if the current file is
+ZIO_CDEV_CTRL or ZIO_CDEV_DATA.  Every buffer is expected to
+call zio_generic_release() at the end of its own release operation, or
+used zio_generic_release() directly in the file operations.
+
+ZIO offers other generic file operations, that may be enough for your
+buffer code or not. See zio-buf-kmalloc.c for a working example of
+buffer file operations.
Documentation/zio/device.txt new file +69 -0
new file mode 100644
index 0000000..0c960e2
@@ -0,0 +1,69 @@
+
+	ZIO Device
+	==========
+
+A device, registered through zio_register_device() is the description
+of an I/O peripheral. It is made up of channel-sets, called csets
+from now on. A device may represent a PCI board or an SPI integrated
+circuit or whatever it makes sense to manage from a single device driver.
+All I/O operations are performed on csets, so the device is just an
+array of csets.
+
+	Csets
+	=====
+
+A cset (channel-set) is an homogeneous set of I/O channels. All
+channels in the set are feature the same physical characteristics;
+moreover, a cset refers to a trigger object, so all channels in a set
+are triggered by the same event. This is the typical use case for
+logic analysers (digital input) or multi-probe scopes (analog input),
+as well as multi-waveform output. If your device has several input
+channels which are separately triggered, they should be defined as
+several cset items, each featuring one channel only.  Finally, all
+channels in a cset use the same buffer object for in-kernel data
+storage. Both the buffer and the trigger for a cset are set by
+writing the proper name in sysfs. At device registration defaults
+apply. If ZIO can't find the trigger/buffer name you wrote,
+it will return EINVAL and leave the previous trigger/buffer in place.
+
+	Channels
+	========
+
+The channel is the lowest object in the ZIO hierarchy. It represents
+the single physical connector of the device: analog or digital, input
+or output. Time-to-digital and digital-to-time devices can be represented
+as channels as well.
+
+	Attributes
+	==========
+
+Most configuration and information in ZIO happens through sysfs.
+See sysfs.txt for information about attributes. (FIXME: sysfs.txt)
+
+	Data Transfers
+	==============
+
+Data transfer in ZIO uses two char devices for each channel offered by
+the driver. One char device is used to describe data blocks (we call
+it control device); the other is used to transfer the data blocks (we
+call it data device). The control device returns (or accepts) a
+fixed-size structure that describes the next data transfer, including
+the trigger in use, data size, number of samples and various
+attributes.  Applications may choose to read the data device alone,
+without retrieving control information: when any data of a new block
+is transferred, the associated control information is discarded.
+Similarly, data is discarded if you re-read the control device after
+having retrieved the description of a data block you are not
+interested in.  For output, writing data without writing control uses
+the default control information, or the one from the previous
+transfer.
+
+The full set of rules for data and control transfers is described
+elsewhere (FIXME: link to other docs) but it is pretty intuitive once
+you get the idea.
+
+See the "zio-dump" host tool in the top-level zio dir for an example
+of generic and simple input application that shows use of control and
+data files.
+
+
Documentation/zio/modules.txt new file +45 -0
new file mode 100644
index 0000000..b3df00a
@@ -0,0 +1,45 @@
+
+This is the list of ZIO modules, at the time of writing. It is there
+to help new users understanding how the parts stick together.
+
+  drivers/zio/zio-core.ko
+
+This module (which is linked from several source files) includes the
+core sysfs and attribute management. It exports the register and
+unregister functions for top-level objects. Moreover, it includes the
+default buffer, called "kmalloc" and default trigger, called
+"app-request".
+
+  drivers/zio/trigger/trig-ktimer.ko
+  drivers/zio/trigger/trig-hrt.ko
+  drivers/zio/trigger/trig-irq.ko
+
+Three other generic triggers. Two of them are time-based, and the
+third hooks to an external interrupt (or more than one) as source of
+trigger that can be used be any zio cset).
+
+  drivers/zio/dev/zio-null.ko
+  drivers/zio/dev/zio-parport.ko
+  drivers/zio/dev/zio-ad7888.ko
+  drivers/zio/dev/zio-uart.ko
+
+These modules are examples. "null" does nothing: it discards output
+data and returns zeroes as input data. It can be used to experiment
+with generic triggers and as a sandbox for local modifications and
+testing.
+
+The parport driver registers two output csets and two input cset.
+In each group one cset is byte-oriented and the other is bit-oriented.
+
+The ad7888 is an SPI ADC we mounted on an ARM board. It's a real
+8-channel ADC we are using for internal development, and this is a
+real driver for a real thing. Over time it will handle its own buffer
+type (our SPI master uses DMA) and its own data-driven trigger (even
+if the data will be scanned by the CPU, so it can only work at low
+data rates).
+
+The uart driver is a line discpline that can receive data from a
+serial port. The first implementation expects to receive an endless
+stream of 16-bit data, big endian (we used this to run on-board ADC on
+cortex-m3), but we plan to extend it as a serious test case. You can
+drive it from a pty slave, for example.
Documentation/zio/trigger.txt new file +128 -0
new file mode 100644
index 0000000..95b426f
@@ -0,0 +1,128 @@
+
+ZIO defines a "trigger" object type, and each cset is connected to
+a trigger.
+
+Each cset in a device can use a different trigger, which is specified
+as an attribute of the cset.  When the trigger fires, it acts on all
+the non-disabled channels of the cset.  Only the "app-request" trigger
+can act on a single channel at a time.
+
+Please read <linux/zio-trigger.h> together with this file.
+
+	Trigger Types
+	=============
+
+Triggers may be device-specific or generic. A few generic triggers
+are part of zio-core. The "app-request" trigger fires input when
+the application calls read and fires output when the application calls
+write (it acts on a single channel). The "ktimer" trigger uses a kernel
+timer as trigger source. The "irq" trigger uses any interrupt (e.g.,
+a GPIO interrupt, or pin 10 of the PC parallel port) as trigger event.
+
+A device-specific trigger declares to be such within its attributes.  A
+device-specific trigger can only be used by csets that declare its name
+as preferred trigger type.  When such csets are registered, if the
+trigger is already known to ZIO, it will be activated by default instead
+of "app-request".
+
+	Trigger Operations
+	==================
+
+Trigger operations are the following:
+
+	struct zio_ti *(*create)(struct zio_trigger_type *trig,
+				 struct zio_cset *cset,
+				 struct zio_control *ctrl,
+				 fmode_t flags);
+	void (*destroy)(struct zio_ti *ti);
+
+Create and destroy a trigger instance for a cset. ZIO calls create() when
+attaching the trigger to a cset; it calls destroy() when the trigger is
+replaced by a different one or the cset is being unregistered from ZIO.
+The instance structure is trigger-specific, but it must include the
+generic structure zio_ti. Every time this structure is passed over, trigger
+code may use container_of if it needs to access the private enclosing
+structure.
+
+	int (*config)(struct zio_ti *ti, stuct zio_control *ctrl);
+
+The method is called by ZIO whenever the attributes for a trigger
+instance are modified by the user (by writing to sysfs or otherwise).
+
+	int (*push_block)(struct zio_ti *ti,
+			  struct zio_channel *chan,
+			  struct zio_control *ctrl);
+
+This is used for output channels: when a new data block is ready, it
+must be sent to the trigger so it can be output when the event fires.
+Buffer code, therefore, is expected to call this trigger method.  The
+function can return -EAGAIN if it has no space in the queue, or 0 on
+success. If EAGAIN happens, the buffer should handle it (by storing
+locally or notifying the user).
+
+	void (*pull_block)(struct zio_ti *ti,
+	  		   struct zio_channel *chan);
+
+The method asks the trigger for a new block. It may be called by
+the buffer, if it wants a block immediately. The trigger that offers
+this method (which may be NULL) is responsible of storing a block
+when available.  Since driver->input_cset completes asynchronously, this
+method can't return a block directly.  The block that will be stored
+may be shorter than what the trigger would have stored in the buffer
+by itself.
+
+        void (*data_done)(struct zio_cset *cset);
+
+The function is called by the device, and signals the trigger that
+the input or output operation on the cset is over. For input, the
+trigger will push blocks to the buffer, for output it will release
+the blocks.  zio-core offers zio_generic_data_done() for triggers
+that don't need special handling.
+
+	File Operations
+	===============
+
+The trigger may include a non-NULL f_ops pointer. Most triggers will
+not need it, but for example "app-request" does, because it needs to
+look at individual read and write calls performed by applications.
+ZIO will use these file operations (instead of the buffer file operations)
+when the open method of the char device detects that the active trigger
+declares a non-NULL f_ops field.  These operations will most
+likely fall back to buffer->f_ops for most of their actual work.
+
+See zio-trig-app-request.c for details about how this is used.
+
+	When the trigger fires
+	======================
+
+The trigger event may happen for a variety of reasons. It can be
+time-driven, data-driven or whatever else.  In any case, there is
+a time when the trigger fires, so input or output may happen.
+(With most hardware-specific triggers, the actual input or output of
+data has already happened when the trigger interrupt runs, but this
+doesn't change the software flow).
+
+Hardware-driven triggers will need to make their own work by themselves,
+but ZIO offers this help macro to loop over all non-disabled channels:
+
+	cset_for_each(struct zio_cset *cset, struct zio_channel *ch)
+
+The macro works like "task_for_each" or "list_for_each" in the kernel
+headers.
+
+For software-based triggers (where actual I/O happens when software
+wants it to happen, even if it is in response to an interrupt), the
+asynchronous code that runs the event will just need to call
+
+	zio_fire_trigger(struct zio_ti *ti);
+
+This function, part of zio-core, calls the internal helpers
+__zio_fire_input_trigger for input or __zio_fire_output_trigger for
+output. For input, block allocation is performed for each
+non-disabled channel, and drv->input_cset is called.
+For output, drv->outoput_cset is called.
+
+You can refer to "zio-trig-timer" for an example of a multi-instance
+generic timer and to "zio-trig-app-request" for a non-conventional
+implementation based on trigger-local file_operations.
+
drivers/zio/README new file +95 -0
new file mode 100644
index 0000000..d537353
@@ -0,0 +1,105 @@
+
+Zio is "the ultimate I/O framework".  Is being developed on the open
+hardware repository at http://www.ohwr.org/projects/zio .
+
+This version is known to compile and run with kernels 2.6.34 onwards.
+
+This README refers to version "beta3", but work is ongoing towards
+a stable package. See the TODO file on ohwr for details.
+
+To test zio you need to load the core modules (later, the default
+trigger and default buffer will be part of zio-core):
+
+   	insmod zio-core.ko
+   	insmod buffers/zio-buf-kmalloc.ko
+   	insmod triggers/zio-trig-timer.ko
+
+Drivers can't live without a trigger and a buffer, so the modules above
+must be loaded first.
+
+The kmalloc buffer is a simple buffer that hosts a list of data blocks,
+for either input or output.
+
+The timer trigger is a kernel-timer based trigger, that fires a block
+transfer on a timely basis. You can use the "ms" parameter to set the
+inter-block time, in milliseconds (the default is two seconds). You
+can also pass the "nsamples" parameter to say how many samples are
+aquired at each trigger instance.
+
+With the core in place, you can load a driver:
+
+	insmod drivers/zio-zero.ko
+
+zio-zero has a single channel-set (number 0) with three channels.
+They simulate three analog inputs, 8-bit per sample.
+
+     channel 0: returns zero forever
+     channel 1: returns random numbers
+     channel 2: returns a sawtooth signal (0 to 255 and back)
+
+The char devices are called using device-cset-channel:
+
+    /dev/zzero-0-0-ctrl
+    /dev/zzero-0-0-data
+    /dev/zzero-0-1-ctrl
+    /dev/zzero-0-1-data
+    /dev/zzero-0-2-ctrl
+    /dev/zzero-0-2-data
+
+(later versions will use a /dev/zio/ directory for all zio files)
+
+To read data you can just cat, or "od -t x1" the data device.
+To get control information meta-information) together with data, you
+can use the "zio-dump" user-space utility, in this directory.
+
+For example:
+
+    ./zio-dump /dev/zzero-0-2-ctrl /dev/zzero-0-2-data
+
+This is the result with a trigger that uses 2000 as msec and 32
+as nsample:
+
+    ./zio-dump /dev/zzero-0-2-ctrl /dev/zzero-0-2-data
+
+    Ctrl: version 0.2, trigger timer, dev zzero, cset 0, chan 2
+    Ctrl: seq 1, n 32, size 1, bits 8, flags 01000001 (little-endian)
+    Ctrl: stamp 1320403540.084798370 (0)
+    Data: 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f
+    Data: 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f
+
+    Ctrl: version 0.2, trigger timer, dev zzero, cset 0, chan 2
+    Ctrl: seq 2, n 32, size 1, bits 8, flags 01000001 (little-endian)
+    Ctrl: stamp 1320403542.091093781 (0)
+    Data: 20 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f
+    Data: 30 31 32 33 34 35 36 37 38 39 3a 3b 3c 3d 3e 3f
+
+    Ctrl: version 0.2, trigger timer, dev zzero, cset 0, chan 2
+    Ctrl: seq 3, n 32, size 1, bits 8, flags 01000001 (little-endian)
+    Ctrl: stamp 1320403544.084790274 (0)
+    Data: 40 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f
+    Data: 50 51 52 53 54 55 56 57 58 59 5a 5b 5c 5d 5e 5f
+
+Zio dump is able to access several pairs of devices (control and data),
+and you can change the trigger and buffer attributes for the cset.
+
+Example:
+
+    echo 500 > /sys/zio/devices/zzero/cset0/trigger/ms-period
+    echo 4 > /sys/zio/devices/zzero/cset0/trigger/nsamples
+    echo 3 > /sys/zio/devices/zzero/cset0/chan0/buffer/max-buffer-len
+    ./zio-dump /dev/zzero-0-*
+
+    Ctrl: version 0.2, trigger timer, dev zzero, cset 0, chan 0
+    Ctrl: seq 102, n 4, size 1, bits 8, flags 01000001 (little-endian)
+    Ctrl: stamp 4066.519285605 (0)
+    Data: 00 00 00 00

drivers/zio/README line 105

Quoted 10 lines
drivers/zio/README new file +10 -0
+
+    Ctrl: version 0.2, trigger timer, dev zzero, cset 0, chan 1
+    Ctrl: seq 102, n 4, size 1, bits 8, flags 01000001 (little-endian)
+    Ctrl: stamp 4066.519285605 (0)
+    Data: 71 29 a6 53
+
+    Ctrl: version 0.2, trigger timer, dev zzero, cset 0, chan 2
+    Ctrl: seq 102, n 4, size 1, bits 8, flags 01000001 (little-endian)
+    Ctrl: stamp 4066.519285605 (0)
+    Data: 60 61 62 63

Interesting approach to meta data handling. It's kind of 'partly' out of band as it can apply to large chunks of data.

How does it map if you have triggers causing single captures from each channel? I would imagine you will then store a whole meta data set per sample? I know this isn't your use case, but I'm currious to see where the overlap lies between this and IIO as you can imagine!

#5 lore raw

Re: [RFC PATCH 1/7] Documentation: add docs for drivers/zio

zio readme:

Quoted 4 lines

drivers/zio/README line 105

Quoted 4 lines
drivers/zio/README new file +4 -0
+    Ctrl: version 0.2, trigger timer, dev zzero, cset 0, chan 2
+    Ctrl: seq 102, n 4, size 1, bits 8, flags 01000001 (little-endian)
+    Ctrl: stamp 4066.519285605 (0)
+    Data: 60 61 62 63

Jonathan Cameron:

Quoted 2 lines

Interesting approach to meta data handling. It's kind of 'partly' out of band as it can apply to large chunks of data.

Exactly. Then, you can ignore the metadata if you want. It's like having a line of packed food, with detailed labels. You can read the label before getting each content blob, or just read the blob and discard the label. Or you can pass everything to someone else, for off-line handling.

We are aware there is a serious overhead if blocks are small, but the use case is different, as said.

Quoted 3 lines

How does it map if you have triggers causing single captures from each channel? I would imagine you will then store a whole meta data set per sample?

Yes. Worse: csets are acquired (or output) concurrently, so there's one control structure per channel (actually, gain and offset may be different in each channel, so there's a reason).

But when blocks are acquired by a hardware card with 256MB of internal memory and then transferred in a single DMA burst for offline analysis, then the overhead is negligible and I see an advantage in simplicity.

Actually, we are considering a buffer that reassembles samples, returning bigger blocks on demand, so we get rid of some of the overhead. But that's more a stress-test for the buffer concept than for real use cases.

Sure we lack any in-kernel users and don't want to have them in the future, that's helping us a lot.

Quoted 2 lines

I know this isn't your use case, but I'm currious to see where the overlap lies between this and IIO as you can imagine!

Yes, we are too. Federico has an ad7888 driver working, both for IIO and ZIO (and Comedi, but that's out of the game already), and we are going to write for a few more IIO-supported devices. In this way we both validate (or not) our design and compare with IIO.

Thank you for your feedback, both here and in the off-list email.

/alessandro

#6 lore raw

Re: [RFC PATCH 1/7] Documentation: add docs for drivers/zio

In reply to Alessandro Rubini
Quoted 33 lines · Alessandro Rubini

This is documentation for the beta3 release of zio. The files match commit 7d37663 in git://ohwr.org/misc/zio.git .

We are aware the "modules.txt" file is not correct as it lists files that are not ready. We decided to avoid fixing it for this RFC submission, which won't go upstream anyways.

---
 Documentation/zio/00-INDEX    |   10 +++
 Documentation/zio/buffer.txt  |  114 ++++++++++++++++++++++++++++++++++++
 Documentation/zio/device.txt  |   69 ++++++++++++++++++++++
 Documentation/zio/modules.txt |   45 ++++++++++++++
 Documentation/zio/trigger.txt |  128 +++++++++++++++++++++++++++++++++++++++++
 drivers/zio/README            |  105 +++++++++++++++++++++++++++++++++
 6 files changed, 471 insertions(+), 0 deletions(-)
 create mode 100644 Documentation/zio/00-INDEX
 create mode 100644 Documentation/zio/buffer.txt
 create mode 100644 Documentation/zio/device.txt
 create mode 100644 Documentation/zio/modules.txt
 create mode 100644 Documentation/zio/trigger.txt
 create mode 100644 drivers/zio/README
Documentation/zio/00-INDEX new file +0 -0
new file mode 100644
index 0000000..093d9fb

Documentation/zio/00-INDEX line 6

Quoted 6 lines
Documentation/zio/00-INDEX new file +6 -0
@@ -0,0 +1,10 @@
+00-INDEX
+	- this file
+device.txt
+	- description of what ZIO devices (and csets and channels) are.
+buffer.txt
+	- description of the buffer, it's methods and how it is used.

its

Quoted 19 lines
Documentation/zio/00-INDEX new file +4 -0
+trigger.txt
+	- what is a trigger and what's its role in ZIO.
+modules.txt
+	- list of modules (and description) found in the first ZIO package
Documentation/zio/buffer.txt new file +8 -0
new file mode 100644
index 0000000..f80e63a
@@ -0,0 +1,114 @@
+
+ZIO defines a "buffer" object type, so each device can exploit any
+features it may offer to speed up data transfers.
+
+Each cset in a device can use a different buffer, which is specified
+as an attribute of the cset.  One instance of the buffer type exists
+for each channel, and the char devices (control and data: see
+device.txt) refer to the buffer.

Documentation/zio/buffer.txt line 18

Quoted 10 lines
Documentation/zio/buffer.txt new file +10 -0
+
+Please read <linux/zio-buffer.h> together with this file.
+
+	Buffer Types
+	============
+
+Buffers may be device-specific or generic. A generic buffer called
+"kmalloc" is provided within zio-core; it uses kmalloc for allocation
+data blocks.  Such buffer is activated by default on all new csets
+being registered but is not special in any other way, you can write

way. You can write

Quoted 23 lines
Documentation/zio/buffer.txt new file +23 -0
+your own generic buffer (and if it's better than ours, we may use it
+as default buffer in future releases).
+
+A device-specific buffer declares to be such within its attributes.  A
+device-specific buffer can only be used by csets that declare its name
+as preferred buffer type.  When such csets are registered, if the
+buffer is already known to ZIO, it will be activated by default instead
+of "kmalloc".
+
+Sometimes people write drivers for a set of similar devices, with
+similar DMA capabilities. In this case, all of them may refer to the
+same device-specific buffer type; the buffer type may be registered
+as a standalone kernel module.
+
+The ZIO buffer data structures includes two sets of operations:
+file_operations and buffer_operations.
+
+
+	Buffer Operations
+	=================
+
+Each buffer type must provide the following buffer operations. All
+of them are implemented in zio-buf-kmalloc.c, which may be used as

Documentation/zio/buffer.txt line 51

Quoted 10 lines
Documentation/zio/buffer.txt new file +10 -0
+reference to better understand the role of each method:
+
+	struct zio_bi *(*create)(struct zio_buffer_type *zbuf,
+				 struct zio_channel *ch,
+				 fmode_t f_flags);
+	void (*destroy)(struct zio_bi *bi);
+
+The create() operation allocates and initializes an instance of the
+buffer type. It is called by ZIO when a channel is opened for the
+first time. The operation return a zio buffer instance (zio_bi),

returns a

Documentation/zio/buffer.txt line 57

Quoted 6 lines
Documentation/zio/buffer.txt new file +6 -0
+which is the generic descriptor of a buffer instance. ZIO handles
+only zio_bi, so complex buffer structures must contain the zio_bi
+structure and use container_of() to access the private enclosing
+structure.
+
+Destroy() deallocates a buffer instance. ZIO calls destroy when the

destroy() destroy()

Documentation/zio/buffer.txt line 61

Quoted 4 lines
Documentation/zio/buffer.txt new file +4 -0
+channel is unregistered from ZIO or when the user assigns a different
+buffer type to the channel.
+
+When the control/data devices are closed, ZIO doesn't call destroy, so

destroy(), so

Quoted 7 lines
Documentation/zio/buffer.txt new file +7 -0
+incoming data can queue up while the application leaves it closed
+(e.g., a shell script).  Actually, the release file operation is not
+handled by ZIO, so it couldn't call destroy on close even if it wanted
+to.
+
+	struct zio_block *(*alloc_block)(struct zio_bi *bi,
+					 struct zio_control *ctrl,

Documentation/zio/buffer.txt line 78

Quoted 10 lines
Documentation/zio/buffer.txt new file +10 -0
+					 size_t datalen, gfp_t gfp);
+	void (*free_block)(struct zio_bi *bi, struct zio_block *block);
+
+For input channels, a block is allocated before the trigger fires, and
+it is freed when the user has read or explicitly ignored it. For
+output, allocation happens on user write and free is called by the
+trigger when it is done. Thus, the functions are sometimes called by
+buffer code itself, and sometimes by the trigger. The generic
+structure hosting a block is zio_block which contain both data
+(samples) and control informations.  If needed, buffers may use a more

information.

Documentation/zio/buffer.txt line 81

Quoted 3 lines
Documentation/zio/buffer.txt new file +3 -0
+complex structure, which will include zio_block, which is the only
+structure that ZIO handles; by using container_of you can retrieve the
+enclosing complex structure used in your buffer

buffer.

Quoted 4 lines
Documentation/zio/buffer.txt new file +4 -0
+
+	int (*store_block)(struct zio_bi *bi, struct zio_block *block);
+	struct zio_block (*retr_block) (struct zio_bi *bi);
+

Documentation/zio/buffer.txt line 95

Quoted 10 lines
Documentation/zio/buffer.txt new file +10 -0
+For input the trigger calls store_block() and the read system call issues
+retr_block().  For output, the write system call runs store_block()
+and the trigger may call retr_block() (although the buffer pushes to
+the trigger when it receives the first data block).
+
+
+	File Operations
+	===============
+
+This field hosts the file_operations used by the char devices (control and

This structure holds

Quoted 7 lines
Documentation/zio/buffer.txt new file +7 -0
+data) for every channel using this buffer type.  When char devices are
+initially opened, the open method being run is within zio-code;
+it  kmallocs f->private_data before calling the buffer-specific open
+method. The private data being used is:
+
+	struct zio_f_priv {
+		struct zio_channel *chan;

Documentation/zio/buffer.txt line 112

Quoted 10 lines
Documentation/zio/buffer.txt new file +10 -0
+		enum zio_cdev_type type;
+	};
+
+All buffer file operations can thus refer to the current channel (and
+its buffer and its trigger), and know if the current file is
+ZIO_CDEV_CTRL or ZIO_CDEV_DATA.  Every buffer is expected to
+call zio_generic_release() at the end of its own release operation, or
+used zio_generic_release() directly in the file operations.
+
+ZIO offers other generic file operations, that may be enough for your

drop comma above.

Documentation/zio/buffer.txt line 113

Quoted 1 line
Documentation/zio/buffer.txt new file +1 -0
+buffer code or not. See zio-buf-kmalloc.c for a working example of

or may not.

Documentation/zio/device.txt line 5

Quoted 13 lines
Documentation/zio/buffer.txt new file +1 -0
+buffer file operations.
Documentation/zio/device.txt new file +5 -0
new file mode 100644
index 0000000..0c960e2
@@ -0,0 +1,69 @@
+
+	ZIO Device
+	==========
+
+A device, registered through zio_register_device() is the description

drop comma above.

Documentation/zio/device.txt line 16

Quoted 11 lines
Documentation/zio/device.txt new file +11 -0
+of an I/O peripheral. It is made up of channel-sets, called csets
+from now on. A device may represent a PCI board or an SPI integrated
+circuit or whatever it makes sense to manage from a single device driver.
+All I/O operations are performed on csets, so the device is just an
+array of csets.
+
+	Csets
+	=====
+
+A cset (channel-set) is an homogeneous set of I/O channels. All
+channels in the set are feature the same physical characteristics;

drop are ??

Quoted 39 lines
Documentation/zio/device.txt new file +39 -0
+moreover, a cset refers to a trigger object, so all channels in a set
+are triggered by the same event. This is the typical use case for
+logic analysers (digital input) or multi-probe scopes (analog input),
+as well as multi-waveform output. If your device has several input
+channels which are separately triggered, they should be defined as
+several cset items, each featuring one channel only.  Finally, all
+channels in a cset use the same buffer object for in-kernel data
+storage. Both the buffer and the trigger for a cset are set by
+writing the proper name in sysfs. At device registration defaults
+apply. If ZIO can't find the trigger/buffer name you wrote,
+it will return EINVAL and leave the previous trigger/buffer in place.
+
+	Channels
+	========
+
+The channel is the lowest object in the ZIO hierarchy. It represents
+the single physical connector of the device: analog or digital, input
+or output. Time-to-digital and digital-to-time devices can be represented
+as channels as well.
+
+	Attributes
+	==========
+
+Most configuration and information in ZIO happens through sysfs.
+See sysfs.txt for information about attributes. (FIXME: sysfs.txt)
+
+	Data Transfers
+	==============
+
+Data transfer in ZIO uses two char devices for each channel offered by
+the driver. One char device is used to describe data blocks (we call
+it control device); the other is used to transfer the data blocks (we
+call it data device). The control device returns (or accepts) a
+fixed-size structure that describes the next data transfer, including
+the trigger in use, data size, number of samples and various
+attributes.  Applications may choose to read the data device alone,
+without retrieving control information: when any data of a new block
+is transferred, the associated control information is discarded.
+Similarly, data is discarded if you re-read the control device after

Documentation/zio/device.txt line 65

Quoted 10 lines
Documentation/zio/device.txt new file +10 -0
+having retrieved the description of a data block you are not
+interested in.  For output, writing data without writing control uses
+the default control information, or the one from the previous
+transfer.
+
+The full set of rules for data and control transfers is described
+elsewhere (FIXME: link to other docs) but it is pretty intuitive once
+you get the idea.
+
+See the "zio-dump" host tool in the top-level zio dir for an example

directory

Documentation/zio/device.txt line 66

Quoted 1 line
Documentation/zio/device.txt new file +1 -0
+of generic and simple input application that shows use of control and

of a generic and simple

Documentation/zio/device.txt line 69

Quoted 3 lines
Documentation/zio/device.txt new file +3 -0
+data files.
+
+

Drop ending blank lines.

Documentation/zio/modules.txt line 2

Quoted 8 lines
Documentation/zio/modules.txt new file +2 -0
new file mode 100644
index 0000000..b3df00a
@@ -0,0 +1,45 @@
+
+This is the list of ZIO modules, at the time of writing. It is there

here

Quoted 19 lines
Documentation/zio/modules.txt new file +19 -0
+to help new users understanding how the parts stick together.
+
+  drivers/zio/zio-core.ko
+
+This module (which is linked from several source files) includes the
+core sysfs and attribute management. It exports the register and
+unregister functions for top-level objects. Moreover, it includes the
+default buffer, called "kmalloc" and default trigger, called
+"app-request".
+
+  drivers/zio/trigger/trig-ktimer.ko
+  drivers/zio/trigger/trig-hrt.ko
+  drivers/zio/trigger/trig-irq.ko
+
+Three other generic triggers. Two of them are time-based, and the
+third hooks to an external interrupt (or more than one) as source of
+trigger that can be used be any zio cset).
+
+  drivers/zio/dev/zio-null.ko

Documentation/zio/modules.txt line 31

Quoted 10 lines
Documentation/zio/modules.txt new file +10 -0
+  drivers/zio/dev/zio-parport.ko
+  drivers/zio/dev/zio-ad7888.ko
+  drivers/zio/dev/zio-uart.ko
+
+These modules are examples. "null" does nothing: it discards output
+data and returns zeroes as input data. It can be used to experiment
+with generic triggers and as a sandbox for local modifications and
+testing.
+
+The parport driver registers two output csets and two input cset.

csets.

Documentation/zio/modules.txt line 41

Quoted 10 lines
Documentation/zio/modules.txt new file +10 -0
+In each group one cset is byte-oriented and the other is bit-oriented.
+
+The ad7888 is an SPI ADC we mounted on an ARM board. It's a real
+8-channel ADC we are using for internal development, and this is a
+real driver for a real thing. Over time it will handle its own buffer
+type (our SPI master uses DMA) and its own data-driven trigger (even
+if the data will be scanned by the CPU, so it can only work at low
+data rates).
+
+The uart driver is a line discpline that can receive data from a

UART discipline

Quoted 69 lines
Documentation/zio/modules.txt new file +4 -0
+serial port. The first implementation expects to receive an endless
+stream of 16-bit data, big endian (we used this to run on-board ADC on
+cortex-m3), but we plan to extend it as a serious test case. You can
+drive it from a pty slave, for example.
Documentation/zio/trigger.txt new file +58 -0
new file mode 100644
index 0000000..95b426f
@@ -0,0 +1,128 @@
+
+ZIO defines a "trigger" object type, and each cset is connected to
+a trigger.
+
+Each cset in a device can use a different trigger, which is specified
+as an attribute of the cset.  When the trigger fires, it acts on all
+the non-disabled channels of the cset.  Only the "app-request" trigger
+can act on a single channel at a time.
+
+Please read <linux/zio-trigger.h> together with this file.
+
+	Trigger Types
+	=============
+
+Triggers may be device-specific or generic. A few generic triggers
+are part of zio-core. The "app-request" trigger fires input when
+the application calls read and fires output when the application calls
+write (it acts on a single channel). The "ktimer" trigger uses a kernel
+timer as trigger source. The "irq" trigger uses any interrupt (e.g.,
+a GPIO interrupt, or pin 10 of the PC parallel port) as trigger event.
+
+A device-specific trigger declares to be such within its attributes.  A
+device-specific trigger can only be used by csets that declare its name
+as preferred trigger type.  When such csets are registered, if the
+trigger is already known to ZIO, it will be activated by default instead
+of "app-request".
+
+	Trigger Operations
+	==================
+
+Trigger operations are the following:
+
+	struct zio_ti *(*create)(struct zio_trigger_type *trig,
+				 struct zio_cset *cset,
+				 struct zio_control *ctrl,
+				 fmode_t flags);
+	void (*destroy)(struct zio_ti *ti);
+
+Create and destroy a trigger instance for a cset. ZIO calls create() when
+attaching the trigger to a cset; it calls destroy() when the trigger is
+replaced by a different one or the cset is being unregistered from ZIO.
+The instance structure is trigger-specific, but it must include the
+generic structure zio_ti. Every time this structure is passed over, trigger
+code may use container_of if it needs to access the private enclosing
+structure.
+
+	int (*config)(struct zio_ti *ti, stuct zio_control *ctrl);
+
+The method is called by ZIO whenever the attributes for a trigger
+instance are modified by the user (by writing to sysfs or otherwise).
+
+	int (*push_block)(struct zio_ti *ti,
+			  struct zio_channel *chan,
+			  struct zio_control *ctrl);
+
+This is used for output channels: when a new data block is ready, it
+must be sent to the trigger so it can be output when the event fires.
+Buffer code, therefore, is expected to call this trigger method.  The

Documentation/zio/trigger.txt line 68

Quoted 10 lines
Documentation/zio/trigger.txt new file +10 -0
+function can return -EAGAIN if it has no space in the queue, or 0 on
+success. If EAGAIN happens, the buffer should handle it (by storing
+locally or notifying the user).
+
+	void (*pull_block)(struct zio_ti *ti,
+	  		   struct zio_channel *chan);
+
+The method asks the trigger for a new block. It may be called by
+the buffer, if it wants a block immediately. The trigger that offers
+this method (which may be NULL) is responsible of storing a block

for storing

Documentation/zio/trigger.txt line 78

Quoted 10 lines
Documentation/zio/trigger.txt new file +10 -0
+when available.  Since driver->input_cset completes asynchronously, this
+method can't return a block directly.  The block that will be stored
+may be shorter than what the trigger would have stored in the buffer
+by itself.
+
+        void (*data_done)(struct zio_cset *cset);
+
+The function is called by the device, and signals the trigger that
+the input or output operation on the cset is over. For input, the
+trigger will push blocks to the buffer, for output it will release

buffer; for

Quoted 18 lines
Documentation/zio/trigger.txt new file +18 -0
+the blocks.  zio-core offers zio_generic_data_done() for triggers
+that don't need special handling.
+
+	File Operations
+	===============
+
+The trigger may include a non-NULL f_ops pointer. Most triggers will
+not need it, but for example "app-request" does, because it needs to
+look at individual read and write calls performed by applications.
+ZIO will use these file operations (instead of the buffer file operations)
+when the open method of the char device detects that the active trigger
+declares a non-NULL f_ops field.  These operations will most
+likely fall back to buffer->f_ops for most of their actual work.
+
+See zio-trig-app-request.c for details about how this is used.
+
+	When the trigger fires
+	======================

Documentation/zio/trigger.txt line 106

Quoted 10 lines
Documentation/zio/trigger.txt new file +10 -0
+
+The trigger event may happen for a variety of reasons. It can be
+time-driven, data-driven or whatever else.  In any case, there is
+a time when the trigger fires, so input or output may happen.
+(With most hardware-specific triggers, the actual input or output of
+data has already happened when the trigger interrupt runs, but this
+doesn't change the software flow).
+
+Hardware-driven triggers will need to make their own work by themselves,
+but ZIO offers this help macro to loop over all non-disabled channels:

helper macro

Quoted 12 lines
Documentation/zio/trigger.txt new file +12 -0
+
+	cset_for_each(struct zio_cset *cset, struct zio_channel *ch)
+
+The macro works like "task_for_each" or "list_for_each" in the kernel
+headers.
+
+For software-based triggers (where actual I/O happens when software
+wants it to happen, even if it is in response to an interrupt), the
+asynchronous code that runs the event will just need to call
+
+	zio_fire_trigger(struct zio_ti *ti);
+

Documentation/zio/trigger.txt line 128

Quoted 10 lines
Documentation/zio/trigger.txt new file +10 -0
+This function, part of zio-core, calls the internal helpers
+__zio_fire_input_trigger for input or __zio_fire_output_trigger for
+output. For input, block allocation is performed for each
+non-disabled channel, and drv->input_cset is called.
+For output, drv->outoput_cset is called.
+
+You can refer to "zio-trig-timer" for an example of a multi-instance
+generic timer and to "zio-trig-app-request" for a non-conventional
+implementation based on trigger-local file_operations.
+

Drop last blank line.

drivers/zio/README

Quoted 5 lines
drivers/zio/README new file +0 -0
new file mode 100644
index 0000000..d537353

I'd prefer to see this file in Documentation/zio/ with the other doc files.

drivers/zio/README line 2

Quoted 3 lines
drivers/zio/README new file +2 -0
@@ -0,0 +1,105 @@
+
+Zio is "the ultimate I/O framework".  Is being developed on the open

It is being

Quoted 15 lines
drivers/zio/README new file +15 -0
+hardware repository at http://www.ohwr.org/projects/zio .
+
+This version is known to compile and run with kernels 2.6.34 onwards.
+
+This README refers to version "beta3", but work is ongoing towards
+a stable package. See the TODO file on ohwr for details.
+
+To test zio you need to load the core modules (later, the default
+trigger and default buffer will be part of zio-core):
+
+   	insmod zio-core.ko
+   	insmod buffers/zio-buf-kmalloc.ko
+   	insmod triggers/zio-trig-timer.ko
+
+Drivers can't live without a trigger and a buffer, so the modules above

drivers/zio/README line 27

Quoted 10 lines
drivers/zio/README new file +10 -0
+must be loaded first.
+
+The kmalloc buffer is a simple buffer that hosts a list of data blocks,
+for either input or output.
+
+The timer trigger is a kernel-timer based trigger, that fires a block
+transfer on a timely basis. You can use the "ms" parameter to set the
+inter-block time, in milliseconds (the default is two seconds). You
+can also pass the "nsamples" parameter to say how many samples are
+aquired at each trigger instance.

acquired

drivers/zio/README line 34

Quoted 7 lines
drivers/zio/README new file +7 -0
+
+With the core in place, you can load a driver:
+
+	insmod drivers/zio-zero.ko
+
+zio-zero has a single channel-set (number 0) with three channels.
+They simulate three analog inputs, 8-bit per sample.

8 bits per sample.

Quoted 38 lines
drivers/zio/README new file +38 -0
+
+     channel 0: returns zero forever
+     channel 1: returns random numbers
+     channel 2: returns a sawtooth signal (0 to 255 and back)
+
+The char devices are called using device-cset-channel:
+
+    /dev/zzero-0-0-ctrl
+    /dev/zzero-0-0-data
+    /dev/zzero-0-1-ctrl
+    /dev/zzero-0-1-data
+    /dev/zzero-0-2-ctrl
+    /dev/zzero-0-2-data
+
+(later versions will use a /dev/zio/ directory for all zio files)
+
+To read data you can just cat, or "od -t x1" the data device.
+To get control information meta-information) together with data, you
+can use the "zio-dump" user-space utility, in this directory.
+
+For example:
+
+    ./zio-dump /dev/zzero-0-2-ctrl /dev/zzero-0-2-data
+
+This is the result with a trigger that uses 2000 as msec and 32
+as nsample:
+
+    ./zio-dump /dev/zzero-0-2-ctrl /dev/zzero-0-2-data
+
+    Ctrl: version 0.2, trigger timer, dev zzero, cset 0, chan 2
+    Ctrl: seq 1, n 32, size 1, bits 8, flags 01000001 (little-endian)
+    Ctrl: stamp 1320403540.084798370 (0)
+    Data: 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f
+    Data: 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f
+
+    Ctrl: version 0.2, trigger timer, dev zzero, cset 0, chan 2
+    Ctrl: seq 2, n 32, size 1, bits 8, flags 01000001 (little-endian)
+    Ctrl: stamp 1320403542.091093781 (0)

drivers/zio/README line 82

Quoted 10 lines
drivers/zio/README new file +10 -0
+    Data: 20 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f
+    Data: 30 31 32 33 34 35 36 37 38 39 3a 3b 3c 3d 3e 3f
+
+    Ctrl: version 0.2, trigger timer, dev zzero, cset 0, chan 2
+    Ctrl: seq 3, n 32, size 1, bits 8, flags 01000001 (little-endian)
+    Ctrl: stamp 1320403544.084790274 (0)
+    Data: 40 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f
+    Data: 50 51 52 53 54 55 56 57 58 59 5a 5b 5c 5d 5e 5f
+
+Zio dump is able to access several pairs of devices (control and data),

zio-dump

Quoted 23 lines
drivers/zio/README new file +23 -0
+and you can change the trigger and buffer attributes for the cset.
+
+Example:
+
+    echo 500 > /sys/zio/devices/zzero/cset0/trigger/ms-period
+    echo 4 > /sys/zio/devices/zzero/cset0/trigger/nsamples
+    echo 3 > /sys/zio/devices/zzero/cset0/chan0/buffer/max-buffer-len
+    ./zio-dump /dev/zzero-0-*
+
+    Ctrl: version 0.2, trigger timer, dev zzero, cset 0, chan 0
+    Ctrl: seq 102, n 4, size 1, bits 8, flags 01000001 (little-endian)
+    Ctrl: stamp 4066.519285605 (0)
+    Data: 00 00 00 00
+
+    Ctrl: version 0.2, trigger timer, dev zzero, cset 0, chan 1
+    Ctrl: seq 102, n 4, size 1, bits 8, flags 01000001 (little-endian)
+    Ctrl: stamp 4066.519285605 (0)
+    Data: 71 29 a6 53
+
+    Ctrl: version 0.2, trigger timer, dev zzero, cset 0, chan 2
+    Ctrl: seq 102, n 4, size 1, bits 8, flags 01000001 (little-endian)
+    Ctrl: stamp 4066.519285605 (0)
+    Data: 60 61 62 63
Signature · 2 lines
~Randy
*** Remember to use Documentation/SubmitChecklist when testing your code ***
#7 lore raw

RFC PATCH 2/7 include/linux: add headers for drivers/zio

In reply to Alessandro Rubini

Header files for the beta3 release of zio.
The files match commit 7d37663 in git://ohwr.org/misc/zio.git .

---
 include/linux/zio-buffer.h  |  246 +++++++++++++++++++++++++++++++++++++++++++
 include/linux/zio-sysfs.h   |  122 +++++++++++++++++++++
 include/linux/zio-trigger.h |   99 +++++++++++++++++
 include/linux/zio.h         |  244 ++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 711 insertions(+), 0 deletions(-)
 create mode 100644 include/linux/zio-buffer.h
 create mode 100644 include/linux/zio-sysfs.h
 create mode 100644 include/linux/zio-trigger.h
 create mode 100644 include/linux/zio.h
include/linux/zio-buffer.h new file +246 -0
new file mode 100644
index 0000000..2e5500c
@@ -0,0 +1,246 @@
+/* Alessandro Rubini, Federico Vaga for CERN, 2011, GNU GPLv2 or later */
+#ifndef __ZIO_BUFFER_H__
+#define __ZIO_BUFFER_H__
+
+/*
+ * Data transfers on the control channel only happen by half a kB.
+ * This is fixed for forward compatibility; zio_control may have more
+ * fields in the future, and current apps should handle it.
+ */
+#define ZIO_CONTROL_SIZE	512
+
+/*
+ * The timestamp is mostly app-specific. It cam be timspec-alike but
+ * indidual devices may do whatever they want to match hardware.
+ */
+struct zio_timestamp {
+	uint64_t secs;
+	uint64_t ticks;
+	uint64_t bins;
+};
+
+/*
+ * The following data item is the control structure that is being exchanged
+ * on the control device associated to each data device. The size of each
+ * fields is fixed to ease portability of binary dumps (esp i386/x86-64).
+ * The endianness, however, is native for speed reasons.
+ */
+
+struct zio_control {
+	/* byte 0 */
+	uint8_t major_version;
+	uint8_t minor_version;
+	uint8_t unused[2];
+	/* byte 4*/
+	uint32_t seq_num;	/* block sequence number */
+	uint32_t flags;		/* endianness etc, see below */
+	uint32_t nsamples;	/* number of samples in this data block */
+	/* byte 16 */
+	uint16_t ssize;		/* sample-size for each of them, in bytes */
+	uint16_t sbits;		/* sample-bits: number of valid bits */
+	uint16_t cset_i;	/* index of channel-set within device */
+	uint16_t chan_i;	/* index of channel within cset */
+
+	/* byte 24 */
+	/* The control block includes what device the data belong to */
+	char devname[ZIO_NAME_LEN];
+
+	/* byte 56 */
+	/* Each data block is associated with a trigger and its features */
+	char triggername[ZIO_NAME_LEN];
+
+	/* byte 88 */
+	struct zio_timestamp tstamp;
+
+	/* byte 112 */
+	uint32_t ext_attr_mask;	/* mask of active extended attributes */
+	uint32_t std_attr_mask;	/* mask of active standard attributes */
+	/* byte 120 */
+	uint32_t std_attrs[32];	/* value of each standard attribute */
+	uint32_t ext_attrs[32];	/* value of each extended attribute */
+
+	/* This filler must be updated if you change fields above */
+	uint8_t __fill_end[ZIO_CONTROL_SIZE - 120 - 4 * (32 + 32)];
+};
+
+/* The following flags are used in the control structure */
+#define ZIO_CONTROL_LITTLE_ENDIAN	0x01000001
+#define ZIO_CONTROL_BIG_ENDIAN		0x02000002
+
+#define ZIO_CONTROL_MSB_ALIGN		0x00000004 /* for analog data */
+#define ZIO_CONTROL_LSB_ALIGN		0x00000008 /* for analog data */
+
+#ifdef __KERNEL__
+#include <linux/module.h>
+#include <linux/kobject.h>
+#include <linux/slab.h>
+#include <linux/zio.h>
+#include <linux/gfp.h>
+#include <linux/fs.h>
+#include <linux/list.h>
+#include <linux/spinlock.h>
+#include <linux/wait.h>
+
+#define ZIO_DEFAULT_BUFFER "kmalloc" /* For devices with no own buffer type */
+
+/* Compile-time check that the control structure is the right size */
+static inline void __unused_check_size(void)
+{
+	/* if zio_control is smaller then ZIO_CONTROL_SIZE, compile error */
+	static int __used v1[sizeof(struct zio_control) - ZIO_CONTROL_SIZE];
+	/* if zio_control is greater then ZIO_CONTROL_SIZE, compile error */
+	static int __used v2[ZIO_CONTROL_SIZE - sizeof(struct zio_control)];
+
+	BUILD_BUG_ON(sizeof(struct zio_control) != ZIO_CONTROL_SIZE);
+}
+
+/* FIXME: use a kmem_cache and real functions for control alloc/free */
+static inline struct zio_control *zio_alloc_control(gfp_t gfp)
+{
+	struct zio_control *ctrl;
+
+	ctrl = kzalloc(sizeof(*ctrl), gfp);
+	if (!ctrl)
+		return NULL;
+	ctrl->major_version = ZIO_MAJOR_VERSION;
+	ctrl->minor_version = ZIO_MINOR_VERSION;
+	if (ntohl(1) == 1)
+		ctrl->flags |= ZIO_CONTROL_BIG_ENDIAN;
+	else
+		ctrl->flags |= ZIO_CONTROL_LITTLE_ENDIAN;
+	return ctrl;
+}
+static inline void zio_free_control(struct zio_control *ctrl)
+{
+	kfree(ctrl);
+}
+
+/*
+ * The following structure defines a buffer type, with methods.
+ * An instance is created for each channel using it
+ */
+struct zio_buffer_operations;
+struct zio_buffer_type {
+	struct zio_obj_head	head;
+	struct module		*owner;
+	struct list_head	list; /* instances, and list lock */
+	struct spinlock		lock;
+	unsigned long		flags; /* to be defined */
+
+	/* file operations (read/write etc) are buffer-specific too */
+	const struct zio_sys_operations		*s_op;
+	const struct zio_buffer_operations	*b_op;
+	const struct file_operations		*f_op;
+
+	/* default attributes for instance */
+	struct zio_attribute_set		zattr_set;
+	/* FIXME: how "own" devices are listed (here or elsewhere?) */
+	struct zio_device	*zdev_owner;
+	unsigned int		n_zdev_owner;
+};
+#define to_zio_buf(obj) container_of(obj, struct zio_buffer, head.kobj)
+
+/* read and write may often be the generic ones */
+ssize_t zio_generic_read(struct file *, char __user *,
+			 size_t, loff_t *);
+ssize_t zio_generic_write(struct file *, const char __user *,
+			  size_t, loff_t *);
+unsigned int zio_generic_poll(struct file *, struct poll_table_struct *);
+int zio_generic_release(struct inode *inode, struct file *f);
+
+
+int __must_check zio_register_buf(struct zio_buffer_type *zbuf,
+				  const char *name);
+void zio_unregister_buf(struct zio_buffer_type *zbuf);
+
+struct zio_bi {
+	struct zio_obj_head	head;
+	struct list_head	list;		/* instance list */
+	struct zio_channel	*chan;
+	struct zio_cset		*cset;		/* short for chan->cset */
+
+	/* Those using generic_read need this information */
+	unsigned long flags;			/* input or output, etc */
+	wait_queue_head_t q;			/* for reading or writing */
+
+	/* Standard and extended attributes for this object */
+	struct zio_attribute_set		zattr_set;
+
+	const struct zio_buffer_operations	*b_op;
+	const struct file_operations		*f_op;
+};
+#define to_zio_bi(_kobj) container_of(_kobj, struct zio_bi, head.kobj)
+
+/* The block is the basic data item being transferred */
+struct zio_block {
+	unsigned long		ctrl_flags;
+	void			*data;
+	size_t			datalen;
+	size_t			uoff;
+};
+
+/*
+ * We must know whether the ctrl block has been filled/read or not: "cdone"
+ * No "set_ctrl" or "clr_cdone" are needed, as cdone starts 0 and is only set
+ */
+#define zio_get_ctrl(block) ((struct zio_control *)((block)->ctrl_flags & ~1))
+#define zio_set_ctrl(block, ctrl) ((block)->ctrl_flags = (unsigned long)(ctrl))
+#define zio_is_cdone(block)  ((block)->ctrl_flags & 1)
+#define zio_set_cdone(block)  ((block)->ctrl_flags |= 1)
+
+
+/*
+ * Each buffer implementation must provide the following methods, because
+ * internal management of individual data instances is left to each of them.
+ *
+ * "store" is for input and "retr" for output (called by low-level driver).
+ * After store, the block is ready for user space and freed internally;
+ * after retr, it's the low level driver that must cal the free method.
+ * The "alloc" method is called on trigger setup (activate), because the
+ * data storage must be available when data transfer really happens (thus,
+ * a DMA-only device will have its own buffer as the preferred one).
+ * The buffer may use its own alloc for blocks created at write(2) time.
+ *
+ * Note that each buffer type will need more information, so the block
+ * is usually inside a custom structure, reached by container_of().
+ * Thus, all blocks for a buffer type must be allocated and freed using
+ * the methods of that specific buffer type.
+ */
+struct zio_buffer_operations {
+	struct zio_block *	(*alloc_block)(struct zio_bi *bi,
+					       struct zio_control *ctrl,
+					       size_t datalen, gfp_t gfp);
+	void			(*free_block)(struct zio_bi *bi,
+					      struct zio_block *block);
+
+	int			(*store_block)(struct zio_bi *bi,
+					       struct zio_block *block);
+	struct zio_block *	(*retr_block) (struct zio_bi *bi);
+
+	struct zio_bi *		(*create)(struct zio_buffer_type *zbuf,
+					  struct zio_channel *chan,
+					  fmode_t f_flags);
+	void			(*destroy)(struct zio_bi *bi);
+};
+
+/*
+ * This is the structure we place in f->private_data at open time.
+ * Note that the buffer_create function is called by zio-core.
+ */
+enum zio_cdev_type {
+	ZIO_CDEV_CTRL,
+	ZIO_CDEV_DATA,
+};
+struct zio_f_priv {
+	struct zio_channel *chan; /* where current block and buffer live */
+	enum zio_cdev_type type;
+};
+
+ssize_t zio_generic_read(struct file *f, char __user *ubuf,
+			 size_t count, loff_t *offp);
+ssize_t zio_generic_write(struct file *f, const char __user *ubuf,
+			  size_t count, loff_t *offp);
+unsigned int zio_generic_poll(struct file *f, struct poll_table_struct *w);
+
+#endif /* __KERNEL__ */
+#endif /* __ZIO_BUFFER_H__ */
include/linux/zio-sysfs.h new file +122 -0

122 lines not on this page · raw message

include/linux/zio-trigger.h new file +99 -0

99 lines not on this page · raw message

include/linux/zio.h new file +244 -0

244 lines not on this page · raw message

Signature · 1 line
1.7.7.2
#8 lore raw

Re: [RFC PATCH 2/7] include/linux: add headers for drivers/zio

Quoted 5 lines · Alessandro Rubini

+/*
+ * We use the same functions to deal with attributes, but the structures
+ * we act on may be different (dev, cset, channel). Thus, all structures
+ * begin with the type identifier, and zio_obj_head is used in container_of
+ */

Because you are using container_of, you don't have to have the structure at the beginning of the structure it is included in, right?

Quoted 7 lines
include/linux/zio.h new file +7 -0
+enum zio_object_type {
+	ZNONE = 0,	/* reserved for non zio object */
+	ZDEV, ZCSET, ZCHAN,
+	ZTRIG, ZTI,	/* trigger and trigger instance */
+	ZBUF, ZBI,	/* buffer and buffer instance */
+};
+

include/linux/zio.h line 62

Quoted 10 lines
include/linux/zio.h new file +10 -0
+/* zio_obj_head is for internal use only, as explained above */
+struct zio_obj_head {
+	struct kobject		kobj;
+	enum zio_object_type	zobj_type;
+	char			name[ZIO_NAME_LEN];
+};
+#define to_zio_head(_kobj) container_of(_kobj, struct zio_obj_head, kobj)
+#define to_zio_dev(_kobj) container_of(_kobj, struct zio_device, head.kobj)
+#define to_zio_cset(_kobj) container_of(_kobj, struct zio_cset, head.kobj)
+#define to_zio_chan(_kobj) container_of(_kobj, struct zio_channel, head.kobj)

Why are you using a "raw" kobject and not 'struct device' instead? If you use a kobject, you loose all of the device tree information that a real struct device provides to userspace, and can only cause confusion in the long run.

This also will provide you the "type" and name that you are needing here, as well as lots of other good things (properly formatted logging messages, uevents, etc.)

Please consider moving to that instead.

thanks,

greg k-h

#9 lore raw

Re: [RFC PATCH 2/7] include/linux: add headers for drivers/zio

In data sabato 26 novembre 2011 12:02:16, Greg KH ha scritto:

Quoted 9 lines · Alessandro Rubini
Quoted 5 lines

+/*
+ * We use the same functions to deal with attributes, but the structures
+ * we act on may be different (dev, cset, channel). Thus, all structures
+ * begin with the type identifier, and zio_obj_head is used in container_of + */

Because you are using container_of, you don't have to have the structure at the beginning of the structure it is included in, right?

Different structures have similar features and we use zio_obj_head->zobj_type to identify the correct container_of to apply. Sometimes we use the head only, so we delay container_of later.

Quoted 11 lines
Quoted 11 lines
include/linux/zio.h new file +11 -0
+enum zio_object_type {
+   ZNONE = 0,      /* reserved for non zio object */
+   ZDEV, ZCSET, ZCHAN,
+   ZTRIG, ZTI,     /* trigger and trigger instance */
+   ZBUF, ZBI,      /* buffer and buffer instance */
+};
+
+/* zio_obj_head is for internal use only, as explained above */
+struct zio_obj_head {
+   struct kobject          kobj;
+   enum zio_object_type    zobj_type;
Quoted 8 lines
Quoted 7 lines
include/linux/zio.h new file +4 -0
+   char                    name[ZIO_NAME_LEN];
+};
+#define to_zio_head(_kobj) container_of(_kobj, struct zio_obj_head, kobj)
+#define to_zio_dev(_kobj) container_of(_kobj, struct zio_device,

head.kobj) +#define to_zio_cset(_kobj) container_of(_kobj, struct zio_cset, head.kobj) +#define to_zio_chan(_kobj) container_of(_kobj, struct zio_channel, head.kobj)

Why are you using a "raw" kobject and not 'struct device' instead?

The device way was experimented and we can move in that direction. I also tried a mixed solution with device and kobject, because not all the zio objects can be device.

I decided to use the kobject way because it was an easier and flexible solution for a fast development.

Quoted 2 lines

If you use a kobject, you loose all of the device tree information that a real struct device provides to userspace,

You mean the device sysfs tree? Acctually we don't need that information

Quoted 1 line

and can only cause confusion in the long run.

I think it can be confusing to declare a device what is not a device, for
example: buffer, trigger, channel-set (maybe in some
sense can be a device) and channel

Quoted 3 lines

This also will provide you the "type" and name that you are needing here, as well as lots of other good things (properly formatted logging messages, uevents, etc.)

If you refer to device_type, I think it is too complex for our purpose (also tried during the device "experiment"), we only need to recognize a zio object, we don't need al the stuff within device_type.

You are right, device is full of great things and the migration to device is always a point of discussion, but actually kobject meet well with our needs.

Quoted 1 line

Please consider moving to that instead.

We can re-evaluate and better explain the choice if kobj is still the preferrable one

Quoted 3 lines

thanks,

greg k-h

Signature · 1 line
Federico Vaga
#10 lore raw

Re: [RFC PATCH 2/7] include/linux: add headers for drivers/zio

Quoted 8 lines · Federico Vaga

In data sabato 26 novembre 2011 12:02:16, Greg KH ha scritto:

Quoted 7 lines · Alessandro Rubini
Quoted 5 lines

+/*
+ * We use the same functions to deal with attributes, but the structures
+ * we act on may be different (dev, cset, channel). Thus, all structures
+ * begin with the type identifier, and zio_obj_head is used in container_of + */

Quoted 6 lines
Quoted 2 lines

Because you are using container_of, you don't have to have the structure at the beginning of the structure it is included in, right?

Different structures have similar features and we use zio_obj_head->zobj_type to identify the correct container_of to apply. Sometimes we use the head only, so we delay container_of later.

That's usually not a good idea, which is why we don't do it generally in the rest of the kernel.

You should "almost" always already know the type of device you are pointing to when pointing to it, so that you can properly dereference it. I think you are doing the right thing here, but the true test would be to move that structure somewhere else other than "first" and see what breaks.

Quoted 24 lines
Quoted 11 lines
Quoted 11 lines
include/linux/zio.h new file +11 -0
+enum zio_object_type {
+   ZNONE = 0,      /* reserved for non zio object */
+   ZDEV, ZCSET, ZCHAN,
+   ZTRIG, ZTI,     /* trigger and trigger instance */
+   ZBUF, ZBI,      /* buffer and buffer instance */
+};
+
+/* zio_obj_head is for internal use only, as explained above */
+struct zio_obj_head {
+   struct kobject          kobj;
+   enum zio_object_type    zobj_type;
Quoted 8 lines
Quoted 7 lines
include/linux/zio.h new file +4 -0
+   char                    name[ZIO_NAME_LEN];
+};
+#define to_zio_head(_kobj) container_of(_kobj, struct zio_obj_head, kobj)
+#define to_zio_dev(_kobj) container_of(_kobj, struct zio_device,

head.kobj) +#define to_zio_cset(_kobj) container_of(_kobj, struct zio_cset, head.kobj) +#define to_zio_chan(_kobj) container_of(_kobj, struct zio_channel, head.kobj)

Why are you using a "raw" kobject and not 'struct device' instead?

The device way was experimented and we can move in that direction. I also tried a mixed solution with device and kobject, because not all the zio objects can be device.

Quoted 7 lines

I decided to use the kobject way because it was an easier and flexible solution for a fast development.

Quoted 2 lines

If you use a kobject, you loose all of the device tree information that a real struct device provides to userspace,

You mean the device sysfs tree? Acctually we don't need that information

Yes you do, you are already using it, right?

By using kobjects you "skip" notifying userspace the whole tree and it only knows about "parts" of it, which is why you should not do this.

Quoted 5 lines
Quoted 1 line

and can only cause confusion in the long run.

I think it can be confusing to declare a device what is not a device, for
example: buffer, trigger, channel-set (maybe in some
sense can be a device) and channel

Nope, they seem like "devices" to me in that you want them showing up in sysfs, which is why you used kobjects, right? Because of that, you are in the device tree, so you need to use a 'struct device'.

Quoted 10 lines
Quoted 3 lines

This also will provide you the "type" and name that you are needing here, as well as lots of other good things (properly formatted logging messages, uevents, etc.)

If you refer to device_type, I think it is too complex for our purpose (also tried during the device "experiment"), we only need to recognize a zio object, we don't need al the stuff within device_type.

You are right, device is full of great things and the migration to device is always a point of discussion, but actually kobject meet well with our needs.

I beg to differ.

Quoted 4 lines
Quoted 1 line

Please consider moving to that instead.

We can re-evaluate and better explain the choice if kobj is still the preferrable one

kobject is not the preferrable one, sorry.

greg k-h

#11 lore raw

Re: [RFC PATCH 2/7] include/linux: add headers for drivers/zio

2011/11/27 Greg KH <[email protected]>:

Quoted 5 lines · Federico Vaga
Quoted 4 lines

In data sabato 26 novembre 2011 12:02:16, Greg KH ha scritto:

Quoted 3 lines · Alessandro Rubini
Quoted 2 lines

+/*
+ * We use the same functions to deal with attributes, but the s=

tructures

Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line

+ * we act on may be different (dev, cset, channel). Thus, all s=

tructures

Quoted 4 lines
Quoted 4 lines
Quoted 4 lines
Quoted 2 lines

+ * begin with the type identifier, and zio_obj_head is used in container_of + */

Because you are using container_of, you don't have to have the str=

ucture

Quoted 3 lines
Quoted 3 lines
Quoted 1 line

at the beginning of the structure it is included in, right?

Different structures have similar features and we use zio_obj_head->=

zobj_type to

Quoted 1 line
Quoted 1 line

identify the correct container_of to apply. =C2=A0Sometimes we use t=

he head only, so

Quoted 3 lines
Quoted 1 line

we delay container_of later.

That's usually not a good idea, which is why we don't do it generally=

in

Quoted 5 lines

the rest of the kernel.

You should "almost" always already know the type of device you are pointing to when pointing to it, so that you can properly dereference it. =C2=A0I think you are doing the right thing here, but the true te=

st would

Quoted 1 line

be to move that structure somewhere else other than "first" and see w=

hat

Quoted 1 line

breaks.

One of our next commits will be the moving of this field somewhere else in the structures for bug finding. Thank you for the suggestion.

Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines

+enum zio_object_type {
+ =C2=A0 ZNONE =3D 0, =C2=A0 =C2=A0 =C2=A0/* reserved for non zi=

o object */

Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines

+ =C2=A0 ZDEV, ZCSET, ZCHAN,
+ =C2=A0 ZTRIG, ZTI, =C2=A0 =C2=A0 /* trigger and trigger instan=

ce */

Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line

+ =C2=A0 ZBUF, ZBI, =C2=A0 =C2=A0 =C2=A0/* buffer and buffer ins=

tance */

Quoted 7 lines
Quoted 7 lines
Quoted 7 lines

include/linux/zio.h

Quoted 7 lines
include/linux/zio.h new file +7 -0
+};
+
+/* zio_obj_head is for internal use only, as explained above */
+struct zio_obj_head {
+ =C2=A0 struct kobject =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0kobj;
+ =C2=A0 enum zio_object_type =C2=A0 =C2=A0zobj_type;
+ =C2=A0 char =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=

=A0 =C2=A0 =C2=A0name[ZIO_NAME_LEN];

Quoted 2 lines
Quoted 2 lines
Quoted 2 lines

Review

Quoted 2 lines
(quoted diff) +2 -0
+};
+#define to_zio_head(_kobj) container_of(_kobj, struct zio_obj_h=

ead, kobj)

Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line

+#define to_zio_dev(_kobj) container_of(_kobj, struct zio_device=

,

Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line

head.kobj) +#define to_zio_cset(_kobj) container_of(_kobj, struc=

t

Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line

zio_cset, head.kobj) +#define to_zio_chan(_kobj) container_of(_k=

obj,

Quoted 4 lines
Quoted 4 lines
Quoted 2 lines
Quoted 1 line

struct zio_channel, head.kobj)

Why are you using a "raw" kobject and not 'struct device' instead?

The device way was experimented and we can move in that direction. I=

also

Quoted 1 line
Quoted 1 line

tried a mixed solution with device and kobject, because not all the =

zio objects

Quoted 3 lines
Quoted 3 lines

can be device.

I decided to use the kobject way because it was an easier and flexib=

le solution

Quoted 3 lines
Quoted 3 lines

for a fast development.

Quoted 1 line

If you use a kobject, you loose all of the device tree information=

that a

Quoted 3 lines
Quoted 3 lines
Quoted 1 line

real struct device provides to userspace,

You mean the device sysfs tree? Acctually we don't need that informa=

tion

Quoted 4 lines

Yes you do, you are already using it, right?

By using kobjects you "skip" notifying userspace the whole tree and i=

t

Quoted 5 lines

only knows about "parts" of it, which is why you should not do this.

Quoted 3 lines
Quoted 1 line

and can only cause confusion in the long run.

I think it can be confusing to declare a device what is not a device=

, for

Quoted 4 lines
Quoted 2 lines

example: buffer, trigger, channel-set (maybe in some sense can be a device) and channel

Nope, they seem like "devices" to me in that you want them showing up=

in

Quoted 1 line

sysfs, which is why you used kobjects, right? =C2=A0Because of that, =

you are

Quoted 3 lines

in the device tree, so you need to use a 'struct device'.

Quoted 1 line
Quoted 1 line

This also will provide you the "type" and name that you are needin=

g

Quoted 1 line
Quoted 1 line
Quoted 1 line

here, as well as lots of other good things (properly formatted log=

ging

Quoted 3 lines
Quoted 3 lines
Quoted 1 line

messages, uevents, etc.)

If you refer to device_type, I think it is too complex for our purpo=

se (also

Quoted 1 line
Quoted 1 line

tried during the device "experiment"), we only need to recognize a z=

io object,

Quoted 3 lines
Quoted 3 lines

we don't need al the stuff within device_type.

You are right, device is full of great things and the migration to d=

evice is

Quoted 1 line
Quoted 1 line

always a point of discussion, but actually kobject meet well with ou=

r needs.

Quoted 6 lines

I beg to differ.

Quoted 3 lines
Quoted 1 line

Please consider moving to that instead.

We can re-evaluate and better explain the choice if kobj is still th=

e

Quoted 3 lines
Quoted 1 line

preferrable one

kobject is not the preferrable one, sorry.

I don't reply to each point because I suppose the point is: "kobject or device for sysfs?", maybe I misunderstood.
I know that it is not a good thing reply with a new question, but I think it can clarify the problem.

Why device is it preferred to export some sysfs attributes when sysfs ask me kobject?

As I tested both device and kobject, I'll do a parallel implementation with device.

Quoted 2 lines

greg k-h

--=20
=46ederico Vaga

#12 lore raw

Re: [RFC PATCH 2/7] include/linux: add headers for drivers/zio

Quoted 2 lines · Federico Vaga

I don't reply to each point because I suppose the point is: "kobject or device for sysfs?", maybe I misunderstood.

That is correct.

Quoted 5 lines

I know that it is not a good thing reply with a new question, but I think it can clarify the problem.

Why device is it preferred to export some sysfs attributes when sysfs ask me kobject?

If your code is working properly, you don't have to ever make sysfs calls, only driver core calls, for sysfs files. There might be a few minor exceptions, but I think the coverage is all there now.

Quoted 2 lines

As I tested both device and kobject, I'll do a parallel implementation with device.

As you are using a tree of devices, please use struct device, I can't accept the code otherwise.

greg k-h

#13 lore raw

RFC PATCH 3/7 drivers/zio: core files for the ZIO input/output

In reply to Alessandro Rubini

From: Federico Vaga <[email protected]>

This adds the core files for ZIO.
The files match commit 7d37663 in git://ohwr.org/misc/zio.git .

The Makefile already includes material that is added by later patches. This doesn't imply a compilation error as drivers/zio is not yet being compiled by drivers/Makefile.

---
 drivers/zio/Makefile   |   10 +
 drivers/zio/zio-cdev.c |  498 +++++++++++++++++
 drivers/zio/zio-sys.c  | 1423 ++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 1931 insertions(+), 0 deletions(-)
 create mode 100644 drivers/zio/Makefile
 create mode 100644 drivers/zio/zio-cdev.c
 create mode 100644 drivers/zio/zio-sys.c
drivers/zio/Makefile new file +10 -0
new file mode 100644
index 0000000..fb5dd14
@@ -0,0 +1,10 @@
+
+zio-core-objs := zio-cdev.o zio-sys.o
+obj-$(CONFIG_ZIO) += zio-core.o
+
+obj-$(CONFIG_ZIO) += drivers/
+obj-$(CONFIG_ZIO) += buffers/
+obj-$(CONFIG_ZIO) += triggers/
+
+hostprogs-y := zio-dump
+
drivers/zio/zio-cdev.c new file +498 -0

498 lines not on this page · raw message

drivers/zio/zio-sys.c new file +1423 -0

1,423 lines not on this page · raw message

Signature · 1 line
1.7.7.2
#14 lore raw

Re: [RFC PATCH 3/7] drivers/zio: core files for the ZIO input/output

drivers/zio/zio-sys.c line 544

Quoted 2 lines · Alessandro Rubini
drivers/zio/zio-sys.c new file +2 -0
+static struct kobj_type zdktype = { /* For standard and extended attribute */
+	.release   = NULL,

Sweet!

As-per the in-kernel documentation, I now get to mock you for doing this :)

Please NEVER DO THIS, you are ignoring the messages that the kernel sends you when you remove one of these devices, and causing a memory leak.

Not nice at all, yet another reason to use a 'struct device'.

thanks,

greg k-h

#15 lore raw

Re: [RFC PATCH 3/7] drivers/zio: core files for the ZIO input/output

In data sabato 26 novembre 2011 12:03:41, Greg KH ha scritto:

Quoted 12 lines · Alessandro Rubini
Quoted 2 lines

+static struct kobj_type zdktype = { /* For standard and extended
attribute */ + .release = NULL,

Sweet!

As-per the in-kernel documentation, I now get to mock you for doing this :)

Please NEVER DO THIS, you are ignoring the messages that the kernel sends you when you remove one of these devices, and causing a memory leak.

Honestly we never see any messages about this.

Quoted 1 line

Not nice at all, yet another reason to use a 'struct device'.

I don't think is a valid reason, because device_release implementation require us to implement a release method within device, or device_type or class; so we can use kobj_type as well.

Quoted 3 lines

thanks,

greg k-h

Signature · 1 line
Federico Vaga
#16 lore raw

Re: [RFC PATCH 3/7] drivers/zio: core files for the ZIO input/output

Quoted 7 lines · Federico Vaga

In data sabato 26 novembre 2011 12:03:41, Greg KH ha scritto:

Quoted 6 lines · Alessandro Rubini
Quoted 2 lines

+static struct kobj_type zdktype = { /* For standard and extended
attribute */ + .release = NULL,

Sweet!

Quoted 8 lines
Quoted 6 lines

As-per the in-kernel documentation, I now get to mock you for doing this :)

Please NEVER DO THIS, you are ignoring the messages that the kernel sends you when you remove one of these devices, and causing a memory leak.

Honestly we never see any messages about this.

Really? Then you never removed that kobject from memory. Please go read the kobject documentation for more details.

Quoted 5 lines
Quoted 1 line

Not nice at all, yet another reason to use a 'struct device'.

I don't think is a valid reason, because device_release implementation require us to implement a release method within device, or device_type or class; so we can use kobj_type as well.

True, but it tries to make things easier to not get wrong, like you are here.

Please fix this.

greg k-h

#17 lore raw

Re: [RFC PATCH 3/7] drivers/zio: core files for the ZIO input/output

2011/11/27 Greg KH <[email protected]>:

Quoted 4 lines · Federico Vaga
Quoted 3 lines

In data sabato 26 novembre 2011 12:03:41, Greg KH ha scritto:

Quoted 2 lines · Alessandro Rubini
Quoted 1 line

+static struct kobj_type zdktype =3D { /* For standard and exten=

ded

Quoted 5 lines
Quoted 5 lines
Quoted 5 lines
Quoted 1 line

attribute */ + =C2=A0 =C2=A0.release =C2=A0 =3D NULL,

Sweet!

As-per the in-kernel documentation, I now get to mock you for doin=

g

Quoted 3 lines
Quoted 3 lines
Quoted 3 lines

this :)

Please NEVER DO THIS, you are ignoring the messages that the kerne=

l

Quoted 1 line
Quoted 1 line
Quoted 1 line

sends you when you remove one of these devices, and causing a memo=

ry

Quoted 5 lines
Quoted 3 lines
Quoted 1 line

leak.

Honestly we never see any messages about this.

Really? =C2=A0Then you never removed that kobject from memory. =C2=A0=

Please go

Quoted 1 line

read the kobject documentation for more details.

Yes. All the kobjects are correctly removed and no memory leak was foun= d.

I took a look into kobject.c and I found (I suppose) the message but it is a pr_debug(); if it is so important we can think to "promote" it to pr_warning()

Quoted 3 lines
Quoted 3 lines
Quoted 1 line

Not nice at all, yet another reason to use a 'struct device'.

I don't think is a valid reason, because device_release implementati=

on require

Quoted 1 line
Quoted 1 line

us to implement a release method within device, or device_type or cl=

ass; so we

Quoted 3 lines
Quoted 1 line

can use kobj_type as well.

True, but it tries to make things easier to not get wrong, like you a=

re

Quoted 3 lines

here.

Please fix this.

I'll fix it

Quoted 2 lines

greg k-h

--=20
=46ederico Vaga

#18 lore raw

RFC PATCH 4/7 drivers/zio: add triggers and buffers

In reply to Alessandro Rubini

This adds two triggers and one buffer.
The files match commit 7d37663 in git://ohwr.org/misc/zio.git .

---
 drivers/zio/buffers/Makefile          |    1 +
 drivers/zio/buffers/zio-buf-kmalloc.c |  273 +++++++++++++++++++++++++++++++++
 drivers/zio/triggers/Makefile         |    2 +
 drivers/zio/triggers/zio-trig-irq.c   |  203 ++++++++++++++++++++++++
 drivers/zio/triggers/zio-trig-timer.c |  193 +++++++++++++++++++++++
 5 files changed, 672 insertions(+), 0 deletions(-)
 create mode 100644 drivers/zio/buffers/Makefile
 create mode 100644 drivers/zio/buffers/zio-buf-kmalloc.c
 create mode 100644 drivers/zio/triggers/Makefile
 create mode 100644 drivers/zio/triggers/zio-trig-irq.c
 create mode 100644 drivers/zio/triggers/zio-trig-timer.c
drivers/zio/buffers/Makefile new file +1 -0
new file mode 100644
index 0000000..34b2f85
@@ -0,0 +1 @@
+obj-$(CONFIG_ZIO) += zio-buf-kmalloc.o
drivers/zio/buffers/zio-buf-kmalloc.c new file +273 -0

273 lines not on this page · raw message

drivers/zio/triggers/Makefile new file +2 -0
new file mode 100644
index 0000000..8e24b00
@@ -0,0 +1,2 @@
+obj-$(CONFIG_ZIO) += zio-trig-timer.o
+obj-$(CONFIG_ZIO) += zio-trig-irq.o
drivers/zio/triggers/zio-trig-irq.c new file +203 -0

203 lines not on this page · raw message

drivers/zio/triggers/zio-trig-timer.c new file +193 -0

193 lines not on this page · raw message

Signature · 1 line
1.7.7.2
#19 lore raw

RFC PATCH 5/7 drivers/zio: add the zio-zero device driver

In reply to Alessandro Rubini

From: Federico Vaga <[email protected]>

zio-zero is a demonstration driver that generates /dev/zero-like data. I can be used to test the default trigger and the default buffer. The files match commit 7d37663 in git://ohwr.org/misc/zio.git .

---
 drivers/zio/drivers/Makefile   |    1 +
 drivers/zio/drivers/zio-zero.c |   87 ++++++++++++++++++++++++++++++++++++++++
 2 files changed, 88 insertions(+), 0 deletions(-)
 create mode 100644 drivers/zio/drivers/Makefile
 create mode 100644 drivers/zio/drivers/zio-zero.c
drivers/zio/drivers/Makefile new file +1 -0
new file mode 100644
index 0000000..d59387b
@@ -0,0 +1 @@
+obj-$(CONFIG_ZIO) += zio-zero.o
drivers/zio/drivers/zio-zero.c new file +87 -0

87 lines not on this page · raw message

Signature · 1 line
1.7.7.2
#20 lore raw

RFC PATCH 6/7 drivers/zio: add user-space tool zio-dump

In reply to Alessandro Rubini

Use of zio-dump is described in the README.
The files match commit 7d37663 in git://ohwr.org/misc/zio.git .

---
 drivers/zio/zio-dump.c |  196 ++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 196 insertions(+), 0 deletions(-)
 create mode 100644 drivers/zio/zio-dump.c
drivers/zio/zio-dump.c new file +196 -0
new file mode 100644
index 0000000..e6f2149
@@ -0,0 +1,196 @@
+/*
+ * Trivial utility that reports data from ZIO input channels
+ */
+#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/select.h>
+
+#include <linux/zio.h>
+#include <linux/zio-buffer.h>
+
+unsigned char buf[1024*1024];
+char *prgname;
+
+void read_channel(int cfd, int dfd, FILE *log)
+{
+	int err = 0;
+	struct zio_control ctrl;
+	int i, j;
+
+	i = read(cfd, &ctrl, sizeof(ctrl));
+	switch (i) {
+	case -1:
+		fprintf(stderr, "%s: control read: %s\n",
+			prgname, strerror(errno));
+		exit(1);
+	case 0:
+		fprintf(stderr, "%s: control read: unexpected EOF\n",
+			prgname);
+		exit(1);
+	default:
+		fprintf(stderr, "%s: ctrl read: %i bytes (expected %i)\n",
+			prgname, i, sizeof(ctrl));
+		/* continue anyways */
+	case sizeof(ctrl):
+		break; /* ok */
+	}
+
+	/* Fail badly if the version is not the right one */
+	if (ctrl.major_version != ZIO_MAJOR_VERSION)
+		err++;
+	if (ZIO_MAJOR_VERSION == 0 && ctrl.minor_version != ZIO_MINOR_VERSION)
+		err++;
+	if (err) {
+		fprintf(stderr, "%s: kernel has zio %i.%i, "
+			"but I'm compiled for %i.%i\n", prgname,
+			ctrl.major_version, ctrl.minor_version,
+			ZIO_MAJOR_VERSION, ZIO_MINOR_VERSION);
+		exit(1);
+	}
+	if (ctrl.minor_version != ZIO_MINOR_VERSION) {
+		static int warned;
+
+		if (!warned++)
+			fprintf(stderr, "%s: warning: minor version mismatch\n",
+				prgname);
+	}
+
+	printf("Ctrl: version %i.%i, trigger %.16s, dev %.16s, "
+	       "cset %i, chan %i\n",
+	       ctrl.major_version, ctrl.minor_version,
+	       ctrl.triggername, ctrl.devname, ctrl.cset_i,
+	       ctrl.chan_i);
+	printf("Ctrl: seq %i, n %i, size %i, bits %i, "
+	       "flags %08x (%s)\n",
+	       ctrl.seq_num,
+	       ctrl.nsamples,
+	       ctrl.ssize,
+	       ctrl.sbits,
+	       ctrl.flags,
+	       ctrl.flags & ZIO_CONTROL_LITTLE_ENDIAN
+	       ? "little-endian" :
+	       ctrl.flags & ZIO_CONTROL_BIG_ENDIAN
+	       ? "big-endian" : "unknown-endian");
+	printf("Ctrl: stamp %lli.%09lli (%lli)\n",
+	       (long long)ctrl.tstamp.secs,
+	       (long long)ctrl.tstamp.ticks,
+	       (long long)ctrl.tstamp.bins);
+	/* FIXME: some control information is missing */
+
+	i = read(dfd, buf, sizeof(buf));
+	if (i < 0) {
+		fprintf(stderr, "%s: data read: %s\n",
+			prgname, strerror(errno));
+		return; /* next ctrl, let's see... */
+	}
+	if (!i) {
+		fprintf(stderr, "%s: data read: unexpected EOF\n", prgname);
+		return;
+	}
+	if (i != ctrl.nsamples * ctrl.ssize) {
+		if (i == sizeof(buf)) {
+			fprintf(stderr, "%s: buffer too small: "
+				"please fix me and recompile\n", prgname);
+			/* FIXME: empty the data channel */
+		} else {
+			fprintf(stderr, "%s: ctrl: read %i bytes "
+				"(exp %i)\n", prgname, i,
+				ctrl.nsamples * ctrl.ssize);
+		}
+		/* continue anyways */
+	}
+	fwrite(buf, 1, i, log);
+
+	/* report data to stdout */
+	for (j = 0; j < i; j++) {
+		if (!(j & 0xf))
+			printf("Data:");
+		printf(" %02x", buf[j]);
+		if ((j & 0xf) == 0xf || j == i - 1)
+			putchar('\n');
+	}
+	putchar('\n');
+}
+
+int main(int argc, char **argv)
+{
+	FILE *f;
+	char *outfname;
+	int *cfd; /* control file descriptors */
+	int *dfd; /* data file descriptors */
+	fd_set control_set, ready_set;
+	int i, j, maxfd, ndev;
+
+	if (argc < 3 || (argc & 1) != 1) {
+		fprintf(stderr, "%s: Wrong number of arguments\n"
+			"Use: \"%s <ctrl-file> <data-file> [...]\"\n",
+			argv[0], argv[0]);
+		exit(1);
+	}
+	prgname = argv[0];
+	cfd = malloc(argc / 2 * sizeof(*cfd));
+	dfd = malloc(argc / 2 * sizeof(*dfd));
+	if (!cfd || !dfd) {
+		fprintf(stderr, "%s: malloc: %s\n", prgname, strerror(errno));
+		exit(1);
+	}
+
+	/* Open all pairs, and build the fd_set for later select() */
+	FD_ZERO(&control_set);
+	for (i = 1, j = 0; i < argc; i += 2, j++) {
+		cfd[j] = open(argv[i], O_RDONLY);
+		dfd[j] = open(argv[i + 1], O_RDONLY);
+		if (cfd[j] < 0) {
+			fprintf(stderr, "%s: %s: %s\n", prgname, argv[i],
+				strerror(errno));
+			exit(1);
+		}
+		if (dfd[j] < 0) {
+			fprintf(stderr, "%s: %s: %s\n", prgname, argv[i + 1],
+				strerror(errno));
+			exit(1);
+		}
+		/* ctrl file is used in select, data file is non-blocking */
+		FD_SET(cfd[j], &control_set);
+		fcntl(dfd[j], F_SETFL, fcntl(dfd[j], F_GETFL) | O_NONBLOCK);
+		maxfd = dfd[j];
+	}
+	ndev = j;
+
+	/* always log data we read to some filename */
+	outfname = getenv("ZIO_DUMP_TO");
+	if (!outfname)
+		outfname = "/dev/null";
+	f = fopen(outfname, "w");
+	if (!f) {
+		fprintf(stderr, "%s: %s: %s\n", prgname, outfname,
+			strerror(errno));
+		exit(1);
+	}
+	/* ensure proper strace information and output to pipes */
+	setlinebuf(stdout);
+	setbuf(f, NULL);
+
+	/* now read control and then data, forever */
+	while (1) {
+		ready_set = control_set;
+		i = select(maxfd + 1, &ready_set, NULL, NULL, NULL);
+		if (i < 0 && errno == EINTR)
+			continue;
+		if (i < 0) {
+			fprintf(stderr, "%s: select(): %s\n", prgname,
+				strerror(errno));
+			exit(1);
+		}
+		for (j = 0; j < ndev; j++)
+			if (FD_ISSET(cfd[j], &ready_set))
+				read_channel(cfd[j], dfd[j], f);
+	}
+}
Signature · 1 line
1.7.7.2
#21 lore raw

RFC PATCH 7/7 zio: insert in Kbuild so it is actually compiled

In reply to Alessandro Rubini
---
 drivers/Kconfig     |    2 ++
 drivers/Makefile    |    1 +
 drivers/zio/Kconfig |   12 ++++++++++++
 3 files changed, 15 insertions(+), 0 deletions(-)
 create mode 100644 drivers/zio/Kconfig
drivers/Kconfig +2 -0
index 5289508..ef7bf06 100644
@@ -118,6 +118,8 @@ source "drivers/vlynq/Kconfig"
 
 source "drivers/virtio/Kconfig"
 
+source "drivers/zio/Kconfig"
+
 source "drivers/xen/Kconfig"
 
 source "drivers/staging/Kconfig"
drivers/Makefile +1 -0
index 91077ac..96da622 100644
@@ -118,6 +118,7 @@ obj-$(CONFIG_SSB)		+= ssb/
 obj-$(CONFIG_BCMA)		+= bcma/
 obj-$(CONFIG_VHOST_NET)		+= vhost/
 obj-$(CONFIG_VLYNQ)		+= vlynq/
+obj-$(CONFIG_ZIO)		+= zio/
 obj-$(CONFIG_STAGING)		+= staging/
 obj-y				+= platform/
 obj-y				+= ieee802154/
drivers/zio/Kconfig new file +12 -0
new file mode 100644
index 0000000..774a185
@@ -0,0 +1,12 @@
+
+config ZIO
+	tristate "The ZIO framework for high-bandwidth I/O"
+	help
+	  This is a new proposed framework for input/output, whose
+	  main use case is multi-megabyte per second I/O on several
+	  channels, with hardware timestamping and offline elaboration.
+
+	  Currently, all drivers (and triggers, and buffers) are compiled,
+	  with no Kconfig selection at a finer resolution.
+
+	  See www.ohwr.org/projects/zio for docs, slides, repo and list.
Signature · 1 line
1.7.7.2
#22 lore raw
In reply to Alessandro Rubini
Quoted 17 lines · Alessandro Rubini

This RFC patch-set introduces the ZIO framework for input/output, which will be used in the new series of drivers by the BE-CO-HT group at CERN.

The use-case it is meant to cover is very fast I/O with hardware-provided timestamps. The first production driver we will support is a 100Ms/s 4-channel 14-bit ADC (developed on ohwr: see
http://www.ohwr.org/projects/fmc-adc-100m14b4cha ). We need similar bandwidth on output.

The synchronization engine of that FMC card and other ones is going to be White Rabbit (http://www.ohwr.org/projects/white-rabbit).

Currently, the patch-set includes one example driver (zio-zero) that behaves like /dev/zero and /dev/urandom. Other drivers will come soon, both demo and real hardware.

Quoted 5 lines

Slides for a tutorial on the design ideas are online here:
http://www.ohwr.org/attachments/881/zio-111123.pdf

A list of pending issues and development plans is online at:
http://www.ohwr.org/projects/zio/wiki/Todo

You've Cc'ed the IIO mailinglist, so you know about the IIO framework. Could you explain why you need a new framework and your devices can't be supported by the IIO framework? After a first quick glance ZIO looks to me like a subset of IIO.

- Lars

#23 lore raw
Quoted 2 lines

You've Cc'ed the IIO mailinglist, so you know about the IIO framework.

Yes, we are aware of it. Initially we hoped to use it for our boards. There is an analysis by Federico on the ohwr wiki:

http://www.ohwr.org/projects/zio/wiki/Iio

See especially the final table about how it fits our requirements:

http://www.ohwr.org/projects/zio/wiki/Requirements

Quoted 2 lines

Could you explain why you need a new framework and your devices can't be supported by the IIO framework?

Mainly, because the use-cases it is designed for are different. It handles data one sample at a time while our data blocks are tens of hundreds of megabytes; there is still no support for output; data is expected to be analog only; timestamps are assumed to be nanoseconds. Also, we need easy off-line elaboration of data, that's why we attach a control structure to each data block (and user-space can ignore the control structure and work with data alone, if needed).

ZIO can work with accelerometers (we have one we'll support soon), but we need to support accelerators too. I think IIO is much better than ZIO for accelerometers, thermometers and similar stuff.

Quoted 1 line

After a first quick glance ZIO looks to me like a subset of IIO.

In some sense, yes. It's only a mechanism for data transfer, insisting to not attach any meaning to the data it carries around.

I'm open to suggestions (_we_ are) about how to easily use IIO for output, for hardware timestamps (we have 3 32-bit fields) and for very large data blocks, with DMA to/from user space -- sure we don't have this last point in ZIO at this point in time.

Thank you for your interest
/alessandro

#24 lore raw

2011/11/26 Alessandro Rubini <[email protected]>:

Quoted 4 lines

I'm open to suggestions (_we_ are) about how to easily use IIO for output, for hardware timestamps (we have 3 32-bit fields) and for very large data blocks, with DMA to/from user space -- sure we don't have this last point in ZIO at this point in time.

The latter seem like a case for the dma-buf mechanism.
http://lwn.net/Articles/462524/

(Interesting hardware you found Alessandro! :)

Yours,
Linus Walleij