Commit 03eeb819 authored by Marek Gumiński's avatar Marek Gumiński Committed by Jacek Kołodziejski

Replaced old zio repo with submodule of latest commit

parent 70f80683
......@@ -16,3 +16,6 @@
[submodule "software/fpga-config-space"]
path = software/fpga-config-space
url = git://ohwr.org/hdl-core-lib/fpga-config-space.git
[submodule "software/fmc-adc-100m14b4cha-sw/zio"]
path = software/fmc-adc-100m14b4cha-sw/zio
url = git://ohwr.org/misc/zio.git
zio @ 0aea6955
Subproject commit 0aea6955d010ac9f4e5983cad36bdfa438b63888
*~
.*cmd
.*ersions
*.o
*.ko
*.order
*.symvers
*.mod.c
\#*\#
*.sh
# eclipse files
.cproject
.project
.settings
.*.d
TAGS*
\ No newline at end of file
This diff is collapsed.
Where: /sys/bus/zio/version
Date: April 2013
Kernel Version: 3.x
Contact: zio@ohwr.org (mailing list)
Description: This attribute return the version of the ZIO framework in use.
Users:
Where: /sys/bus/zio/available_buffers
Date: April 2013
Kernel Version: 3.x
Contact: zio@ohwr.org (mailing list)
Description: This attribute return the list of available buffer types.
Users:
Where: /sys/bus/zio/available_triggers
Date: April 2013
Kernel Version: 3.x
Contact: zio@ohwr.org (mailing list)
Description: This attribute return the list of available trigger types.
Users:
Where: /sys/bus/zio/devices/hw-<zdev>/
Date: April 2013
Kernel Version: 3.x
Contact: zio@ohwr.org (mailing list)
Description: This directory represents a fake instance of a device the
real device (<zdev>). Once the device match with a ZIO
driver, then it creates the real device directory.
Users:
Where: /sys/bus/zio/devices/<zdev>/
Date: April 2013
Kernel Version: 3.x
Contact: zio@ohwr.org (mailing list)
Description: This directory represents a real device; it is child of
the fake device. This is the highest level of the device
hierarchy.
Users:
Where: /sys/bus/zio/devices/<zdev>/name
/sys/bus/zio/devices/<zdev>/<cset>/name
/sys/bus/zio/devices/<zdev>/<cset>/<chan>/name
/sys/bus/zio/devices/<zdev>/<cset>/trigger/name
/sys/bus/zio/devices/<zdev>/<cset>/<chan>/buffer/name
Date: April 2013
Kernel Version: 3.x
Contact: zio@ohwr.org (mailing list)
Description: This attribute returns the name of a ZIO object. It is a
read only attribute.
Users:
Where: /sys/bus/zio/devices/<zdev>/enable
/sys/bus/zio/devices/<zdev>/<cset>/enable
/sys/bus/zio/devices/<zdev>/<cset>/<chan>/enable
/sys/bus/zio/devices/<zdev>/<cset>/trigger/enable
/sys/bus/zio/devices/<zdev>/<cset>/<chan>/buffer/enable
Date: April 2013
Kernel Version: 3.x
Contact: zio@ohwr.org (mailing list)
Description: This attribute enable/disable a ZIO object. To enable a
ZIO object you must write '1', to disable '0'
Users:
Where: /sys/bus/zio/devices/<zdev>/<cset>/current_buffer
Date: April 2013
Kernel Version: 3.x
Contact: zio@ohwr.org (mailing list)
Description: This attribute return the current buffer in use by the
channel within the channel-set. You can change the kind of
buffer by writing its name in this attribute.
Users:
Where: /sys/bus/zio/devices/<zdev>/<cset>/current_trigger
Date: April 2013
Kernel Version: 3.x
Contact: zio@ohwr.org (mailing list)
Description: This attribute return the current trigger in use by the
channel-set. You can change the kind of trigger by writing
its name in this attribute.
Users:
Where: /sys/bus/zio/devices/<zdev>/<cset>/<chan>/buffer/
Date: April 2013
Kernel Version: 3.x
Contact: zio@ohwr.org (mailing list)
Description: This is a collection of ZIO buffer attributes. It
contains both: standard attributes (described later) and
extended attributes defined by each driver (not described
in this document). This collection refers to a single
instance of a buffer implementation. Each buffer
implementation can decide to support or not the standard
attributes; if it supports the standard attributes it
works as described in this document.
Finally, remember that there is a buffer instance of the
same implementation for each channel within the same
channel-set of your devices
Note: The permission on the standard attributes depend on
the buffer implementation
Users:
Where: /sys/bus/zio/devices/<zdev>/<cset>/<chan>/buffer/version
Date: April 2013
Kernel Version: 3.x
Contact: zio@ohwr.org (mailing list)
Description: This attribute define the version of the collection of
attributes that a buffer implementation exports. A
collection can change during the time. This attribute allow
an user-space program to recognize if it can work with a
particular version or not
Users:
Where: /sys/bus/zio/devices/<zdev>/<cset>/<chan>/buffer/max-buffer-len
Date: April 2013
Kernel Version: 3.x
Contact: zio@ohwr.org (mailing list)
Description: This attribute define the maximum number of blocks that
the buffer instance can store.
Users:
Where: /sys/bus/zio/devices/<zdev>/<cset>/<chan>/buffer/max-buffer-kb
Date: April 2013
Kernel Version: 3.x
Contact: zio@ohwr.org (mailing list)
Description: This attribute define the maximum kilo-byte of data (only
data not block) that the buffer instance can store.
Users:
Where: /sys/bus/zio/devices/<zdev>/
/sys/bus/zio/devices/<zdev>/<cset>/
/sys/bus/zio/devices/<zdev>/<cset>/<chan>/
Date: April 2013
Kernel Version: 3.x
Contact: zio@ohwr.org (mailing list)
Description: These are collections of attributes of the ZIO device
hierarchy. Each collection contains both: standard
attributes (described later) and extended attributes
defined by each driver (not described in this document).
A standard attribute can appear *only* one time in the
device hierarchy (e.g. The attribute X can be in a <cset>,
but it cannot be, at the same time, in a <chan> or a <zdev>
level). In this documentation we indicate each attribute
at all level, but remember that it can be available only
in one level. If an attribute appears only on a single
level it means that it can leave only there.
Attributes that live in an high level automatically apply
the configuration on all lower levels.
This collection refers to a single instance of a device.
Each driver can decide to support or not the standard
attributes; if it supports the standard attributes it works
as described in this document.
Note: The permission on the standard attributes depend on
the driver implementation
Users:
Where: /sys/bus/zio/devices/<zdev>/version
/sys/bus/zio/devices/<zdev>/<cset>/version
/sys/bus/zio/devices/<zdev>/<cset>/<chan>/version
Date: April 2013
Kernel Version: 3.x
Contact: zio@ohwr.org (mailing list)
Description: This attribute define the version of the collection of
attributes that a device driver exports. A
collection can change during the time. This attribute allow
an user-space program to recognize if it can work with a
particular version or not
Users:
Where: /sys/bus/zio/devices/<zdev>/gain_factor
/sys/bus/zio/devices/<zdev>/<cset>/gain_factor
/sys/bus/zio/devices/<zdev>/<cset>/<chan>/gain_factor
Date: April 2013
Kernel Version: 3.x
Contact: zio@ohwr.org (mailing list)
Description: This attribute define the gain factor of an I/O signal.
Users:
Where: /sys/bus/zio/devices/<zdev>/offset
/sys/bus/zio/devices/<zdev>/<cset>/offset
/sys/bus/zio/devices/<zdev>/<cset>/<chan>/offset
Date: April 2013
Kernel Version: 3.x
Contact: zio@ohwr.org (mailing list)
Description: This attribute define the offset to apply on an I/O
signal.
Users:
Where: /sys/bus/zio/devices/<zdev>/resolution-bits
/sys/bus/zio/devices/<zdev>/<cset>/resolution-bits
/sys/bus/zio/devices/<zdev>/<cset>/<chan>/resolution-bits
Date: April 2013
Kernel Version: 3.x
Contact: zio@ohwr.org (mailing list)
Description: This attribute define the resolution bit of a digitalized
I/O signal.
Users:
Where: /sys/bus/zio/devices/<zdev>/max-sample-rate
/sys/bus/zio/devices/<zdev>/<cset>/max-sample-rate
/sys/bus/zio/devices/<zdev>/<cset>/<chan>/max-sample-rate
Date: April 2013
Kernel Version: 3.x
Contact: zio@ohwr.org (mailing list)
Description: This attribute define the maximum sample rate of the I/O
signal.
Users:
Where: /sys/bus/zio/devices/<zdev>/vref-src
/sys/bus/zio/devices/<zdev>/<cset>/vref-src
/sys/bus/zio/devices/<zdev>/<cset>/<chan>/vref-src
Date: April 2013
Kernel Version: 3.x
Contact: zio@ohwr.org (mailing list)
Description: This attribute define the Volt reference source for the I/O
signal.
Users:
Where: /sys/bus/zio/devices/<zdev>/<cset>/trigger/
Date: April 2013
Kernel Version: 3.x
Contact: zio@ohwr.org (mailing list)
Description: This is a collection of ZIO trigger attributes. It
contains both: standard attributes (described later) and
extended attributes defined by each driver (not described
in this document). This collection refers to a single
instance of a trigger implementation. Each trigger
implementation can decide to support or not the standard
attributes; if it supports the standard attributes it
works as described in this document.
Finally, remember that there is a trigger instance of the
same implementation for each channel-set of your devices
Note: The permission on the standard attributes depend on
the trigger implementation
Users:
Where: /sys/bus/zio/devices/<zdev>/<cset>/trigger/version
Date: April 2013
Kernel Version: 3.x
Contact: zio@ohwr.org (mailing list)
Description: This attribute define the version of the collection of
attributes that a trigger implementation exports. A
collection can change during the time. This attribute allow
an user-space program to recognize if it can work with a
particular version or not
Users:
Where: /sys/bus/zio/devices/<zdev>/<cset>/trigger/nshots
Date: April 2013
Kernel Version: 3.x
Contact: zio@ohwr.org (mailing list)
Description: This attribute define the number of consecutive shots that
a trigger must perform. The value '0' mean infinite; not
all trigger implementation supports this feature. If a
trigger does not support infinite shots, it must prevents
the user to set '0' in this attribute.
Users:
Where: /sys/bus/zio/devices/<zdev>/<cset>/trigger/pre-samples
Date: April 2013
Kernel Version: 3.x
Contact: zio@ohwr.org (mailing list)
Description: This attribute define the number of pre-samples acquire for
each programmed shots.
Users:
Where: /sys/bus/zio/devices/<zdev>/<cset>/trigger/post-samples
Date: April 2013
Kernel Version: 3.x
Contact: zio@ohwr.org (mailing list)
Description: This attribute define the number of post-samples acquire for
each programmed shots.
Users:
LINUX ?= /lib/modules/$(shell uname -r)/build
zio-y := core.o chardev.o sysfs.o misc.o
zio-y += bus.o objects.o helpers.o dma.o
zio-y += buffers/zio-buf-kmalloc.o triggers/zio-trig-user.o
# Waiting for Kconfig...
CONFIG_ZIO_SNIFF_DEV:=y
zio-$(CONFIG_ZIO_SNIFF_DEV) += sniff-dev.o
obj-m = zio.o
obj-m += drivers/
obj-m += buffers/
obj-m += triggers/
GIT_VERSION = $(shell cd $(src); git describe --dirty --long --tags)
# For this CSM_VERSION, please see ohwr.org/csm documentation
ifdef CONFIG_CSM_VERSION
ccflags-y += -D"CERN_SUPER_MODULE=MODULE_VERSION(\"$(CONFIG_CSM_VERSION)\")"
else
ccflags-y += -DCERN_SUPER_MODULE=""
endif
# WARNING: the line below doesn't work in-kernel if you compile with O=
ccflags-y += -I$(src)/include/ -DGIT_VERSION=\"$(GIT_VERSION)\"
ccflags-$(CONFIG_ZIO_DEBUG) += -DDEBUG
all: modules tools
modules:
$(MAKE) -C $(LINUX) M=$(shell /bin/pwd)
modules_install:
$(MAKE) -C $(LINUX) M=$(shell /bin/pwd) $@
coccicheck:
$(MAKE) -C $(LINUX) M=$(shell /bin/pwd) coccicheck
.PHONY: tools
tools:
$(MAKE) -C tools M=$(shell /bin/pwd)
# this make clean is ugly, I'm aware...
clean:
rm -rf `find . -name \*.o -o -name \*.ko -o -name \*~ `
rm -rf `find . -name Module.\* -o -name \*.mod.c`
rm -rf .tmp_versions modules.order
$(MAKE) -C tools clean
Zio is "the ultimate I/O framework". It 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 3.3 onwards
(it used to work from 2.6.34 onwards, and we may fix the dev.id issue
to restore such backward compatibility.
This README in not updated very often, so please take this information
with a grain of salt. The architecture of ZIO and the basic concepts
are explained on www.ohwr.org/projects/zio/ (in particular the "files"
and "documents" tabs).
To test zio you need to load the core module:
insmod zio.ko
By detault ZIO uses "kmalloc" as a buffer, it is a simple buffer that
hosts a list of data blocks, for either input or output.
The default trigger is called "user", and it fires data transfers when
the user reads or writes. We also have the "timer" trigger: it 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 acquired at each
trigger instance.
With the core in place, you can load a driver (we have several, this only
shows the basics of zio-zero for input):
insmod drivers/zio-zero.ko
zio-zero has three channel sets. cset 0 has three channels.
They simulate three analog inputs, 8-bits 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/zio/zzero-0-0-ctrl
/dev/zio/zzero-0-0-data
/dev/zio/zzero-0-1-ctrl
/dev/zio/zzero-0-1-data
/dev/zio/zzero-0-2-ctrl
/dev/zio/zzero-0-2-data
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/zio/zzero-0-2-*
This is the result with a trigger that uses 2000 as msec and 32
as nsample:
./zio-dump /dev/zio/zzero-0-2-*
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
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
LINUX ?= /lib/modules/$(shell uname -r)/build
GIT_VERSION = $(shell cd $(src); git describe --dirty --long --tags)
# For this CSM_VERSION, please see ohwr.org/csm documentation
ifdef CONFIG_CSM_VERSION
ccflags-y += -D"CERN_SUPER_MODULE=MODULE_VERSION(\"$(CONFIG_CSM_VERSION)\")"
else
ccflags-y += -DCERN_SUPER_MODULE=""
endif
ccflags-y += -I$(src)/../include/ -DGIT_VERSION=\"$(GIT_VERSION)\"
ccflags-$(CONFIG_ZIO_DEBUG) += -DDEBUG
# zio-buf-kmalloc.o is now part of zio-core
obj-m = zio-buf-vmalloc.o
/* Alessandro Rubini for CERN, 2011, GNU GPLv2 or later */
/*
* This is a kmalloc-based buffer for the ZIO framework. It is used both
* as a default when no buffer is selected by applications and as an
* example about our our structures and methods are used.
*/
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/sched.h>
#include <linux/list.h>
#include <linux/err.h>
#include <linux/fs.h>
#include <linux/spinlock.h>
#include <linux/types.h>
#include <linux/zio.h>
#include <linux/zio-buffer.h>
#include <linux/zio-trigger.h>
#include <linux/zio-sysfs.h>
/* This is an instance of a buffer, associated to two cdevs */
struct zbk_instance {
struct zio_bi bi;
int nitem; /* allocated item */
struct list_head list; /* items list and lock */
};
#define to_zbki(bi) container_of(bi, struct zbk_instance, bi)
static struct kmem_cache *zbk_slab;
/* The list in the structure above collects a bunch of these */
struct zbk_item {
struct zio_block block;
struct list_head list; /* item list */
struct zbk_instance *instance;
size_t len; /* block.datalen may change, so save this */
};
#define to_item(block) container_of(block, struct zbk_item, block)
static ZIO_ATTR_DEFINE_STD(ZIO_BUF, zbk_std_zattr) = {
ZIO_ATTR(zbuf, ZIO_ATTR_ZBUF_MAXLEN, ZIO_RW_PERM,
ZIO_ATTR_ZBUF_MAXLEN, 16),
ZIO_ATTR(zbuf, ZIO_ATTR_ZBUF_ALLOC_LEN, ZIO_RO_PERM,
ZIO_ATTR_ZBUF_ALLOC_LEN, 0),
};
static int zbk_conf_set(struct device *dev, struct zio_attribute *zattr,
uint32_t usr_val)
{
struct zio_bi *bi = to_zio_bi(dev);
/* If somebody is sleeping for write and we increase the size... */
wake_up_interruptible(&bi->q);
return 0;
}
static int zbk_info_get(struct device *dev, struct zio_attribute *zattr,
uint32_t *usr_val)
{
struct zio_bi *bi = to_zio_bi(dev);
struct zbk_instance *zbki = to_zbki(bi);
switch (zattr->id) {
case ZIO_ATTR_ZBUF_ALLOC_LEN:
*usr_val = zbki->nitem;
break;
case ZIO_ATTR_ZBUF_MAXLEN:
default:
break;
}
return 0;
}
struct zio_sysfs_operations zbk_sysfs_ops = {
.conf_set = zbk_conf_set,
.info_get = zbk_info_get,
};
/* Alloc is called by the trigger (for input) or by f->write (for output) */
static struct zio_block *zbk_alloc_block(struct zio_bi *bi,
size_t datalen, gfp_t gfp)
{
struct zbk_instance *zbki = to_zbki(bi);
struct zbk_item *item;
struct zio_control *ctrl;
unsigned long flags;
void *data;
pr_debug("%s:%d\n", __func__, __LINE__);
/* alloc fails if we overflow the buffer size */
spin_lock_irqsave(&bi->lock, flags);
if (zbki->nitem >= zio_bi_std_val(bi, ZIO_ATTR_ZBUF_MAXLEN)) {
bi->flags |= ZIO_BI_NOSPACE;
goto out_unlock;
}
zbki->nitem++;
spin_unlock_irqrestore(&bi->lock, flags);
/* alloc item and data. Control remains null at this point */
item = kmem_cache_alloc(zbk_slab, gfp);
data = kmalloc(datalen, gfp);
ctrl = zio_alloc_control(gfp);
if (!item || !data || !ctrl)
goto out_free;
memset(item, 0, sizeof(*item));
item->block.data = data;
item->block.datalen = datalen;
item->len = datalen;
item->instance = zbki;
zio_set_ctrl(&item->block, ctrl);
return &item->block;
out_free:
kfree(data);
kmem_cache_free(zbk_slab, item);
zio_free_control(ctrl);
spin_lock_irqsave(&bi->lock, flags);
zbki->nitem--;
out_unlock:
spin_unlock_irqrestore(&bi->lock, flags);
return NULL;
}
/* Free is called by f->read (for input) or by the trigger (for output) */
static void zbk_free_block(struct zio_bi *bi, struct zio_block *block)
{
struct zbk_item *item;
struct zbk_instance *zbki;
unsigned long flags;
int awake = 0;
pr_debug("%s:%d\n", __func__, __LINE__);
item = to_item(block);
zbki = item->instance;
if (bi->flags & ZIO_BI_PUSHING) {
/* freed while pushing: we hold the bi lock already */
zbki->nitem--;
goto out_free;
}
spin_lock_irqsave(&bi->lock, flags);
if (((bi->flags & ZIO_DIR) == ZIO_DIR_OUTPUT) &&
zbki->nitem < zio_bi_std_val(bi, ZIO_ATTR_ZBUF_MAXLEN))
awake = 1;
bi->flags &= ~ZIO_BI_NOSPACE;
zbki->nitem--;
spin_unlock_irqrestore(&bi->lock, flags);
out_free:
kfree(block->data);
zio_free_control(zio_get_ctrl(block));
kmem_cache_free(zbk_slab, item);
if (awake)
wake_up_interruptible(&bi->q);
}
/* Store is called by the trigger (for input) or by f->write (for output) */
static int zbk_store_block(struct zio_bi *bi, struct zio_block *block)
{
struct zbk_instance *zbki = to_zbki(bi);
struct zio_channel *chan = bi->chan;
struct zbk_item *item = to_item(block);
unsigned long flags;
int awake = 0, pushed = 0, isempty;
int output = (bi->flags & ZIO_DIR) == ZIO_DIR_OUTPUT;
pr_debug("%s:%d (%p, %p)\n", __func__, __LINE__, bi, block);
/* add to the buffer instance or push to the trigger */
spin_lock_irqsave(&bi->lock, flags);
isempty = list_empty(&zbki->list);
if (isempty) {
if (unlikely(output))
pushed = zio_trigger_try_push(bi, chan, block);
else
awake = 1;
}
if (!pushed)
list_add_tail(&item->list, &zbki->list);
spin_unlock_irqrestore(&bi->lock, flags);
/* if first input, awake user space */
if (awake)
wake_up_interruptible(&bi->q);
return 0;
}
/* Retr is called by f->read (for input) or by the trigger (for output) */
static struct zio_block *zbk_retr_block(struct zio_bi *bi)
{
struct zbk_item *item;
struct zbk_instance *zbki;
struct zio_ti *ti;
struct list_head *first;
unsigned long flags;
zbki = to_zbki(bi);
/* PUSHING is only active temporarily during locked context */
if (bi->flags & ZIO_BI_PUSHING)
return NULL;
/* There is no trig->push in our call trace, proceed to get the lock */
spin_lock_irqsave(&bi->lock, flags);
if (list_empty(&zbki->list))
goto out_unlock;
first = zbki->list.next;
item = list_entry(first, struct zbk_item, list);
list_del(&item->list);
spin_unlock_irqrestore(&bi->lock, flags);
pr_debug("%s:%d (%p, %p)\n", __func__, __LINE__, bi, item);
return &item->block;
out_unlock:
spin_unlock_irqrestore(&bi->lock, flags);
/* There is no data in buffer, and we may pull to have data soon */
ti = bi->cset->ti;
if ((bi->flags & ZIO_DIR) == ZIO_DIR_INPUT && ti->t_op->pull_block) {
/* chek if trigger is disabled */
if (unlikely((ti->flags & ZIO_STATUS) == ZIO_DISABLED))
return NULL;
ti->t_op->pull_block(ti, bi->chan);
}
pr_debug("%s:%d (%p, %p)\n", __func__, __LINE__, bi, NULL);
return NULL;
}
/* Create is called by zio for each channel electing to use this buffer type */
static struct zio_bi *zbk_create(struct zio_buffer_type *zbuf,
struct zio_channel *chan)
{
struct zbk_instance *zbki;
pr_debug("%s:%d\n", __func__, __LINE__);
zbki = kzalloc(sizeof(*zbki), GFP_ATOMIC);
if (!zbki)
return ERR_PTR(-ENOMEM);
INIT_LIST_HEAD(&zbki->list);
/* all the fields of zio_bi are initialied by the caller */
return &zbki->bi;
}
/* destroy is called by zio on channel removal or if it changes buffer type */
static void zbk_destroy(struct zio_bi *bi)
{
struct zbk_instance *zbki = to_zbki(bi);
struct zbk_item *item;
struct list_head *pos, *tmp;
pr_debug("%s:%d\n", __func__, __LINE__);
/* no need to lock here, zio ensures we are not active */
list_for_each_safe(pos, tmp, &zbki->list) {
item = list_entry(pos, struct zbk_item, list);
zbk_free_block(&zbki->bi, &item->block);
}
kfree(zbki);
}
static const struct zio_buffer_operations zbk_buffer_ops = {
.alloc_block = zbk_alloc_block,
.free_block = zbk_free_block,
.store_block = zbk_store_block,
.retr_block = zbk_retr_block,
.create = zbk_create,
.destroy = zbk_destroy,
};
static struct zio_buffer_type zbk_buffer = {
.owner = THIS_MODULE,
.zattr_set = {
.std_zattr = zbk_std_zattr,
},
.s_op = &zbk_sysfs_ops,
.b_op = &zbk_buffer_ops,
.f_op = &zio_generic_file_operations,
};
static int __init zbk_init(void)
{
int ret;
/* Can't use "zbk_item" as name and KMEM_CACHE_NAMED is not there */
zbk_slab = kmem_cache_create("zio-kmalloc", sizeof(struct zbk_item),
__alignof__(struct zbk_item), 0, NULL);
if (!zbk_slab)
return -ENOMEM;
ret = zio_register_buf(&zbk_buffer, "kmalloc");
if (ret < 0)
kmem_cache_destroy(zbk_slab);
return ret;
}
static void __exit zbk_exit(void)
{
zio_unregister_buf(&zbk_buffer);
kmem_cache_destroy(zbk_slab);
}
/* This is the default buffer, and is part of zio-core: no module init/exit */
int __init __attribute__((alias("zbk_init"))) zio_default_buffer_init(void);
void __exit __attribute__((alias("zbk_exit"))) zio_default_buffer_exit(void);
/*
* Copyright 2011 CERN
* Author: Federico Vaga <federico.vaga@gmail.com>
*
* GNU GPLv2 or later
*/
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/version.h>
#include <linux/init.h>
#include <linux/types.h>
#include <linux/zio.h>
#include <linux/zio-sysfs.h>
#include "zio-internal.h"
static struct zio_status *zstat = &zio_global_status; /* Always use ptr */
/*
* zio_show_version
* It shows the current version of ZIO
*/
static ssize_t zio_show_version(struct bus_type *bus, char *buf)
{
return sprintf(buf, "%d.%d\n", ZIO_MAJOR_VERSION, ZIO_MINOR_VERSION);
}
/*
* zio_show_buffers
* It shows all buffers available
*/
static ssize_t zio_show_buffers(struct bus_type *bus, char *buf)
{
struct zio_object_list_item *cur;
ssize_t len = 0;
spin_lock(&zstat->lock);
list_for_each_entry(cur, &zstat->all_buffer_types.list, list)
len = sprintf(buf, "%s%s\n", buf, cur->name);
spin_unlock(&zstat->lock);
return len;
}
/*
* zio_show_triggers
* It shows all triggers available
*/
static ssize_t zio_show_triggers(struct bus_type *bus, char *buf)
{
struct zio_object_list_item *cur;
ssize_t len = 0;
spin_lock(&zstat->lock);
list_for_each_entry(cur, &zstat->all_trigger_types.list, list)
len = sprintf(buf, "%s%s\n", buf, cur->name);
spin_unlock(&zstat->lock);
return len;
}
enum zio_bus_attributs_enumeration {
ZIO_DAN_BUS_VERSION,
ZIO_DAN_BUS_TRIGGERS,
ZIO_DAN_BUS_BUFFERS,
};
static struct bus_attribute def_bus_attrs[] = {
[ZIO_DAN_BUS_VERSION] = __ATTR(version, ZIO_RO_PERM,
zio_show_version, NULL),
[ZIO_DAN_BUS_TRIGGERS] = __ATTR(available_buffers, ZIO_RO_PERM,
zio_show_buffers, NULL),
[ZIO_DAN_BUS_BUFFERS] = __ATTR(available_triggers, ZIO_RO_PERM,
zio_show_triggers, NULL),
__ATTR_NULL,
};
#if LINUX_VERSION_CODE > KERNEL_VERSION(3,11,0)
static struct attribute *zio_bus_def_attrs[] = {
&def_bus_attrs[ZIO_DAN_BUS_VERSION].attr,
&def_bus_attrs[ZIO_DAN_BUS_TRIGGERS].attr,
&def_bus_attrs[ZIO_DAN_BUS_BUFFERS].attr,
};
ATTRIBUTE_GROUPS(zio_bus_def);
#endif
/*
* zio_match_id
* @id list of zio_device_if supported by a driver
* @head the ZIO header to compare with the list
*
* It matches a list of zio_device_if with a name. It returns the matched
* zio_device_id otherwise a NULL pointer.
*/
static const struct zio_device_id *zio_match_id(const struct zio_device_id *id,
const struct zio_obj_head *head)
{
while (id->name[0]) {
dev_dbg(&head->dev, "%s comparing %s == %s\n", __func__,
id->name, head->name);
if (!strcmp(head->name, id->name))
return id;
++id;
}
dev_dbg(&head->dev, "%s fail\n", __func__);
return NULL;
}
/*
* zio_get_device_id
* @zdev ZIO device
*
* It returns a zio_device_id which match with zdev
*/
const struct zio_device_id *zio_get_device_id(const struct zio_device *zdev)
{
const struct zio_driver *zdrv = to_zio_drv(zdev->head.dev.driver);
return zio_match_id(zdrv->id_table, &zdev->head);
}
EXPORT_SYMBOL(zio_get_device_id);
/*
* zio_match_device
* @drv driver to match
* @dev device to match
*
* This function is the core of the ZIO bus system. It matches drivers with
* devices. To allow the definition of custom sysfs attributes of different
* devices, ZIO use a mechanism of double registration. At driver load time,
* the driver registers a fake zio_device, then (if it match with a driver)
* this match function will register the real ZIO device which always match.
*/
static int zio_match_device(struct device *dev, struct device_driver *drv)
{
const struct zio_driver *zdrv = to_zio_drv(drv);
const struct zio_device_id *id;
struct zio_device *child;
int err = 0;
if (!zdrv->id_table)
return 0;
id = zio_match_id(zdrv->id_table, to_zio_head(dev));
if (!id)
return 0;
/* device and driver match */
if (dev->type == &zdevhw_device_type) {
/* Register the real zio device */
err = __zdev_register(to_zio_dev(dev), id);
if (err) {
pr_err("ZIO: Cannot register real zio_device (%d)\n",
err);
return 0;
}
child = zio_device_find_child(to_zio_dev(dev));
/*
* Probe the device because the real device always match. We
* cannot do probe when the zio_device is registered because
* we need also its sub-devices for a safe probe. More over it
* allow us to easily remove the device on probe failure.
*/
if (zdrv->probe)
err = zdrv->probe(child);
if (err) {
dev_err(&child->head.dev, "probe() fail with error %d",
err);
__zdev_unregister(child);
} else {
dev_info(&child->head.dev, "device loaded\n");
}
/* We done everything with child */
put_device(&child->head.dev);
return 0;
} else if (dev->type == &zdev_device_type) {
return 1; /* real device always match*/
}
return 0;
}
struct bus_type zio_bus_type = {
.name = "zio",
#if LINUX_VERSION_CODE > KERNEL_VERSION(3,11,0)
.bus_groups = zio_bus_def_groups,
#else
.bus_attrs = def_bus_attrs,
#endif
.match = zio_match_device,
};
/*
* zio_drv_remove
* @dev device to remove
*
* It invokes the ZIO driver remove function
*/
static int zio_drv_remove(struct device *dev)
{
struct zio_driver *zdrv = to_zio_drv(dev->driver);
struct zio_device *zdev = to_zio_dev(dev);
if (zdrv->remove)
return zdrv->remove(zdev);
return 0;
}
/*
* _zdev_template_check_and_init
*
* zio_register_driver() invokes this function to perform a preliminary test
* and initialization on templates registered within the driver.
*
* NOTE: this not perform a complete test and initialization, during
* driver->probe ZIO can rise new error and performs other initialization stuff
*
* FIXME try to move all the validations here
*/
static int _zdev_template_check_and_init(struct zio_device *zdev,
const char *name)
{
struct zio_cset *cset;
int i;
if (!zdev) {
pr_err("%s:%d missing zio_device template\n",
__func__, __LINE__);
return -EINVAL;
}
if (!zdev->owner) {
/* FIXME I can use driver->owner */
dev_err(&zdev->head.dev, "device template %s has no owner\n",
name);
return -EINVAL;
}
if (!zdev->cset || !zdev->n_cset) {
dev_err(&zdev->head.dev, "no cset in device template %s",
name);
return -EINVAL;
}
for (i = 0; i < zdev->n_cset; ++i) {
cset = &zdev->cset[i];
if (!cset->n_chan) {
dev_err(&zdev->head.dev,
"no channels in %s cset%i\n",
name, cset->index);
return -EINVAL;
}
/*
* Only time-type can have a zero-sized sample. This
* protects against users who forgot to fill fields.
*/
if (!cset->ssize &&
(cset->flags & ZIO_CSET_TYPE) != ZIO_CSET_TYPE_TIME) {
dev_err(&zdev->head.dev,
"ssize can not be 0 in %s cset%i\n",
name, cset->index);
return -EINVAL;
}
}
return 0;
}
int zio_register_driver(struct zio_driver *zdrv)
{
int i, err;
if (!zdrv->id_table) {
pr_err("ZIO: id_table is mandatory for a zio driver\n");
return -EINVAL;
}
for (i = 0; zdrv->id_table[i].name[0]; ++i) {
err = _zdev_template_check_and_init(zdrv->id_table[i].template,
zdrv->id_table[i].name);
if (err)
return err;
}
zdrv->driver.bus = &zio_bus_type;
zdrv->driver.remove = zio_drv_remove;
return driver_register(&zdrv->driver);
}
EXPORT_SYMBOL(zio_register_driver);
void zio_unregister_driver(struct zio_driver *zdrv)
{
driver_unregister(&zdrv->driver);
}
EXPORT_SYMBOL(zio_unregister_driver);
This diff is collapsed.
/*
* Copyright 2011 CERN
* Author: Federico Vaga <federico.vaga@gmail.com>
* Author: Alessandro Rubini <rubini@gnudd.com>
*
* GNU GPLv2 or later
*/
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/types.h>
#include <linux/slab.h>
#include <linux/string.h>
#include <linux/zio.h>
#include <linux/zio-buffer.h>
#include "zio-internal.h"
struct zio_status zio_global_status;
static struct zio_status *zstat = &zio_global_status; /* Always use ptr */
/*
* We use a local slab for control structures.
*/
static struct kmem_cache *zio_ctrl_slab;
struct zio_control *zio_alloc_control(gfp_t gfp)
{
struct zio_control *ctrl;
ctrl = kmem_cache_zalloc(zio_ctrl_slab, 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;
}
EXPORT_SYMBOL(zio_alloc_control);
/* At control release time, we can copy it to sniffers, if configured so */
void __weak zio_sniffdev_add(struct zio_control *ctrl)
{
}
void zio_free_control(struct zio_control *ctrl)
{
zio_sniffdev_add(ctrl);
kmem_cache_free(zio_ctrl_slab, ctrl);
}
EXPORT_SYMBOL(zio_free_control);
int __init zio_slab_init(void)
{
zio_ctrl_slab = KMEM_CACHE(zio_control, 0);
if (!zio_ctrl_slab)
return -ENOMEM;
return 0;
}
void zio_slab_exit(void) /* not __exit: called from zio_init on failures */
{
if (zio_ctrl_slab)
kmem_cache_destroy(zio_ctrl_slab);
return;
}
struct zio_device *zio_find_device(char *name, uint32_t dev_id)
{
struct zio_object_list_item *cur;
struct zio_device *zdev;
if (!name)
return NULL;
list_for_each_entry(cur, &zstat->all_devices.list, list) {
zdev = to_zio_dev(&cur->obj_head->dev);
if (strcmp(cur->name, name) == 0 && zdev->dev_id == dev_id)
return zdev; /* found */
}
return NULL;
}
EXPORT_SYMBOL(zio_find_device);
/* if CONFIG_ZIO_SNIFF_DEV code in sniff-dev.c overrides the following two */
int __weak zio_sniffdev_init(void)
{
return 0;
}
void __weak zio_sniffdev_exit(void)
{
return;
}
/* Oerall init and exit */
static int __init zio_init(void)
{
int err;
/* The standard attributes must be less than ZIO_MAX_STD_ATTR */
BUILD_BUG_ON(_ZIO_DEV_ATTR_STD_NUM > ZIO_MAX_STD_ATTR);
BUILD_BUG_ON(_ZIO_TRG_ATTR_STD_NUM > ZIO_MAX_STD_ATTR);
BUILD_BUG_ON(_ZIO_BUF_ATTR_STD_NUM > ZIO_MAX_STD_ATTR);
/* The attribute 'version' must be the last attributes */
BUILD_BUG_ON(_ZIO_DEV_ATTR_STD_NUM != ZIO_ATTR_VERSION + 1);
BUILD_BUG_ON(_ZIO_TRG_ATTR_STD_NUM != ZIO_ATTR_VERSION + 1);
BUILD_BUG_ON(_ZIO_BUF_ATTR_STD_NUM != ZIO_ATTR_VERSION + 1);
/* Some compile-time checks, so developers are free to hack around */
BUILD_BUG_ON(_ZIO_DEV_ATTR_STD_NUM != ARRAY_SIZE(zio_zdev_attr_names));
BUILD_BUG_ON(_ZIO_BUF_ATTR_STD_NUM != ARRAY_SIZE(zio_zbuf_attr_names));
BUILD_BUG_ON(_ZIO_TRG_ATTR_STD_NUM != ARRAY_SIZE(zio_trig_attr_names));
BUILD_BUG_ON(ZIO_NR_MINORS > MINORMASK + 1);
err = zio_slab_init();
if (err)
return err;
/* Register ZIO bus */
err = bus_register(&zio_bus_type);
if (err)
goto out;
/* Initialize char device */
err = zio_register_cdev();
if (err)
goto out_cdev;
spin_lock_init(&zstat->lock);
INIT_LIST_HEAD(&zstat->all_devices.list);
zstat->all_devices.zobj_type = ZIO_DEV;
INIT_LIST_HEAD(&zstat->all_trigger_types.list);
zstat->all_trigger_types.zobj_type = ZIO_TRG;
INIT_LIST_HEAD(&zstat->all_buffer_types.list);
zstat->all_buffer_types.zobj_type = ZIO_BUF;
err = zio_default_buffer_init();
if (err)
pr_warning("%s: cannot register default buffer\n", __func__);
err = zio_default_trigger_init();
if (err)
pr_warning("%s: cannot register default trigger\n", __func__);
if (zio_sniffdev_init())
pr_warning("%s: cannot initialize /dev/zio-sniff.ctrl\n",
__func__);
pr_info("zio-core had been loaded\n");
return 0;
out_cdev:
bus_unregister(&zio_bus_type);
out:
zio_slab_exit();
return err;
}
static void __exit zio_exit(void)
{
zio_sniffdev_exit();
zio_default_trigger_exit();
zio_default_buffer_exit();
/* Remove char device */
zio_unregister_cdev();
/* Remove ZIO bus */
bus_unregister(&zio_bus_type);
zio_slab_exit();
pr_info("zio-core had been unloaded\n");
return;
}
subsys_initcall(zio_init);
module_exit(zio_exit);
MODULE_VERSION(GIT_VERSION); /* Defined in local Makefile */
MODULE_AUTHOR("Federico Vaga and Alessandro Rubini");
/* Federico wrote the core, Alessandro wrote default trigger and buffer */
MODULE_DESCRIPTION("ZIO - ZIO Input Output");
MODULE_LICENSE("GPL");
CERN_SUPER_MODULE;
/*
* Copyright CERN 2014
* Author: Federico Vaga <federico.vaga@gmail.com>
*
* handle DMA mapping
*/
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/init.h>
#include <linux/types.h>
#include <linux/list.h>
#include <linux/mm.h>
#include <linux/dma-mapping.h>
#include <linux/zio-dma.h>
#include "zio-internal.h"
static int zio_calculate_nents(struct zio_blocks_sg *sg_blocks,
unsigned int n_blocks)
{
int i, bytesleft;
void *bufp;
int mapbytes;
int nents = 0;
for (i = 0; i < n_blocks; ++i) {
bytesleft = sg_blocks[i].block->datalen;
bufp = sg_blocks[i].block->data;
sg_blocks[i].first_nent = nents;
while (bytesleft) {
nents++;
if (bytesleft < (PAGE_SIZE - offset_in_page(bufp)))
mapbytes = bytesleft;
else
mapbytes = PAGE_SIZE - offset_in_page(bufp);
bufp += mapbytes;
bytesleft -= mapbytes;
}
}
return nents;
}
static void zio_dma_setup_scatter(struct zio_dma_sgt *zdma)
{
struct scatterlist *sg;
int bytesleft = 0;
void *bufp = NULL;
int mapbytes;
int i, i_blk;
i_blk = 0;
for_each_sg(zdma->sgt.sgl, sg, zdma->sgt.nents, i) {
if (i_blk < zdma->n_blocks && i == zdma->sg_blocks[i_blk].first_nent) {
WARN(bytesleft, "unmapped byte in block %i\n",
i_blk - 1);
/*
* Configure the DMA for a new block, reset index and
* data pointer
*/
bytesleft = zdma->sg_blocks[i_blk].block->datalen;
bufp = zdma->sg_blocks[i_blk].block->data;
i_blk++; /* index the next block */
if (unlikely(i_blk > zdma->n_blocks))
BUG();
}
/*
* If there are less bytes left than what fits
* in the current page (plus page alignment offset)
* we just feed in this, else we stuff in as much
* as we can.
*/
if (bytesleft < (PAGE_SIZE - offset_in_page(bufp)))
mapbytes = bytesleft;
else
mapbytes = PAGE_SIZE - offset_in_page(bufp);
/* Map the page */
if (is_vmalloc_addr(bufp))
sg_set_page(sg, vmalloc_to_page(bufp), mapbytes,
offset_in_page(bufp));
else
sg_set_buf(sg, bufp, mapbytes);
/* Configure next values */
bufp += mapbytes;
bytesleft -= mapbytes;
pr_debug("sg item (%p(+0x%lx), len:%d, left:%d)\n",
virt_to_page(bufp), offset_in_page(bufp),
mapbytes, bytesleft);
}
}
/*
* zio_alloc_scatterlist
* @chan: zio channel associated to this scatterlist
* @hwdev: low level device responsible of the DMA
* @blocks: array of zio_block to transfer
* @n_blocks: number of blocks to transfer
* @gfp: gfp flags for memory allocation
*
* The function allocates and initializes a scatterlist ready for DMA
* transfer
*/
struct zio_dma_sgt *zio_dma_alloc_sg(struct zio_channel *chan,
struct device *hwdev,
struct zio_block **blocks, /* FIXME to array */
unsigned int n_blocks, gfp_t gfp)
{
struct zio_dma_sgt *zdma;
unsigned int i, pages;
int err;
if (unlikely(!chan || !hwdev || !blocks || !n_blocks))
return ERR_PTR(-EINVAL);
/*
* Allocate a new zio_dma_sgt structure that will contains all necessary
* information for DMA
*/
zdma = kzalloc(sizeof(struct zio_dma_sgt), gfp);
if (!zdma)
return ERR_PTR(-ENOMEM);
zdma->chan = chan;
/* Allocate a new list of blocks with sg information */
zdma->sg_blocks = kzalloc(sizeof(struct zio_blocks_sg) * n_blocks, gfp);
if (!zdma->sg_blocks) {
err = -ENOMEM;
goto out;
}
/* fill the zio_dma_sgt structure */
zdma->hwdev = hwdev;
zdma->n_blocks = n_blocks;
for (i = 0; i < n_blocks; ++i)
zdma->sg_blocks[i].block = blocks[i];
/* calculate the number of necessary pages to transfer */
pages = zio_calculate_nents(zdma->sg_blocks, zdma->n_blocks);
if (!pages) {
err = -EINVAL;
goto out_calc_nents;
}
/* Create sglists for the transfers */
err = sg_alloc_table(&zdma->sgt, pages, gfp);
if (err)
goto out_alloc_sg;
/* Setup the scatter list for the provided block */
zio_dma_setup_scatter(zdma);
return zdma;
out_alloc_sg:
out_calc_nents:
kfree(zdma->sg_blocks);
out:
kfree(zdma);
return ERR_PTR(err);
}
EXPORT_SYMBOL(zio_dma_alloc_sg);
/*
* zio_free_scatterlist
* @zdma: zio DMA transfer descriptor
*
* It releases resources
*/
void zio_dma_free_sg(struct zio_dma_sgt *zdma)
{
kfree(zdma->sg_blocks);
kfree(zdma);
}
EXPORT_SYMBOL(zio_dma_free_sg);
/*
* zio_dma_map_sg
* @zdma: zio DMA descriptor from zio_dma_alloc_sg()
* @page_desc_size: the size (in byte) of the dma transfer descriptor of the
* specific hw
* @fill_desc: callback for the driver in order to fill each transfer
* descriptor
*
*It maps a sg table
*
* fill_desc
* @zdma: zio DMA descriptor from zio_dma_alloc_sg()
* @page_idx: index of the current page transfer
* @block_idx: index of the current zio_block
* @page_desc: current descriptor to fill
* @dev_mem_offset: offset within the device memory
* @sg: current sg descriptor
*/
int zio_dma_map_sg(struct zio_dma_sgt *zdma, size_t page_desc_size,
int (*fill_desc)(struct zio_dma_sg *zsg))
{
unsigned int i, err = 0, sglen, i_blk;
uint32_t dev_mem_off = 0;
struct scatterlist *sg;
struct zio_dma_sg zsg;
void *item_ptr;
size_t size;
if (unlikely(!zdma || !fill_desc))
return -EINVAL;
/* Limited to 32-bit (kernel limit) */
zdma->page_desc_size = page_desc_size;
size = zdma->page_desc_size * zdma->sgt.nents;
zdma->page_desc_pool = kzalloc(size, GFP_ATOMIC);
if (!zdma->page_desc_pool) {
dev_err(zdma->hwdev, "cannot allocate coherent dma memory\n");
return -ENOMEM;
}
zdma->dma_page_desc_pool = dma_map_single(zdma->hwdev,
zdma->page_desc_pool, size,
DMA_TO_DEVICE);
if (!zdma->dma_page_desc_pool) {
err = -ENOMEM;
goto out_map_single;
}
/* Map DMA buffers */
sglen = dma_map_sg(zdma->hwdev, zdma->sgt.sgl, zdma->sgt.nents,
DMA_FROM_DEVICE);
if (!sglen) {
dev_err(zdma->hwdev, "cannot map dma SG memory\n");
goto out_map_sg;
}
i_blk = 0;
for_each_sg(zdma->sgt.sgl, sg, zdma->sgt.nents, i) {
dev_dbg(zdma->hwdev, "%d 0x%x\n", i, dev_mem_off);
if (i_blk < zdma->n_blocks && i == zdma->sg_blocks[i_blk].first_nent) {
dev_dbg(zdma->hwdev, "%d is the first nent of block %d\n", i, i_blk);
dev_mem_off = zdma->sg_blocks[i_blk].dev_mem_off;
i_blk++; /* index the next block */
if (unlikely(i_blk > zdma->n_blocks)) {
dev_err(zdma->hwdev, "DMA map out of block\n");
BUG();
}
}
item_ptr = zdma->page_desc_pool + (zdma->page_desc_size * i);
/* Configure hardware pages */
zsg.zsgt = zdma;
zsg.sg = sg;
zsg.dev_mem_off = dev_mem_off;
zsg.page_desc = item_ptr;
zsg.block_idx = i_blk;
zsg.page_idx= i;
err = fill_desc(&zsg);
if (err) {
dev_err(zdma->hwdev, "Cannot fill descriptor %d\n", i);
goto out_fill_desc;
}
dev_mem_off += sg_dma_len(sg);
}
return 0;
out_fill_desc:
dma_unmap_sg(zdma->hwdev, zdma->sgt.sgl, zdma->sgt.nents,
DMA_FROM_DEVICE);
out_map_sg:
dma_unmap_single(zdma->hwdev, zdma->dma_page_desc_pool, size,
DMA_TO_DEVICE);
out_map_single:
kfree(zdma->page_desc_pool);
return err;
}
EXPORT_SYMBOL(zio_dma_map_sg);
/*
* zio_dma_unmap_sg
* @zdma: zio DMA descriptor from zio_dma_alloc_sg()
*
* It unmaps a sg table
*/
void zio_dma_unmap_sg(struct zio_dma_sgt *zdma)
{
size_t size;
size = zdma->page_desc_size * zdma->sgt.nents;
dma_unmap_sg(zdma->hwdev, zdma->sgt.sgl, zdma->sgt.nents,
DMA_FROM_DEVICE);
dma_unmap_single(zdma->hwdev, zdma->dma_page_desc_pool, size,
DMA_TO_DEVICE);
kfree(zdma->page_desc_pool);
zdma->dma_page_desc_pool = 0;
zdma->page_desc_pool = NULL;
}
EXPORT_SYMBOL(zio_dma_unmap_sg);
*~
*.aux
*.cp
*.cps
*.fn
*.html
*.info
*.ky
*.log
/*.pdf
*.pg
*.texi
*.toc
*.tp
/*.txt
*.vr
#
# Makefile for the documentation directory
#
# Copyright 1994,2000,2010,2011 Alessandro Rubini <rubini@linux.it>
#
#################
# There is not basenames here, all *.in are considered input
INPUT = $(wildcard *.in)
TEXI = $(INPUT:.in=.texi)
INFO = $(INPUT:.in=.info)
HTML = $(INPUT:.in=.html)
TXT = $(INPUT:.in=.txt)
PDF = $(INPUT:.in=.pdf)
ALL = $(INFO) $(HTML) $(TXT) $(PDF)
MAKEINFO ?= makeinfo
%.texi: %.in
@rm -f $@
sed -f ./infofilter $< > $@
emacs -batch --no-site-file -l fixinfo $@
chmod -w $@
%.pdf: %.texi
texi2pdf --batch $<
%.info: %.texi
$(MAKEINFO) $< -o $@
%.html: %.texi
$(MAKEINFO) --html --no-split -o $@ $<
%.txt: %.texi
$(MAKEINFO) --no-headers $< > $@
##############################################
.PHONY: all images check terse clean install
.INTERMEDIATE: $(TEXI)
all: images $(ALL)
$(MAKE) terse
images::
if [ -d images ]; then $(MAKE) -C images || exit 1; fi
check: _err.ps
gs -sDEVICE=linux -r320x200x16 $<
terse:
for n in cp fn ky pg toc tp vr aux log; do rm -f *.$$n; done
rm -f *~
clean: terse
rm -f $(ALL) $(TEXI)
install:
;; use:
;; emacs -batch -l ./fixinfo.el <file>
;; or, better:
;; emacs -batch --no-site-file -l ./fixinfo.el <file>
(defun fixinfo (file)
(find-file-other-window file)
(message (concat "Maxing texinfo tree in " file))
(texinfo-all-menus-update)
(texinfo-every-node-update)
(save-buffer)
(kill-buffer (current-buffer))
)
;; loop over command line arguments
(mapcar 'fixinfo command-line-args-left)
(kill-emacs)
# pdftex picks png before pdf, and the result is crap.
# so let's use gif for the html version, instead of png (/me disgusted)
IN := $(wildcard *.ps *.eps)
PDF := $(patsubst %.ps,%.pdf,$(IN))
PDF := $(patsubst %.eps,%.pdf,$(PDF))
GIF := $(patsubst %.pdf,%.gif,$(PDF))
all: $(PDF) $(GIF)
%.pdf: %.ps
epstopdf $^
%.pdf: %.eps
epstopdf $^
%.gif: %.pdf
convert $^ $@
%!PS-Adobe-2.0 EPSF-1.2
%%Creator: Alessandro Rubini
%%Title: zio block dissected
%%BoundingBox: 0 0 270 340
%%EndComments
/S {dup ==} def
/S2 {2 copy == ==} def
/S3 {3 copy == == ==} def
/S4 {4 copy == == == ==} def
/grid { % xmin xmax ymin ymax step
gsave
/step exch def
/maxy exch def
/miny exch def
/maxx exch def
/minx exch def
.8 .8 .8 setrgbcolor
.2 setlinewidth
% vertical lines
minx step maxx {
dup
miny moveto maxy lineto stroke
} for
% horizontal lines
miny step maxy {
dup
minx exch moveto maxx exch lineto stroke
} for
} def
/centerstring { % fontname width string -- fontsize
gsave
3 2 roll findfont setfont % width string
dup 3 1 roll % string width string
stringwidth pop div dup 3 1 roll % scale string scale
dup neg 0 exch rmoveto % scale string scale
currentfont exch scalefont setfont % scale string
show
grestore
} def
/centeratsize { % x y string --
gsave
3 1 roll moveto
dup stringwidth pop 2 div neg 0 rmoveto show
grestore
} def
/wohs { % x y string --
gsave
dup stringwidth pop neg 0 rmoveto show
grestore
} def
/crect { % x y wid hei incolor outcolor --
/xxoutco exch def
/xxinco exch def
4 copy
xxinco rgb rectfill
xxoutco rgb
/hei exch def
/wid exch def
moveto
wid 0 rlineto 0 hei rlineto
wid neg 0 rlineto closepath
stroke
} def
/zrect { % x y wid hei incolor outcolor letter --
/xxname exch def
/xxoutco exch def
/xxinco exch def
4 copy
xxinco rgb rectfill
xxoutco rgb
/hei exch def
/wid exch def
gsave
translate
0 0 moveto
wid 0 rlineto 0 hei rlineto
wid neg 0 rlineto closepath
stroke
/Helvetica-Bold findfont 8 scalefont setfont
wid 10 sub 3 moveto xxname show
grestore
} def
/zzrect { % x y wid hei name
aload pop zrect
} def
/arrow { % x y len angle --
/xxangle exch def
/xxlen exch def
gsave
translate
xxangle rotate
0 0 moveto
xxlen 0 lineto stroke
xxlen 0 moveto
-10 5 rlineto
0 -10 rlineto
closepath fill
grestore
} def
/carrow { % x y len angle color --
rgb
arrow
} def
% inner: S=255, V=193
% outer: S=255, V=116
/Linner [191 193 0] def
/Louter [115 116 0] def
% rifo V=225
/Linner [225 225 0] def
/Finner [105 195 0] def
/Fouter [63 116 0] def
% V=225
/Sinner [225 166 137] def
/Souter [116 85 71] def
% rifo: piu` rosa
/Sinner [255 180 205] def
/Souter [116 82 100] def
/Binner [166 124 83] def
/Bouter [97 72 48] def
/Tinner [226 73 81] def
/Touter [116 40 40] def
/Pinner [225 78 255] def
/Pouter [116 50 151] def
/rgb {
aload pop
255 div 3 1 roll
255 div 3 1 roll
255 div 3 1 roll
setrgbcolor
} def
/Cinner [0 220 224] def
/Couter [0 115 116] def
/Dinner [0 128 128] def
/Douter [0 64 64] def
/BLinner [94 94 225] def
/BLouter [0 0 116] def
% fix B (above is too blue
/BLinner [114 172 216] def
/BLouter [53 99 135] def
% again blue: much less saturated
/BLinner [177 199 216] def
/BLouter [53 99 135] def
% try again D
/Dinner [0 147 232] def
/Douter [0 64 64] def
/Dinner [30 115 144] def
/Dinner [62 146 175] def
/Douter [0 64 64] def
% fix C
/Couter Douter def
/Cinner [142 220 224] def
/L [ Linner Louter (L) ] def
/F [ Finner Fouter (F) ] def
/S [ Sinner Souter (S) ] def
/B [ Binner Bouter (B) ] def
/T [ Tinner Touter (T) ] def
/P [ Pinner Pouter (P) ] def
/C [ Cinner Couter (C) ] def
/D [ Dinner Douter (D) ] def
/BL [ BLinner BLouter (bl) ] def
/Ninner [ 220 220 220 ] def
/Nouter [ 128 128 128] def
/N [ Ninner Nouter (N) ] def
%0 300 0 400 10 grid
1.5 setlinewidth
0 0 0 setrgbcolor
%60 200 100 0 arrow
%60 200 100 30 arrow
180 20 60 200 D zzrect
180 240 60 60 C zzrect
%40 280 40 40 BL zzrect
40 280 40 40 BLinner BLouter (B) zrect
84 310 92 -12 BLouter carrow
84 290 120 -40 BLouter carrow
0 0 0 setrgbcolor
/Helvetica-Bold findfont 16 scalefont setfont
%80 85 moveto gsave (Block) show grestore 70 0 rmoveto (Blue) show
%80 55 moveto gsave (Control) show grestore 70 0 rmoveto (Cyan) show
%80 25 moveto gsave (Data) show grestore 70 0 rmoveto (Darker) show
showpage
%!PS-Adobe-2.0 EPSF-1.2
%%Creator: Alessandro Rubini
%%Title: zio coaleshing buffer
%%BoundingBox: 0 0 600 190
%%EndComments
/S {dup ==} def
/S2 {2 copy == ==} def
/S3 {3 copy == == ==} def
/S4 {4 copy == == == ==} def
/grid { % xmin xmax ymin ymax step
gsave
/step exch def
/maxy exch def
/miny exch def
/maxx exch def
/minx exch def
.8 .8 .8 setrgbcolor
.2 setlinewidth
% vertical lines
minx step maxx {
dup
miny moveto maxy lineto stroke
} for
% horizontal lines
miny step maxy {
dup
minx exch moveto maxx exch lineto stroke
} for
} def
/centerstring { % fontname width string -- fontsize
gsave
3 2 roll findfont setfont % width string
dup 3 1 roll % string width string
stringwidth pop div dup 3 1 roll % scale string scale
dup neg 0 exch rmoveto % scale string scale
currentfont exch scalefont setfont % scale string
show
grestore
} def
/centeratsize { % x y string --
gsave
3 1 roll moveto
dup stringwidth pop 2 div neg 0 rmoveto show
grestore
} def
/wohs { % x y string --
gsave
dup stringwidth pop neg 0 rmoveto show
grestore
} def
/crect { % x y wid hei incolor outcolor --
/xxoutco exch def
/xxinco exch def
4 copy
xxinco rgb rectfill
xxoutco rgb
/hei exch def
/wid exch def
moveto
wid 0 rlineto 0 hei rlineto
wid neg 0 rlineto closepath
stroke
} def
/zrect { % x y wid hei incolor outcolor letter --
/xxname exch def
/xxoutco exch def
/xxinco exch def
4 copy
xxinco rgb rectfill
xxoutco rgb
/hei exch def
/wid exch def
gsave
translate
0 0 moveto
wid 0 rlineto 0 hei rlineto
wid neg 0 rlineto closepath
stroke
/Helvetica-Bold findfont 8 scalefont setfont
wid 10 sub 3 moveto xxname show
grestore
} def
/zzrect { % x y wid hei name
aload pop zrect
} def
/arrow { % x y len angle --
/xxangle exch def
/xxlen exch def
gsave
translate
xxangle rotate
0 0 moveto
xxlen 0 lineto stroke
xxlen 0 moveto
-10 5 rlineto
0 -10 rlineto
closepath fill
grestore
} def
/carrow { % x y len angle color --
rgb
arrow
} def
% inner: S=255, V=193
% outer: S=255, V=116
/Linner [191 193 0] def
/Louter [115 116 0] def
% rifo V=225
/Linner [225 225 0] def
/Finner [105 195 0] def
/Fouter [63 116 0] def
% V=225
/Sinner [225 166 137] def
/Souter [116 85 71] def
% rifo: piu` rosa
/Sinner [255 180 205] def
/Souter [116 82 100] def
/Binner [166 124 83] def
/Bouter [97 72 48] def
/Tinner [226 73 81] def
/Touter [116 40 40] def
/Pinner [225 78 255] def
/Pouter [116 50 151] def
/rgb {
aload pop
255 div 3 1 roll
255 div 3 1 roll
255 div 3 1 roll
setrgbcolor
} def
/Cinner [0 220 224] def
/Couter [0 115 116] def
/Dinner [0 128 128] def
/Douter [0 64 64] def
/BLinner [94 94 225] def
/BLouter [0 0 116] def
% fix B (above is too blue
/BLinner [114 172 216] def
/BLouter [53 99 135] def
% again blue: much less saturated
/BLinner [177 199 216] def
/BLouter [53 99 135] def
% try again D
/Dinner [0 147 232] def
/Douter [0 64 64] def
/Dinner [30 115 144] def
/Dinner [62 146 175] def
/Douter [0 64 64] def
% fix C
/Couter Douter def
/Cinner [142 220 224] def
/L [ Linner Louter (L) ] def
/F [ Finner Fouter (F) ] def
/S [ Sinner Souter (S) ] def
/B [ Binner Bouter (B) ] def
/T [ Tinner Touter (T) ] def
/P [ Pinner Pouter (P) ] def
/C [ Cinner Couter (C) ] def
/D [ Dinner Douter (D) ] def
/BL [ BLinner BLouter (bl) ] def
/Ninner [ 220 220 220 ] def
/Nouter [ 128 128 128] def
/N [ Ninner Nouter (N) ] def
%0 600 0 190 10 grid
1.5 setlinewidth
%120 70 20 20 C zzrect
%140 40 50 20 D zzrect
0 0 0 setrgbcolor
/Helvetica-Bold findfont 16 scalefont setfont
20 165 moveto (ch-0-ctrl) show
20 135 moveto (ch-0-data) show
20 85 moveto (ch-1-ctrl) show
20 55 moveto (ch-1-data) show
/blocks {
110 80 20 20 C zzrect
110 50 480 {
%dup 80 20 20 C zzrect
20 add 50 50 20 D zzrect
} for
} def
blocks gsave 0 80 translate blocks grestore
% overwrite ch-1-data with one data
130 50 400 20 D zzrect
false {
570 30 470 180 arrow
/Helvetica-Bold findfont 12 scalefont setfont
340 15 (Data is flowing in this direction. Within a channel all blobs are strictly ordered) centeratsize
} if
showpage
%!PS-Adobe-2.0 EPSF-1.2
%%Creator: Alessandro Rubini
%%Title: zio buffer for mmap
%%BoundingBox: 0 0 600 190
%%EndComments
/S {dup ==} def
/S2 {2 copy == ==} def
/S3 {3 copy == == ==} def
/S4 {4 copy == == == ==} def
/grid { % xmin xmax ymin ymax step
gsave
/step exch def
/maxy exch def
/miny exch def
/maxx exch def
/minx exch def
.8 .8 .8 setrgbcolor
.2 setlinewidth
% vertical lines
minx step maxx {
dup
miny moveto maxy lineto stroke
} for
% horizontal lines
miny step maxy {
dup
minx exch moveto maxx exch lineto stroke
} for
} def
/centerstring { % fontname width string -- fontsize
gsave
3 2 roll findfont setfont % width string
dup 3 1 roll % string width string
stringwidth pop div dup 3 1 roll % scale string scale
dup neg 0 exch rmoveto % scale string scale
currentfont exch scalefont setfont % scale string
show
grestore
} def
/centeratsize { % x y string --
gsave
3 1 roll moveto
dup stringwidth pop 2 div neg 0 rmoveto show
grestore
} def
/wohs { % x y string --
gsave
dup stringwidth pop neg 0 rmoveto show
grestore
} def
/crect { % x y wid hei incolor outcolor --
/xxoutco exch def
/xxinco exch def
4 copy
xxinco rgb rectfill
xxoutco rgb
/hei exch def
/wid exch def
moveto
wid 0 rlineto 0 hei rlineto
wid neg 0 rlineto closepath
stroke
} def
/zrect { % x y wid hei incolor outcolor letter --
/xxname exch def
/xxoutco exch def
/xxinco exch def
4 copy
xxinco rgb rectfill
xxoutco rgb
/hei exch def
/wid exch def
gsave
translate
0 0 moveto
wid 0 rlineto 0 hei rlineto
wid neg 0 rlineto closepath
stroke
/Helvetica-Bold findfont 8 scalefont setfont
wid 10 sub 3 moveto xxname show
grestore
} def
/zzrect { % x y wid hei name
aload pop zrect
} def
/arrow { % x y len angle --
/xxangle exch def
/xxlen exch def
gsave
translate
xxangle rotate
0 0 moveto
xxlen 0 lineto stroke
xxlen 0 moveto
-10 5 rlineto
0 -10 rlineto
closepath fill
grestore
} def
/carrow { % x y len angle color --
rgb
arrow
} def
% inner: S=255, V=193
% outer: S=255, V=116
/Linner [191 193 0] def
/Louter [115 116 0] def
% rifo V=225
/Linner [225 225 0] def
/Finner [105 195 0] def
/Fouter [63 116 0] def
% V=225
/Sinner [225 166 137] def
/Souter [116 85 71] def
% rifo: piu` rosa
/Sinner [255 180 205] def
/Souter [116 82 100] def
/Binner [166 124 83] def
/Bouter [97 72 48] def
/Tinner [226 73 81] def
/Touter [116 40 40] def
/Pinner [225 78 255] def
/Pouter [116 50 151] def
/rgb {
aload pop
255 div 3 1 roll
255 div 3 1 roll
255 div 3 1 roll
setrgbcolor
} def
/Cinner [0 220 224] def
/Couter [0 115 116] def
/Dinner [0 128 128] def
/Douter [0 64 64] def
/BLinner [94 94 225] def
/BLouter [0 0 116] def
% fix B (above is too blue
/BLinner [114 172 216] def
/BLouter [53 99 135] def
% again blue: much less saturated
/BLinner [177 199 216] def
/BLouter [53 99 135] def
% try again D
/Dinner [0 147 232] def
/Douter [0 64 64] def
/Dinner [30 115 144] def
/Dinner [62 146 175] def
/Douter [0 64 64] def
% fix C
/Couter Douter def
/Cinner [142 220 224] def
/L [ Linner Louter (L) ] def
/F [ Finner Fouter (F) ] def
/S [ Sinner Souter (S) ] def
/B [ Binner Bouter (B) ] def
/T [ Tinner Touter (T) ] def
/P [ Pinner Pouter (P) ] def
/C [ Cinner Couter (C) ] def
/D [ Dinner Douter (D) ] def
/BL [ BLinner BLouter (bl) ] def
/Ninner [ 220 220 220 ] def
/Nouter [ 128 128 128] def
/N [ Ninner Nouter (N) ] def
%0 600 0 190 10 grid
1.5 setlinewidth
0 0 0 setrgbcolor
/Helvetica-Bold findfont 16 scalefont setfont
20 145 moveto (ctrl dev) show
20 55 moveto (data \(mmap\)) show
150 45 400 30 [ 220 220 220 ] [ 128 128 128] () zrect
.5 .5 .5 setrgbcolor
/Helvetica-Bold findfont 8 scalefont setfont
515 50 moveto (vmalloc) show
/cblocks {
160 50 410 {
140 20 20 C zzrect
} for
} def
/dblocks {
160 50 410 {
20 add 50 50 20 D zzrect
} for
} def
/mmaparr {
160 50 410 {
Couter rgb
10 add 140 70 -75 arrow
} for
} def
cblocks dblocks mmaparr
%!PS-Adobe-2.0 EPSF-1.2
%%Creator: Alessandro Rubini
%%Title: zio char devices
%%BoundingBox: 0 0 600 190
%%EndComments
/S {dup ==} def
/S2 {2 copy == ==} def
/S3 {3 copy == == ==} def
/S4 {4 copy == == == ==} def
/grid { % xmin xmax ymin ymax step
gsave
/step exch def
/maxy exch def
/miny exch def
/maxx exch def
/minx exch def
.8 .8 .8 setrgbcolor
.2 setlinewidth
% vertical lines
minx step maxx {
dup
miny moveto maxy lineto stroke
} for
% horizontal lines
miny step maxy {
dup
minx exch moveto maxx exch lineto stroke
} for
} def
/centerstring { % fontname width string -- fontsize
gsave
3 2 roll findfont setfont % width string
dup 3 1 roll % string width string
stringwidth pop div dup 3 1 roll % scale string scale
dup neg 0 exch rmoveto % scale string scale
currentfont exch scalefont setfont % scale string
show
grestore
} def
/centeratsize { % x y string --
gsave
3 1 roll moveto
dup stringwidth pop 2 div neg 0 rmoveto show
grestore
} def
/wohs { % x y string --
gsave
dup stringwidth pop neg 0 rmoveto show
grestore
} def
/crect { % x y wid hei incolor outcolor --
/xxoutco exch def
/xxinco exch def
4 copy
xxinco rgb rectfill
xxoutco rgb
/hei exch def
/wid exch def
moveto
wid 0 rlineto 0 hei rlineto
wid neg 0 rlineto closepath
stroke
} def
/zrect { % x y wid hei incolor outcolor letter --
/xxname exch def
/xxoutco exch def
/xxinco exch def
4 copy
xxinco rgb rectfill
xxoutco rgb
/hei exch def
/wid exch def
gsave
translate
0 0 moveto
wid 0 rlineto 0 hei rlineto
wid neg 0 rlineto closepath
stroke
/Helvetica-Bold findfont 8 scalefont setfont
wid 10 sub 3 moveto xxname show
grestore
} def
/zzrect { % x y wid hei name
aload pop zrect
} def
/arrow { % x y len angle --
/xxangle exch def
/xxlen exch def
gsave
translate
xxangle rotate
0 0 moveto
xxlen 0 lineto stroke
xxlen 0 moveto
-10 5 rlineto
0 -10 rlineto
closepath fill
grestore
} def
/carrow { % x y len angle color --
rgb
arrow
} def
% inner: S=255, V=193
% outer: S=255, V=116
/Linner [191 193 0] def
/Louter [115 116 0] def
% rifo V=225
/Linner [225 225 0] def
/Finner [105 195 0] def
/Fouter [63 116 0] def
% V=225
/Sinner [225 166 137] def
/Souter [116 85 71] def
% rifo: piu` rosa
/Sinner [255 180 205] def
/Souter [116 82 100] def
/Binner [166 124 83] def
/Bouter [97 72 48] def
/Tinner [226 73 81] def
/Touter [116 40 40] def
/Pinner [225 78 255] def
/Pouter [116 50 151] def
/rgb {
aload pop
255 div 3 1 roll
255 div 3 1 roll
255 div 3 1 roll
setrgbcolor
} def
/Cinner [0 220 224] def
/Couter [0 115 116] def
/Dinner [0 128 128] def
/Douter [0 64 64] def
/BLinner [94 94 225] def
/BLouter [0 0 116] def
% fix B (above is too blue
/BLinner [114 172 216] def
/BLouter [53 99 135] def
% again blue: much less saturated
/BLinner [177 199 216] def
/BLouter [53 99 135] def
% try again D
/Dinner [0 147 232] def
/Douter [0 64 64] def
/Dinner [30 115 144] def
/Dinner [62 146 175] def
/Douter [0 64 64] def
% fix C
/Couter Douter def
/Cinner [142 220 224] def
/L [ Linner Louter (L) ] def
/F [ Finner Fouter (F) ] def
/S [ Sinner Souter (S) ] def
/B [ Binner Bouter (B) ] def
/T [ Tinner Touter (T) ] def
/P [ Pinner Pouter (P) ] def
/C [ Cinner Couter (C) ] def
/D [ Dinner Douter (D) ] def
/BL [ BLinner BLouter (bl) ] def
/Ninner [ 220 220 220 ] def
/Nouter [ 128 128 128] def
/N [ Ninner Nouter (N) ] def
%0 600 0 190 10 grid
1.5 setlinewidth
%120 70 20 20 C zzrect
%140 40 50 20 D zzrect
0 0 0 setrgbcolor
/Helvetica-Bold findfont 16 scalefont setfont
20 165 moveto (ch-0-ctrl) show
20 135 moveto (ch-0-data) show
20 85 moveto (ch-1-ctrl) show
20 55 moveto (ch-1-data) show
/blocks {
110 90 510 {
dup 80 20 20 C zzrect
20 add 50 50 20 D zzrect
} for
} def
blocks gsave 0 80 translate blocks grestore
570 30 470 180 arrow
/Helvetica-Bold findfont 12 scalefont setfont
340 15 (Data is flowing in this direction. Within a channel all blobs are strictly ordered) centeratsize
showpage
%!PS-Adobe-2.0 EPSF-1.2
%%Creator: Alessandro Rubini
%%Title: zio control internals
%%BoundingBox: 0 0 600 600
%%EndComments
/S {dup ==} def
/S2 {2 copy == ==} def
/S3 {3 copy == == ==} def
/S4 {4 copy == == == ==} def
/grid { % xmin xmax ymin ymax step
gsave
/step exch def
/maxy exch def
/miny exch def
/maxx exch def
/minx exch def
.8 .8 .8 setrgbcolor
.2 setlinewidth
% vertical lines
minx step maxx {
dup
miny moveto maxy lineto stroke
} for
% horizontal lines
miny step maxy {
dup
minx exch moveto maxx exch lineto stroke
} for
} def
/centerstring { % fontname width string -- fontsize
gsave
3 2 roll findfont setfont % width string
dup 3 1 roll % string width string
stringwidth pop div dup 3 1 roll % scale string scale
dup neg 0 exch rmoveto % scale string scale
currentfont exch scalefont setfont % scale string
show
grestore
} def
/centeratsize { % x y string --
gsave
3 1 roll moveto
dup stringwidth pop 2 div neg 0 rmoveto show
grestore
} def
/wohs { % x y string --
gsave
dup stringwidth pop neg 0 rmoveto show
grestore
} def
/crect { % x y wid hei incolor outcolor --
/xxoutco exch def
/xxinco exch def
4 copy
xxinco rgb rectfill
xxoutco rgb
/hei exch def
/wid exch def
moveto
wid 0 rlineto 0 hei rlineto
wid neg 0 rlineto closepath
stroke
} def
/zrect { % x y wid hei incolor outcolor letter --
/xxname exch def
/xxoutco exch def
/xxinco exch def
4 copy
xxinco rgb rectfill
xxoutco rgb
/hei exch def
/wid exch def
gsave
translate
0 0 moveto
wid 0 rlineto 0 hei rlineto
wid neg 0 rlineto closepath
stroke
/Helvetica-Bold findfont 8 scalefont setfont
wid 10 sub 3 moveto xxname show
grestore
} def
/zzrect { % x y wid hei name
aload pop zrect
} def
/arrow { % x y len angle --
/xxangle exch def
/xxlen exch def
gsave
translate
xxangle rotate
0 0 moveto
xxlen 0 lineto stroke
xxlen 0 moveto
-10 5 rlineto
0 -10 rlineto
closepath fill
grestore
} def
/carrow { % x y len angle color --
rgb
arrow
} def
% inner: S=255, V=193
% outer: S=255, V=116
/Linner [191 193 0] def
/Louter [115 116 0] def
% rifo V=225
/Linner [225 225 0] def
/Finner [105 195 0] def
/Fouter [63 116 0] def
% V=225
/Sinner [225 166 137] def
/Souter [116 85 71] def
% rifo: piu` rosa
/Sinner [255 180 205] def
/Souter [116 82 100] def
/Binner [166 124 83] def
/Bouter [97 72 48] def
/Tinner [226 73 81] def
/Touter [116 40 40] def
/Pinner [225 78 255] def
/Pouter [116 50 151] def
/rgb {
aload pop
255 div 3 1 roll
255 div 3 1 roll
255 div 3 1 roll
setrgbcolor
} def
/Cinner [0 220 224] def
/Couter [0 115 116] def
/Dinner [0 128 128] def
/Douter [0 64 64] def
/BLinner [94 94 225] def
/BLouter [0 0 116] def
% fix B (above is too blue
/BLinner [114 172 216] def
/BLouter [53 99 135] def
% again blue: much less saturated
/BLinner [177 199 216] def
/BLouter [53 99 135] def
% try again D
/Dinner [0 147 232] def
/Douter [0 64 64] def
/Dinner [30 115 144] def
/Dinner [62 146 175] def
/Douter [0 64 64] def
% fix C
/Couter Douter def
/Cinner [142 220 224] def
/L [ Linner Louter (L) ] def
/F [ Finner Fouter (F) ] def
/S [ Sinner Souter (S) ] def
/B [ Binner Bouter (B) ] def
/T [ Tinner Touter (T) ] def
/P [ Pinner Pouter (P) ] def
/C [ Cinner Couter (C) ] def
/D [ Dinner Douter (D) ] def
/BL [ BLinner BLouter (bl) ] def
/Ninner [ 220 220 220 ] def
/Nouter [ 128 128 128] def
/N [ Ninner Nouter (N) ] def
% was 400x400
1.5 1.5 scale
%0 400 0 400 20 grid
gsave
%60 20 320 360 Cinner Couter () zrect
60 380 translate
1 -1 scale
20 20 scale
.05 setlinewidth
0 0 16 18 Cinner Couter () zrect
/cfield { % x y wid str --
/xxstr exch def
/xxwid exch def
2 copy
xxwid 1 Cinner Couter () zrect
gsave
0 0 0 setrgbcolor
/Helvetica-Bold findfont 0.7 scalefont setfont
1 add translate
1 -1 scale
xxwid 2 div 0.3 xxstr centeratsize
%wid 2 div .1 rmoveto xxstr centerstring
grestore
} def
/afield { % x y wid str --
/xxstr exch def
/xxwid exch def
2 copy
xxwid 1 [ 220 220 220 ] Couter () zrect
gsave
0 0 0 setrgbcolor
/Helvetica-Bold findfont 0.7 scalefont setfont
1 add translate
1 -1 scale
xxwid 2 div 0.3 xxstr centeratsize
%wid 2 div .1 rmoveto xxstr centerstring
grestore
} def
/tfield { % x y wid str --
/xxstr exch def
/xxwid exch def
2 copy
xxwid 1 [ 177 255 216 ] Couter () zrect
gsave
0 0 0 setrgbcolor
/Helvetica-Bold findfont 0.7 scalefont setfont
1 add translate
1 -1 scale
xxwid 2 div 0.3 xxstr centeratsize
%wid 2 div .1 rmoveto xxstr centerstring
grestore
} def
0 0 1 (V) cfield
1 0 1 (v) cfield
2 0 1 (A) cfield
3 0 1 (a) cfield
4 0 4 (sequence) cfield
8 0 4 (nsamples) cfield
12 0 2 (ssize) cfield
14 0 2 (nbits) cfield
0 1 2 (fam) afield
2 1 2 (type) afield
4 1 8 (host-identification) afield
12 1 4 (device-id) afield
0 2 2 (cset) afield
2 2 2 (chan) afield
4 2 12 (device name) afield
0 3 8 (tstamp: secs) tfield
8 3 8 (tstamp: ticks) tfield
0 4 8 (tstamp: bins) tfield
8 4 4 (mem-addr) cfield
12 4 4 (reserved) cfield
0 5 4 (flags) cfield
4 5 12 (trigger name) cfield
0 17 16 (TLV record for optional extra information) cfield
gsave
0 15 translate 1 -1 scale
/Helvetica-Bold findfont 0.7 scalefont setfont
8 7 (This area hosts attributes for the device) centeratsize
8 6 (and for the currently active trigger.) centeratsize
8 4 (Device and trigger are each characterized by) centeratsize
8 3 (16 "standard" attrs and 32 "extended" attrs.) centeratsize
8 2 (A bit-mask states which attrs are active.) centeratsize
8 0 (Each attribute is a 32-bit word) centeratsize
grestore
gsave
/Helvetica-Bold findfont 0.8 scalefont setfont
0 0 0 setrgbcolor
-2 6.8 translate 1 -1 scale
0 6 moveto (0x00) show
0 5 moveto (0x10) show
0 4 moveto (0x20) show
0 3 moveto (0x30) show
0 2 moveto (0x40) show
0 1 moveto (0x50) show
0 0 moveto (0x60) show
grestore
/Helvetica-Bold findfont 0.8 scalefont setfont
0 0 0 setrgbcolor
-2.5 17.8 translate 1 -1 scale
0 0 moveto (0x1F0) show
%80 85 moveto gsave (Block) show grestore 70 0 rmoveto (Blue) show
%80 55 moveto gsave (Control) show grestore 70 0 rmoveto (Cyan) show
%80 25 moveto gsave (Data) show grestore 70 0 rmoveto (Darker) show
grestore
%0 400 0 400 20 grid
showpage
This diff is collapsed.
%!PS-Adobe-2.0 EPSF-1.2
%%Creator: Alessandro Rubini
%%Title: zio block control and data
%%BoundingBox: 0 0 220 190
%%EndComments
/S {dup ==} def
/S2 {2 copy == ==} def
/S3 {3 copy == == ==} def
/S4 {4 copy == == == ==} def
/grid { % xmin xmax ymin ymax step
gsave
/step exch def
/maxy exch def
/miny exch def
/maxx exch def
/minx exch def
.8 .8 .8 setrgbcolor
.2 setlinewidth
% vertical lines
minx step maxx {
dup
miny moveto maxy lineto stroke
} for
% horizontal lines
miny step maxy {
dup
minx exch moveto maxx exch lineto stroke
} for
} def
/centerstring { % fontname width string -- fontsize
gsave
3 2 roll findfont setfont % width string
dup 3 1 roll % string width string
stringwidth pop div dup 3 1 roll % scale string scale
dup neg 0 exch rmoveto % scale string scale
currentfont exch scalefont setfont % scale string
show
grestore
} def
/centeratsize { % x y string --
gsave
3 1 roll moveto
dup stringwidth pop 2 div neg 0 rmoveto show
grestore
} def
/wohs { % x y string --
gsave
dup stringwidth pop neg 0 rmoveto show
grestore
} def
/crect { % x y wid hei incolor outcolor --
/xxoutco exch def
/xxinco exch def
4 copy
xxinco rgb rectfill
xxoutco rgb
/hei exch def
/wid exch def
moveto
wid 0 rlineto 0 hei rlineto
wid neg 0 rlineto closepath
stroke
} def
/zrect { % x y wid hei incolor outcolor letter --
/xxname exch def
/xxoutco exch def
/xxinco exch def
4 copy
xxinco rgb rectfill
xxoutco rgb
/hei exch def
/wid exch def
gsave
translate
0 0 moveto
wid 0 rlineto 0 hei rlineto
wid neg 0 rlineto closepath
stroke
/Helvetica-Bold findfont 8 scalefont setfont
wid 10 sub 3 moveto xxname show
grestore
} def
/zzrect { % x y wid hei name
aload pop zrect
} def
/arrow { % x y len angle --
/xxangle exch def
/xxlen exch def
gsave
translate
xxangle rotate
0 0 moveto
xxlen 0 lineto stroke
xxlen 0 moveto
-10 5 rlineto
0 -10 rlineto
closepath fill
grestore
} def
/carrow { % x y len angle color --
rgb
arrow
} def
% inner: S=255, V=193
% outer: S=255, V=116
/Linner [191 193 0] def
/Louter [115 116 0] def
% rifo V=225
/Linner [225 225 0] def
/Finner [105 195 0] def
/Fouter [63 116 0] def
% V=225
/Sinner [225 166 137] def
/Souter [116 85 71] def
% rifo: piu` rosa
/Sinner [255 180 205] def
/Souter [116 82 100] def
/Binner [166 124 83] def
/Bouter [97 72 48] def
/Tinner [226 73 81] def
/Touter [116 40 40] def
/Pinner [225 78 255] def
/Pouter [116 50 151] def
/rgb {
aload pop
255 div 3 1 roll
255 div 3 1 roll
255 div 3 1 roll
setrgbcolor
} def
/Cinner [0 220 224] def
/Couter [0 115 116] def
/Dinner [0 128 128] def
/Douter [0 64 64] def
/BLinner [94 94 225] def
/BLouter [0 0 116] def
% fix B (above is too blue
/BLinner [114 172 216] def
/BLouter [53 99 135] def
% again blue: much less saturated
/BLinner [177 199 216] def
/BLouter [53 99 135] def
% try again D
/Dinner [0 147 232] def
/Douter [0 64 64] def
/Dinner [30 115 144] def
/Dinner [62 146 175] def
/Douter [0 64 64] def
% fix C
/Couter Douter def
/Cinner [142 220 224] def
/L [ Linner Louter (L) ] def
/F [ Finner Fouter (F) ] def
/S [ Sinner Souter (S) ] def
/B [ Binner Bouter (B) ] def
/T [ Tinner Touter (T) ] def
/P [ Pinner Pouter (P) ] def
/C [ Cinner Couter (C) ] def
/D [ Dinner Douter (D) ] def
/BL [ BLinner BLouter (bl) ] def
/Ninner [ 220 220 220 ] def
/Nouter [ 128 128 128] def
/N [ Ninner Nouter (N) ] def
%0 220 0 190 10 grid
1.5 setlinewidth
30 130 170 40 BL zzrect
35 145 20 20 C zzrect
55 145 140 20 D zzrect
20 80 50 20 BL zzrect
20 50 50 20 C zzrect
20 20 50 20 D zzrect
0 0 0 setrgbcolor
/Helvetica-Bold findfont 11 scalefont setfont
80 85 moveto gsave (The block is overall blue) show
/Helvetica-Bold findfont 16 scalefont setfont
80 55 moveto gsave (Control) show grestore 70 0 rmoveto (Cyan) show
80 25 moveto gsave (Data) show grestore 70 0 rmoveto (Darker) show
showpage
%!PS-Adobe-2.0 EPSF-1.2
%%Creator: Alessandro Rubini
%%Title: zio definitions and colors
%%BoundingBox: 0 0 250 240
%%EndComments
/S {dup ==} def
/S2 {2 copy == ==} def
/S3 {3 copy == == ==} def
/S4 {4 copy == == == ==} def
/grid { % xmin xmax ymin ymax step
gsave
/step exch def
/maxy exch def
/miny exch def
/maxx exch def
/minx exch def
.8 .8 .8 setrgbcolor
.2 setlinewidth
% vertical lines
minx step maxx {
dup
miny moveto maxy lineto stroke
} for
% horizontal lines
miny step maxy {
dup
minx exch moveto maxx exch lineto stroke
} for
} def
/centerstring { % fontname width string -- fontsize
gsave
3 2 roll findfont setfont % width string
dup 3 1 roll % string width string
stringwidth pop div dup 3 1 roll % scale string scale
dup neg 0 exch rmoveto % scale string scale
currentfont exch scalefont setfont % scale string
show
grestore
} def
/centeratsize { % x y string --
gsave
3 1 roll moveto
dup stringwidth pop 2 div neg 0 rmoveto show
grestore
} def
/wohs { % x y string --
gsave
dup stringwidth pop neg 0 rmoveto show
grestore
} def
/crect { % x y wid hei incolor outcolor --
/xxoutco exch def
/xxinco exch def
4 copy
xxinco rgb rectfill
xxoutco rgb
/hei exch def
/wid exch def
moveto
wid 0 rlineto 0 hei rlineto
wid neg 0 rlineto closepath
stroke
} def
/zrect { % x y wid hei incolor outcolor letter --
/xxname exch def
/xxoutco exch def
/xxinco exch def
4 copy
xxinco rgb rectfill
xxoutco rgb
/hei exch def
/wid exch def
gsave
translate
0 0 moveto
wid 0 rlineto 0 hei rlineto
wid neg 0 rlineto closepath
stroke
/Helvetica-Bold findfont 8 scalefont setfont
wid 10 sub 3 moveto xxname show
grestore
} def
/zzrect { % x y wid hei name
aload pop zrect
} def
/arrow { % x y len angle --
/xxangle exch def
/xxlen exch def
gsave
translate
xxangle rotate
0 0 moveto
xxlen 0 lineto stroke
xxlen 0 moveto
-10 5 rlineto
0 -10 rlineto
closepath fill
grestore
} def
/carrow { % x y len angle color --
rgb
arrow
} def
% inner: S=255, V=193
% outer: S=255, V=116
/Linner [191 193 0] def
/Louter [115 116 0] def
% rifo V=225
/Linner [225 225 0] def
/Finner [105 195 0] def
/Fouter [63 116 0] def
% V=225
/Sinner [225 166 137] def
/Souter [116 85 71] def
% rifo: piu` rosa
/Sinner [255 180 205] def
/Souter [116 82 100] def
/Binner [166 124 83] def
/Bouter [97 72 48] def
/Tinner [226 73 81] def
/Touter [116 40 40] def
/Pinner [225 78 255] def
/Pouter [116 50 151] def
/rgb {
aload pop
255 div 3 1 roll
255 div 3 1 roll
255 div 3 1 roll
setrgbcolor
} def
/Cinner [0 220 224] def
/Couter [0 115 116] def
/Dinner [0 128 128] def
/Douter [0 64 64] def
/BLinner [94 94 225] def
/BLouter [0 0 116] def
% fix B (above is too blue
/BLinner [114 172 216] def
/BLouter [53 99 135] def
% again blue: much less saturated
/BLinner [177 199 216] def
/BLouter [53 99 135] def
% try again D
/Dinner [0 147 232] def
/Douter [0 64 64] def
/Dinner [30 115 144] def
/Dinner [62 146 175] def
/Douter [0 64 64] def
% fix C
/Couter Douter def
/Cinner [142 220 224] def
/L [ Linner Louter (L) ] def
/F [ Finner Fouter (F) ] def
/S [ Sinner Souter (S) ] def
/B [ Binner Bouter (B) ] def
/T [ Tinner Touter (T) ] def
/P [ Pinner Pouter (P) ] def
/C [ Cinner Couter (C) ] def
/D [ Dinner Douter (D) ] def
/BL [ BLinner BLouter (bl) ] def
/Ninner [ 220 220 220 ] def
/Nouter [ 128 128 128] def
/N [ Ninner Nouter (N) ] def
%0 220 0 240 10 grid
1.5 setlinewidth
gsave 0 30 translate
20 170 50 20 L zzrect
20 140 50 20 F zzrect
20 110 50 20 S zzrect
20 80 50 20 B zzrect
20 50 50 20 T zzrect
20 20 50 20 P zzrect
0 0 0 setrgbcolor
/Helvetica-Bold findfont 16 scalefont setfont
80 175 moveto gsave (Luser) show grestore 70 0 rmoveto (Lemon) show
80 145 moveto gsave (Fops) show grestore 70 0 rmoveto (Forest) show
80 115 moveto gsave (Socket) show grestore 70 0 rmoveto (Salmon) show
80 85 moveto gsave (Buffer) show grestore 70 0 rmoveto (Brown) show
80 55 moveto gsave (Trigger) show grestore 70 0 rmoveto (Tomato) show
80 25 moveto gsave (Periph.) show grestore 70 0 rmoveto (Purple) show
grestore
% add network
20 20 50 20 N zzrect
0 0 0 setrgbcolor
/Helvetica-Bold findfont 16 scalefont setfont
80 25 moveto gsave (Network) show grestore 70 0 rmoveto (Neutral) show
showpage
#! /usr/bin/sed -f
# allow "%" as a comment char, but only at the beginning of the line
s/^%/@c /
#s/[^\\]%.*$//
s/^\\%/%/
#preserve blanks and braces in @example blocks
/@example/,/@end example/ s/{/@{/g
/@example/,/@end example/ s/}/@}/g
/@example/,/@end example/ p
/@example/,/@end example/ d
/@smallexample/,/@end smallexample/ s/{/@{/g
/@smallexample/,/@end smallexample/ s/}/@}/g
/@smallexample/,/@end smallexample/ p
/@smallexample/,/@end smallexample/ d
# remove leading blanks
s/^[ ]*//
This diff is collapsed.
LINUX ?= /lib/modules/$(shell uname -r)/build
GIT_VERSION = $(shell cd $(src); git describe --dirty --long --tags)
# For this CSM_VERSION, please see ohwr.org/csm documentation
ifdef CONFIG_CSM_VERSION
ccflags-y += -D"CERN_SUPER_MODULE=MODULE_VERSION(\"$(CONFIG_CSM_VERSION)\")"
else
ccflags-y += -DCERN_SUPER_MODULE=""
endif
ccflags-y += -I$(src)/../include/ -DGIT_VERSION=\"$(GIT_VERSION)\"
ccflags-$(CONFIG_ZIO_DEBUG) += -DDEBUG
obj-m = zio-zero.o
obj-m += zio-loop.o
obj-m += zio-irq-tdc.o
obj-m += zio-fake-dtc.o
obj-m += zio-mini.o
obj-m += zio-gpio.o
ifdef CONFIG_USB
obj-m += zio-vmk8055.o
endif
ifdef CONFIG_SPI
obj-m += zio-ad788x.o
endif
/* Alessandro Rubini for CERN, 2013, GNU GPLv2 or later */
/*
* This is a simple DTC (digital to time converter). It just sends out
* a printk when the event fires. The event is just the timestamp in
* the control block, and is managed by a high-resolution timer.
*/
#define DEBUG
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/ktime.h>
#include <linux/hrtimer.h>
#include <linux/zio.h>
#include <linux/zio-trigger.h>
/* One device, one cset, one timer (one channel too). So one lazy structure */
static struct {
struct hrtimer timer;
struct zio_cset *cset;
struct timespec ts;
} zdtc;
#define ZDTC_SLACK 1000 /* 1us */
static enum hrtimer_restart zdtc_fn(struct hrtimer *timer)
{
struct timespec ts;
getnstimeofday(&ts);
dev_dbg(&zdtc.cset->head.dev, "%s: %9li.%09li\n", __func__,
ts.tv_sec, ts.tv_nsec);
zio_trigger_data_done(zdtc.cset);
return HRTIMER_NORESTART;
}
/*
* stop_io: called when a trigger needs to be aborted and re-armed
* The function is called in locked context. Here is it only used
* for the data cset, so we can just return the partial block.
*/
static void zdtc_stop_io(struct zio_cset *cset)
{
dev_dbg(&cset->head.dev, "%s\n", __func__);
hrtimer_cancel(&zdtc.timer);
zio_generic_data_done(cset);
}
/* raw_io method: arm the timer with the currently requested time */
static int zdtc_raw_io(struct zio_cset *cset)
{
struct timespec ts;
struct zio_control *ctrl;
ktime_t ktime;
/* We cannot be armed if there's no block. Wait for next push */
if (!cset->chan->active_block)
return -EIO;
ctrl = zio_get_ctrl(cset->chan->active_block);
zdtc.cset = cset;
/* If sec is less than one hour, it is relative to the current sec. */
getnstimeofday(&ts);
ts.tv_nsec = ctrl->tstamp.ticks;
if (ctrl->tstamp.secs > 3600)
ts.tv_sec = ctrl->tstamp.secs;
else
ts.tv_sec += ctrl->tstamp.secs;
ktime = timespec_to_ktime(ts);
zdtc.ts = ts;
hrtimer_start_range_ns(&zdtc.timer, ktime, ZDTC_SLACK,
HRTIMER_MODE_ABS);
return -EAGAIN; /* Will data_done later */
}
static int zdtc_probe(struct zio_device *zdev)
{
return 0;
}
static struct zio_cset zdtc_cset[] = {
{
ZIO_SET_OBJ_NAME("dtc"),
.raw_io = zdtc_raw_io,
.stop_io = zdtc_stop_io,
.flags = ZIO_DIR_OUTPUT | ZIO_CSET_TYPE_TIME |
ZIO_CSET_SELF_TIMED,
.n_chan = 1,
.ssize = 0,
},
};
static struct zio_device zdtc_tmpl = {
.owner = THIS_MODULE,
.cset = zdtc_cset,
.n_cset = ARRAY_SIZE(zdtc_cset),
};
/* The driver uses a table of templates */
static const struct zio_device_id zdtc_table[] = {
{"zdtc", &zdtc_tmpl},
{},
};
static struct zio_driver zdtc_zdrv = {
.driver = {
.name = "zdtc",
.owner = THIS_MODULE,
},
.id_table = zdtc_table,
.probe = zdtc_probe,
};
/* Lazily, use a single global device */
static struct zio_device *zdtc_init_dev;
static int __init zdtc_init(void)
{
int err;
err = zio_register_driver(&zdtc_zdrv);
if (err)
return err;
zdtc_init_dev = zio_allocate_device();
if (IS_ERR(zdtc_init_dev)) {
err = PTR_ERR(zdtc_init_dev);
goto out_alloc;
}
zdtc_init_dev->owner = THIS_MODULE;
err = zio_register_device(zdtc_init_dev, "zdtc", 0);
if (err)
goto out_register;
hrtimer_init(&zdtc.timer, CLOCK_REALTIME, HRTIMER_MODE_ABS);
zdtc.timer.function = zdtc_fn;
return 0;
out_register:
zio_free_device(zdtc_init_dev);
out_alloc:
zio_unregister_driver(&zdtc_zdrv);
return err;
}
static void __exit zdtc_exit(void)
{
zio_unregister_device(zdtc_init_dev);
zio_free_device(zdtc_init_dev);
zio_unregister_driver(&zdtc_zdrv);
}
module_init(zdtc_init);
module_exit(zdtc_exit);
MODULE_VERSION(GIT_VERSION); /* Defined in local Makefile */
MODULE_LICENSE("GPL");
CERN_SUPER_MODULE;
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
# build user-space tools for zio
CFLAGS = -I$(M)/include/ -Wall $(EXTRACFLAGS)
CC ?= $(CROSS_COMPILE)gcc
progs := zio-dump
progs += zio-cat-file
progs += test-dtc
# The following is ugly, please forgive me by now
user: $(progs)
clean:
rm -f $(progs) *~ *.o
%: %.c
$(CC) $(CFLAGS) $^ -o $@
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
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