Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
midibuf.c
Go to the documentation of this file.
1 /*
2  * sound/oss/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 #include <linux/spinlock.h>
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 DEFINE_TIMER(poll_timer, midi_poll, 0, 0);
54 
55 static volatile int open_devs;
56 static DEFINE_SPINLOCK(lock);
57 
58 #define DATA_AVAIL(q) (q->len)
59 #define SPACE_AVAIL(q) (MAX_QUEUE_SIZE - q->len)
60 
61 #define QUEUE_BYTE(q, data) \
62  if (SPACE_AVAIL(q)) \
63  { \
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); \
69  }
70 
71 #define REMOVE_BYTE(q, data) \
72  if (DATA_AVAIL(q)) \
73  { \
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); \
79  }
80 
81 static void drain_midi_queue(int dev)
82 {
83 
84  /*
85  * Give the Midi driver time to drain its output queues
86  */
87 
88  if (midi_devs[dev]->buffer_status != NULL)
89  while (!signal_pending(current) && midi_devs[dev]->buffer_status(dev))
90  interruptible_sleep_on_timeout(&midi_sleeper[dev],
91  HZ/10);
92 }
93 
94 static void midi_input_intr(int dev, unsigned char data)
95 {
96  if (midi_in_buf[dev] == NULL)
97  return;
98 
99  if (data == 0xfe) /*
100  * Active sensing
101  */
102  return; /*
103  * Ignore
104  */
105 
106  if (SPACE_AVAIL(midi_in_buf[dev])) {
107  QUEUE_BYTE(midi_in_buf[dev], data);
108  wake_up(&input_sleeper[dev]);
109  }
110 }
111 
112 static void midi_output_intr(int dev)
113 {
114  /*
115  * Currently NOP
116  */
117 }
118 
119 static void midi_poll(unsigned long dummy)
120 {
121  unsigned long flags;
122  int dev;
123 
124  spin_lock_irqsave(&lock, flags);
125  if (open_devs)
126  {
127  for (dev = 0; dev < num_midis; dev++)
128  if (midi_devs[dev] != NULL && midi_out_buf[dev] != NULL)
129  {
130  while (DATA_AVAIL(midi_out_buf[dev]))
131  {
132  int ok;
133  int c = midi_out_buf[dev]->queue[midi_out_buf[dev]->head];
134 
135  spin_unlock_irqrestore(&lock,flags);/* Give some time to others */
136  ok = midi_devs[dev]->outputc(dev, c);
137  spin_lock_irqsave(&lock, flags);
138  if (!ok)
139  break;
140  midi_out_buf[dev]->head = (midi_out_buf[dev]->head + 1) % MAX_QUEUE_SIZE;
141  midi_out_buf[dev]->len--;
142  }
143 
144  if (DATA_AVAIL(midi_out_buf[dev]) < 100)
145  wake_up(&midi_sleeper[dev]);
146  }
147  poll_timer.expires = (1) + jiffies;
148  add_timer(&poll_timer);
149  /*
150  * Come back later
151  */
152  }
153  spin_unlock_irqrestore(&lock, flags);
154 }
155 
156 int MIDIbuf_open(int dev, struct file *file)
157 {
158  int mode, err;
159 
160  dev = dev >> 4;
161  mode = translate_mode(file);
162 
163  if (num_midis > MAX_MIDI_DEV)
164  {
165  printk(KERN_ERR "midi: Too many midi interfaces\n");
166  num_midis = MAX_MIDI_DEV;
167  }
168  if (dev < 0 || dev >= num_midis || midi_devs[dev] == NULL)
169  return -ENXIO;
170  /*
171  * Interrupts disabled. Be careful
172  */
173 
174  module_put(midi_devs[dev]->owner);
175 
176  if ((err = midi_devs[dev]->open(dev, mode,
177  midi_input_intr, midi_output_intr)) < 0)
178  return err;
179 
180  parms[dev].prech_timeout = MAX_SCHEDULE_TIMEOUT;
181  midi_in_buf[dev] = vmalloc(sizeof(struct midi_buf));
182 
183  if (midi_in_buf[dev] == NULL)
184  {
185  printk(KERN_WARNING "midi: Can't allocate buffer\n");
186  midi_devs[dev]->close(dev);
187  return -EIO;
188  }
189  midi_in_buf[dev]->len = midi_in_buf[dev]->head = midi_in_buf[dev]->tail = 0;
190 
191  midi_out_buf[dev] = vmalloc(sizeof(struct midi_buf));
192 
193  if (midi_out_buf[dev] == NULL)
194  {
195  printk(KERN_WARNING "midi: Can't allocate buffer\n");
196  midi_devs[dev]->close(dev);
197  vfree(midi_in_buf[dev]);
198  midi_in_buf[dev] = NULL;
199  return -EIO;
200  }
201  midi_out_buf[dev]->len = midi_out_buf[dev]->head = midi_out_buf[dev]->tail = 0;
202  open_devs++;
203 
204  init_waitqueue_head(&midi_sleeper[dev]);
205  init_waitqueue_head(&input_sleeper[dev]);
206 
207  if (open_devs < 2) /* This was first open */
208  {
209  poll_timer.expires = 1 + jiffies;
210  add_timer(&poll_timer); /* Start polling */
211  }
212  return err;
213 }
214 
215 void MIDIbuf_release(int dev, struct file *file)
216 {
217  int mode;
218 
219  dev = dev >> 4;
220  mode = translate_mode(file);
221 
222  if (dev < 0 || dev >= num_midis || midi_devs[dev] == NULL)
223  return;
224 
225  /*
226  * Wait until the queue is empty
227  */
228 
229  if (mode != OPEN_READ)
230  {
231  midi_devs[dev]->outputc(dev, 0xfe); /*
232  * Active sensing to shut the
233  * devices
234  */
235 
236  while (!signal_pending(current) && DATA_AVAIL(midi_out_buf[dev]))
237  interruptible_sleep_on(&midi_sleeper[dev]);
238  /*
239  * Sync
240  */
241 
242  drain_midi_queue(dev); /*
243  * Ensure the output queues are empty
244  */
245  }
246 
247  midi_devs[dev]->close(dev);
248 
249  open_devs--;
250  if (open_devs == 0)
251  del_timer_sync(&poll_timer);
252  vfree(midi_in_buf[dev]);
253  vfree(midi_out_buf[dev]);
254  midi_in_buf[dev] = NULL;
255  midi_out_buf[dev] = NULL;
256 
257  module_put(midi_devs[dev]->owner);
258 }
259 
260 int MIDIbuf_write(int dev, struct file *file, const char __user *buf, int count)
261 {
262  int c, n, i;
263  unsigned char tmp_data;
264 
265  dev = dev >> 4;
266 
267  if (!count)
268  return 0;
269 
270  c = 0;
271 
272  while (c < count)
273  {
274  n = SPACE_AVAIL(midi_out_buf[dev]);
275 
276  if (n == 0) { /*
277  * No space just now.
278  */
279 
280  if (file->f_flags & O_NONBLOCK) {
281  c = -EAGAIN;
282  goto out;
283  }
284 
285  interruptible_sleep_on(&midi_sleeper[dev]);
286  if (signal_pending(current))
287  {
288  c = -EINTR;
289  goto out;
290  }
291  n = SPACE_AVAIL(midi_out_buf[dev]);
292  }
293  if (n > (count - c))
294  n = count - c;
295 
296  for (i = 0; i < n; i++)
297  {
298  /* BROKE BROKE BROKE - CAN'T DO THIS WITH CLI !! */
299  /* yes, think the same, so I removed the cli() brackets
300  QUEUE_BYTE is protected against interrupts */
301  if (copy_from_user((char *) &tmp_data, &(buf)[c], 1)) {
302  c = -EFAULT;
303  goto out;
304  }
305  QUEUE_BYTE(midi_out_buf[dev], tmp_data);
306  c++;
307  }
308  }
309 out:
310  return c;
311 }
312 
313 
314 int MIDIbuf_read(int dev, struct file *file, char __user *buf, int count)
315 {
316  int n, c = 0;
317  unsigned char tmp_data;
318 
319  dev = dev >> 4;
320 
321  if (!DATA_AVAIL(midi_in_buf[dev])) { /*
322  * No data yet, wait
323  */
324  if (file->f_flags & O_NONBLOCK) {
325  c = -EAGAIN;
326  goto out;
327  }
328  interruptible_sleep_on_timeout(&input_sleeper[dev],
329  parms[dev].prech_timeout);
330 
331  if (signal_pending(current))
332  c = -EINTR; /* The user is getting restless */
333  }
334  if (c == 0 && DATA_AVAIL(midi_in_buf[dev])) /*
335  * Got some bytes
336  */
337  {
338  n = DATA_AVAIL(midi_in_buf[dev]);
339  if (n > count)
340  n = count;
341  c = 0;
342 
343  while (c < n)
344  {
345  char *fixit;
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)) {
352  c = -EFAULT;
353  goto out;
354  }
355  c++;
356  }
357  }
358 out:
359  return c;
360 }
361 
362 int MIDIbuf_ioctl(int dev, struct file *file,
363  unsigned int cmd, void __user *arg)
364 {
365  int val;
366 
367  dev = dev >> 4;
368 
369  if (((cmd >> 8) & 0xff) == 'C')
370  {
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);*/
374  return -ENXIO;
375  }
376  else
377  {
378  switch (cmd)
379  {
380  case SNDCTL_MIDI_PRETIME:
381  if (get_user(val, (int __user *)arg))
382  return -EFAULT;
383  if (val < 0)
384  val = 0;
385  val = (HZ * val) / 10;
386  parms[dev].prech_timeout = val;
387  return put_user(val, (int __user *)arg);
388 
389  default:
390  if (!midi_devs[dev]->ioctl)
391  return -EINVAL;
392  return midi_devs[dev]->ioctl(dev, cmd, arg);
393  }
394  }
395 }
396 
397 /* No kernel lock - fine */
398 unsigned int MIDIbuf_poll(int dev, struct file *file, poll_table * wait)
399 {
400  unsigned int mask = 0;
401 
402  dev = dev >> 4;
403 
404  /* input */
405  poll_wait(file, &input_sleeper[dev], wait);
406  if (DATA_AVAIL(midi_in_buf[dev]))
407  mask |= POLLIN | POLLRDNORM;
408 
409  /* output */
410  poll_wait(file, &midi_sleeper[dev], wait);
411  if (!SPACE_AVAIL(midi_out_buf[dev]))
412  mask |= POLLOUT | POLLWRNORM;
413 
414  return mask;
415 }
416 
417 
418 int MIDIbuf_avail(int dev)
419 {
420  if (midi_in_buf[dev])
421  return DATA_AVAIL (midi_in_buf[dev]);
422  return 0;
423 }
425