1 /*
2 * sound/midibuf.c
3 *
4 * Device file manager for /dev/midi#
5 */
6 /*
7 * Copyright (C) by Hannu Savolainen 1993-1997
8 *
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.
12 */
13 /*
14 * Thomas Sailer : ioctl code reworked (vmalloc/vfree removed)
15 */
16 #include <linux/stddef.h>
17 #include <linux/kmod.h>
18
19 #define MIDIBUF_C
20
21 #include "sound_config.h"
22
23
24 /*
25 * Don't make MAX_QUEUE_SIZE larger than 4000
26 */
27
28 #define MAX_QUEUE_SIZE 4000
29
30 static wait_queue_head_t midi_sleeper[MAX_MIDI_DEV];
31 static wait_queue_head_t input_sleeper[MAX_MIDI_DEV];
32
33 struct midi_buf
34 {
35 int len, head, tail;
36 unsigned char queue[MAX_QUEUE_SIZE];
37 };
38
39 struct midi_parms
40 {
41 long prech_timeout; /*
42 * Timeout before the first ch
43 */
44 };
45
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];
49
50 static void midi_poll(unsigned long dummy);
51
52
53 static struct timer_list poll_timer = {
54 function: midi_poll
55 };
56
57 static volatile int open_devs = 0;
58
59 #define DATA_AVAIL(q) (q->len)
60 #define SPACE_AVAIL(q) (MAX_QUEUE_SIZE - q->len)
61
62 #define QUEUE_BYTE(q, data) \
63 if (SPACE_AVAIL(q)) \
64 { \
65 unsigned long flags; \
66 save_flags( flags);cli(); \
67 q->queue[q->tail] = (data); \
68 q->len++; q->tail = (q->tail+1) % MAX_QUEUE_SIZE; \
69 restore_flags(flags); \
70 }
71
72 #define REMOVE_BYTE(q, data) \
73 if (DATA_AVAIL(q)) \
74 { \
75 unsigned long flags; \
76 save_flags( flags);cli(); \
77 data = q->queue[q->head]; \
78 q->len--; q->head = (q->head+1) % MAX_QUEUE_SIZE; \
79 restore_flags(flags); \
80 }
81
drain_midi_queue(int dev)82 static void drain_midi_queue(int dev)
83 {
84
85 /*
86 * Give the Midi driver time to drain its output queues
87 */
88
89 if (midi_devs[dev]->buffer_status != NULL)
90 while (!signal_pending(current) && midi_devs[dev]->buffer_status(dev))
91 interruptible_sleep_on_timeout(&midi_sleeper[dev],
92 HZ/10);
93 }
94
midi_input_intr(int dev,unsigned char data)95 static void midi_input_intr(int dev, unsigned char data)
96 {
97 if (midi_in_buf[dev] == NULL)
98 return;
99
100 if (data == 0xfe) /*
101 * Active sensing
102 */
103 return; /*
104 * Ignore
105 */
106
107 if (SPACE_AVAIL(midi_in_buf[dev])) {
108 QUEUE_BYTE(midi_in_buf[dev], data);
109 wake_up(&input_sleeper[dev]);
110 }
111 }
112
midi_output_intr(int dev)113 static void midi_output_intr(int dev)
114 {
115 /*
116 * Currently NOP
117 */
118 }
119
midi_poll(unsigned long dummy)120 static void midi_poll(unsigned long dummy)
121 {
122 unsigned long flags;
123 int dev;
124
125 save_flags(flags);
126 cli();
127 if (open_devs)
128 {
129 for (dev = 0; dev < num_midis; dev++)
130 if (midi_devs[dev] != NULL && midi_out_buf[dev] != NULL)
131 {
132 while (DATA_AVAIL(midi_out_buf[dev]))
133 {
134 int ok;
135 int c = midi_out_buf[dev]->queue[midi_out_buf[dev]->head];
136
137 restore_flags(flags); /* Give some time to others */
138 ok = midi_devs[dev]->outputc(dev, c);
139 cli();
140 if (!ok)
141 break;
142 midi_out_buf[dev]->head = (midi_out_buf[dev]->head + 1) % MAX_QUEUE_SIZE;
143 midi_out_buf[dev]->len--;
144 }
145
146 if (DATA_AVAIL(midi_out_buf[dev]) < 100)
147 wake_up(&midi_sleeper[dev]);
148 }
149 poll_timer.expires = (1) + jiffies;
150 add_timer(&poll_timer);
151 /*
152 * Come back later
153 */
154 }
155 restore_flags(flags);
156 }
157
MIDIbuf_open(int dev,struct file * file)158 int MIDIbuf_open(int dev, struct file *file)
159 {
160 int mode, err;
161
162 dev = dev >> 4;
163 mode = translate_mode(file);
164
165 if (num_midis > MAX_MIDI_DEV)
166 {
167 printk(KERN_ERR "midi: Too many midi interfaces\n");
168 num_midis = MAX_MIDI_DEV;
169 }
170 if (dev < 0 || dev >= num_midis || midi_devs[dev] == NULL)
171 return -ENXIO;
172 /*
173 * Interrupts disabled. Be careful
174 */
175
176 if (midi_devs[dev]->owner)
177 __MOD_INC_USE_COUNT (midi_devs[dev]->owner);
178
179 if ((err = midi_devs[dev]->open(dev, mode,
180 midi_input_intr, midi_output_intr)) < 0)
181 return err;
182
183 parms[dev].prech_timeout = MAX_SCHEDULE_TIMEOUT;
184 midi_in_buf[dev] = (struct midi_buf *) vmalloc(sizeof(struct midi_buf));
185
186 if (midi_in_buf[dev] == NULL)
187 {
188 printk(KERN_WARNING "midi: Can't allocate buffer\n");
189 midi_devs[dev]->close(dev);
190 return -EIO;
191 }
192 midi_in_buf[dev]->len = midi_in_buf[dev]->head = midi_in_buf[dev]->tail = 0;
193
194 midi_out_buf[dev] = (struct midi_buf *) vmalloc(sizeof(struct midi_buf));
195
196 if (midi_out_buf[dev] == NULL)
197 {
198 printk(KERN_WARNING "midi: Can't allocate buffer\n");
199 midi_devs[dev]->close(dev);
200 vfree(midi_in_buf[dev]);
201 midi_in_buf[dev] = NULL;
202 return -EIO;
203 }
204 midi_out_buf[dev]->len = midi_out_buf[dev]->head = midi_out_buf[dev]->tail = 0;
205 open_devs++;
206
207 init_waitqueue_head(&midi_sleeper[dev]);
208 init_waitqueue_head(&input_sleeper[dev]);
209
210 if (open_devs < 2) /* This was first open */
211 {
212 poll_timer.expires = 1 + jiffies;
213 add_timer(&poll_timer); /* Start polling */
214 }
215 return err;
216 }
217
MIDIbuf_release(int dev,struct file * file)218 void MIDIbuf_release(int dev, struct file *file)
219 {
220 int mode;
221 unsigned long flags;
222
223 dev = dev >> 4;
224 mode = translate_mode(file);
225
226 if (dev < 0 || dev >= num_midis || midi_devs[dev] == NULL)
227 return;
228
229 save_flags(flags);
230 cli();
231
232 /*
233 * Wait until the queue is empty
234 */
235
236 if (mode != OPEN_READ)
237 {
238 midi_devs[dev]->outputc(dev, 0xfe); /*
239 * Active sensing to shut the
240 * devices
241 */
242
243 while (!signal_pending(current) && DATA_AVAIL(midi_out_buf[dev]))
244 interruptible_sleep_on(&midi_sleeper[dev]);
245 /*
246 * Sync
247 */
248
249 drain_midi_queue(dev); /*
250 * Ensure the output queues are empty
251 */
252 }
253 restore_flags(flags);
254
255 midi_devs[dev]->close(dev);
256
257 open_devs--;
258 if (open_devs == 0)
259 del_timer_sync(&poll_timer);
260 vfree(midi_in_buf[dev]);
261 vfree(midi_out_buf[dev]);
262 midi_in_buf[dev] = NULL;
263 midi_out_buf[dev] = NULL;
264
265 if (midi_devs[dev]->owner)
266 __MOD_DEC_USE_COUNT (midi_devs[dev]->owner);
267 }
268
MIDIbuf_write(int dev,struct file * file,const char * buf,int count)269 int MIDIbuf_write(int dev, struct file *file, const char *buf, int count)
270 {
271 unsigned long flags;
272 int c, n, i;
273 unsigned char tmp_data;
274
275 dev = dev >> 4;
276
277 if (!count)
278 return 0;
279
280 save_flags(flags);
281 cli();
282
283 c = 0;
284
285 while (c < count)
286 {
287 n = SPACE_AVAIL(midi_out_buf[dev]);
288
289 if (n == 0) { /*
290 * No space just now.
291 */
292
293 if (file->f_flags & O_NONBLOCK) {
294 restore_flags(flags);
295 return -EAGAIN;
296 }
297
298 interruptible_sleep_on(&midi_sleeper[dev]);
299 if (signal_pending(current))
300 {
301 restore_flags(flags);
302 return -EINTR;
303 }
304 n = SPACE_AVAIL(midi_out_buf[dev]);
305 }
306 if (n > (count - c))
307 n = count - c;
308
309 for (i = 0; i < n; i++)
310 {
311 /* BROKE BROKE BROKE - CANT DO THIS WITH CLI !! */
312 copy_from_user((char *) &tmp_data, &(buf)[c], 1);
313 QUEUE_BYTE(midi_out_buf[dev], tmp_data);
314 c++;
315 }
316 }
317 restore_flags(flags);
318 return c;
319 }
320
321
MIDIbuf_read(int dev,struct file * file,char * buf,int count)322 int MIDIbuf_read(int dev, struct file *file, char *buf, int count)
323 {
324 int n, c = 0;
325 unsigned long flags;
326 unsigned char tmp_data;
327
328 dev = dev >> 4;
329
330 save_flags(flags);
331 cli();
332
333 if (!DATA_AVAIL(midi_in_buf[dev])) { /*
334 * No data yet, wait
335 */
336 if (file->f_flags & O_NONBLOCK) {
337 restore_flags(flags);
338 return -EAGAIN;
339 }
340 interruptible_sleep_on_timeout(&input_sleeper[dev],
341 parms[dev].prech_timeout);
342
343 if (signal_pending(current))
344 c = -EINTR; /* The user is getting restless */
345 }
346 if (c == 0 && DATA_AVAIL(midi_in_buf[dev])) /*
347 * Got some bytes
348 */
349 {
350 n = DATA_AVAIL(midi_in_buf[dev]);
351 if (n > count)
352 n = count;
353 c = 0;
354
355 while (c < n)
356 {
357 char *fixit;
358 REMOVE_BYTE(midi_in_buf[dev], tmp_data);
359 fixit = (char *) &tmp_data;
360 /* BROKE BROKE BROKE */
361 copy_to_user(&(buf)[c], fixit, 1);
362 c++;
363 }
364 }
365 restore_flags(flags);
366 return c;
367 }
368
MIDIbuf_ioctl(int dev,struct file * file,unsigned int cmd,caddr_t arg)369 int MIDIbuf_ioctl(int dev, struct file *file,
370 unsigned int cmd, caddr_t arg)
371 {
372 int val;
373
374 dev = dev >> 4;
375
376 if (((cmd >> 8) & 0xff) == 'C')
377 {
378 if (midi_devs[dev]->coproc) /* Coprocessor ioctl */
379 return midi_devs[dev]->coproc->ioctl(midi_devs[dev]->coproc->devc, cmd, arg, 0);
380 /* printk("/dev/midi%d: No coprocessor for this device\n", dev);*/
381 return -ENXIO;
382 }
383 else
384 {
385 switch (cmd)
386 {
387 case SNDCTL_MIDI_PRETIME:
388 if (get_user(val, (int *)arg))
389 return -EFAULT;
390 if (val < 0)
391 val = 0;
392 val = (HZ * val) / 10;
393 parms[dev].prech_timeout = val;
394 return put_user(val, (int *)arg);
395
396 default:
397 if (!midi_devs[dev]->ioctl)
398 return -EINVAL;
399 return midi_devs[dev]->ioctl(dev, cmd, arg);
400 }
401 }
402 }
403
404 /* No kernel lock - fine */
MIDIbuf_poll(int dev,struct file * file,poll_table * wait)405 unsigned int MIDIbuf_poll(int dev, struct file *file, poll_table * wait)
406 {
407 unsigned int mask = 0;
408
409 dev = dev >> 4;
410
411 /* input */
412 poll_wait(file, &input_sleeper[dev], wait);
413 if (DATA_AVAIL(midi_in_buf[dev]))
414 mask |= POLLIN | POLLRDNORM;
415
416 /* output */
417 poll_wait(file, &midi_sleeper[dev], wait);
418 if (!SPACE_AVAIL(midi_out_buf[dev]))
419 mask |= POLLOUT | POLLWRNORM;
420
421 return mask;
422 }
423
424
MIDIbuf_init(void)425 void MIDIbuf_init(void)
426 {
427 /* drag in midi_syms.o */
428 {
429 extern char midi_syms_symbol;
430 midi_syms_symbol = 0;
431 }
432 }
433
MIDIbuf_avail(int dev)434 int MIDIbuf_avail(int dev)
435 {
436 if (midi_in_buf[dev])
437 return DATA_AVAIL (midi_in_buf[dev]);
438 return 0;
439 }
440