4 * Device file manager for /dev/midi#
6 * Copyright by Hannu Savolainen 1993
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions are
10 * met: 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer. 2.
12 * Redistributions in binary form must reproduce the above copyright notice,
13 * this list of conditions and the following disclaimer in the documentation
14 * and/or other materials provided with the distribution.
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
20 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
22 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
23 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28 * $DragonFly: src/sys/dev/sound/isa/i386/Attic/midibuf.c,v 1.2 2003/08/07 21:17:12 dillon Exp $
31 #include "sound_config.h"
34 #if defined(CONFIG_MIDI)
36 #include <sys/select.h>
39 * Don't make MAX_QUEUE_SIZE larger than 4000
42 #define MAX_QUEUE_SIZE 4000
44 MIDIbuf_poll (int dev, struct fileinfo *file, int events, select_table * wait);
47 drain_midi_queue(int dev);
49 static int *midi_sleeper[MAX_MIDI_DEV] = {NULL};
50 static volatile struct snd_wait midi_sleep_flag[MAX_MIDI_DEV] = { {0}};
51 static int *input_sleeper[MAX_MIDI_DEV] = {NULL};
52 static volatile struct snd_wait input_sleep_flag[MAX_MIDI_DEV] = { {0}};
56 u_char queue[MAX_QUEUE_SIZE];
60 int prech_timeout; /* Timeout before the first ch */
63 static struct midi_buf *midi_out_buf[MAX_MIDI_DEV] = {NULL};
64 static struct midi_buf *midi_in_buf[MAX_MIDI_DEV] = {NULL};
65 static struct midi_parms parms[MAX_MIDI_DEV];
67 static void midi_poll(void *dummy);
69 static volatile int open_devs = 0;
71 #define DATA_AVAIL(q) (q->len)
72 #define SPACE_AVAIL(q) (MAX_QUEUE_SIZE - q->len)
74 #define QUEUE_BYTE(q, data) \
75 if (SPACE_AVAIL(q)) { \
78 q->queue[q->tail] = (data); \
79 q->len++; q->tail = (q->tail+1) % MAX_QUEUE_SIZE; \
83 #define REMOVE_BYTE(q, data) \
84 if (DATA_AVAIL(q)) { \
87 data = q->queue[q->head]; \
88 q->len--; q->head = (q->head+1) % MAX_QUEUE_SIZE; \
93 drain_midi_queue(int dev)
97 * Give the Midi driver time to drain its output queues
100 if (midi_devs[dev]->buffer_status != NULL)
101 while (!(PROCESS_ABORTING (midi_sleep_flag[dev])) &&
102 midi_devs[dev]->buffer_status(dev)) {
105 midi_sleeper[dev] = &chn;
106 DO_SLEEP(chn, midi_sleep_flag[dev], hz / 10);
112 midi_input_intr(int dev, u_char data)
114 if (midi_in_buf[dev] == NULL)
117 if (data == 0xfe) /* Active sensing */
120 if (SPACE_AVAIL(midi_in_buf[dev])) {
121 QUEUE_BYTE(midi_in_buf[dev], data);
122 if ((input_sleep_flag[dev].mode & WK_SLEEP)) {
123 input_sleep_flag[dev].mode = WK_WAKEUP;
124 wakeup(input_sleeper[dev]);
130 midi_output_intr(int dev)
138 midi_poll(void *dummy)
145 for (dev = 0; dev < num_midis; dev++)
146 if (midi_out_buf[dev] != NULL) {
147 while (DATA_AVAIL(midi_out_buf[dev]) &&
148 midi_devs[dev]->putc(dev,
149 midi_out_buf[dev]->queue[midi_out_buf[dev]->head])) {
150 midi_out_buf[dev]->head = (midi_out_buf[dev]->head + 1) % MAX_QUEUE_SIZE;
151 midi_out_buf[dev]->len--;
154 if (DATA_AVAIL(midi_out_buf[dev]) < 100 &&
155 (midi_sleep_flag[dev].mode & WK_SLEEP)) {
156 midi_sleep_flag[dev].mode = WK_WAKEUP;
157 wakeup(midi_sleeper[dev]);
160 timeout( midi_poll, 0, 1);; /* Come back later */
166 MIDIbuf_open(int dev, struct fileinfo * file)
171 mode = file->mode & O_ACCMODE;
173 if (num_midis > MAX_MIDI_DEV) {
174 printf("Sound: FATAL ERROR: Too many midi interfaces\n");
175 num_midis = MAX_MIDI_DEV;
177 if (dev < 0 || dev >= num_midis) {
178 printf("Sound: Nonexistent MIDI interface %d\n", dev);
182 * Interrupts disabled. Be careful
185 if ((err = midi_devs[dev]->open(dev, mode,
186 midi_input_intr, midi_output_intr)) < 0) {
189 parms[dev].prech_timeout = 0;
191 midi_in_buf[dev] = (struct midi_buf *) malloc(sizeof(struct midi_buf), M_TEMP, M_WAITOK);
193 if (midi_in_buf[dev] == NULL) {
194 printf("midi: Can't allocate buffer\n");
195 midi_devs[dev]->close(dev);
198 midi_in_buf[dev]->len = midi_in_buf[dev]->head = midi_in_buf[dev]->tail = 0;
200 midi_out_buf[dev] = (struct midi_buf *) malloc(sizeof(struct midi_buf), M_TEMP, M_WAITOK);
202 if (midi_out_buf[dev] == NULL) {
203 printf("midi: Can't allocate buffer\n");
204 midi_devs[dev]->close(dev);
205 free(midi_in_buf[dev], M_TEMP);
206 midi_in_buf[dev] = NULL;
209 midi_out_buf[dev]->len = midi_out_buf[dev]->head = midi_out_buf[dev]->tail = 0;
213 midi_sleep_flag[dev].aborting = 0;
214 midi_sleep_flag[dev].mode = WK_NONE;
217 input_sleep_flag[dev].aborting = 0;
218 input_sleep_flag[dev].mode = WK_NONE;
221 if (open_devs < 2) { /* This was first open */
225 timeout( midi_poll, 0, 1);; /* Start polling */
231 MIDIbuf_release(int dev, struct fileinfo * file)
237 mode = file->mode & O_ACCMODE;
239 if (dev < 0 || dev >= num_midis)
245 * Wait until the queue is empty
248 if (mode != OPEN_READ) {
249 midi_devs[dev]->putc(dev, 0xfe); /* Active sensing to
250 * shut the devices */
252 while (!(PROCESS_ABORTING (midi_sleep_flag[dev])) &&
253 DATA_AVAIL(midi_out_buf[dev])) {
255 midi_sleeper[dev] = &chn;
256 DO_SLEEP(chn, midi_sleep_flag[dev], 0);
260 drain_midi_queue(dev); /* Ensure the output queues are empty */
264 midi_devs[dev]->close(dev);
266 free(midi_in_buf[dev], M_TEMP);
267 free(midi_out_buf[dev], M_TEMP);
268 midi_in_buf[dev] = NULL;
269 midi_out_buf[dev] = NULL;
276 MIDIbuf_write(int dev, struct fileinfo * file, snd_rw_buf * buf, int count)
292 n = SPACE_AVAIL(midi_out_buf[dev]);
294 if (n == 0) { /* No space just now. We have to sleep */
299 midi_sleeper[dev] = &chn;
300 DO_SLEEP(chn, midi_sleep_flag[dev], 0);
303 if (PROCESS_ABORTING(midi_sleep_flag[dev])) {
307 n = SPACE_AVAIL(midi_out_buf[dev]);
312 for (i = 0; i < n; i++) {
314 if (uiomove((char *) &tmp_data, 1, buf)) {
315 printf("sb: Bad copyin()!\n");
317 QUEUE_BYTE(midi_out_buf[dev], tmp_data);
329 MIDIbuf_read(int dev, struct fileinfo * file, snd_rw_buf * buf, int count)
339 if (!DATA_AVAIL(midi_in_buf[dev])) { /* No data yet, wait */
345 input_sleeper[dev] = &chn;
346 DO_SLEEP(chn, input_sleep_flag[dev],
347 parms[dev].prech_timeout);
350 if (PROCESS_ABORTING(input_sleep_flag[dev]))
351 c = -(EINTR); /* The user is getting restless */
353 if (c == 0 && DATA_AVAIL(midi_in_buf[dev])) { /* Got some bytes */
354 n = DATA_AVAIL(midi_in_buf[dev]);
360 REMOVE_BYTE(midi_in_buf[dev], tmp_data);
362 if (uiomove((char *) &tmp_data, 1, buf)) {
363 printf("sb: Bad copyout()!\n");
374 MIDIbuf_ioctl(int dev, struct fileinfo * file, u_int cmd, ioctl_arg arg)
380 if (((cmd >> 8) & 0xff) == 'C') {
381 if (midi_devs[dev]->coproc) /* Coprocessor ioctl */
382 return midi_devs[dev]->coproc->ioctl(midi_devs[dev]->coproc->devc, cmd, arg, 0);
384 printf("/dev/midi%d: No coprocessor for this device\n", dev);
390 case SNDCTL_MIDI_PRETIME:
391 val = (int) (*(int *) arg);
395 val = (hz * val) / 10;
396 parms[dev].prech_timeout = val;
397 return *(int *) arg = val;
401 return midi_devs[dev]->ioctl(dev, cmd, arg);
407 MIDIbuf_poll (int dev, struct fileinfo *file, int events, select_table * wait)
413 if (events & (POLLIN | POLLRDNORM))
414 if (!DATA_AVAIL (midi_in_buf[dev]))
415 selrecord(wait, &selinfo[dev]);
417 revents |= events & (POLLIN | POLLRDNORM);
419 if (events & (POLLOUT | POLLWRNORM))
420 if (SPACE_AVAIL (midi_out_buf[dev]))
421 selrecord(wait, &selinfo[dev]);
423 revents |= events & (POLLOUT | POLLWRNORM);
428 #endif /* ALLOW_SELECT */