Commit 65c8d4aa authored by Federico Vaga's avatar Federico Vaga

Documentation: add sysfs.txt and spinlock.txt

Signed-off-by: 's avatarFederico Vaga <federico.vaga@gmail.com>
Acked-by: Alessandro Rubini's avatarAlessandro Rubini <rubini@gnudd.com>
parent 76668830
......@@ -6,5 +6,7 @@ buffer.txt
- description of the buffer, its methods and how it is used.
trigger.txt
- what is a trigger and what's its role in ZIO.
sysfs.txt
- description of how ZIO uses sysfs
modules.txt
- list of modules (and description) found in the first ZIO package
......@@ -38,7 +38,7 @@ as channels as well.
==========
Most configuration and information in ZIO happens through sysfs.
See sysfs.txt for information about attributes. (FIXME: sysfs.txt)
See sysfs.txt for information about attributes.
Data Transfers
==============
......
Spinlocks
=========
zio_status->lock
----------------
ZIO takes track of all registered devices, csets, trigger types and
buffer types with a list for each object. When you add or remove an
element from these lists, alock must be taken. These lists can be
modified only during registration and unregistration operations,
nowhere else.
zio_device->lock
----------------
This lock is used to serialize every configuration operation performed
through zio attributes. Independently from which ZIO object is the
owner of the ZIO attribute, the correspondent zio_device lock is taken:
zio_device->lock
zio_cset->zdev->lock
zio_channel->cset->zdev->lock
zio_ti->cset->zdev->lock
zio_bi->cset->zdev->lock
Device, buffer and trigger are registered as different objects but
are usually on the same peripheral; so, registers which correspond to
zio attributes are all on the same peripheral. If buffer or trigger
are not on the same peripheral of device, it is usally because are software
implementation, then taking the zio_device->lock still works. In the
rare case where buffer or trigger are not on the same peripheral of
device and they are not software implemented and they can be shared with
other devices, then, you must handle concurrency within your drivers.
This lock is also used to protect the enable status of device, cset,
channel and trigger instance. When one of these element change its
status, no one else can change its status or modify any zio attributes.
In this case the trigger operations abort() and change_status() run in a
locked contest.
zio_cset->lock
--------------
This lock is used to protect the concurrent access to transfer
informations such as: ti->flags ZTI_STATUS bit
zio_bi->lock
------------
zio_ti->lock
------------
/* FIXME useless ?*/
zio_buffer_type->lock and zio_trigger_type->lock
---------------------
Both types take track of every instances created with a list. When a
new instance is added or removed from its list, the correspondent
lock must be taken. ZIO modifies these list only during registration
and unregistration of the correspondent instance.
zio_attribute
=============
The main idea behind the zio_attribute is that generally what is a
sysfs attribute is also a register in a I/O peripheral; ZIO attributes
can thus be used to export to the host system the device internal
registers. ZIO uses a pair of numbers: address and value. The address
represents the way to gain access to a device register; it is an union
of two elements: addr which is the register address, and ptr which is
a pointer to a private structure defined within the low-level driver;
the driver implementor can choose whether to use an address alone or
allocate its own private structure.
struct zio_attribute {
struct attribute attr;
uint32_t flags;
int index;
union {
void *ptr;
unsigned long addr;
} priv;
uint32_t value;
const struct zio_sysfs_operations *s_op;
};
ZIO sysfs Operations
====================
ZIO uses two sysfs operations: conf_set() and info_get(); the former
writes a configuration value to a register and the latter retrieves a
value from a register.
The ZIO core takes care of ASCII conversion between ZIO and sysfs
because ZIO attributes must all be integer values. ZIO also ensures
that access to info_get and conf_set is serialized, by using spinlocks
at device scope.
int (*info_get)(struct kobject *kobj,
struct zio_attribute *zattr,
uint32_t *usr_val);
int (*conf_set)(struct kobject *kobj,
struct zio_attribute *zattr,
uint32_t usr_val);
ZIO calls the conf_set operation every time a user changes an attribute
value. Drivers can avoid defining info_get if the attributes are only
changed by the user. If values may change for other reasons (for
example to reflect internal device status), you must implement info_get
to re-syncronize the ZIO attribute value with the register value. When
the info_get method is not implemented, ZIO returns the current value
of the attribute.
Attribute Classification
========================
ZIO classifies its own sysfs attributes in two categories: standard
and extended.
Standard Attributes
-------------------
Standard attributes are the most common attributes among I/O
peripherals; for example gain, offset, sample-rate. The main feature
of a standard attribute is that its name in sysfs and its meaning are
clearly defined, irrespective of the peculiarities of the individual
device. Standard attributes are not mandatory, so each object
declares which one within the standard set apply to itself.
Within standard ZIO attributes, all times (such as delay and sample
period) are represented as nanoseconds, all voltages (such as range or
trigger value) are represented as microvolts. Special needs (such as
picoseconds or nanovolts) may be handled in extended attributes.
Following the list of the current standard attributes:
ZATTR_NBIT /* number of bits per sample */
ZATTR_GAIN /* gain for signal, integer in 0.001 steps */
ZATTR_OFFSET /* microvolts */
ZATTR_MAXRATE /* hertz */
ZATTR_VREFTYPE /* source of Vref (0 = default) */
ZATTR_TRIG_REENABLE /* re-arm trigger */
ZATTR_TRIG_NSAMPLES /* samples for each transfer */
ZATTR_ZBUF_MAXLEN /* max number of element in buffer */
Extended Attributes
-------------------
Extended attributes are object-specific. They are defined to
cater for unique device features that cannot be generalized to a
framework-wide abstraction. Each extended attribute has a different
name defined by developer, and its meaning is not the same among the
set of I/O peripherals or conf_set implementations.
Attribute Set
-------------
All ZIO objects (devices, triggers and buffers) have standard and
extended attributes which are part of the zio_attribute_set container.
struct zio_attribute_set {
struct zio_attribute *std_zattr;
unsigned int n_std_attr;
struct zio_attribute *ext_zattr;
unsigned int n_ext_attr;
struct attribute_group group;
};
The ZIO attribute-set defines the ZIO standard attributes and the
extended ones. In order to register attributes within the
sysfs file system, the code needs to pass an attribute_group
How define a ZIO attribute
============================
Each zio object (device, buffer and trigger) can define its own zio
attribute. In order to define a new zio attribute (standard or
extended), the zio framework provides some macros. The following
macro:
DEFINE_ZATTR_STD(_type, _name)
must be used to declare a new set of standard attributes; _type is
used to specify the kind of zio object, _name is the name of the
array of standard attributes. The following macros are used to
define each single attributes:
ZATTR_REG(zobj, _type, _mode, _add, _val)
ZATTR_PRV(zobj, _type, _mode, _priv, _val)
ZATTR_EXT_REG(_name, _mode, _add, _val)
ZATTR_EXT_PRV(_name, _mode, _priv, _val)
Where:
_val: is the default value of the zio attribute (the
register on the peripheral)
_add: is the address to gain access to the physical
register
_priv: is a pointer to a private structure to use to gain
access to the physical register
_mode: is the permission mask for the sysfs file
_name: is the name shown in sysfs
_type: is the type of standard attribute
_zobj: is the kind of zio object
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment