75
75
#endif /* CONFIG_XENO_EXPORT_REGISTRY */
77
#define X_FIFO_HANDLER2(handler) ((int (*)(int, ...))(handler))
77
#define CALL_FIFO_HANDLER(fifo, type) \
78
((int (*)(int, ...))((fifo)->handler))((fifo) - __fifo_table, (type))
79
static int __fifo_exec_handler(int minor,
80
struct xnpipe_mh *mh, int retval, void *cookie)
80
static int __fifo_input_handler(struct xnpipe_mh *mh, int retval, void *xstate) /* nklock held */
82
RT_FIFO *fifo = __fifo_table + minor;
82
RT_FIFO *fifo = xstate;
86
fifo->handler != NULL &&
87
(err = X_FIFO_HANDLER2(fifo->handler) (minor, 'w') < 0))
85
if (retval >= 0 && fifo->handler) {
86
err = CALL_FIFO_HANDLER(fifo, 'w');
93
static int __fifo_output_handler(int minor,
94
xnpipe_mh_t *mh, int retval, void *cookie)
96
RT_FIFO *fifo = __fifo_table + minor;
94
static void __fifo_output_handler(xnpipe_mh_t *mh, void *xstate) /* nklock held */
96
RT_FIFO *fifo = xstate;
99
CALL_FIFO_HANDLER(fifo, 'r');
102
static void __fifo_ifree_handler(void *buf, void *xstate) /* nklock free */
107
static void __fifo_ofree_handler(void *buf, void *xstate) /* nklock free except when resizing */
109
RT_FIFO *fifo = xstate;
112
xnlock_get_irqsave(&nklock, s);
100
114
__clear_bit(RTFIFO_SYNCWAIT, &fifo->status);
103
fifo->handler != NULL &&
104
(err = X_FIFO_HANDLER2(fifo->handler) (minor, 'r') < 0))
115
xnlock_put_irqrestore(&nklock, s);
118
static void __fifo_release_handler(void *xstate) /* nklock free */
120
RT_FIFO *fifo = xstate;
125
xnlock_get_irqsave(&nklock, s); /* Protect against resizes. */
126
buffer = fifo->buffer;
129
xnlock_put_irqrestore(&nklock, s);
132
xnarch_free_host_mem(buffer, size + sizeof(xnpipe_mh_t));
110
135
int __rtai_fifo_pkg_init(void)
145
171
fifo = __fifo_table + minor;
147
err = xnpipe_connect(minor,
148
&__fifo_output_handler,
149
&__fifo_exec_handler, NULL, fifo);
172
ops.output = &__fifo_output_handler;
173
ops.input = &__fifo_input_handler;
174
ops.release = &__fifo_release_handler;
175
ops.free_ibuf = &__fifo_ifree_handler;
176
ops.free_obuf = &__fifo_ofree_handler;
178
ops.alloc_ibuf = NULL; /* i.e. xnmalloc() */
180
err = xnpipe_connect(minor, &ops, fifo);
151
181
if (err < 0 && err != -EBUSY)
159
189
/* Resize the fifo on-the-fly if the specified buffer
160
190
size is different from the current one. */
193
* Make sure the streaming buffer is not enqueued for
196
xnpipe_flush(minor, XNPIPE_OFLUSH);
162
198
buffer = fifo->buffer;
163
199
oldsize = fifo->bufsz;
182
218
xnlock_put_irqrestore(&nklock, s);
183
219
buffer = xnarch_alloc_host_mem(size + sizeof(xnpipe_mh_t));
184
xnlock_get_irqsave(&nklock, s);
186
221
if (buffer == NULL) {
188
/* First open, we need to disconnect upon
189
* error. Caveat: we still hold the lock while
190
* flushing the message pipe's input and
191
* output queues during disconnection. */
192
223
xnpipe_disconnect(minor);
224
xnlock_get_irqsave(&nklock, s);
230
xnlock_get_irqsave(&nklock, s);
199
232
fifo->buffer = buffer;
200
233
fifo->bufsz = size;
201
234
fifo->fillsz = 0;
257
290
if (fifo->handle)
258
291
xnregistry_remove(fifo->handle);
259
292
#endif /* CONFIG_XENO_OPT_REGISTRY */
260
xnpipe_disconnect(minor);
261
293
fifo->refcnt = 0;
262
294
xnlock_put_irqrestore(&nklock, s);
263
xnarch_free_host_mem(buffer, oldsize + sizeof(xnpipe_mh_t));
295
xnpipe_disconnect(minor);