Import 2.3.18pre1
[davej-history.git] / drivers / sound / midibuf.c
blob42682175381a6eff85631db2a6a545175cc4097a
1 /*
2 * sound/midibuf.c
4 * Device file manager for /dev/midi#
5 */
6 /*
7 * Copyright (C) by Hannu Savolainen 1993-1997
9 * OSS/Free for Linux is distributed under the GNU GENERAL PUBLIC LICENSE (GPL)
10 * Version 2 (June 1991). See the "COPYING" file distributed with this software
11 * for more info.
14 * Thomas Sailer : ioctl code reworked (vmalloc/vfree removed)
16 #include <linux/config.h>
17 #include <linux/stddef.h>
18 #include <linux/kmod.h>
20 #define MIDIBUF_C
22 #include "sound_config.h"
24 #ifdef CONFIG_MIDI
27 * Don't make MAX_QUEUE_SIZE larger than 4000
30 #define MAX_QUEUE_SIZE 4000
32 static wait_queue_head_t midi_sleeper[MAX_MIDI_DEV];
33 static wait_queue_head_t input_sleeper[MAX_MIDI_DEV];
35 struct midi_buf
37 int len, head, tail;
38 unsigned char queue[MAX_QUEUE_SIZE];
41 struct midi_parms
43 long prech_timeout; /*
44 * Timeout before the first ch
48 static struct midi_buf *midi_out_buf[MAX_MIDI_DEV] = {NULL};
49 static struct midi_buf *midi_in_buf[MAX_MIDI_DEV] = {NULL};
50 static struct midi_parms parms[MAX_MIDI_DEV];
52 static void midi_poll(unsigned long dummy);
55 static struct timer_list poll_timer = {
56 NULL, NULL, 0, 0, midi_poll
59 static volatile int open_devs = 0;
61 #define DATA_AVAIL(q) (q->len)
62 #define SPACE_AVAIL(q) (MAX_QUEUE_SIZE - q->len)
64 #define QUEUE_BYTE(q, data) \
65 if (SPACE_AVAIL(q)) \
66 { \
67 unsigned long flags; \
68 save_flags( flags);cli(); \
69 q->queue[q->tail] = (data); \
70 q->len++; q->tail = (q->tail+1) % MAX_QUEUE_SIZE; \
71 restore_flags(flags); \
74 #define REMOVE_BYTE(q, data) \
75 if (DATA_AVAIL(q)) \
76 { \
77 unsigned long flags; \
78 save_flags( flags);cli(); \
79 data = q->queue[q->head]; \
80 q->len--; q->head = (q->head+1) % MAX_QUEUE_SIZE; \
81 restore_flags(flags); \
84 static void drain_midi_queue(int dev)
88 * Give the Midi driver time to drain its output queues
91 if (midi_devs[dev]->buffer_status != NULL)
92 while (!signal_pending(current) && midi_devs[dev]->buffer_status(dev))
93 interruptible_sleep_on_timeout(&midi_sleeper[dev],
94 HZ/10);
97 static void midi_input_intr(int dev, unsigned char data)
99 if (midi_in_buf[dev] == NULL)
100 return;
102 if (data == 0xfe) /*
103 * Active sensing
105 return; /*
106 * Ignore
109 if (SPACE_AVAIL(midi_in_buf[dev])) {
110 QUEUE_BYTE(midi_in_buf[dev], data);
111 wake_up(&input_sleeper[dev]);
115 static void midi_output_intr(int dev)
118 * Currently NOP
122 static void midi_poll(unsigned long dummy)
124 unsigned long flags;
125 int dev;
127 save_flags(flags);
128 cli();
129 if (open_devs)
131 for (dev = 0; dev < num_midis; dev++)
132 if (midi_devs[dev] != NULL && midi_out_buf[dev] != NULL)
134 int ok = 1;
136 while (DATA_AVAIL(midi_out_buf[dev]) && ok)
138 int c = midi_out_buf[dev]->queue[midi_out_buf[dev]->head];
140 restore_flags(flags); /* Give some time to others */
141 ok = midi_devs[dev]->outputc(dev, c);
142 cli();
143 midi_out_buf[dev]->head = (midi_out_buf[dev]->head + 1) % MAX_QUEUE_SIZE;
144 midi_out_buf[dev]->len--;
147 if (DATA_AVAIL(midi_out_buf[dev]) < 100)
148 wake_up(&midi_sleeper[dev]);
150 poll_timer.expires = (1) + jiffies;
151 add_timer(&poll_timer);
153 * Come back later
156 restore_flags(flags);
159 int MIDIbuf_open(int dev, struct file *file)
161 int mode, err;
163 dev = dev >> 4;
164 mode = translate_mode(file);
166 if (num_midis > MAX_MIDI_DEV)
168 printk(KERN_ERR "midi: Too many midi interfaces\n");
169 num_midis = MAX_MIDI_DEV;
171 if (dev < 0 || dev >= num_midis || midi_devs[dev] == NULL)
172 return -ENXIO;
174 * Interrupts disabled. Be careful
177 if ((err = midi_devs[dev]->open(dev, mode,
178 midi_input_intr, midi_output_intr)) < 0)
179 return err;
181 parms[dev].prech_timeout = MAX_SCHEDULE_TIMEOUT;
182 midi_in_buf[dev] = (struct midi_buf *) vmalloc(sizeof(struct midi_buf));
184 if (midi_in_buf[dev] == NULL)
186 printk(KERN_WARNING "midi: Can't allocate buffer\n");
187 midi_devs[dev]->close(dev);
188 return -EIO;
190 midi_in_buf[dev]->len = midi_in_buf[dev]->head = midi_in_buf[dev]->tail = 0;
192 midi_out_buf[dev] = (struct midi_buf *) vmalloc(sizeof(struct midi_buf));
194 if (midi_out_buf[dev] == NULL)
196 printk(KERN_WARNING "midi: Can't allocate buffer\n");
197 midi_devs[dev]->close(dev);
198 vfree(midi_in_buf[dev]);
199 midi_in_buf[dev] = NULL;
200 return -EIO;
202 midi_out_buf[dev]->len = midi_out_buf[dev]->head = midi_out_buf[dev]->tail = 0;
203 open_devs++;
205 init_waitqueue_head(&midi_sleeper[dev]);
206 init_waitqueue_head(&input_sleeper[dev]);
208 if (open_devs < 2) /* This was first open */
210 poll_timer.expires = 1 + jiffies;
211 add_timer(&poll_timer); /* Start polling */
213 return err;
216 void MIDIbuf_release(int dev, struct file *file)
218 int mode;
219 unsigned long flags;
221 dev = dev >> 4;
222 mode = translate_mode(file);
224 if (dev < 0 || dev >= num_midis || midi_devs[dev] == NULL)
225 return;
227 save_flags(flags);
228 cli();
231 * Wait until the queue is empty
234 if (mode != OPEN_READ)
236 midi_devs[dev]->outputc(dev, 0xfe); /*
237 * Active sensing to shut the
238 * devices
241 while (!signal_pending(current) && DATA_AVAIL(midi_out_buf[dev]))
242 interruptible_sleep_on(&midi_sleeper[dev]);
244 * Sync
247 drain_midi_queue(dev); /*
248 * Ensure the output queues are empty
251 restore_flags(flags);
253 midi_devs[dev]->close(dev);
255 vfree(midi_in_buf[dev]);
256 vfree(midi_out_buf[dev]);
257 midi_in_buf[dev] = NULL;
258 midi_out_buf[dev] = NULL;
259 if (open_devs < 2)
260 del_timer(&poll_timer);;
261 open_devs--;
264 int MIDIbuf_write(int dev, struct file *file, const char *buf, int count)
266 unsigned long flags;
267 int c, n, i;
268 unsigned char tmp_data;
270 dev = dev >> 4;
272 if (!count)
273 return 0;
275 save_flags(flags);
276 cli();
278 c = 0;
280 while (c < count)
282 n = SPACE_AVAIL(midi_out_buf[dev]);
284 if (n == 0) { /*
285 * No space just now.
288 if (file->f_flags & O_NONBLOCK) {
289 restore_flags(flags);
290 return -EAGAIN;
293 interruptible_sleep_on(&midi_sleeper[dev]);
294 if (signal_pending(current))
296 restore_flags(flags);
297 return -EINTR;
299 n = SPACE_AVAIL(midi_out_buf[dev]);
301 if (n > (count - c))
302 n = count - c;
304 for (i = 0; i < n; i++)
306 /* BROKE BROKE BROKE - CANT DO THIS WITH CLI !! */
307 copy_from_user((char *) &tmp_data, &(buf)[c], 1);
308 QUEUE_BYTE(midi_out_buf[dev], tmp_data);
309 c++;
312 restore_flags(flags);
313 return c;
317 int MIDIbuf_read(int dev, struct file *file, char *buf, int count)
319 int n, c = 0;
320 unsigned long flags;
321 unsigned char tmp_data;
323 dev = dev >> 4;
325 save_flags(flags);
326 cli();
328 if (!DATA_AVAIL(midi_in_buf[dev])) { /*
329 * No data yet, wait
331 if (file->f_flags & O_NONBLOCK) {
332 restore_flags(flags);
333 return -EAGAIN;
335 interruptible_sleep_on_timeout(&input_sleeper[dev],
336 parms[dev].prech_timeout);
338 if (signal_pending(current))
339 c = -EINTR; /* The user is getting restless */
341 if (c == 0 && DATA_AVAIL(midi_in_buf[dev])) /*
342 * Got some bytes
345 n = DATA_AVAIL(midi_in_buf[dev]);
346 if (n > count)
347 n = count;
348 c = 0;
350 while (c < n)
352 char *fixit;
353 REMOVE_BYTE(midi_in_buf[dev], tmp_data);
354 fixit = (char *) &tmp_data;
355 /* BROKE BROKE BROKE */
356 copy_to_user(&(buf)[c], fixit, 1);
357 c++;
360 restore_flags(flags);
361 return c;
364 int MIDIbuf_ioctl(int dev, struct file *file,
365 unsigned int cmd, caddr_t arg)
367 int val;
369 dev = dev >> 4;
371 if (((cmd >> 8) & 0xff) == 'C')
373 if (midi_devs[dev]->coproc) /* Coprocessor ioctl */
374 return midi_devs[dev]->coproc->ioctl(midi_devs[dev]->coproc->devc, cmd, arg, 0);
375 /* printk("/dev/midi%d: No coprocessor for this device\n", dev);*/
376 return -ENXIO;
378 else
380 switch (cmd)
382 case SNDCTL_MIDI_PRETIME:
383 if (get_user(val, (int *)arg))
384 return -EFAULT;
385 if (val < 0)
386 val = 0;
387 val = (HZ * val) / 10;
388 parms[dev].prech_timeout = val;
389 return put_user(val, (int *)arg);
391 default:
392 if (!midi_devs[dev]->ioctl)
393 return -EINVAL;
394 return midi_devs[dev]->ioctl(dev, cmd, arg);
399 unsigned int MIDIbuf_poll(int dev, struct file *file, poll_table * wait)
401 unsigned int mask = 0;
403 dev = dev >> 4;
405 /* input */
406 poll_wait(file, &input_sleeper[dev], wait);
407 if (DATA_AVAIL(midi_in_buf[dev]))
408 mask |= POLLIN | POLLRDNORM;
410 /* output */
411 poll_wait(file, &midi_sleeper[dev], wait);
412 if (!SPACE_AVAIL(midi_out_buf[dev]))
413 mask |= POLLOUT | POLLWRNORM;
415 return mask;
419 void MIDIbuf_init(void)
421 /* drag in midi_syms.o */
423 extern char midi_syms_symbol;
424 midi_syms_symbol = 0;
428 int MIDIbuf_avail(int dev)
430 if (midi_in_buf[dev])
431 return DATA_AVAIL (midi_in_buf[dev]);
432 return 0;
436 #endif