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 DEFINE_WAIT_QUEUES (midi_sleeper[MAX_MIDI_DEV], midi_sleep_flag[MAX_MIDI_DEV]);
41 DEFINE_WAIT_QUEUES (input_sleeper[MAX_MIDI_DEV], input_sleep_flag[MAX_MIDI_DEV]);
42
43 struct midi_buf
44 {
45 int len, head, tail;
46 unsigned char queue[MAX_QUEUE_SIZE];
47 };
48
49 struct midi_parms
50 {
51 int prech_timeout;
52
53
54 };
55
56 static struct midi_buf *midi_out_buf[MAX_MIDI_DEV] =
57 {NULL};
58 static struct midi_buf *midi_in_buf[MAX_MIDI_DEV] =
59 {NULL};
60 static struct midi_parms parms[MAX_MIDI_DEV];
61
62 static void midi_poll (unsigned long dummy);
63
64 DEFINE_TIMER (poll_timer, midi_poll);
65 static volatile int open_devs = 0;
66
67 #define DATA_AVAIL(q) (q->len)
68 #define SPACE_AVAIL(q) (MAX_QUEUE_SIZE - q->len)
69
70 #define QUEUE_BYTE(q, data) \
71 if (SPACE_AVAIL(q)) \
72 { \
73 unsigned long flags; \
74 DISABLE_INTR(flags); \
75 q->queue[q->tail] = (data); \
76 q->len++; q->tail = (q->tail+1) % MAX_QUEUE_SIZE; \
77 RESTORE_INTR(flags); \
78 }
79
80 #define REMOVE_BYTE(q, data) \
81 if (DATA_AVAIL(q)) \
82 { \
83 unsigned long flags; \
84 DISABLE_INTR(flags); \
85 data = q->queue[q->head]; \
86 q->len--; q->head = (q->head+1) % MAX_QUEUE_SIZE; \
87 RESTORE_INTR(flags); \
88 }
89
90 void
91 drain_midi_queue (int dev)
92 {
93
94
95
96
97
98 if (midi_devs[dev]->buffer_status != NULL)
99 while (!PROCESS_ABORTING (midi_sleeper[dev], midi_sleep_flag[dev]) &&
100 midi_devs[dev]->buffer_status (dev))
101 DO_SLEEP (midi_sleeper[dev], midi_sleep_flag[dev], HZ / 10);
102 }
103
104 static void
105 midi_input_intr (int dev, unsigned char data)
106 {
107 if (midi_in_buf[dev] == NULL)
108 return;
109
110 if (data == 0xfe)
111
112
113 return;
114
115
116
117 if (SPACE_AVAIL (midi_in_buf[dev]))
118 {
119 QUEUE_BYTE (midi_in_buf[dev], data);
120 if (SOMEONE_WAITING (input_sleeper[dev], input_sleep_flag[dev]))
121 WAKE_UP (input_sleeper[dev], input_sleep_flag[dev]);
122 }
123
124 }
125
126 static void
127 midi_output_intr (int dev)
128 {
129
130
131
132 }
133
134 static void
135 midi_poll (unsigned long dummy)
136 {
137 unsigned long flags;
138 int dev;
139
140 DISABLE_INTR (flags);
141 if (open_devs)
142 {
143 for (dev = 0; dev < num_midis; dev++)
144 if (midi_out_buf[dev] != NULL)
145 {
146 while (DATA_AVAIL (midi_out_buf[dev]) &&
147 midi_devs[dev]->putc (dev,
148 midi_out_buf[dev]->queue[midi_out_buf[dev]->head]))
149 {
150 midi_out_buf[dev]->head = (midi_out_buf[dev]->head + 1) % MAX_QUEUE_SIZE;
151 midi_out_buf[dev]->len--;
152 }
153
154 if (DATA_AVAIL (midi_out_buf[dev]) < 100 &&
155 SOMEONE_WAITING (midi_sleeper[dev], midi_sleep_flag[dev]))
156 WAKE_UP (midi_sleeper[dev], midi_sleep_flag[dev]);
157 }
158 ACTIVATE_TIMER (poll_timer, midi_poll, 1);
159
160
161 }
162 RESTORE_INTR (flags);
163 }
164
165 int
166 MIDIbuf_open (int dev, struct fileinfo *file)
167 {
168 int mode, err;
169 unsigned long flags;
170
171 dev = dev >> 4;
172 mode = file->mode & O_ACCMODE;
173
174 if (num_midis > MAX_MIDI_DEV)
175 {
176 printk ("Sound: FATAL ERROR: Too many midi interfaces\n");
177 num_midis = MAX_MIDI_DEV;
178 }
179
180 if (dev < 0 || dev >= num_midis)
181 {
182 printk ("Sound: Nonexistent MIDI interface %d\n", dev);
183 return RET_ERROR (ENXIO);
184 }
185
186
187
188
189
190 DISABLE_INTR (flags);
191 if ((err = midi_devs[dev]->open (dev, mode,
192 midi_input_intr, midi_output_intr)) < 0)
193 {
194 RESTORE_INTR (flags);
195 return err;
196 }
197
198 parms[dev].prech_timeout = 0;
199
200 RESET_WAIT_QUEUE (midi_sleeper[dev], midi_sleep_flag[dev]);
201 RESET_WAIT_QUEUE (input_sleeper[dev], input_sleep_flag[dev]);
202
203 midi_in_buf[dev] = (struct midi_buf *) KERNEL_MALLOC (sizeof (struct midi_buf));
204
205 if (midi_in_buf[dev] == NULL)
206 {
207 printk ("midi: Can't allocate buffer\n");
208 midi_devs[dev]->close (dev);
209 RESTORE_INTR (flags);
210 return RET_ERROR (EIO);
211 }
212 midi_in_buf[dev]->len = midi_in_buf[dev]->head = midi_in_buf[dev]->tail = 0;
213
214 midi_out_buf[dev] = (struct midi_buf *) KERNEL_MALLOC (sizeof (struct midi_buf));
215
216 if (midi_out_buf[dev] == NULL)
217 {
218 printk ("midi: Can't allocate buffer\n");
219 midi_devs[dev]->close (dev);
220 KERNEL_FREE (midi_in_buf[dev]);
221 midi_in_buf[dev] = NULL;
222 RESTORE_INTR (flags);
223 return RET_ERROR (EIO);
224 }
225 midi_out_buf[dev]->len = midi_out_buf[dev]->head = midi_out_buf[dev]->tail = 0;
226 if (!open_devs)
227 ACTIVATE_TIMER (poll_timer, midi_poll, 1);
228
229
230 open_devs++;
231 RESTORE_INTR (flags);
232
233 return err;
234 }
235
236 void
237 MIDIbuf_release (int dev, struct fileinfo *file)
238 {
239 int mode;
240 unsigned long flags;
241
242 dev = dev >> 4;
243 mode = file->mode & O_ACCMODE;
244
245 DISABLE_INTR (flags);
246
247
248
249
250
251 if (mode != OPEN_READ)
252 {
253 midi_devs[dev]->putc (dev, 0xfe);
254
255
256
257
258 while (!PROCESS_ABORTING (midi_sleeper[dev], midi_sleep_flag[dev]) &&
259 DATA_AVAIL (midi_out_buf[dev]))
260 DO_SLEEP (midi_sleeper[dev], midi_sleep_flag[dev], 0);
261
262
263
264 drain_midi_queue (dev);
265
266
267 }
268
269 midi_devs[dev]->close (dev);
270 KERNEL_FREE (midi_in_buf[dev]);
271 KERNEL_FREE (midi_out_buf[dev]);
272 midi_in_buf[dev] = NULL;
273 midi_out_buf[dev] = NULL;
274 open_devs--;
275 RESTORE_INTR (flags);
276 }
277
278 int
279 MIDIbuf_write (int dev, struct fileinfo *file, snd_rw_buf * buf, int count)
280 {
281 unsigned long flags;
282 int c, n, i;
283 unsigned char tmp_data;
284
285 dev = dev >> 4;
286
287 if (!count)
288 return 0;
289
290 DISABLE_INTR (flags);
291
292 c = 0;
293
294 while (c < count)
295 {
296 n = SPACE_AVAIL (midi_out_buf[dev]);
297
298 if (n == 0)
299
300
301 {
302 DO_SLEEP (midi_sleeper[dev], midi_sleep_flag[dev], 0);
303 if (PROCESS_ABORTING (midi_sleeper[dev], midi_sleep_flag[dev]))
304 {
305 RESTORE_INTR (flags);
306 return RET_ERROR (EINTR);
307 }
308
309 n = SPACE_AVAIL (midi_out_buf[dev]);
310 }
311
312 if (n > (count - c))
313 n = count - c;
314
315 for (i = 0; i < n; i++)
316 {
317 COPY_FROM_USER (&tmp_data, buf, c, 1);
318 QUEUE_BYTE (midi_out_buf[dev], tmp_data);
319 c++;
320 }
321 }
322
323 RESTORE_INTR (flags);
324
325 return c;
326 }
327
328
329 int
330 MIDIbuf_read (int dev, struct fileinfo *file, snd_rw_buf * buf, int count)
331 {
332 int n, c = 0;
333 unsigned long flags;
334 unsigned char tmp_data;
335
336 dev = dev >> 4;
337
338 DISABLE_INTR (flags);
339
340 if (!DATA_AVAIL (midi_in_buf[dev]))
341
342
343 {
344 DO_SLEEP (input_sleeper[dev], input_sleep_flag[dev],
345 parms[dev].prech_timeout);
346 if (PROCESS_ABORTING (input_sleeper[dev], input_sleep_flag[dev]))
347 c = RET_ERROR (EINTR);
348
349
350 }
351
352 if (c == 0 && DATA_AVAIL (midi_in_buf[dev]))
353
354
355 {
356 n = DATA_AVAIL (midi_in_buf[dev]);
357 if (n > count)
358 n = count;
359 c = 0;
360
361 while (c < n)
362 {
363 REMOVE_BYTE (midi_in_buf[dev], tmp_data);
364 COPY_TO_USER (buf, c, &tmp_data, 1);
365 c++;
366 }
367 }
368
369 RESTORE_INTR (flags);
370
371 return c;
372 }
373
374 int
375 MIDIbuf_ioctl (int dev, struct fileinfo *file,
376 unsigned int cmd, unsigned int arg)
377 {
378 int val;
379
380 dev = dev >> 4;
381
382 if (((cmd >> 8) & 0xff) == 'C')
383 {
384 if (midi_devs[dev]->coproc)
385 return midi_devs[dev]->coproc->ioctl (midi_devs[dev]->coproc->devc, cmd, arg, 0);
386 else
387 printk ("/dev/midi%d: No coprocessor for this device\n", dev);
388
389 return RET_ERROR (EREMOTEIO);
390 }
391 else
392 switch (cmd)
393 {
394
395 case SNDCTL_MIDI_PRETIME:
396 val = IOCTL_IN (arg);
397 if (val < 0)
398 val = 0;
399
400 val = (HZ * val) / 10;
401 parms[dev].prech_timeout = val;
402 return IOCTL_OUT (arg, val);
403 break;
404
405 default:
406 return midi_devs[dev]->ioctl (dev, cmd, arg);
407 }
408 }
409
410 #ifdef ALLOW_SELECT
411 int
412 MIDIbuf_select (int dev, struct fileinfo *file, int sel_type, select_table * wait)
413 {
414 dev = dev >> 4;
415
416 switch (sel_type)
417 {
418 case SEL_IN:
419 if (!DATA_AVAIL (midi_in_buf[dev]))
420 {
421 input_sleep_flag[dev].mode = WK_SLEEP;
422 select_wait (&input_sleeper[dev], wait);
423 return 0;
424 }
425 return 1;
426 break;
427
428 case SEL_OUT:
429 if (SPACE_AVAIL (midi_out_buf[dev]))
430 {
431 midi_sleep_flag[dev].mode = WK_SLEEP;
432 select_wait (&midi_sleeper[dev], wait);
433 return 0;
434 }
435 return 1;
436 break;
437
438 case SEL_EX:
439 return 0;
440 }
441
442 return 0;
443 }
444
445 #endif
446
447 long
448 MIDIbuf_init (long mem_start)
449 {
450 return mem_start;
451 }
452
453 #endif