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 *) (
250 {
251 caddr_t x;
252 x = kmalloc (sizeof (struct midi_buf), GFP_KERNEL);
253
254 x;
255 }
256 );
257
258 if (midi_in_buf[dev] == NULL)
259 {
260 printk ("midi: Can't allocate buffer\n");
261 midi_devs[dev]->close (dev);
262 restore_flags (flags);
263 return -EIO;
264 }
265 midi_in_buf[dev]->len = midi_in_buf[dev]->head = midi_in_buf[dev]->tail = 0;
266
267 midi_out_buf[dev] = (struct midi_buf *) (
268 {
269 caddr_t x;
270 x = kmalloc (sizeof (struct midi_buf), GFP_KERNEL);
271
272 x;
273 }
274 );
275
276 if (midi_out_buf[dev] == NULL)
277 {
278 printk ("midi: Can't allocate buffer\n");
279 midi_devs[dev]->close (dev);
280 kfree (midi_in_buf[dev]);
281 midi_in_buf[dev] = NULL;
282 restore_flags (flags);
283 return -EIO;
284 }
285 midi_out_buf[dev]->len = midi_out_buf[dev]->head = midi_out_buf[dev]->tail = 0;
286 if (!open_devs)
287
288 {
289 poll_timer.expires = (1) + jiffies;
290 add_timer (&poll_timer);
291 };
292
293
294 open_devs++;
295 restore_flags (flags);
296
297 return err;
298 }
299
300 void
301 MIDIbuf_release (int dev, struct fileinfo *file)
302 {
303 int mode;
304 unsigned long flags;
305
306 dev = dev >> 4;
307 mode = file->mode & O_ACCMODE;
308
309 save_flags (flags);
310 cli ();
311
312
313
314
315
316 if (mode != OPEN_READ)
317 {
318 midi_devs[dev]->putc (dev, 0xfe);
319
320
321
322
323 while (!((current->signal & ~current->blocked)) &&
324 DATA_AVAIL (midi_out_buf[dev]))
325
326 {
327 unsigned long tl;
328
329 if (0)
330 tl = current->timeout = jiffies + (0);
331 else
332 tl = 0xffffffff;
333 midi_sleep_flag[dev].mode = WK_SLEEP;
334 interruptible_sleep_on (&midi_sleeper[dev]);
335 if (!(midi_sleep_flag[dev].mode & WK_WAKEUP))
336 {
337 if (current->signal & ~current->blocked)
338 midi_sleep_flag[dev].aborting = 1;
339 else if (jiffies >= tl)
340 midi_sleep_flag[dev].mode |= WK_TIMEOUT;
341 }
342 midi_sleep_flag[dev].mode &= ~WK_SLEEP;
343 };
344
345
346
347 drain_midi_queue (dev);
348
349
350 }
351
352 midi_devs[dev]->close (dev);
353 kfree (midi_in_buf[dev]);
354 kfree (midi_out_buf[dev]);
355 midi_in_buf[dev] = NULL;
356 midi_out_buf[dev] = NULL;
357 open_devs--;
358 del_timer (&poll_timer);;
359 restore_flags (flags);
360 }
361
362 int
363 MIDIbuf_write (int dev, struct fileinfo *file, const snd_rw_buf * buf, int count)
364 {
365 unsigned long flags;
366 int c, n, i;
367 unsigned char tmp_data;
368
369 dev = dev >> 4;
370
371 if (!count)
372 return 0;
373
374 save_flags (flags);
375 cli ();
376
377 c = 0;
378
379 while (c < count)
380 {
381 n = SPACE_AVAIL (midi_out_buf[dev]);
382
383 if (n == 0)
384
385
386 {
387
388 {
389 unsigned long tl;
390
391 if (0)
392 tl = current->timeout = jiffies + (0);
393 else
394 tl = 0xffffffff;
395 midi_sleep_flag[dev].mode = WK_SLEEP;
396 interruptible_sleep_on (&midi_sleeper[dev]);
397 if (!(midi_sleep_flag[dev].mode & WK_WAKEUP))
398 {
399 if (current->signal & ~current->blocked)
400 midi_sleep_flag[dev].aborting = 1;
401 else if (jiffies >= tl)
402 midi_sleep_flag[dev].mode |= WK_TIMEOUT;
403 }
404 midi_sleep_flag[dev].mode &= ~WK_SLEEP;
405 };
406 if (((current->signal & ~current->blocked)))
407 {
408 restore_flags (flags);
409 return -EINTR;
410 }
411
412 n = SPACE_AVAIL (midi_out_buf[dev]);
413 }
414
415 if (n > (count - c))
416 n = count - c;
417
418 for (i = 0; i < n; i++)
419 {
420 memcpy_fromfs ((&tmp_data), &((buf)[c]), (1));
421 QUEUE_BYTE (midi_out_buf[dev], tmp_data);
422 c++;
423 }
424 }
425
426 restore_flags (flags);
427
428 return c;
429 }
430
431
432 int
433 MIDIbuf_read (int dev, struct fileinfo *file, snd_rw_buf * buf, int count)
434 {
435 int n, c = 0;
436 unsigned long flags;
437 unsigned char tmp_data;
438
439 dev = dev >> 4;
440
441 save_flags (flags);
442 cli ();
443
444 if (!DATA_AVAIL (midi_in_buf[dev]))
445
446
447 {
448
449 {
450 unsigned long tl;
451
452 if (parms[dev].prech_timeout)
453 tl = current->timeout = jiffies + (parms[dev].prech_timeout);
454 else
455 tl = 0xffffffff;
456 input_sleep_flag[dev].mode = WK_SLEEP;
457 interruptible_sleep_on (&input_sleeper[dev]);
458 if (!(input_sleep_flag[dev].mode & WK_WAKEUP))
459 {
460 if (current->signal & ~current->blocked)
461 input_sleep_flag[dev].aborting = 1;
462 else if (jiffies >= tl)
463 input_sleep_flag[dev].mode |= WK_TIMEOUT;
464 }
465 input_sleep_flag[dev].mode &= ~WK_SLEEP;
466 };
467 if (((current->signal & ~current->blocked)))
468 c = -EINTR;
469
470
471 }
472
473 if (c == 0 && DATA_AVAIL (midi_in_buf[dev]))
474
475
476 {
477 n = DATA_AVAIL (midi_in_buf[dev]);
478 if (n > count)
479 n = count;
480 c = 0;
481
482 while (c < n)
483 {
484 REMOVE_BYTE (midi_in_buf[dev], tmp_data);
485 memcpy_tofs (&((buf)[c]), (&tmp_data), (1));
486 c++;
487 }
488 }
489
490 restore_flags (flags);
491
492 return c;
493 }
494
495 int
496 MIDIbuf_ioctl (int dev, struct fileinfo *file,
497 unsigned int cmd, ioctl_arg arg)
498 {
499 int val;
500
501 dev = dev >> 4;
502
503 if (((cmd >> 8) & 0xff) == 'C')
504 {
505 if (midi_devs[dev]->coproc)
506 return midi_devs[dev]->coproc->ioctl (midi_devs[dev]->coproc->devc, cmd, arg, 0);
507 else
508 printk ("/dev/midi%d: No coprocessor for this device\n", dev);
509
510 return -ENXIO;
511 }
512 else
513 switch (cmd)
514 {
515
516 case SNDCTL_MIDI_PRETIME:
517 val = (int) get_fs_long ((long *) arg);
518 if (val < 0)
519 val = 0;
520
521 val = (HZ * val) / 10;
522 parms[dev].prech_timeout = val;
523 return snd_ioctl_return ((int *) arg, val);
524 break;
525
526 default:
527 return midi_devs[dev]->ioctl (dev, cmd, arg);
528 }
529 }
530
531 int
532 MIDIbuf_select (int dev, struct fileinfo *file, int sel_type, select_table * wait)
533 {
534 dev = dev >> 4;
535
536 switch (sel_type)
537 {
538 case SEL_IN:
539 if (!DATA_AVAIL (midi_in_buf[dev]))
540 {
541 input_sleep_flag[dev].mode = WK_SLEEP;
542 select_wait (&input_sleeper[dev], wait);
543 return 0;
544 }
545 return 1;
546 break;
547
548 case SEL_OUT:
549 if (SPACE_AVAIL (midi_out_buf[dev]))
550 {
551 midi_sleep_flag[dev].mode = WK_SLEEP;
552 select_wait (&midi_sleeper[dev], wait);
553 return 0;
554 }
555 return 1;
556 break;
557
558 case SEL_EX:
559 return 0;
560 }
561
562 return 0;
563 }
564
565
566 long
567 MIDIbuf_init (long mem_start)
568 {
569 return mem_start;
570 }
571
572 #endif