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