This source file includes following definitions.
- drain_midi_queue
- midi_input_intr
- midi_output_intr
- midi_poll
- MIDIbuf_open
- MIDIbuf_release
- MIDIbuf_write
- MIDIbuf_read
- MIDIbuf_ioctl
- MIDIbuf_select
- MIDIbuf_init
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30 #include "sound_config.h"
31
32 #if defined(CONFIGURE_SOUNDCARD) && !defined(EXCLUDE_MIDI)
33
34
35
36
37
38 #define MAX_QUEUE_SIZE 4000
39
40 static struct wait_queue *midi_sleeper[MAX_MIDI_DEV] =
41 {NULL};
42 static volatile struct snd_wait midi_sleep_flag[MAX_MIDI_DEV] =
43 {
44 {0}};
45 static struct wait_queue *input_sleeper[MAX_MIDI_DEV] =
46 {NULL};
47 static volatile struct snd_wait input_sleep_flag[MAX_MIDI_DEV] =
48 {
49 {0}};
50
51 struct midi_buf
52 {
53 int len, head, tail;
54 unsigned char queue[MAX_QUEUE_SIZE];
55 };
56
57 struct midi_parms
58 {
59 int prech_timeout;
60
61
62 };
63
64 static struct midi_buf *midi_out_buf[MAX_MIDI_DEV] =
65 {NULL};
66 static struct midi_buf *midi_in_buf[MAX_MIDI_DEV] =
67 {NULL};
68 static struct midi_parms parms[MAX_MIDI_DEV];
69
70 static void midi_poll (unsigned long dummy);
71
72
73 static struct timer_list poll_timer =
74 {NULL, NULL, 0, 0, midi_poll};
75 static volatile int open_devs = 0;
76
77 #define DATA_AVAIL(q) (q->len)
78 #define SPACE_AVAIL(q) (MAX_QUEUE_SIZE - q->len)
79
80 #define QUEUE_BYTE(q, data) \
81 if (SPACE_AVAIL(q)) \
82 { \
83 unsigned long flags; \
84 save_flags(flags);cli(); \
85 q->queue[q->tail] = (data); \
86 q->len++; q->tail = (q->tail+1) % MAX_QUEUE_SIZE; \
87 restore_flags(flags); \
88 }
89
90 #define REMOVE_BYTE(q, data) \
91 if (DATA_AVAIL(q)) \
92 { \
93 unsigned long flags; \
94 save_flags(flags);cli(); \
95 data = q->queue[q->head]; \
96 q->len--; q->head = (q->head+1) % MAX_QUEUE_SIZE; \
97 restore_flags(flags); \
98 }
99
100 void
101 drain_midi_queue (int dev)
102 {
103
104
105
106
107
108 if (midi_devs[dev]->buffer_status != NULL)
109 while (!((current->signal & ~current->blocked)) &&
110 midi_devs[dev]->buffer_status (dev))
111
112 {
113 unsigned long tl;
114
115 if (HZ / 10)
116 tl = current->timeout = jiffies + (HZ / 10);
117 else
118 tl = 0xffffffff;
119 midi_sleep_flag[dev].mode = WK_SLEEP;
120 interruptible_sleep_on (&midi_sleeper[dev]);
121 if (!(midi_sleep_flag[dev].mode & WK_WAKEUP))
122 {
123 if (current->signal & ~current->blocked)
124 midi_sleep_flag[dev].aborting = 1;
125 else if (jiffies >= tl)
126 midi_sleep_flag[dev].mode |= WK_TIMEOUT;
127 }
128 midi_sleep_flag[dev].mode &= ~WK_SLEEP;
129 };
130 }
131
132 static void
133 midi_input_intr (int dev, unsigned char data)
134 {
135 if (midi_in_buf[dev] == NULL)
136 return;
137
138 if (data == 0xfe)
139
140
141 return;
142
143
144
145 if (SPACE_AVAIL (midi_in_buf[dev]))
146 {
147 QUEUE_BYTE (midi_in_buf[dev], data);
148 if ((input_sleep_flag[dev].mode & WK_SLEEP))
149 {
150 input_sleep_flag[dev].mode = WK_WAKEUP;
151 wake_up (&input_sleeper[dev]);
152 };
153 }
154
155 }
156
157 static void
158 midi_output_intr (int dev)
159 {
160
161
162
163 }
164
165 static void
166 midi_poll (unsigned long dummy)
167 {
168 unsigned long flags;
169 int dev;
170
171 save_flags (flags);
172 cli ();
173 if (open_devs)
174 {
175 for (dev = 0; dev < num_midis; dev++)
176 if (midi_out_buf[dev] != NULL)
177 {
178 while (DATA_AVAIL (midi_out_buf[dev]) &&
179 midi_devs[dev]->putc (dev,
180 midi_out_buf[dev]->queue[midi_out_buf[dev]->head]))
181 {
182 midi_out_buf[dev]->head = (midi_out_buf[dev]->head + 1) % MAX_QUEUE_SIZE;
183 midi_out_buf[dev]->len--;
184 }
185
186 if (DATA_AVAIL (midi_out_buf[dev]) < 100 &&
187 (midi_sleep_flag[dev].mode & WK_SLEEP))
188 {
189 midi_sleep_flag[dev].mode = WK_WAKEUP;
190 wake_up (&midi_sleeper[dev]);
191 };
192 }
193
194 {
195 poll_timer.expires = (1) + jiffies;
196 add_timer (&poll_timer);
197 };
198
199
200 }
201 restore_flags (flags);
202 }
203
204 int
205 MIDIbuf_open (int dev, struct fileinfo *file)
206 {
207 int mode, err;
208 unsigned long flags;
209
210 dev = dev >> 4;
211 mode = file->mode & O_ACCMODE;
212
213 if (num_midis > MAX_MIDI_DEV)
214 {
215 printk ("Sound: FATAL ERROR: Too many midi interfaces\n");
216 num_midis = MAX_MIDI_DEV;
217 }
218
219 if (dev < 0 || dev >= num_midis)
220 {
221 printk ("Sound: Nonexistent MIDI interface %d\n", dev);
222 return -ENXIO;
223 }
224
225
226
227
228
229 save_flags (flags);
230 cli ();
231 if ((err = midi_devs[dev]->open (dev, mode,
232 midi_input_intr, midi_output_intr)) < 0)
233 {
234 restore_flags (flags);
235 return err;
236 }
237
238 parms[dev].prech_timeout = 0;
239
240 {
241 midi_sleep_flag[dev].aborting = 0;
242 midi_sleep_flag[dev].mode = WK_NONE;
243 };
244 {
245 input_sleep_flag[dev].aborting = 0;
246 input_sleep_flag[dev].mode = WK_NONE;
247 };
248
249 midi_in_buf[dev] = (struct midi_buf *) kmalloc (sizeof (struct midi_buf), GFP_KERNEL);
250
251 if (midi_in_buf[dev] == NULL)
252 {
253 printk ("midi: Can't allocate buffer\n");
254 midi_devs[dev]->close (dev);
255 restore_flags (flags);
256 return -EIO;
257 }
258 midi_in_buf[dev]->len = midi_in_buf[dev]->head = midi_in_buf[dev]->tail = 0;
259
260 midi_out_buf[dev] = (struct midi_buf *) kmalloc (sizeof (struct midi_buf), GFP_KERNEL);
261
262 if (midi_out_buf[dev] == NULL)
263 {
264 printk ("midi: Can't allocate buffer\n");
265 midi_devs[dev]->close (dev);
266 kfree (midi_in_buf[dev]);
267 midi_in_buf[dev] = NULL;
268 restore_flags (flags);
269 return -EIO;
270 }
271 midi_out_buf[dev]->len = midi_out_buf[dev]->head = midi_out_buf[dev]->tail = 0;
272 if (!open_devs)
273
274 {
275 poll_timer.expires = (1) + jiffies;
276 add_timer (&poll_timer);
277 };
278
279
280 open_devs++;
281 restore_flags (flags);
282
283 return err;
284 }
285
286 void
287 MIDIbuf_release (int dev, struct fileinfo *file)
288 {
289 int mode;
290 unsigned long flags;
291
292 dev = dev >> 4;
293 mode = file->mode & O_ACCMODE;
294
295 save_flags (flags);
296 cli ();
297
298
299
300
301
302 if (mode != OPEN_READ)
303 {
304 midi_devs[dev]->putc (dev, 0xfe);
305
306
307
308
309 while (!((current->signal & ~current->blocked)) &&
310 DATA_AVAIL (midi_out_buf[dev]))
311
312 {
313 unsigned long tl;
314
315 if (0)
316 tl = current->timeout = jiffies + (0);
317 else
318 tl = 0xffffffff;
319 midi_sleep_flag[dev].mode = WK_SLEEP;
320 interruptible_sleep_on (&midi_sleeper[dev]);
321 if (!(midi_sleep_flag[dev].mode & WK_WAKEUP))
322 {
323 if (current->signal & ~current->blocked)
324 midi_sleep_flag[dev].aborting = 1;
325 else if (jiffies >= tl)
326 midi_sleep_flag[dev].mode |= WK_TIMEOUT;
327 }
328 midi_sleep_flag[dev].mode &= ~WK_SLEEP;
329 };
330
331
332
333 drain_midi_queue (dev);
334
335
336 }
337
338 midi_devs[dev]->close (dev);
339 kfree (midi_in_buf[dev]);
340 kfree (midi_out_buf[dev]);
341 midi_in_buf[dev] = NULL;
342 midi_out_buf[dev] = NULL;
343 open_devs--;
344 del_timer (&poll_timer);;
345 restore_flags (flags);
346 }
347
348 int
349 MIDIbuf_write (int dev, struct fileinfo *file, const snd_rw_buf * buf, int count)
350 {
351 unsigned long flags;
352 int c, n, i;
353 unsigned char tmp_data;
354
355 dev = dev >> 4;
356
357 if (!count)
358 return 0;
359
360 save_flags (flags);
361 cli ();
362
363 c = 0;
364
365 while (c < count)
366 {
367 n = SPACE_AVAIL (midi_out_buf[dev]);
368
369 if (n == 0)
370
371
372 {
373
374 {
375 unsigned long tl;
376
377 if (0)
378 tl = current->timeout = jiffies + (0);
379 else
380 tl = 0xffffffff;
381 midi_sleep_flag[dev].mode = WK_SLEEP;
382 interruptible_sleep_on (&midi_sleeper[dev]);
383 if (!(midi_sleep_flag[dev].mode & WK_WAKEUP))
384 {
385 if (current->signal & ~current->blocked)
386 midi_sleep_flag[dev].aborting = 1;
387 else if (jiffies >= tl)
388 midi_sleep_flag[dev].mode |= WK_TIMEOUT;
389 }
390 midi_sleep_flag[dev].mode &= ~WK_SLEEP;
391 };
392 if (((current->signal & ~current->blocked)))
393 {
394 restore_flags (flags);
395 return -EINTR;
396 }
397
398 n = SPACE_AVAIL (midi_out_buf[dev]);
399 }
400
401 if (n > (count - c))
402 n = count - c;
403
404 for (i = 0; i < n; i++)
405 {
406 memcpy_fromfs (&tmp_data, &((buf)[c]), 1);
407 QUEUE_BYTE (midi_out_buf[dev], tmp_data);
408 c++;
409 }
410 }
411
412 restore_flags (flags);
413
414 return c;
415 }
416
417
418 int
419 MIDIbuf_read (int dev, struct fileinfo *file, snd_rw_buf * buf, int count)
420 {
421 int n, c = 0;
422 unsigned long flags;
423 unsigned char tmp_data;
424
425 dev = dev >> 4;
426
427 save_flags (flags);
428 cli ();
429
430 if (!DATA_AVAIL (midi_in_buf[dev]))
431
432
433 {
434
435 {
436 unsigned long tl;
437
438 if (parms[dev].prech_timeout)
439 tl = current->timeout = jiffies + (parms[dev].prech_timeout);
440 else
441 tl = 0xffffffff;
442 input_sleep_flag[dev].mode = WK_SLEEP;
443 interruptible_sleep_on (&input_sleeper[dev]);
444 if (!(input_sleep_flag[dev].mode & WK_WAKEUP))
445 {
446 if (current->signal & ~current->blocked)
447 input_sleep_flag[dev].aborting = 1;
448 else if (jiffies >= tl)
449 input_sleep_flag[dev].mode |= WK_TIMEOUT;
450 }
451 input_sleep_flag[dev].mode &= ~WK_SLEEP;
452 };
453 if (((current->signal & ~current->blocked)))
454 c = -EINTR;
455
456
457 }
458
459 if (c == 0 && DATA_AVAIL (midi_in_buf[dev]))
460
461
462 {
463 n = DATA_AVAIL (midi_in_buf[dev]);
464 if (n > count)
465 n = count;
466 c = 0;
467
468 while (c < n)
469 {
470 REMOVE_BYTE (midi_in_buf[dev], tmp_data);
471 memcpy_tofs (&((buf)[c]), &tmp_data, 1);
472 c++;
473 }
474 }
475
476 restore_flags (flags);
477
478 return c;
479 }
480
481 int
482 MIDIbuf_ioctl (int dev, struct fileinfo *file,
483 unsigned int cmd, ioctl_arg arg)
484 {
485 int val;
486
487 dev = dev >> 4;
488
489 if (((cmd >> 8) & 0xff) == 'C')
490 {
491 if (midi_devs[dev]->coproc)
492 return midi_devs[dev]->coproc->ioctl (midi_devs[dev]->coproc->devc, cmd, arg, 0);
493 else
494 printk ("/dev/midi%d: No coprocessor for this device\n", dev);
495
496 return -ENXIO;
497 }
498 else
499 switch (cmd)
500 {
501
502 case SNDCTL_MIDI_PRETIME:
503 val = (int) get_fs_long ((long *) arg);
504 if (val < 0)
505 val = 0;
506
507 val = (HZ * val) / 10;
508 parms[dev].prech_timeout = val;
509 return snd_ioctl_return ((int *) arg, val);
510 break;
511
512 default:
513 return midi_devs[dev]->ioctl (dev, cmd, arg);
514 }
515 }
516
517 int
518 MIDIbuf_select (int dev, struct fileinfo *file, int sel_type, select_table * wait)
519 {
520 dev = dev >> 4;
521
522 switch (sel_type)
523 {
524 case SEL_IN:
525 if (!DATA_AVAIL (midi_in_buf[dev]))
526 {
527 input_sleep_flag[dev].mode = WK_SLEEP;
528 select_wait (&input_sleeper[dev], wait);
529 return 0;
530 }
531 return 1;
532 break;
533
534 case SEL_OUT:
535 if (SPACE_AVAIL (midi_out_buf[dev]))
536 {
537 midi_sleep_flag[dev].mode = WK_SLEEP;
538 select_wait (&midi_sleeper[dev], wait);
539 return 0;
540 }
541 return 1;
542 break;
543
544 case SEL_EX:
545 return 0;
546 }
547
548 return 0;
549 }
550
551
552 long
553 MIDIbuf_init (long mem_start)
554 {
555 return mem_start;
556 }
557
558 #endif