4 * Device file manager for /dev/midi#
7 * Copyright (C) by Hannu Savolainen 1993-1997
9 * OSS/Free for Linux is distributed under the GNU GENERAL PUBLIC LICENSE (GPL)
10 * Version 2 (June 1991). See the "COPYING" file distributed with this software
14 * Thomas Sailer : ioctl code reworked (vmalloc/vfree removed)
16 #include <linux/stddef.h>
17 #include <linux/kmod.h>
18 #include <linux/spinlock.h>
21 #include "sound_config.h"
25 * Don't make MAX_QUEUE_SIZE larger than 4000
28 #define MAX_QUEUE_SIZE 4000
30 static wait_queue_head_t midi_sleeper
[MAX_MIDI_DEV
];
31 static wait_queue_head_t input_sleeper
[MAX_MIDI_DEV
];
36 unsigned char queue
[MAX_QUEUE_SIZE
];
41 long prech_timeout
; /*
42 * Timeout before the first ch
46 static struct midi_buf
*midi_out_buf
[MAX_MIDI_DEV
] = {NULL
};
47 static struct midi_buf
*midi_in_buf
[MAX_MIDI_DEV
] = {NULL
};
48 static struct midi_parms parms
[MAX_MIDI_DEV
];
50 static void midi_poll(unsigned long dummy
);
53 static DEFINE_TIMER(poll_timer
, midi_poll
, 0, 0);
55 static volatile int open_devs
;
56 static DEFINE_SPINLOCK(lock
);
58 #define DATA_AVAIL(q) (q->len)
59 #define SPACE_AVAIL(q) (MAX_QUEUE_SIZE - q->len)
61 #define QUEUE_BYTE(q, data) \
64 unsigned long flags; \
65 spin_lock_irqsave(&lock, flags); \
66 q->queue[q->tail] = (data); \
67 q->len++; q->tail = (q->tail+1) % MAX_QUEUE_SIZE; \
68 spin_unlock_irqrestore(&lock, flags); \
71 #define REMOVE_BYTE(q, data) \
74 unsigned long flags; \
75 spin_lock_irqsave(&lock, flags); \
76 data = q->queue[q->head]; \
77 q->len--; q->head = (q->head+1) % MAX_QUEUE_SIZE; \
78 spin_unlock_irqrestore(&lock, flags); \
81 static void drain_midi_queue(int dev
)
85 * Give the Midi driver time to drain its output queues
88 if (midi_devs
[dev
]->buffer_status
!= NULL
)
89 wait_event_interruptible_timeout(midi_sleeper
[dev
],
90 !midi_devs
[dev
]->buffer_status(dev
), HZ
/10);
93 static void midi_input_intr(int dev
, unsigned char data
)
95 if (midi_in_buf
[dev
] == NULL
)
105 if (SPACE_AVAIL(midi_in_buf
[dev
])) {
106 QUEUE_BYTE(midi_in_buf
[dev
], data
);
107 wake_up(&input_sleeper
[dev
]);
111 static void midi_output_intr(int dev
)
118 static void midi_poll(unsigned long dummy
)
123 spin_lock_irqsave(&lock
, flags
);
126 for (dev
= 0; dev
< num_midis
; dev
++)
127 if (midi_devs
[dev
] != NULL
&& midi_out_buf
[dev
] != NULL
)
129 while (DATA_AVAIL(midi_out_buf
[dev
]))
132 int c
= midi_out_buf
[dev
]->queue
[midi_out_buf
[dev
]->head
];
134 spin_unlock_irqrestore(&lock
,flags
);/* Give some time to others */
135 ok
= midi_devs
[dev
]->outputc(dev
, c
);
136 spin_lock_irqsave(&lock
, flags
);
139 midi_out_buf
[dev
]->head
= (midi_out_buf
[dev
]->head
+ 1) % MAX_QUEUE_SIZE
;
140 midi_out_buf
[dev
]->len
--;
143 if (DATA_AVAIL(midi_out_buf
[dev
]) < 100)
144 wake_up(&midi_sleeper
[dev
]);
146 poll_timer
.expires
= (1) + jiffies
;
147 add_timer(&poll_timer
);
152 spin_unlock_irqrestore(&lock
, flags
);
155 int MIDIbuf_open(int dev
, struct file
*file
)
160 mode
= translate_mode(file
);
162 if (num_midis
> MAX_MIDI_DEV
)
164 printk(KERN_ERR
"midi: Too many midi interfaces\n");
165 num_midis
= MAX_MIDI_DEV
;
167 if (dev
< 0 || dev
>= num_midis
|| midi_devs
[dev
] == NULL
)
170 * Interrupts disabled. Be careful
173 module_put(midi_devs
[dev
]->owner
);
175 if ((err
= midi_devs
[dev
]->open(dev
, mode
,
176 midi_input_intr
, midi_output_intr
)) < 0)
179 parms
[dev
].prech_timeout
= MAX_SCHEDULE_TIMEOUT
;
180 midi_in_buf
[dev
] = vmalloc(sizeof(struct midi_buf
));
182 if (midi_in_buf
[dev
] == NULL
)
184 printk(KERN_WARNING
"midi: Can't allocate buffer\n");
185 midi_devs
[dev
]->close(dev
);
188 midi_in_buf
[dev
]->len
= midi_in_buf
[dev
]->head
= midi_in_buf
[dev
]->tail
= 0;
190 midi_out_buf
[dev
] = vmalloc(sizeof(struct midi_buf
));
192 if (midi_out_buf
[dev
] == NULL
)
194 printk(KERN_WARNING
"midi: Can't allocate buffer\n");
195 midi_devs
[dev
]->close(dev
);
196 vfree(midi_in_buf
[dev
]);
197 midi_in_buf
[dev
] = NULL
;
200 midi_out_buf
[dev
]->len
= midi_out_buf
[dev
]->head
= midi_out_buf
[dev
]->tail
= 0;
203 init_waitqueue_head(&midi_sleeper
[dev
]);
204 init_waitqueue_head(&input_sleeper
[dev
]);
206 if (open_devs
< 2) /* This was first open */
208 poll_timer
.expires
= 1 + jiffies
;
209 add_timer(&poll_timer
); /* Start polling */
214 void MIDIbuf_release(int dev
, struct file
*file
)
219 mode
= translate_mode(file
);
221 if (dev
< 0 || dev
>= num_midis
|| midi_devs
[dev
] == NULL
)
225 * Wait until the queue is empty
228 if (mode
!= OPEN_READ
)
230 midi_devs
[dev
]->outputc(dev
, 0xfe); /*
231 * Active sensing to shut the
235 wait_event_interruptible(midi_sleeper
[dev
],
236 !DATA_AVAIL(midi_out_buf
[dev
]));
241 drain_midi_queue(dev
); /*
242 * Ensure the output queues are empty
246 midi_devs
[dev
]->close(dev
);
250 del_timer_sync(&poll_timer
);
251 vfree(midi_in_buf
[dev
]);
252 vfree(midi_out_buf
[dev
]);
253 midi_in_buf
[dev
] = NULL
;
254 midi_out_buf
[dev
] = NULL
;
256 module_put(midi_devs
[dev
]->owner
);
259 int MIDIbuf_write(int dev
, struct file
*file
, const char __user
*buf
, int count
)
262 unsigned char tmp_data
;
273 n
= SPACE_AVAIL(midi_out_buf
[dev
]);
279 if (file
->f_flags
& O_NONBLOCK
) {
284 if (wait_event_interruptible(midi_sleeper
[dev
],
285 SPACE_AVAIL(midi_out_buf
[dev
])))
290 n
= SPACE_AVAIL(midi_out_buf
[dev
]);
295 for (i
= 0; i
< n
; i
++)
297 /* BROKE BROKE BROKE - CAN'T DO THIS WITH CLI !! */
298 /* yes, think the same, so I removed the cli() brackets
299 QUEUE_BYTE is protected against interrupts */
300 if (copy_from_user((char *) &tmp_data
, &(buf
)[c
], 1)) {
304 QUEUE_BYTE(midi_out_buf
[dev
], tmp_data
);
313 int MIDIbuf_read(int dev
, struct file
*file
, char __user
*buf
, int count
)
316 unsigned char tmp_data
;
320 if (!DATA_AVAIL(midi_in_buf
[dev
])) { /*
323 if (file
->f_flags
& O_NONBLOCK
) {
327 wait_event_interruptible_timeout(input_sleeper
[dev
],
328 DATA_AVAIL(midi_in_buf
[dev
]),
329 parms
[dev
].prech_timeout
);
331 if (signal_pending(current
))
332 c
= -EINTR
; /* The user is getting restless */
334 if (c
== 0 && DATA_AVAIL(midi_in_buf
[dev
])) /*
338 n
= DATA_AVAIL(midi_in_buf
[dev
]);
346 REMOVE_BYTE(midi_in_buf
[dev
], tmp_data
);
347 fixit
= (char *) &tmp_data
;
348 /* BROKE BROKE BROKE */
349 /* yes removed the cli() brackets again
350 should q->len,tail&head be atomic_t? */
351 if (copy_to_user(&(buf
)[c
], fixit
, 1)) {
362 int MIDIbuf_ioctl(int dev
, struct file
*file
,
363 unsigned int cmd
, void __user
*arg
)
369 if (((cmd
>> 8) & 0xff) == 'C')
371 if (midi_devs
[dev
]->coproc
) /* Coprocessor ioctl */
372 return midi_devs
[dev
]->coproc
->ioctl(midi_devs
[dev
]->coproc
->devc
, cmd
, arg
, 0);
373 /* printk("/dev/midi%d: No coprocessor for this device\n", dev);*/
380 case SNDCTL_MIDI_PRETIME
:
381 if (get_user(val
, (int __user
*)arg
))
385 val
= (HZ
* val
) / 10;
386 parms
[dev
].prech_timeout
= val
;
387 return put_user(val
, (int __user
*)arg
);
390 if (!midi_devs
[dev
]->ioctl
)
392 return midi_devs
[dev
]->ioctl(dev
, cmd
, arg
);
397 /* No kernel lock - fine */
398 unsigned int MIDIbuf_poll(int dev
, struct file
*file
, poll_table
* wait
)
400 unsigned int mask
= 0;
405 poll_wait(file
, &input_sleeper
[dev
], wait
);
406 if (DATA_AVAIL(midi_in_buf
[dev
]))
407 mask
|= POLLIN
| POLLRDNORM
;
410 poll_wait(file
, &midi_sleeper
[dev
], wait
);
411 if (!SPACE_AVAIL(midi_out_buf
[dev
]))
412 mask
|= POLLOUT
| POLLWRNORM
;
418 int MIDIbuf_avail(int dev
)
420 if (midi_in_buf
[dev
])
421 return DATA_AVAIL (midi_in_buf
[dev
]);
424 EXPORT_SYMBOL(MIDIbuf_avail
);