~ubuntu-branches/ubuntu/lucid/xenomai/lucid

« back to all changes in this revision

Viewing changes to ksrc/skins/rtai/fifo.c

  • Committer: Bazaar Package Importer
  • Author(s): Andres Rodriguez
  • Date: 2009-06-24 22:17:01 UTC
  • mfrom: (3.1.2 squeeze)
  • Revision ID: james.westby@ubuntu.com-20090624221701-mwnah8aj90zmp6uj
Tags: 2.4.8-2ubuntu1
* Merge from debian unstable (LP: #391918), remaining changes:
  - Add lpia to supported architectures.
  - debian/rules: Create file for debhelper to pick up, use debhelper to
    install it.
  - debian/libxenomai1.dirs: Do not create directory.
  - debian/libxenomai1.preinst: Remove symlink on upgrade, remove old udev.
    rule unless modified in which case move to new name.
  - debian/libxenomai1.postinst: Do not create symlink.
  - debian/libxenomai1.postrm: No symlink to remove.
  - Bump build-depend on debhelper to install udev rules into
    /lib/udev/rules.d, add Breaks on udev to get correct version.

Show diffs side-by-side

added added

removed removed

Lines of Context:
74
74
 
75
75
#endif /* CONFIG_XENO_EXPORT_REGISTRY */
76
76
 
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))
78
79
 
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 */
81
81
{
82
 
        RT_FIFO *fifo = __fifo_table + minor;
 
82
        RT_FIFO *fifo = xstate;
83
83
        int err;
84
84
 
85
 
        if (retval >= 0 &&
86
 
            fifo->handler != NULL &&
87
 
            (err = X_FIFO_HANDLER2(fifo->handler) (minor, 'w') < 0))
88
 
                retval = err;
 
85
        if (retval >= 0 && fifo->handler) {
 
86
                err = CALL_FIFO_HANDLER(fifo, 'w');
 
87
                if (err < 0)
 
88
                        retval = err;
 
89
        }
89
90
 
90
91
        return retval;
91
92
}
92
93
 
93
 
static int __fifo_output_handler(int minor,
94
 
                                 xnpipe_mh_t *mh, int retval, void *cookie)
95
 
{
96
 
        RT_FIFO *fifo = __fifo_table + minor;
97
 
        int err;
98
 
 
 
94
static void __fifo_output_handler(xnpipe_mh_t *mh, void *xstate) /* nklock held */
 
95
{
 
96
        RT_FIFO *fifo = xstate;
 
97
 
 
98
        if (fifo->handler)
 
99
                CALL_FIFO_HANDLER(fifo, 'r');
 
100
}
 
101
 
 
102
static void __fifo_ifree_handler(void *buf, void *xstate) /* nklock free */
 
103
{
 
104
        xnfree(buf);
 
105
}
 
106
 
 
107
static void __fifo_ofree_handler(void *buf, void *xstate) /* nklock free except when resizing */
 
108
{
 
109
        RT_FIFO *fifo = xstate;
 
110
        spl_t s;
 
111
 
 
112
        xnlock_get_irqsave(&nklock, s);
99
113
        fifo->fillsz = 0;
100
114
        __clear_bit(RTFIFO_SYNCWAIT, &fifo->status);
101
 
 
102
 
        if (retval >= 0 &&
103
 
            fifo->handler != NULL &&
104
 
            (err = X_FIFO_HANDLER2(fifo->handler) (minor, 'r') < 0))
105
 
                retval = err;
106
 
 
107
 
        return retval;
 
115
        xnlock_put_irqrestore(&nklock, s);
 
116
}
 
117
 
 
118
static void __fifo_release_handler(void *xstate) /* nklock free */
 
119
{
 
120
        RT_FIFO *fifo = xstate;
 
121
        void *buffer;
 
122
        int size;
 
123
        spl_t s;
 
124
 
 
125
        xnlock_get_irqsave(&nklock, s); /* Protect against resizes. */
 
126
        buffer = fifo->buffer;
 
127
        size = fifo->bufsz;
 
128
        fifo->buffer = NULL;
 
129
        xnlock_put_irqrestore(&nklock, s);
 
130
 
 
131
        if (buffer)
 
132
                xnarch_free_host_mem(buffer, size + sizeof(xnpipe_mh_t));
108
133
}
109
134
 
110
135
int __rtai_fifo_pkg_init(void)
123
148
 
124
149
int rtf_create(unsigned minor, int size)
125
150
{
 
151
        struct xnpipe_operations ops;
126
152
        int err, oldsize;
127
153
        RT_FIFO *fifo;
128
154
        void *buffer;
143
169
                return -EINVAL;
144
170
 
145
171
        fifo = __fifo_table + minor;
146
 
 
147
 
        err = xnpipe_connect(minor,
148
 
                             &__fifo_output_handler,
149
 
                             &__fifo_exec_handler, NULL, fifo);
150
 
 
 
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;
 
177
        /* Use defaults: */
 
178
        ops.alloc_ibuf = NULL;  /* i.e. xnmalloc() */
 
179
 
 
180
        err = xnpipe_connect(minor, &ops, fifo);
151
181
        if (err < 0 && err != -EBUSY)
152
182
                return err;
153
183
 
159
189
                /* Resize the fifo on-the-fly if the specified buffer
160
190
                   size is different from the current one. */
161
191
 
 
192
                /*
 
193
                 * Make sure the streaming buffer is not enqueued for
 
194
                 * output.
 
195
                 */
 
196
                xnpipe_flush(minor, XNPIPE_OFLUSH);
 
197
 
162
198
                buffer = fifo->buffer;
163
199
                oldsize = fifo->bufsz;
164
200
 
181
217
 
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);
185
220
 
186
221
        if (buffer == NULL) {
187
222
                if (err >= 0)
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);
193
 
 
 
224
                xnlock_get_irqsave(&nklock, s);
194
225
                --fifo->refcnt;
195
226
                err = -ENOMEM;
196
227
                goto fail;
197
228
        }
198
229
 
 
230
        xnlock_get_irqsave(&nklock, s);
 
231
 
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);
264
296
 
265
297
                        return 0;
266
298
                }