1 /*
2  * sound/midibuf.c
3  *
4  * Device file manager for /dev/midi#
5  */
6 /*
7  * Copyright (C) by Hannu Savolainen 1993-1997
8  *
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
11  * for more info.
12  */
13 /*
14  * Thomas Sailer   : ioctl code reworked (vmalloc/vfree removed)
15  */
16 #include <linux/stddef.h>
17 #include <linux/kmod.h>
18 
19 #define MIDIBUF_C
20 
21 #include "sound_config.h"
22 
23 
24 /*
25  * Don't make MAX_QUEUE_SIZE larger than 4000
26  */
27 
28 #define MAX_QUEUE_SIZE	4000
29 
30 static wait_queue_head_t midi_sleeper[MAX_MIDI_DEV];
31 static wait_queue_head_t input_sleeper[MAX_MIDI_DEV];
32 
33 struct midi_buf
34 {
35 	int len, head, tail;
36 	unsigned char queue[MAX_QUEUE_SIZE];
37 };
38 
39 struct midi_parms
40 {
41 	long prech_timeout;	/*
42 				 * Timeout before the first ch
43 				 */
44 };
45 
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];
49 
50 static void midi_poll(unsigned long dummy);
51 
52 
53 static struct timer_list poll_timer = {
54 	function: midi_poll
55 };
56 
57 static volatile int open_devs = 0;
58 
59 #define DATA_AVAIL(q) (q->len)
60 #define SPACE_AVAIL(q) (MAX_QUEUE_SIZE - q->len)
61 
62 #define QUEUE_BYTE(q, data) \
63 	if (SPACE_AVAIL(q)) \
64 	{ \
65 	  unsigned long flags; \
66 	  save_flags( flags);cli(); \
67 	  q->queue[q->tail] = (data); \
68 	  q->len++; q->tail = (q->tail+1) % MAX_QUEUE_SIZE; \
69 	  restore_flags(flags); \
70 	}
71 
72 #define REMOVE_BYTE(q, data) \
73 	if (DATA_AVAIL(q)) \
74 	{ \
75 	  unsigned long flags; \
76 	  save_flags( flags);cli(); \
77 	  data = q->queue[q->head]; \
78 	  q->len--; q->head = (q->head+1) % MAX_QUEUE_SIZE; \
79 	  restore_flags(flags); \
80 	}
81 
drain_midi_queue(int dev)82 static void drain_midi_queue(int dev)
83 {
84 
85 	/*
86 	 * Give the Midi driver time to drain its output queues
87 	 */
88 
89 	if (midi_devs[dev]->buffer_status != NULL)
90 		while (!signal_pending(current) && midi_devs[dev]->buffer_status(dev))
91 			interruptible_sleep_on_timeout(&midi_sleeper[dev],
92 						       HZ/10);
93 }
94 
midi_input_intr(int dev,unsigned char data)95 static void midi_input_intr(int dev, unsigned char data)
96 {
97 	if (midi_in_buf[dev] == NULL)
98 		return;
99 
100 	if (data == 0xfe)	/*
101 				 * Active sensing
102 				 */
103 		return;		/*
104 				 * Ignore
105 				 */
106 
107 	if (SPACE_AVAIL(midi_in_buf[dev])) {
108 		QUEUE_BYTE(midi_in_buf[dev], data);
109 		wake_up(&input_sleeper[dev]);
110 	}
111 }
112 
midi_output_intr(int dev)113 static void midi_output_intr(int dev)
114 {
115 	/*
116 	 * Currently NOP
117 	 */
118 }
119 
midi_poll(unsigned long dummy)120 static void midi_poll(unsigned long dummy)
121 {
122 	unsigned long   flags;
123 	int             dev;
124 
125 	save_flags(flags);
126 	cli();
127 	if (open_devs)
128 	{
129 		for (dev = 0; dev < num_midis; dev++)
130 			if (midi_devs[dev] != NULL && midi_out_buf[dev] != NULL)
131 			{
132 				while (DATA_AVAIL(midi_out_buf[dev]))
133 				{
134 					int ok;
135 					int c = midi_out_buf[dev]->queue[midi_out_buf[dev]->head];
136 
137 					restore_flags(flags);	/* Give some time to others */
138 					ok = midi_devs[dev]->outputc(dev, c);
139 					cli();
140 					if (!ok)
141 						break;
142 					midi_out_buf[dev]->head = (midi_out_buf[dev]->head + 1) % MAX_QUEUE_SIZE;
143 					midi_out_buf[dev]->len--;
144 				}
145 
146 				if (DATA_AVAIL(midi_out_buf[dev]) < 100)
147 					wake_up(&midi_sleeper[dev]);
148 			}
149 		poll_timer.expires = (1) + jiffies;
150 		add_timer(&poll_timer);
151 		/*
152 		 * Come back later
153 		 */
154 	}
155 	restore_flags(flags);
156 }
157 
MIDIbuf_open(int dev,struct file * file)158 int MIDIbuf_open(int dev, struct file *file)
159 {
160 	int mode, err;
161 
162 	dev = dev >> 4;
163 	mode = translate_mode(file);
164 
165 	if (num_midis > MAX_MIDI_DEV)
166 	{
167 		printk(KERN_ERR "midi: Too many midi interfaces\n");
168 		num_midis = MAX_MIDI_DEV;
169 	}
170 	if (dev < 0 || dev >= num_midis || midi_devs[dev] == NULL)
171 		  return -ENXIO;
172 	/*
173 	 *    Interrupts disabled. Be careful
174 	 */
175 
176 	if (midi_devs[dev]->owner)
177 		__MOD_INC_USE_COUNT (midi_devs[dev]->owner);
178 
179 	if ((err = midi_devs[dev]->open(dev, mode,
180 				 midi_input_intr, midi_output_intr)) < 0)
181 		return err;
182 
183 	parms[dev].prech_timeout = MAX_SCHEDULE_TIMEOUT;
184 	midi_in_buf[dev] = (struct midi_buf *) vmalloc(sizeof(struct midi_buf));
185 
186 	if (midi_in_buf[dev] == NULL)
187 	{
188 		printk(KERN_WARNING "midi: Can't allocate buffer\n");
189 		midi_devs[dev]->close(dev);
190 		return -EIO;
191 	}
192 	midi_in_buf[dev]->len = midi_in_buf[dev]->head = midi_in_buf[dev]->tail = 0;
193 
194 	midi_out_buf[dev] = (struct midi_buf *) vmalloc(sizeof(struct midi_buf));
195 
196 	if (midi_out_buf[dev] == NULL)
197 	{
198 		printk(KERN_WARNING "midi: Can't allocate buffer\n");
199 		midi_devs[dev]->close(dev);
200 		vfree(midi_in_buf[dev]);
201 		midi_in_buf[dev] = NULL;
202 		return -EIO;
203 	}
204 	midi_out_buf[dev]->len = midi_out_buf[dev]->head = midi_out_buf[dev]->tail = 0;
205 	open_devs++;
206 
207 	init_waitqueue_head(&midi_sleeper[dev]);
208 	init_waitqueue_head(&input_sleeper[dev]);
209 
210 	if (open_devs < 2)	/* This was first open */
211 	{
212 		poll_timer.expires = 1 + jiffies;
213 		add_timer(&poll_timer);	/* Start polling */
214 	}
215 	return err;
216 }
217 
MIDIbuf_release(int dev,struct file * file)218 void MIDIbuf_release(int dev, struct file *file)
219 {
220 	int mode;
221 	unsigned long flags;
222 
223 	dev = dev >> 4;
224 	mode = translate_mode(file);
225 
226 	if (dev < 0 || dev >= num_midis || midi_devs[dev] == NULL)
227 		return;
228 
229 	save_flags(flags);
230 	cli();
231 
232 	/*
233 	 * Wait until the queue is empty
234 	 */
235 
236 	if (mode != OPEN_READ)
237 	{
238 		midi_devs[dev]->outputc(dev, 0xfe);	/*
239 							   * Active sensing to shut the
240 							   * devices
241 							 */
242 
243 		while (!signal_pending(current) && DATA_AVAIL(midi_out_buf[dev]))
244 			  interruptible_sleep_on(&midi_sleeper[dev]);
245 		/*
246 		 *	Sync
247 		 */
248 
249 		drain_midi_queue(dev);	/*
250 					 * Ensure the output queues are empty
251 					 */
252 	}
253 	restore_flags(flags);
254 
255 	midi_devs[dev]->close(dev);
256 
257 	open_devs--;
258 	if (open_devs == 0)
259 		del_timer_sync(&poll_timer);
260 	vfree(midi_in_buf[dev]);
261 	vfree(midi_out_buf[dev]);
262 	midi_in_buf[dev] = NULL;
263 	midi_out_buf[dev] = NULL;
264 
265 	if (midi_devs[dev]->owner)
266 		__MOD_DEC_USE_COUNT (midi_devs[dev]->owner);
267 }
268 
MIDIbuf_write(int dev,struct file * file,const char * buf,int count)269 int MIDIbuf_write(int dev, struct file *file, const char *buf, int count)
270 {
271 	unsigned long flags;
272 	int c, n, i;
273 	unsigned char tmp_data;
274 
275 	dev = dev >> 4;
276 
277 	if (!count)
278 		return 0;
279 
280 	save_flags(flags);
281 	cli();
282 
283 	c = 0;
284 
285 	while (c < count)
286 	{
287 		n = SPACE_AVAIL(midi_out_buf[dev]);
288 
289 		if (n == 0) {	/*
290 				 * No space just now.
291 				 */
292 
293 			if (file->f_flags & O_NONBLOCK) {
294 				restore_flags(flags);
295 				return -EAGAIN;
296 			}
297 
298 			interruptible_sleep_on(&midi_sleeper[dev]);
299 			if (signal_pending(current))
300 			{
301 				restore_flags(flags);
302 				return -EINTR;
303 			}
304 			n = SPACE_AVAIL(midi_out_buf[dev]);
305 		}
306 		if (n > (count - c))
307 			n = count - c;
308 
309 		for (i = 0; i < n; i++)
310 		{
311 			/* BROKE BROKE BROKE - CANT DO THIS WITH CLI !! */
312 			copy_from_user((char *) &tmp_data, &(buf)[c], 1);
313 			QUEUE_BYTE(midi_out_buf[dev], tmp_data);
314 			c++;
315 		}
316 	}
317 	restore_flags(flags);
318 	return c;
319 }
320 
321 
MIDIbuf_read(int dev,struct file * file,char * buf,int count)322 int MIDIbuf_read(int dev, struct file *file, char *buf, int count)
323 {
324 	int n, c = 0;
325 	unsigned long flags;
326 	unsigned char tmp_data;
327 
328 	dev = dev >> 4;
329 
330 	save_flags(flags);
331 	cli();
332 
333 	if (!DATA_AVAIL(midi_in_buf[dev])) {	/*
334 						 * No data yet, wait
335 						 */
336  		if (file->f_flags & O_NONBLOCK) {
337  			restore_flags(flags);
338  			return -EAGAIN;
339  		}
340 		interruptible_sleep_on_timeout(&input_sleeper[dev],
341 					       parms[dev].prech_timeout);
342 
343 		if (signal_pending(current))
344 			c = -EINTR;	/* The user is getting restless */
345 	}
346 	if (c == 0 && DATA_AVAIL(midi_in_buf[dev]))	/*
347 							 * Got some bytes
348 							 */
349 	{
350 		n = DATA_AVAIL(midi_in_buf[dev]);
351 		if (n > count)
352 			n = count;
353 		c = 0;
354 
355 		while (c < n)
356 		{
357 			char *fixit;
358 			REMOVE_BYTE(midi_in_buf[dev], tmp_data);
359 			fixit = (char *) &tmp_data;
360 			/* BROKE BROKE BROKE */
361 			copy_to_user(&(buf)[c], fixit, 1);
362 			c++;
363 		}
364 	}
365 	restore_flags(flags);
366 	return c;
367 }
368 
MIDIbuf_ioctl(int dev,struct file * file,unsigned int cmd,caddr_t arg)369 int MIDIbuf_ioctl(int dev, struct file *file,
370 		  unsigned int cmd, caddr_t arg)
371 {
372 	int val;
373 
374 	dev = dev >> 4;
375 
376 	if (((cmd >> 8) & 0xff) == 'C')
377 	{
378 		if (midi_devs[dev]->coproc)	/* Coprocessor ioctl */
379 			return midi_devs[dev]->coproc->ioctl(midi_devs[dev]->coproc->devc, cmd, arg, 0);
380 /*		printk("/dev/midi%d: No coprocessor for this device\n", dev);*/
381 		return -ENXIO;
382 	}
383 	else
384 	{
385 		switch (cmd)
386 		{
387 			case SNDCTL_MIDI_PRETIME:
388 				if (get_user(val, (int *)arg))
389 					return -EFAULT;
390 				if (val < 0)
391 					val = 0;
392 				val = (HZ * val) / 10;
393 				parms[dev].prech_timeout = val;
394 				return put_user(val, (int *)arg);
395 
396 			default:
397 				if (!midi_devs[dev]->ioctl)
398 					return -EINVAL;
399 				return midi_devs[dev]->ioctl(dev, cmd, arg);
400 		}
401 	}
402 }
403 
404 /* No kernel lock - fine */
MIDIbuf_poll(int dev,struct file * file,poll_table * wait)405 unsigned int MIDIbuf_poll(int dev, struct file *file, poll_table * wait)
406 {
407 	unsigned int mask = 0;
408 
409 	dev = dev >> 4;
410 
411 	/* input */
412 	poll_wait(file, &input_sleeper[dev], wait);
413 	if (DATA_AVAIL(midi_in_buf[dev]))
414 		mask |= POLLIN | POLLRDNORM;
415 
416 	/* output */
417 	poll_wait(file, &midi_sleeper[dev], wait);
418 	if (!SPACE_AVAIL(midi_out_buf[dev]))
419 		mask |= POLLOUT | POLLWRNORM;
420 
421 	return mask;
422 }
423 
424 
MIDIbuf_init(void)425 void MIDIbuf_init(void)
426 {
427 	/* drag in midi_syms.o */
428 	{
429 		extern char midi_syms_symbol;
430 		midi_syms_symbol = 0;
431 	}
432 }
433 
MIDIbuf_avail(int dev)434 int MIDIbuf_avail(int dev)
435 {
436         if (midi_in_buf[dev])
437 		return DATA_AVAIL (midi_in_buf[dev]);
438 	return 0;
439 }
440