4 * Device file manager for /dev/midi#
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
14 * Thomas Sailer : ioctl code reworked (vmalloc/vfree removed)
16 #include <linux/stddef.h>
17 #include <linux/kmod.h>
18 #include <linux/spinlock.h>
21 #include "sound_config.h"
25 * Don't make MAX_QUEUE_SIZE larger than 4000
28 #define MAX_QUEUE_SIZE 4000
30 static wait_queue_head_t midi_sleeper[MAX_MIDI_DEV];
31 static wait_queue_head_t input_sleeper[MAX_MIDI_DEV];
36 unsigned char queue[MAX_QUEUE_SIZE];
41 long prech_timeout; /*
42 * Timeout before the first ch
46 static struct midi_buf *midi_out_buf[MAX_MIDI_DEV] = {NULL};
47 static struct midi_buf *midi_in_buf[MAX_MIDI_DEV] = {NULL};
48 static struct midi_parms parms[MAX_MIDI_DEV];
50 static void midi_poll(unsigned long dummy);
53 static DEFINE_TIMER(poll_timer, midi_poll, 0, 0);
55 static volatile int open_devs;
56 static DEFINE_SPINLOCK(lock);
58 #define DATA_AVAIL(q) (q->len)
59 #define SPACE_AVAIL(q) (MAX_QUEUE_SIZE - q->len)
61 #define QUEUE_BYTE(q, data) \
64 unsigned long flags; \
65 spin_lock_irqsave(&lock, flags); \
66 q->queue[q->tail] = (data); \
67 q->len++; q->tail = (q->tail+1) % MAX_QUEUE_SIZE; \
68 spin_unlock_irqrestore(&lock, flags); \
71 #define REMOVE_BYTE(q, data) \
74 unsigned long flags; \
75 spin_lock_irqsave(&lock, flags); \
76 data = q->queue[q->head]; \
77 q->len--; q->head = (q->head+1) % MAX_QUEUE_SIZE; \
78 spin_unlock_irqrestore(&lock, flags); \
81 static void drain_midi_queue(int dev)
85 * Give the Midi driver time to drain its output queues
88 if (midi_devs[dev]->buffer_status != NULL)
89 wait_event_interruptible_timeout(midi_sleeper[dev],
90 !midi_devs[dev]->buffer_status(dev), HZ/10);
93 static void midi_input_intr(int dev, unsigned char data)
95 if (midi_in_buf[dev] == NULL)
105 if (SPACE_AVAIL(midi_in_buf[dev])) {
106 QUEUE_BYTE(midi_in_buf[dev], data);
107 wake_up(&input_sleeper[dev]);
111 static void midi_output_intr(int dev)
118 static void midi_poll(unsigned long dummy)
123 spin_lock_irqsave(&lock, flags);
126 for (dev = 0; dev < num_midis; dev++)
127 if (midi_devs[dev] != NULL && midi_out_buf[dev] != NULL)
129 while (DATA_AVAIL(midi_out_buf[dev]))
132 int c = midi_out_buf[dev]->queue[midi_out_buf[dev]->head];
134 spin_unlock_irqrestore(&lock,flags);/* Give some time to others */
135 ok = midi_devs[dev]->outputc(dev, c);
136 spin_lock_irqsave(&lock, flags);
139 midi_out_buf[dev]->head = (midi_out_buf[dev]->head + 1) % MAX_QUEUE_SIZE;
140 midi_out_buf[dev]->len--;
143 if (DATA_AVAIL(midi_out_buf[dev]) < 100)
144 wake_up(&midi_sleeper[dev]);
146 poll_timer.expires = (1) + jiffies;
147 add_timer(&poll_timer);
152 spin_unlock_irqrestore(&lock, flags);
155 int MIDIbuf_open(int dev, struct file *file)
160 mode = translate_mode(file);
162 if (num_midis > MAX_MIDI_DEV)
164 printk(KERN_ERR "midi: Too many midi interfaces\n");
165 num_midis = MAX_MIDI_DEV;
167 if (dev < 0 || dev >= num_midis || midi_devs[dev] == NULL)
170 * Interrupts disabled. Be careful
173 module_put(midi_devs[dev]->owner);
175 if ((err = midi_devs[dev]->open(dev, mode,
176 midi_input_intr, midi_output_intr)) < 0)
179 parms[dev].prech_timeout = MAX_SCHEDULE_TIMEOUT;
180 midi_in_buf[dev] = vmalloc(sizeof(struct midi_buf));
182 if (midi_in_buf[dev] == NULL)
184 printk(KERN_WARNING "midi: Can't allocate buffer\n");
185 midi_devs[dev]->close(dev);
188 midi_in_buf[dev]->len = midi_in_buf[dev]->head = midi_in_buf[dev]->tail = 0;
190 midi_out_buf[dev] = vmalloc(sizeof(struct midi_buf));
192 if (midi_out_buf[dev] == NULL)
194 printk(KERN_WARNING "midi: Can't allocate buffer\n");
195 midi_devs[dev]->close(dev);
196 vfree(midi_in_buf[dev]);
197 midi_in_buf[dev] = NULL;
200 midi_out_buf[dev]->len = midi_out_buf[dev]->head = midi_out_buf[dev]->tail = 0;
203 init_waitqueue_head(&midi_sleeper[dev]);
204 init_waitqueue_head(&input_sleeper[dev]);
206 if (open_devs < 2) /* This was first open */
208 poll_timer.expires = 1 + jiffies;
209 add_timer(&poll_timer); /* Start polling */
214 void MIDIbuf_release(int dev, struct file *file)
219 mode = translate_mode(file);
221 if (dev < 0 || dev >= num_midis || midi_devs[dev] == NULL)
225 * Wait until the queue is empty
228 if (mode != OPEN_READ)
230 midi_devs[dev]->outputc(dev, 0xfe); /*
231 * Active sensing to shut the
235 wait_event_interruptible(midi_sleeper[dev],
236 !DATA_AVAIL(midi_out_buf[dev]));
241 drain_midi_queue(dev); /*
242 * Ensure the output queues are empty
246 midi_devs[dev]->close(dev);
250 del_timer_sync(&poll_timer);
251 vfree(midi_in_buf[dev]);
252 vfree(midi_out_buf[dev]);
253 midi_in_buf[dev] = NULL;
254 midi_out_buf[dev] = NULL;
256 module_put(midi_devs[dev]->owner);
259 int MIDIbuf_write(int dev, struct file *file, const char __user *buf, int count)
262 unsigned char tmp_data;
273 n = SPACE_AVAIL(midi_out_buf[dev]);
279 if (file->f_flags & O_NONBLOCK) {
284 if (wait_event_interruptible(midi_sleeper[dev],
285 SPACE_AVAIL(midi_out_buf[dev])))
290 n = SPACE_AVAIL(midi_out_buf[dev]);
295 for (i = 0; i < n; i++)
297 /* BROKE BROKE BROKE - CAN'T DO THIS WITH CLI !! */
298 /* yes, think the same, so I removed the cli() brackets
299 QUEUE_BYTE is protected against interrupts */
300 if (copy_from_user((char *) &tmp_data, &(buf)[c], 1)) {
304 QUEUE_BYTE(midi_out_buf[dev], tmp_data);
313 int MIDIbuf_read(int dev, struct file *file, char __user *buf, int count)
316 unsigned char tmp_data;
320 if (!DATA_AVAIL(midi_in_buf[dev])) { /*
323 if (file->f_flags & O_NONBLOCK) {
327 wait_event_interruptible_timeout(input_sleeper[dev],
328 DATA_AVAIL(midi_in_buf[dev]),
329 parms[dev].prech_timeout);
331 if (signal_pending(current))
332 c = -EINTR; /* The user is getting restless */
334 if (c == 0 && DATA_AVAIL(midi_in_buf[dev])) /*
338 n = DATA_AVAIL(midi_in_buf[dev]);
346 REMOVE_BYTE(midi_in_buf[dev], tmp_data);
347 fixit = (char *) &tmp_data;
348 /* BROKE BROKE BROKE */
349 /* yes removed the cli() brackets again
350 should q->len,tail&head be atomic_t? */
351 if (copy_to_user(&(buf)[c], fixit, 1)) {
362 int MIDIbuf_ioctl(int dev, struct file *file,
363 unsigned int cmd, void __user *arg)
369 if (((cmd >> 8) & 0xff) == 'C')
371 if (midi_devs[dev]->coproc) /* Coprocessor ioctl */
372 return midi_devs[dev]->coproc->ioctl(midi_devs[dev]->coproc->devc, cmd, arg, 0);
373 /* printk("/dev/midi%d: No coprocessor for this device\n", dev);*/
380 case SNDCTL_MIDI_PRETIME:
381 if (get_user(val, (int __user *)arg))
385 val = (HZ * val) / 10;
386 parms[dev].prech_timeout = val;
387 return put_user(val, (int __user *)arg);
390 if (!midi_devs[dev]->ioctl)
392 return midi_devs[dev]->ioctl(dev, cmd, arg);
397 /* No kernel lock - fine */
398 unsigned int MIDIbuf_poll(int dev, struct file *file, poll_table * wait)
400 unsigned int mask = 0;
405 poll_wait(file, &input_sleeper[dev], wait);
406 if (DATA_AVAIL(midi_in_buf[dev]))
407 mask |= POLLIN | POLLRDNORM;
410 poll_wait(file, &midi_sleeper[dev], wait);
411 if (!SPACE_AVAIL(midi_out_buf[dev]))
412 mask |= POLLOUT | POLLWRNORM;
418 int MIDIbuf_avail(int dev)
420 if (midi_in_buf[dev])
421 return DATA_AVAIL (midi_in_buf[dev]);
424 EXPORT_SYMBOL(MIDIbuf_avail);