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