Newer
Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
/* Alessandro Rubini, Federico Vaga for CERN, 2011, GNU GPLv2 or later */
#ifndef __ZIO_BUFFER_H__
#define __ZIO_BUFFER_H__
#ifdef __KERNEL__
#include <linux/time.h>
#else
#include <time.h>
#endif
/*
* Data transfers on the control channel only happen by half a kB.
* This is fixed for forward compatibility; zio_control may have more
* fields in the future, and current apps should handle it.
*/
#define ZIO_CONTROL_SIZE 512
/*
* The timestamp is mostly app-specific. It cam be timspec-alike but
* indidual devices may do whatever they want to match hardware.
*/
struct zio_timestamp {
uint64_t secs;
uint64_t ticks;
uint64_t bins;
};
/*
* The following data item is the control structure that is being exchanged
* on the control device associated to each data device. The size of each
* fields is fixed to ease portability of binary dumps (esp i386/x86-64).
* The endianness, however, is native for speed reasons.
*/
struct zio_control {
/* byte 0 */
uint8_t major_version;
uint8_t minor_version;
uint8_t unused[2];
/* byte 4*/
uint32_t seq_num; /* block sequence number */
uint32_t flags; /* endianness etc, see below */
uint32_t nsamples; /* number of samples in this data block */
/* byte 16 */
uint16_t ssize; /* sample-size for each of them, in bytes */
uint16_t sbits; /* sample-bits: number of valid bits */
uint16_t cset_i; /* index of channel-set within device */
uint16_t chan_i; /* index of channel within cset */
/* byte 24 */
/* The control block includes what device the data belong to */
char devname[ZIO_NAME_LEN];
/* byte 56 */
/* Each data block is associated with a trigger and its features */
char triggername[ZIO_NAME_LEN];
/* byte 88 */
struct zio_timestamp tstamp;
/* byte 112 */
uint32_t ext_attr_mask; /* mask of active extended attributes */
uint32_t std_attr_mask; /* mask of active standard attributes */
/* byte 120 */
uint32_t std_attrs[32]; /* value of each standard attribute */
uint32_t ext_attrs[32]; /* value of each extended attribute */
/* This filler must be updated if you change fields above */
uint8_t __fill_end[ZIO_CONTROL_SIZE - 120 - 4 * (32 + 32)];
};
/* The following flags are used in the control structure */
#define ZIO_CONTROL_LITTLE_ENDIAN 0x01000001
#define ZIO_CONTROL_BIG_ENDIAN 0x02000002
#define ZIO_CONTROL_MSB_ALIGN 0x00000004 /* for analog data */
#define ZIO_CONTROL_LSB_ALIGN 0x00000008 /* for analog data */
#ifdef __KERNEL__
#include <linux/module.h>
#include <linux/kobject.h>
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
#include <linux/zio.h>
#include <linux/gfp.h>
#include <linux/fs.h>
#include <linux/list.h>
#include <linux/spinlock.h>
#include <linux/wait.h>
#define ZIO_DEFAULT_BUFFER "kmalloc" /* For devices with no own buffer type */
/* Compile-time check that the control structure is the right size */
static inline void __unused_check_size(void)
{
/* if zio_control is smaller then ZIO_CONTROL_SIZE, compile error */
static int __used v1[sizeof(struct zio_control) - ZIO_CONTROL_SIZE];
/* if zio_control is greater then ZIO_CONTROL_SIZE, compile error */
static int __used v2[ZIO_CONTROL_SIZE - sizeof(struct zio_control)];
BUILD_BUG_ON(sizeof(struct zio_control) != ZIO_CONTROL_SIZE);
}
/* FIXME: use a kmem_cache and real functions for control alloc/free */
static inline struct zio_control *zio_alloc_control(gfp_t gfp)
{
struct zio_control *ctrl;
ctrl = kzalloc(sizeof(*ctrl), gfp);
if (!ctrl)
return NULL;
ctrl->major_version = ZIO_MAJOR_VERSION;
ctrl->minor_version = ZIO_MINOR_VERSION;
if (ntohl(1) == 1)
ctrl->flags |= ZIO_CONTROL_BIG_ENDIAN;
else
ctrl->flags |= ZIO_CONTROL_LITTLE_ENDIAN;
return ctrl;
}
static inline void zio_free_control(struct zio_control *ctrl)
{
kfree(ctrl);
}
/*
* The following structure defines a buffer type, with methods.
* An instance is created for each channel using it
*/
struct zio_buffer_operations;
struct zio_buffer_type {
struct zio_obj_head head;
struct module *owner;
struct list_head list; /* instances, and list lock */
struct spinlock lock;
unsigned long flags; /* to be defined */
/* file operations (read/write etc) are buffer-specific too */
const struct zio_sys_operations *s_op;
const struct zio_buffer_operations *b_op;
const struct file_operations *f_op;
/* FIXME: how "own" devices are listed (here or elsewhere?) */
struct zio_device *zdev_owner;
unsigned int n_zdev_owner;
};
#define to_zio_buf(obj) container_of(obj, struct zio_buffer, head.kobj)
/* read and write may often be the generic ones */
ssize_t zio_generic_read(struct file *, char __user *,
size_t, loff_t *);
ssize_t zio_generic_write(struct file *, const char __user *,
size_t, loff_t *);
unsigned int zio_generic_poll(struct file *, struct poll_table_struct *);
int zio_generic_release(struct inode *inode, struct file *f);
int __must_check zio_register_buf(struct zio_buffer_type *zbuf,
const char *name);
void zio_unregister_buf(struct zio_buffer_type *zbuf);
struct zio_bi {
struct zio_obj_head head;
struct list_head list; /* instance list */
struct zio_channel *chan;
struct zio_cset *cset; /* short for chan->cset */
/* Those using generic_read need this information */
unsigned long flags; /* input or output */
wait_queue_head_t q; /* either read or write */
/* Standard and extended attributes for this object */
struct zio_attribute_set zattr_set;
const struct zio_buffer_operations *b_op;
const struct file_operations *f_op;
};
#define to_zio_bi(_kobj) container_of(_kobj, struct zio_bi, head.kobj)
/* the instance is either for input or for output */
#define ZIO_BUFFER_INPUT 0x01
#define ZIO_BUFFER_OUTPUT 0x01
/* The block is the basic data item being transferred */
struct zio_block {
unsigned long ctrl_flags;
void *data;
size_t datalen;
size_t uoff;
};
/*
* We must know whether the ctrl block has been filled/read or not: "cdone"
* No "set_ctrl" or "clr_cdone" are needed, as cdone starts 0 and is only set
*/
#define zio_get_ctrl(block) ((struct zio_control *)((block)->ctrl_flags & ~1))
#define zio_set_ctrl(block, ctrl) ((block)->ctrl_flags = (unsigned long)(ctrl))
#define zio_is_cdone(block) ((block)->ctrl_flags & 1)
#define zio_set_cdone(block) ((block)->ctrl_flags |= 1)
/*
* Each buffer implementation must provide the following methods, because
* internal management of individual data instances is left to each of them.
*
* "store" is for input and "retr" for output (called by low-level driver).
* After store, the block is ready for user space and freed internally;
* after retr, it's the low level driver that must cal the free method.
* The "alloc" method is called on trigger setup (activate), because the
* data storage must be available when data transfer really happens (thus,
* a DMA-only device will have its own buffer as the preferred one).
* The buffer may use its own alloc for blocks created at write(2) time.
*
* Note that each buffer type will need more information, so the block
* is usually inside a custom structure, reached by container_of().
* Thus, all blocks for a buffer type must be allocated and freed using
* the methods of that specific buffer type.
*/
struct zio_buffer_operations {
struct zio_block * (*alloc_block)(struct zio_bi *bi,
struct zio_control *ctrl,
size_t datalen, gfp_t gfp);
void (*free_block)(struct zio_bi *bi,
struct zio_block *block);
int (*store_block)(struct zio_bi *bi,
struct zio_block *block);
struct zio_block * (*retr_block) (struct zio_bi *bi);
struct zio_bi * (*create)(struct zio_buffer_type *zbuf,
struct zio_channel *chan,
fmode_t f_flags);
void (*destroy)(struct zio_bi *bi);
};
/*
* This is the structure we place in f->private_data at open time.
* Note that the buffer_create function is called by zio-core.
*/
enum zio_cdev_type {
ZIO_CDEV_CTRL,
ZIO_CDEV_DATA,
};
struct zio_f_priv {
struct zio_channel *chan; /* where current block and buffer live */
enum zio_cdev_type type;
};
ssize_t zio_generic_read(struct file *f, char __user *ubuf,
size_t count, loff_t *offp);
ssize_t zio_generic_write(struct file *f, const char __user *ubuf,
size_t count, loff_t *offp);
unsigned int zio_generic_poll(struct file *f, struct poll_table_struct *w);
#endif /* __KERNEL__ */
#endif /* __ZIO_BUFFER_H__ */