From b5176d9952357a282bd4ef71edb8a20a4ea59ade Mon Sep 17 00:00:00 2001
From: Federico Vaga <federico.vaga@gmail.com>
Date: Tue, 15 Nov 2011 19:22:12 +0100
Subject: [PATCH] Documentation: updated to match code and partially upgraded.

Signed-off-by: Federico Vaga <federico.vaga@gmail.com>
Signed-off-by: Alessandro Rubini <rubini@gnudd.com>
---
 Documentation/zio/buffer.txt  | 96 +++++++++++++++++++----------------
 Documentation/zio/device.txt  |  2 +-
 Documentation/zio/trigger.txt | 83 +++++++++++++++---------------
 3 files changed, 93 insertions(+), 88 deletions(-)

diff --git a/Documentation/zio/buffer.txt b/Documentation/zio/buffer.txt
index 294fedd..f80e63a 100644
--- a/Documentation/zio/buffer.txt
+++ b/Documentation/zio/buffer.txt
@@ -14,10 +14,10 @@ Please read <linux/zio-buffer.h> together with this file.
 
 Buffers may be device-specific or generic. A generic buffer called
 "kmalloc" is provided within zio-core; it uses kmalloc for allocation
-of control and 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).
+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
@@ -27,7 +27,7 @@ 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 will be registered
+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:
@@ -41,18 +41,22 @@ 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:
 
-	void *(*create)(struct zio_buffer *buffer, struct zio_channel *ch,
-		       fmode_t f_flags);
-	void (*destroy)(void *b_instance);
+	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
+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 instance is a void pointer because each buffer needs a
-different (private) data structure to represent an own instance.
+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 the buffer. ZIO calls destroy when the channel
-is unregistered from ZIO or when the user assigns a different buffer
-type to the channel.
+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
@@ -60,47 +64,51 @@ incoming data can queue up while the application leaves it closed
 handled by ZIO, so it couldn't call destroy on close even if it wanted
 to.
 
-	void *(*alloc_block)(void *b_instance, void **handle_ret,
-			     size_t size, gfp_t gfp);
-	void (*free_block)(void *handle);
+	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 when the trigger fills it,
-and it is freed when user has read or ignored it. For output,
-allocation happens on user write and free is called by the trigger.
-Thus, the function are sometimes called by buffer code itself, and
-sometimes by the trigger.  The data structure hosting a block is
-returned as a void pointer because each buffer needs its own
-private structure.
+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
 
-	ssize_t (*store_block)(void *handle, struct zio_control *ctrl,
-			       void *data, size_t len);
-	ssize_t (*retr_block) (void *handle, struct zio_control *ctrl,
-			       void *data, size_t len);
+	int (*store_block)(struct zio_bi *bi, struct zio_block *block);
+	struct zio_block (*retr_block) (struct zio_bi *bi);
 
-The trigger calls the store method when it has data to push for input
-channels.  If uses an handle it received from the alloc_block method.
-The trigger for output channels uses the retrieve method to extract
-data from the buffer and send it to the hardware driver. After
-retrieving data, it is responsible for freeing it.
-FIXME: how can the trigger know the handle to retrieve?
+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
 	===============
 
-These are the file_operations used by the char devices (control and
-data) for every channel using this buffer type.  The open method of
-the zio file operations kmallocs f->private_data to point to this
-structure:
+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 {
-		void *b_instance;
+		struct zio_channel *chan;
 		enum zio_cdev_type type;
 	};
 
-All buffer file operations can thus refer to the buffer instance for
-this channel and know if the current file is ZIO_CDEV_CTRL or
-ZIO_CDEV_DATA.  The release file operation is expected to free this
-structure.
+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.
 
-See zio-buf-kmalloc.c for a working example of buffer 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.
diff --git a/Documentation/zio/device.txt b/Documentation/zio/device.txt
index 75bd102..c75a38d 100644
--- a/Documentation/zio/device.txt
+++ b/Documentation/zio/device.txt
@@ -56,7 +56,7 @@ 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).
+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
diff --git a/Documentation/zio/trigger.txt b/Documentation/zio/trigger.txt
index 491d59b..1aa701f 100644
--- a/Documentation/zio/trigger.txt
+++ b/Documentation/zio/trigger.txt
@@ -7,6 +7,7 @@ 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
 	=============
@@ -27,37 +28,30 @@ of "app-request".
 	Trigger Operations
 	==================
 
-(NOTE: this is still subject to fine-tuning, as we are still writing code)
-
 Trigger operations are the following:
 
-	struct zio_trigger_instance *(*create)(struct zio_buffer *buffer,
-						struct zio_cset *cset);
-	void (*destroy)(struct zio_trigger_instance *t_instance);
+	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
+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 this
-generic structure:
-
-	struct zio_trigger_instance {
-		struct zio_trigger *trig;
-		struct zio_cset *cset;
-	};
-
-Every time this structure is passed over, trigger code may use container_of
-if it needs to access the private enclosing structure.
+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_trigger_instance *t_instance);
+	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 (*enqueue_block)(struct zio_trigger_instance *t_instance,
-				struct zio_channel *ch,
-				struct zio_control *ctrl,
-				void *data, size_t len);
+	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.
@@ -66,17 +60,20 @@ 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).
 
-	int (*space_in_buffer)(struct zio_trigger_instance *t_instance);
+	struct zio_block (*pull_block)(struct zio_ti *ti,
+			  	       struct zio_channel *chan,);
+
+The method retrives a block from the trigger. I may be called by
+the buffer, if it wants a block immediately. The method returns a
+valid pointer to a block or NULL if there is no valid block that
+can be retrieved immediately.   The returned block may be shorter
+than what the trigger would have stored in the buffer by itself.
 
-The method return either 0 (there is space for one block), a positive
-value (the maximum size of the next block that can be enqueued) or
--EAGAIN.  This can be used by the poll file operation, to ask
-whether the next write(2) will succeed or not.
 
 	File Operations
 	===============
 
-The trigger may include a non-NULL f_ops pointer. Most trigger will
+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)
@@ -96,30 +93,30 @@ a time when the trigger fires, so input or output may happen.
 data has already happened when the trigger interrupt runs, but this
 doesn't change the software flow).
 
-For output triggers, the trigger instance is already hosting the data
-blocks (received through the enqueue_block method), so the code will
-just loop over all the channels and free such data blocks. In some cases
-the trigger will need to perform the output before freeing data, in
-most cases data has been prepared for DMA during enqueue_block,
-so output already happened when the trigger run.
-
-ZIO offers this help macro to loop over all non-disabled channels:
+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 input triggers, the asynchronous code that runs the event will just
-need to call
+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_trigger_instance *instance);
+	zio_fire_trigger(struct zio_ti *ti);
 
-This function, part of zio-core, internally runs "cset_for_each".
-For each non-disabled channel, it calls the drv->input_block method
-and the stores it in the active buffer.
+This function, part of zio-core, calls the internal helpers
+__zio_fire_input_trigger for input or __zio_fire_output_trigger for
+output. These, in turn, internally run "cset_for_each". For each
+non-disabled channel, the input trigger function calls the
+drv->input_block and buffer->store_block; 
+the output trigger function calls the drv->output_block method (which
+will free the block when it is done) and the  buffer->retr_block
+method to prepare for the next operation.
 
-You can refer to "zio-trig-ktimer" for an example of a multi-instance
+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.
 
-- 
GitLab