]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blob - sound/core/rawmidi.c
Merge git://git.infradead.org/mtd-2.6
[linux-2.6-omap-h63xx.git] / sound / core / rawmidi.c
1 /*
2  *  Abstract layer for MIDI v1.0 stream
3  *  Copyright (c) by Jaroslav Kysela <perex@perex.cz>
4  *
5  *
6  *   This program is free software; you can redistribute it and/or modify
7  *   it under the terms of the GNU General Public License as published by
8  *   the Free Software Foundation; either version 2 of the License, or
9  *   (at your option) any later version.
10  *
11  *   This program is distributed in the hope that it will be useful,
12  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  *   GNU General Public License for more details.
15  *
16  *   You should have received a copy of the GNU General Public License
17  *   along with this program; if not, write to the Free Software
18  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
19  *
20  */
21
22 #include <sound/core.h>
23 #include <linux/major.h>
24 #include <linux/init.h>
25 #include <linux/sched.h>
26 #include <linux/slab.h>
27 #include <linux/time.h>
28 #include <linux/wait.h>
29 #include <linux/mutex.h>
30 #include <linux/moduleparam.h>
31 #include <linux/delay.h>
32 #include <sound/rawmidi.h>
33 #include <sound/info.h>
34 #include <sound/control.h>
35 #include <sound/minors.h>
36 #include <sound/initval.h>
37
38 MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>");
39 MODULE_DESCRIPTION("Midlevel RawMidi code for ALSA.");
40 MODULE_LICENSE("GPL");
41
42 #ifdef CONFIG_SND_OSSEMUL
43 static int midi_map[SNDRV_CARDS];
44 static int amidi_map[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS-1)] = 1};
45 module_param_array(midi_map, int, NULL, 0444);
46 MODULE_PARM_DESC(midi_map, "Raw MIDI device number assigned to 1st OSS device.");
47 module_param_array(amidi_map, int, NULL, 0444);
48 MODULE_PARM_DESC(amidi_map, "Raw MIDI device number assigned to 2nd OSS device.");
49 #endif /* CONFIG_SND_OSSEMUL */
50
51 static int snd_rawmidi_free(struct snd_rawmidi *rawmidi);
52 static int snd_rawmidi_dev_free(struct snd_device *device);
53 static int snd_rawmidi_dev_register(struct snd_device *device);
54 static int snd_rawmidi_dev_disconnect(struct snd_device *device);
55
56 static LIST_HEAD(snd_rawmidi_devices);
57 static DEFINE_MUTEX(register_mutex);
58
59 static struct snd_rawmidi *snd_rawmidi_search(struct snd_card *card, int device)
60 {
61         struct snd_rawmidi *rawmidi;
62
63         list_for_each_entry(rawmidi, &snd_rawmidi_devices, list)
64                 if (rawmidi->card == card && rawmidi->device == device)
65                         return rawmidi;
66         return NULL;
67 }
68
69 static inline unsigned short snd_rawmidi_file_flags(struct file *file)
70 {
71         switch (file->f_mode & (FMODE_READ | FMODE_WRITE)) {
72         case FMODE_WRITE:
73                 return SNDRV_RAWMIDI_LFLG_OUTPUT;
74         case FMODE_READ:
75                 return SNDRV_RAWMIDI_LFLG_INPUT;
76         default:
77                 return SNDRV_RAWMIDI_LFLG_OPEN;
78         }
79 }
80
81 static inline int snd_rawmidi_ready(struct snd_rawmidi_substream *substream)
82 {
83         struct snd_rawmidi_runtime *runtime = substream->runtime;
84         return runtime->avail >= runtime->avail_min;
85 }
86
87 static inline int snd_rawmidi_ready_append(struct snd_rawmidi_substream *substream,
88                                            size_t count)
89 {
90         struct snd_rawmidi_runtime *runtime = substream->runtime;
91         return runtime->avail >= runtime->avail_min &&
92                (!substream->append || runtime->avail >= count);
93 }
94
95 static void snd_rawmidi_input_event_tasklet(unsigned long data)
96 {
97         struct snd_rawmidi_substream *substream = (struct snd_rawmidi_substream *)data;
98         substream->runtime->event(substream);
99 }
100
101 static void snd_rawmidi_output_trigger_tasklet(unsigned long data)
102 {
103         struct snd_rawmidi_substream *substream = (struct snd_rawmidi_substream *)data;
104         substream->ops->trigger(substream, 1);
105 }
106
107 static int snd_rawmidi_runtime_create(struct snd_rawmidi_substream *substream)
108 {
109         struct snd_rawmidi_runtime *runtime;
110
111         if ((runtime = kzalloc(sizeof(*runtime), GFP_KERNEL)) == NULL)
112                 return -ENOMEM;
113         spin_lock_init(&runtime->lock);
114         init_waitqueue_head(&runtime->sleep);
115         if (substream->stream == SNDRV_RAWMIDI_STREAM_INPUT)
116                 tasklet_init(&runtime->tasklet,
117                              snd_rawmidi_input_event_tasklet,
118                              (unsigned long)substream);
119         else
120                 tasklet_init(&runtime->tasklet,
121                              snd_rawmidi_output_trigger_tasklet,
122                              (unsigned long)substream);
123         runtime->event = NULL;
124         runtime->buffer_size = PAGE_SIZE;
125         runtime->avail_min = 1;
126         if (substream->stream == SNDRV_RAWMIDI_STREAM_INPUT)
127                 runtime->avail = 0;
128         else
129                 runtime->avail = runtime->buffer_size;
130         if ((runtime->buffer = kmalloc(runtime->buffer_size, GFP_KERNEL)) == NULL) {
131                 kfree(runtime);
132                 return -ENOMEM;
133         }
134         runtime->appl_ptr = runtime->hw_ptr = 0;
135         substream->runtime = runtime;
136         return 0;
137 }
138
139 static int snd_rawmidi_runtime_free(struct snd_rawmidi_substream *substream)
140 {
141         struct snd_rawmidi_runtime *runtime = substream->runtime;
142
143         kfree(runtime->buffer);
144         kfree(runtime);
145         substream->runtime = NULL;
146         return 0;
147 }
148
149 static inline void snd_rawmidi_output_trigger(struct snd_rawmidi_substream *substream,int up)
150 {
151         if (!substream->opened)
152                 return;
153         if (up) {
154                 tasklet_hi_schedule(&substream->runtime->tasklet);
155         } else {
156                 tasklet_kill(&substream->runtime->tasklet);
157                 substream->ops->trigger(substream, 0);
158         }
159 }
160
161 static void snd_rawmidi_input_trigger(struct snd_rawmidi_substream *substream, int up)
162 {
163         if (!substream->opened)
164                 return;
165         substream->ops->trigger(substream, up);
166         if (!up && substream->runtime->event)
167                 tasklet_kill(&substream->runtime->tasklet);
168 }
169
170 int snd_rawmidi_drop_output(struct snd_rawmidi_substream *substream)
171 {
172         unsigned long flags;
173         struct snd_rawmidi_runtime *runtime = substream->runtime;
174
175         snd_rawmidi_output_trigger(substream, 0);
176         runtime->drain = 0;
177         spin_lock_irqsave(&runtime->lock, flags);
178         runtime->appl_ptr = runtime->hw_ptr = 0;
179         runtime->avail = runtime->buffer_size;
180         spin_unlock_irqrestore(&runtime->lock, flags);
181         return 0;
182 }
183
184 int snd_rawmidi_drain_output(struct snd_rawmidi_substream *substream)
185 {
186         int err;
187         long timeout;
188         struct snd_rawmidi_runtime *runtime = substream->runtime;
189
190         err = 0;
191         runtime->drain = 1;
192         timeout = wait_event_interruptible_timeout(runtime->sleep,
193                                 (runtime->avail >= runtime->buffer_size),
194                                 10*HZ);
195         if (signal_pending(current))
196                 err = -ERESTARTSYS;
197         if (runtime->avail < runtime->buffer_size && !timeout) {
198                 snd_printk(KERN_WARNING "rawmidi drain error (avail = %li, buffer_size = %li)\n", (long)runtime->avail, (long)runtime->buffer_size);
199                 err = -EIO;
200         }
201         runtime->drain = 0;
202         if (err != -ERESTARTSYS) {
203                 /* we need wait a while to make sure that Tx FIFOs are empty */
204                 if (substream->ops->drain)
205                         substream->ops->drain(substream);
206                 else
207                         msleep(50);
208                 snd_rawmidi_drop_output(substream);
209         }
210         return err;
211 }
212
213 int snd_rawmidi_drain_input(struct snd_rawmidi_substream *substream)
214 {
215         unsigned long flags;
216         struct snd_rawmidi_runtime *runtime = substream->runtime;
217
218         snd_rawmidi_input_trigger(substream, 0);
219         runtime->drain = 0;
220         spin_lock_irqsave(&runtime->lock, flags);
221         runtime->appl_ptr = runtime->hw_ptr = 0;
222         runtime->avail = 0;
223         spin_unlock_irqrestore(&runtime->lock, flags);
224         return 0;
225 }
226
227 int snd_rawmidi_kernel_open(struct snd_card *card, int device, int subdevice,
228                             int mode, struct snd_rawmidi_file * rfile)
229 {
230         struct snd_rawmidi *rmidi;
231         struct list_head *list1, *list2;
232         struct snd_rawmidi_substream *sinput = NULL, *soutput = NULL;
233         struct snd_rawmidi_runtime *input = NULL, *output = NULL;
234         int err;
235
236         if (rfile)
237                 rfile->input = rfile->output = NULL;
238         mutex_lock(&register_mutex);
239         rmidi = snd_rawmidi_search(card, device);
240         mutex_unlock(&register_mutex);
241         if (rmidi == NULL) {
242                 err = -ENODEV;
243                 goto __error1;
244         }
245         if (!try_module_get(rmidi->card->module)) {
246                 err = -EFAULT;
247                 goto __error1;
248         }
249         if (!(mode & SNDRV_RAWMIDI_LFLG_NOOPENLOCK))
250                 mutex_lock(&rmidi->open_mutex);
251         if (mode & SNDRV_RAWMIDI_LFLG_INPUT) {
252                 if (!(rmidi->info_flags & SNDRV_RAWMIDI_INFO_INPUT)) {
253                         err = -ENXIO;
254                         goto __error;
255                 }
256                 if (subdevice >= 0 && (unsigned int)subdevice >= rmidi->streams[SNDRV_RAWMIDI_STREAM_INPUT].substream_count) {
257                         err = -ENODEV;
258                         goto __error;
259                 }
260                 if (rmidi->streams[SNDRV_RAWMIDI_STREAM_INPUT].substream_opened >=
261                     rmidi->streams[SNDRV_RAWMIDI_STREAM_INPUT].substream_count) {
262                         err = -EAGAIN;
263                         goto __error;
264                 }
265         }
266         if (mode & SNDRV_RAWMIDI_LFLG_OUTPUT) {
267                 if (!(rmidi->info_flags & SNDRV_RAWMIDI_INFO_OUTPUT)) {
268                         err = -ENXIO;
269                         goto __error;
270                 }
271                 if (subdevice >= 0 && (unsigned int)subdevice >= rmidi->streams[SNDRV_RAWMIDI_STREAM_OUTPUT].substream_count) {
272                         err = -ENODEV;
273                         goto __error;
274                 }
275                 if (rmidi->streams[SNDRV_RAWMIDI_STREAM_OUTPUT].substream_opened >=
276                     rmidi->streams[SNDRV_RAWMIDI_STREAM_OUTPUT].substream_count) {
277                         err = -EAGAIN;
278                         goto __error;
279                 }
280         }
281         list1 = rmidi->streams[SNDRV_RAWMIDI_STREAM_INPUT].substreams.next;
282         while (1) {
283                 if (list1 == &rmidi->streams[SNDRV_RAWMIDI_STREAM_INPUT].substreams) {
284                         sinput = NULL;
285                         if (mode & SNDRV_RAWMIDI_LFLG_INPUT) {
286                                 err = -EAGAIN;
287                                 goto __error;
288                         }
289                         break;
290                 }
291                 sinput = list_entry(list1, struct snd_rawmidi_substream, list);
292                 if ((mode & SNDRV_RAWMIDI_LFLG_INPUT) && sinput->opened)
293                         goto __nexti;
294                 if (subdevice < 0 || (subdevice >= 0 && subdevice == sinput->number))
295                         break;
296               __nexti:
297                 list1 = list1->next;
298         }
299         list2 = rmidi->streams[SNDRV_RAWMIDI_STREAM_OUTPUT].substreams.next;
300         while (1) {
301                 if (list2 == &rmidi->streams[SNDRV_RAWMIDI_STREAM_OUTPUT].substreams) {
302                         soutput = NULL;
303                         if (mode & SNDRV_RAWMIDI_LFLG_OUTPUT) {
304                                 err = -EAGAIN;
305                                 goto __error;
306                         }
307                         break;
308                 }
309                 soutput = list_entry(list2, struct snd_rawmidi_substream, list);
310                 if (mode & SNDRV_RAWMIDI_LFLG_OUTPUT) {
311                         if (mode & SNDRV_RAWMIDI_LFLG_APPEND) {
312                                 if (soutput->opened && !soutput->append)
313                                         goto __nexto;
314                         } else {
315                                 if (soutput->opened)
316                                         goto __nexto;
317                         }
318                 }
319                 if (subdevice < 0 || (subdevice >= 0 && subdevice == soutput->number))
320                         break;
321               __nexto:
322                 list2 = list2->next;
323         }
324         if (mode & SNDRV_RAWMIDI_LFLG_INPUT) {
325                 if ((err = snd_rawmidi_runtime_create(sinput)) < 0)
326                         goto __error;
327                 input = sinput->runtime;
328                 if ((err = sinput->ops->open(sinput)) < 0)
329                         goto __error;
330                 sinput->opened = 1;
331                 rmidi->streams[SNDRV_RAWMIDI_STREAM_INPUT].substream_opened++;
332         } else {
333                 sinput = NULL;
334         }
335         if (mode & SNDRV_RAWMIDI_LFLG_OUTPUT) {
336                 if (soutput->opened)
337                         goto __skip_output;
338                 if ((err = snd_rawmidi_runtime_create(soutput)) < 0) {
339                         if (mode & SNDRV_RAWMIDI_LFLG_INPUT)
340                                 sinput->ops->close(sinput);
341                         goto __error;
342                 }
343                 output = soutput->runtime;
344                 if ((err = soutput->ops->open(soutput)) < 0) {
345                         if (mode & SNDRV_RAWMIDI_LFLG_INPUT)
346                                 sinput->ops->close(sinput);
347                         goto __error;
348                 }
349               __skip_output:
350                 soutput->opened = 1;
351                 if (mode & SNDRV_RAWMIDI_LFLG_APPEND)
352                         soutput->append = 1;
353                 if (soutput->use_count++ == 0)
354                         soutput->active_sensing = 1;
355                 rmidi->streams[SNDRV_RAWMIDI_STREAM_OUTPUT].substream_opened++;
356         } else {
357                 soutput = NULL;
358         }
359         if (!(mode & SNDRV_RAWMIDI_LFLG_NOOPENLOCK))
360                 mutex_unlock(&rmidi->open_mutex);
361         if (rfile) {
362                 rfile->rmidi = rmidi;
363                 rfile->input = sinput;
364                 rfile->output = soutput;
365         }
366         return 0;
367
368       __error:
369         if (input != NULL)
370                 snd_rawmidi_runtime_free(sinput);
371         if (output != NULL)
372                 snd_rawmidi_runtime_free(soutput);
373         module_put(rmidi->card->module);
374         if (!(mode & SNDRV_RAWMIDI_LFLG_NOOPENLOCK))
375                 mutex_unlock(&rmidi->open_mutex);
376       __error1:
377         return err;
378 }
379
380 static int snd_rawmidi_open(struct inode *inode, struct file *file)
381 {
382         int maj = imajor(inode);
383         struct snd_card *card;
384         int subdevice;
385         unsigned short fflags;
386         int err;
387         struct snd_rawmidi *rmidi;
388         struct snd_rawmidi_file *rawmidi_file;
389         wait_queue_t wait;
390         struct snd_ctl_file *kctl;
391
392         if (maj == snd_major) {
393                 rmidi = snd_lookup_minor_data(iminor(inode),
394                                               SNDRV_DEVICE_TYPE_RAWMIDI);
395 #ifdef CONFIG_SND_OSSEMUL
396         } else if (maj == SOUND_MAJOR) {
397                 rmidi = snd_lookup_oss_minor_data(iminor(inode),
398                                                   SNDRV_OSS_DEVICE_TYPE_MIDI);
399 #endif
400         } else
401                 return -ENXIO;
402
403         if (rmidi == NULL)
404                 return -ENODEV;
405         if ((file->f_flags & O_APPEND) && !(file->f_flags & O_NONBLOCK)) 
406                 return -EINVAL;         /* invalid combination */
407         card = rmidi->card;
408         err = snd_card_file_add(card, file);
409         if (err < 0)
410                 return -ENODEV;
411         fflags = snd_rawmidi_file_flags(file);
412         if ((file->f_flags & O_APPEND) || maj == SOUND_MAJOR) /* OSS emul? */
413                 fflags |= SNDRV_RAWMIDI_LFLG_APPEND;
414         fflags |= SNDRV_RAWMIDI_LFLG_NOOPENLOCK;
415         rawmidi_file = kmalloc(sizeof(*rawmidi_file), GFP_KERNEL);
416         if (rawmidi_file == NULL) {
417                 snd_card_file_remove(card, file);
418                 return -ENOMEM;
419         }
420         init_waitqueue_entry(&wait, current);
421         add_wait_queue(&rmidi->open_wait, &wait);
422         mutex_lock(&rmidi->open_mutex);
423         while (1) {
424                 subdevice = -1;
425                 read_lock(&card->ctl_files_rwlock);
426                 list_for_each_entry(kctl, &card->ctl_files, list) {
427                         if (kctl->pid == current->pid) {
428                                 subdevice = kctl->prefer_rawmidi_subdevice;
429                                 if (subdevice != -1)
430                                         break;
431                         }
432                 }
433                 read_unlock(&card->ctl_files_rwlock);
434                 err = snd_rawmidi_kernel_open(rmidi->card, rmidi->device,
435                                               subdevice, fflags, rawmidi_file);
436                 if (err >= 0)
437                         break;
438                 if (err == -EAGAIN) {
439                         if (file->f_flags & O_NONBLOCK) {
440                                 err = -EBUSY;
441                                 break;
442                         }
443                 } else
444                         break;
445                 set_current_state(TASK_INTERRUPTIBLE);
446                 mutex_unlock(&rmidi->open_mutex);
447                 schedule();
448                 mutex_lock(&rmidi->open_mutex);
449                 if (signal_pending(current)) {
450                         err = -ERESTARTSYS;
451                         break;
452                 }
453         }
454 #ifdef CONFIG_SND_OSSEMUL
455         if (rawmidi_file->input && rawmidi_file->input->runtime)
456                 rawmidi_file->input->runtime->oss = (maj == SOUND_MAJOR);
457         if (rawmidi_file->output && rawmidi_file->output->runtime)
458                 rawmidi_file->output->runtime->oss = (maj == SOUND_MAJOR);
459 #endif
460         remove_wait_queue(&rmidi->open_wait, &wait);
461         if (err >= 0) {
462                 file->private_data = rawmidi_file;
463         } else {
464                 snd_card_file_remove(card, file);
465                 kfree(rawmidi_file);
466         }
467         mutex_unlock(&rmidi->open_mutex);
468         return err;
469 }
470
471 int snd_rawmidi_kernel_release(struct snd_rawmidi_file * rfile)
472 {
473         struct snd_rawmidi *rmidi;
474         struct snd_rawmidi_substream *substream;
475         struct snd_rawmidi_runtime *runtime;
476
477         if (snd_BUG_ON(!rfile))
478                 return -ENXIO;
479         rmidi = rfile->rmidi;
480         mutex_lock(&rmidi->open_mutex);
481         if (rfile->input != NULL) {
482                 substream = rfile->input;
483                 rfile->input = NULL;
484                 runtime = substream->runtime;
485                 snd_rawmidi_input_trigger(substream, 0);
486                 substream->ops->close(substream);
487                 if (runtime->private_free != NULL)
488                         runtime->private_free(substream);
489                 snd_rawmidi_runtime_free(substream);
490                 substream->opened = 0;
491                 rmidi->streams[SNDRV_RAWMIDI_STREAM_INPUT].substream_opened--;
492         }
493         if (rfile->output != NULL) {
494                 substream = rfile->output;
495                 rfile->output = NULL;
496                 if (--substream->use_count == 0) {
497                         runtime = substream->runtime;
498                         if (substream->active_sensing) {
499                                 unsigned char buf = 0xfe;
500                                 /* sending single active sensing message to shut the device up */
501                                 snd_rawmidi_kernel_write(substream, &buf, 1);
502                         }
503                         if (snd_rawmidi_drain_output(substream) == -ERESTARTSYS)
504                                 snd_rawmidi_output_trigger(substream, 0);
505                         substream->ops->close(substream);
506                         if (runtime->private_free != NULL)
507                                 runtime->private_free(substream);
508                         snd_rawmidi_runtime_free(substream);
509                         substream->opened = 0;
510                         substream->append = 0;
511                 }
512                 rmidi->streams[SNDRV_RAWMIDI_STREAM_OUTPUT].substream_opened--;
513         }
514         mutex_unlock(&rmidi->open_mutex);
515         module_put(rmidi->card->module);
516         return 0;
517 }
518
519 static int snd_rawmidi_release(struct inode *inode, struct file *file)
520 {
521         struct snd_rawmidi_file *rfile;
522         struct snd_rawmidi *rmidi;
523         int err;
524
525         rfile = file->private_data;
526         err = snd_rawmidi_kernel_release(rfile);
527         rmidi = rfile->rmidi;
528         wake_up(&rmidi->open_wait);
529         kfree(rfile);
530         snd_card_file_remove(rmidi->card, file);
531         return err;
532 }
533
534 static int snd_rawmidi_info(struct snd_rawmidi_substream *substream,
535                             struct snd_rawmidi_info *info)
536 {
537         struct snd_rawmidi *rmidi;
538         
539         if (substream == NULL)
540                 return -ENODEV;
541         rmidi = substream->rmidi;
542         memset(info, 0, sizeof(*info));
543         info->card = rmidi->card->number;
544         info->device = rmidi->device;
545         info->subdevice = substream->number;
546         info->stream = substream->stream;
547         info->flags = rmidi->info_flags;
548         strcpy(info->id, rmidi->id);
549         strcpy(info->name, rmidi->name);
550         strcpy(info->subname, substream->name);
551         info->subdevices_count = substream->pstr->substream_count;
552         info->subdevices_avail = (substream->pstr->substream_count -
553                                   substream->pstr->substream_opened);
554         return 0;
555 }
556
557 static int snd_rawmidi_info_user(struct snd_rawmidi_substream *substream,
558                                  struct snd_rawmidi_info __user * _info)
559 {
560         struct snd_rawmidi_info info;
561         int err;
562         if ((err = snd_rawmidi_info(substream, &info)) < 0)
563                 return err;
564         if (copy_to_user(_info, &info, sizeof(struct snd_rawmidi_info)))
565                 return -EFAULT;
566         return 0;
567 }
568
569 int snd_rawmidi_info_select(struct snd_card *card, struct snd_rawmidi_info *info)
570 {
571         struct snd_rawmidi *rmidi;
572         struct snd_rawmidi_str *pstr;
573         struct snd_rawmidi_substream *substream;
574
575         mutex_lock(&register_mutex);
576         rmidi = snd_rawmidi_search(card, info->device);
577         mutex_unlock(&register_mutex);
578         if (!rmidi)
579                 return -ENXIO;
580         if (info->stream < 0 || info->stream > 1)
581                 return -EINVAL;
582         pstr = &rmidi->streams[info->stream];
583         if (pstr->substream_count == 0)
584                 return -ENOENT;
585         if (info->subdevice >= pstr->substream_count)
586                 return -ENXIO;
587         list_for_each_entry(substream, &pstr->substreams, list) {
588                 if ((unsigned int)substream->number == info->subdevice)
589                         return snd_rawmidi_info(substream, info);
590         }
591         return -ENXIO;
592 }
593
594 static int snd_rawmidi_info_select_user(struct snd_card *card,
595                                         struct snd_rawmidi_info __user *_info)
596 {
597         int err;
598         struct snd_rawmidi_info info;
599         if (get_user(info.device, &_info->device))
600                 return -EFAULT;
601         if (get_user(info.stream, &_info->stream))
602                 return -EFAULT;
603         if (get_user(info.subdevice, &_info->subdevice))
604                 return -EFAULT;
605         if ((err = snd_rawmidi_info_select(card, &info)) < 0)
606                 return err;
607         if (copy_to_user(_info, &info, sizeof(struct snd_rawmidi_info)))
608                 return -EFAULT;
609         return 0;
610 }
611
612 int snd_rawmidi_output_params(struct snd_rawmidi_substream *substream,
613                               struct snd_rawmidi_params * params)
614 {
615         char *newbuf;
616         struct snd_rawmidi_runtime *runtime = substream->runtime;
617         
618         if (substream->append && substream->use_count > 1)
619                 return -EBUSY;
620         snd_rawmidi_drain_output(substream);
621         if (params->buffer_size < 32 || params->buffer_size > 1024L * 1024L) {
622                 return -EINVAL;
623         }
624         if (params->avail_min < 1 || params->avail_min > params->buffer_size) {
625                 return -EINVAL;
626         }
627         if (params->buffer_size != runtime->buffer_size) {
628                 newbuf = kmalloc(params->buffer_size, GFP_KERNEL);
629                 if (!newbuf)
630                         return -ENOMEM;
631                 kfree(runtime->buffer);
632                 runtime->buffer = newbuf;
633                 runtime->buffer_size = params->buffer_size;
634                 runtime->avail = runtime->buffer_size;
635         }
636         runtime->avail_min = params->avail_min;
637         substream->active_sensing = !params->no_active_sensing;
638         return 0;
639 }
640
641 int snd_rawmidi_input_params(struct snd_rawmidi_substream *substream,
642                              struct snd_rawmidi_params * params)
643 {
644         char *newbuf;
645         struct snd_rawmidi_runtime *runtime = substream->runtime;
646
647         snd_rawmidi_drain_input(substream);
648         if (params->buffer_size < 32 || params->buffer_size > 1024L * 1024L) {
649                 return -EINVAL;
650         }
651         if (params->avail_min < 1 || params->avail_min > params->buffer_size) {
652                 return -EINVAL;
653         }
654         if (params->buffer_size != runtime->buffer_size) {
655                 newbuf = kmalloc(params->buffer_size, GFP_KERNEL);
656                 if (!newbuf)
657                         return -ENOMEM;
658                 kfree(runtime->buffer);
659                 runtime->buffer = newbuf;
660                 runtime->buffer_size = params->buffer_size;
661         }
662         runtime->avail_min = params->avail_min;
663         return 0;
664 }
665
666 static int snd_rawmidi_output_status(struct snd_rawmidi_substream *substream,
667                                      struct snd_rawmidi_status * status)
668 {
669         struct snd_rawmidi_runtime *runtime = substream->runtime;
670
671         memset(status, 0, sizeof(*status));
672         status->stream = SNDRV_RAWMIDI_STREAM_OUTPUT;
673         spin_lock_irq(&runtime->lock);
674         status->avail = runtime->avail;
675         spin_unlock_irq(&runtime->lock);
676         return 0;
677 }
678
679 static int snd_rawmidi_input_status(struct snd_rawmidi_substream *substream,
680                                     struct snd_rawmidi_status * status)
681 {
682         struct snd_rawmidi_runtime *runtime = substream->runtime;
683
684         memset(status, 0, sizeof(*status));
685         status->stream = SNDRV_RAWMIDI_STREAM_INPUT;
686         spin_lock_irq(&runtime->lock);
687         status->avail = runtime->avail;
688         status->xruns = runtime->xruns;
689         runtime->xruns = 0;
690         spin_unlock_irq(&runtime->lock);
691         return 0;
692 }
693
694 static long snd_rawmidi_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
695 {
696         struct snd_rawmidi_file *rfile;
697         void __user *argp = (void __user *)arg;
698
699         rfile = file->private_data;
700         if (((cmd >> 8) & 0xff) != 'W')
701                 return -ENOTTY;
702         switch (cmd) {
703         case SNDRV_RAWMIDI_IOCTL_PVERSION:
704                 return put_user(SNDRV_RAWMIDI_VERSION, (int __user *)argp) ? -EFAULT : 0;
705         case SNDRV_RAWMIDI_IOCTL_INFO:
706         {
707                 int stream;
708                 struct snd_rawmidi_info __user *info = argp;
709                 if (get_user(stream, &info->stream))
710                         return -EFAULT;
711                 switch (stream) {
712                 case SNDRV_RAWMIDI_STREAM_INPUT:
713                         return snd_rawmidi_info_user(rfile->input, info);
714                 case SNDRV_RAWMIDI_STREAM_OUTPUT:
715                         return snd_rawmidi_info_user(rfile->output, info);
716                 default:
717                         return -EINVAL;
718                 }
719         }
720         case SNDRV_RAWMIDI_IOCTL_PARAMS:
721         {
722                 struct snd_rawmidi_params params;
723                 if (copy_from_user(&params, argp, sizeof(struct snd_rawmidi_params)))
724                         return -EFAULT;
725                 switch (params.stream) {
726                 case SNDRV_RAWMIDI_STREAM_OUTPUT:
727                         if (rfile->output == NULL)
728                                 return -EINVAL;
729                         return snd_rawmidi_output_params(rfile->output, &params);
730                 case SNDRV_RAWMIDI_STREAM_INPUT:
731                         if (rfile->input == NULL)
732                                 return -EINVAL;
733                         return snd_rawmidi_input_params(rfile->input, &params);
734                 default:
735                         return -EINVAL;
736                 }
737         }
738         case SNDRV_RAWMIDI_IOCTL_STATUS:
739         {
740                 int err = 0;
741                 struct snd_rawmidi_status status;
742                 if (copy_from_user(&status, argp, sizeof(struct snd_rawmidi_status)))
743                         return -EFAULT;
744                 switch (status.stream) {
745                 case SNDRV_RAWMIDI_STREAM_OUTPUT:
746                         if (rfile->output == NULL)
747                                 return -EINVAL;
748                         err = snd_rawmidi_output_status(rfile->output, &status);
749                         break;
750                 case SNDRV_RAWMIDI_STREAM_INPUT:
751                         if (rfile->input == NULL)
752                                 return -EINVAL;
753                         err = snd_rawmidi_input_status(rfile->input, &status);
754                         break;
755                 default:
756                         return -EINVAL;
757                 }
758                 if (err < 0)
759                         return err;
760                 if (copy_to_user(argp, &status, sizeof(struct snd_rawmidi_status)))
761                         return -EFAULT;
762                 return 0;
763         }
764         case SNDRV_RAWMIDI_IOCTL_DROP:
765         {
766                 int val;
767                 if (get_user(val, (int __user *) argp))
768                         return -EFAULT;
769                 switch (val) {
770                 case SNDRV_RAWMIDI_STREAM_OUTPUT:
771                         if (rfile->output == NULL)
772                                 return -EINVAL;
773                         return snd_rawmidi_drop_output(rfile->output);
774                 default:
775                         return -EINVAL;
776                 }
777         }
778         case SNDRV_RAWMIDI_IOCTL_DRAIN:
779         {
780                 int val;
781                 if (get_user(val, (int __user *) argp))
782                         return -EFAULT;
783                 switch (val) {
784                 case SNDRV_RAWMIDI_STREAM_OUTPUT:
785                         if (rfile->output == NULL)
786                                 return -EINVAL;
787                         return snd_rawmidi_drain_output(rfile->output);
788                 case SNDRV_RAWMIDI_STREAM_INPUT:
789                         if (rfile->input == NULL)
790                                 return -EINVAL;
791                         return snd_rawmidi_drain_input(rfile->input);
792                 default:
793                         return -EINVAL;
794                 }
795         }
796 #ifdef CONFIG_SND_DEBUG
797         default:
798                 snd_printk(KERN_WARNING "rawmidi: unknown command = 0x%x\n", cmd);
799 #endif
800         }
801         return -ENOTTY;
802 }
803
804 static int snd_rawmidi_control_ioctl(struct snd_card *card,
805                                      struct snd_ctl_file *control,
806                                      unsigned int cmd,
807                                      unsigned long arg)
808 {
809         void __user *argp = (void __user *)arg;
810
811         switch (cmd) {
812         case SNDRV_CTL_IOCTL_RAWMIDI_NEXT_DEVICE:
813         {
814                 int device;
815                 
816                 if (get_user(device, (int __user *)argp))
817                         return -EFAULT;
818                 mutex_lock(&register_mutex);
819                 device = device < 0 ? 0 : device + 1;
820                 while (device < SNDRV_RAWMIDI_DEVICES) {
821                         if (snd_rawmidi_search(card, device))
822                                 break;
823                         device++;
824                 }
825                 if (device == SNDRV_RAWMIDI_DEVICES)
826                         device = -1;
827                 mutex_unlock(&register_mutex);
828                 if (put_user(device, (int __user *)argp))
829                         return -EFAULT;
830                 return 0;
831         }
832         case SNDRV_CTL_IOCTL_RAWMIDI_PREFER_SUBDEVICE:
833         {
834                 int val;
835                 
836                 if (get_user(val, (int __user *)argp))
837                         return -EFAULT;
838                 control->prefer_rawmidi_subdevice = val;
839                 return 0;
840         }
841         case SNDRV_CTL_IOCTL_RAWMIDI_INFO:
842                 return snd_rawmidi_info_select_user(card, argp);
843         }
844         return -ENOIOCTLCMD;
845 }
846
847 /**
848  * snd_rawmidi_receive - receive the input data from the device
849  * @substream: the rawmidi substream
850  * @buffer: the buffer pointer
851  * @count: the data size to read
852  *
853  * Reads the data from the internal buffer.
854  *
855  * Returns the size of read data, or a negative error code on failure.
856  */
857 int snd_rawmidi_receive(struct snd_rawmidi_substream *substream,
858                         const unsigned char *buffer, int count)
859 {
860         unsigned long flags;
861         int result = 0, count1;
862         struct snd_rawmidi_runtime *runtime = substream->runtime;
863
864         if (!substream->opened)
865                 return -EBADFD;
866         if (runtime->buffer == NULL) {
867                 snd_printd("snd_rawmidi_receive: input is not active!!!\n");
868                 return -EINVAL;
869         }
870         spin_lock_irqsave(&runtime->lock, flags);
871         if (count == 1) {       /* special case, faster code */
872                 substream->bytes++;
873                 if (runtime->avail < runtime->buffer_size) {
874                         runtime->buffer[runtime->hw_ptr++] = buffer[0];
875                         runtime->hw_ptr %= runtime->buffer_size;
876                         runtime->avail++;
877                         result++;
878                 } else {
879                         runtime->xruns++;
880                 }
881         } else {
882                 substream->bytes += count;
883                 count1 = runtime->buffer_size - runtime->hw_ptr;
884                 if (count1 > count)
885                         count1 = count;
886                 if (count1 > (int)(runtime->buffer_size - runtime->avail))
887                         count1 = runtime->buffer_size - runtime->avail;
888                 memcpy(runtime->buffer + runtime->hw_ptr, buffer, count1);
889                 runtime->hw_ptr += count1;
890                 runtime->hw_ptr %= runtime->buffer_size;
891                 runtime->avail += count1;
892                 count -= count1;
893                 result += count1;
894                 if (count > 0) {
895                         buffer += count1;
896                         count1 = count;
897                         if (count1 > (int)(runtime->buffer_size - runtime->avail)) {
898                                 count1 = runtime->buffer_size - runtime->avail;
899                                 runtime->xruns += count - count1;
900                         }
901                         if (count1 > 0) {
902                                 memcpy(runtime->buffer, buffer, count1);
903                                 runtime->hw_ptr = count1;
904                                 runtime->avail += count1;
905                                 result += count1;
906                         }
907                 }
908         }
909         if (result > 0) {
910                 if (runtime->event)
911                         tasklet_hi_schedule(&runtime->tasklet);
912                 else if (snd_rawmidi_ready(substream))
913                         wake_up(&runtime->sleep);
914         }
915         spin_unlock_irqrestore(&runtime->lock, flags);
916         return result;
917 }
918
919 static long snd_rawmidi_kernel_read1(struct snd_rawmidi_substream *substream,
920                                      unsigned char __user *userbuf,
921                                      unsigned char *kernelbuf, long count)
922 {
923         unsigned long flags;
924         long result = 0, count1;
925         struct snd_rawmidi_runtime *runtime = substream->runtime;
926
927         while (count > 0 && runtime->avail) {
928                 count1 = runtime->buffer_size - runtime->appl_ptr;
929                 if (count1 > count)
930                         count1 = count;
931                 spin_lock_irqsave(&runtime->lock, flags);
932                 if (count1 > (int)runtime->avail)
933                         count1 = runtime->avail;
934                 if (kernelbuf)
935                         memcpy(kernelbuf + result, runtime->buffer + runtime->appl_ptr, count1);
936                 if (userbuf) {
937                         spin_unlock_irqrestore(&runtime->lock, flags);
938                         if (copy_to_user(userbuf + result,
939                                          runtime->buffer + runtime->appl_ptr, count1)) {
940                                 return result > 0 ? result : -EFAULT;
941                         }
942                         spin_lock_irqsave(&runtime->lock, flags);
943                 }
944                 runtime->appl_ptr += count1;
945                 runtime->appl_ptr %= runtime->buffer_size;
946                 runtime->avail -= count1;
947                 spin_unlock_irqrestore(&runtime->lock, flags);
948                 result += count1;
949                 count -= count1;
950         }
951         return result;
952 }
953
954 long snd_rawmidi_kernel_read(struct snd_rawmidi_substream *substream,
955                              unsigned char *buf, long count)
956 {
957         snd_rawmidi_input_trigger(substream, 1);
958         return snd_rawmidi_kernel_read1(substream, NULL/*userbuf*/, buf, count);
959 }
960
961 static ssize_t snd_rawmidi_read(struct file *file, char __user *buf, size_t count,
962                                 loff_t *offset)
963 {
964         long result;
965         int count1;
966         struct snd_rawmidi_file *rfile;
967         struct snd_rawmidi_substream *substream;
968         struct snd_rawmidi_runtime *runtime;
969
970         rfile = file->private_data;
971         substream = rfile->input;
972         if (substream == NULL)
973                 return -EIO;
974         runtime = substream->runtime;
975         snd_rawmidi_input_trigger(substream, 1);
976         result = 0;
977         while (count > 0) {
978                 spin_lock_irq(&runtime->lock);
979                 while (!snd_rawmidi_ready(substream)) {
980                         wait_queue_t wait;
981                         if ((file->f_flags & O_NONBLOCK) != 0 || result > 0) {
982                                 spin_unlock_irq(&runtime->lock);
983                                 return result > 0 ? result : -EAGAIN;
984                         }
985                         init_waitqueue_entry(&wait, current);
986                         add_wait_queue(&runtime->sleep, &wait);
987                         set_current_state(TASK_INTERRUPTIBLE);
988                         spin_unlock_irq(&runtime->lock);
989                         schedule();
990                         remove_wait_queue(&runtime->sleep, &wait);
991                         if (signal_pending(current))
992                                 return result > 0 ? result : -ERESTARTSYS;
993                         if (!runtime->avail)
994                                 return result > 0 ? result : -EIO;
995                         spin_lock_irq(&runtime->lock);
996                 }
997                 spin_unlock_irq(&runtime->lock);
998                 count1 = snd_rawmidi_kernel_read1(substream,
999                                                   (unsigned char __user *)buf,
1000                                                   NULL/*kernelbuf*/,
1001                                                   count);
1002                 if (count1 < 0)
1003                         return result > 0 ? result : count1;
1004                 result += count1;
1005                 buf += count1;
1006                 count -= count1;
1007         }
1008         return result;
1009 }
1010
1011 /**
1012  * snd_rawmidi_transmit_empty - check whether the output buffer is empty
1013  * @substream: the rawmidi substream
1014  * 
1015  * Returns 1 if the internal output buffer is empty, 0 if not.
1016  */
1017 int snd_rawmidi_transmit_empty(struct snd_rawmidi_substream *substream)
1018 {
1019         struct snd_rawmidi_runtime *runtime = substream->runtime;
1020         int result;
1021         unsigned long flags;
1022
1023         if (runtime->buffer == NULL) {
1024                 snd_printd("snd_rawmidi_transmit_empty: output is not active!!!\n");
1025                 return 1;
1026         }
1027         spin_lock_irqsave(&runtime->lock, flags);
1028         result = runtime->avail >= runtime->buffer_size;
1029         spin_unlock_irqrestore(&runtime->lock, flags);
1030         return result;          
1031 }
1032
1033 /**
1034  * snd_rawmidi_transmit_peek - copy data from the internal buffer
1035  * @substream: the rawmidi substream
1036  * @buffer: the buffer pointer
1037  * @count: data size to transfer
1038  *
1039  * Copies data from the internal output buffer to the given buffer.
1040  *
1041  * Call this in the interrupt handler when the midi output is ready,
1042  * and call snd_rawmidi_transmit_ack() after the transmission is
1043  * finished.
1044  *
1045  * Returns the size of copied data, or a negative error code on failure.
1046  */
1047 int snd_rawmidi_transmit_peek(struct snd_rawmidi_substream *substream,
1048                               unsigned char *buffer, int count)
1049 {
1050         unsigned long flags;
1051         int result, count1;
1052         struct snd_rawmidi_runtime *runtime = substream->runtime;
1053
1054         if (runtime->buffer == NULL) {
1055                 snd_printd("snd_rawmidi_transmit_peek: output is not active!!!\n");
1056                 return -EINVAL;
1057         }
1058         result = 0;
1059         spin_lock_irqsave(&runtime->lock, flags);
1060         if (runtime->avail >= runtime->buffer_size) {
1061                 /* warning: lowlevel layer MUST trigger down the hardware */
1062                 goto __skip;
1063         }
1064         if (count == 1) {       /* special case, faster code */
1065                 *buffer = runtime->buffer[runtime->hw_ptr];
1066                 result++;
1067         } else {
1068                 count1 = runtime->buffer_size - runtime->hw_ptr;
1069                 if (count1 > count)
1070                         count1 = count;
1071                 if (count1 > (int)(runtime->buffer_size - runtime->avail))
1072                         count1 = runtime->buffer_size - runtime->avail;
1073                 memcpy(buffer, runtime->buffer + runtime->hw_ptr, count1);
1074                 count -= count1;
1075                 result += count1;
1076                 if (count > 0) {
1077                         if (count > (int)(runtime->buffer_size - runtime->avail - count1))
1078                                 count = runtime->buffer_size - runtime->avail - count1;
1079                         memcpy(buffer + count1, runtime->buffer, count);
1080                         result += count;
1081                 }
1082         }
1083       __skip:
1084         spin_unlock_irqrestore(&runtime->lock, flags);
1085         return result;
1086 }
1087
1088 /**
1089  * snd_rawmidi_transmit_ack - acknowledge the transmission
1090  * @substream: the rawmidi substream
1091  * @count: the tranferred count
1092  *
1093  * Advances the hardware pointer for the internal output buffer with
1094  * the given size and updates the condition.
1095  * Call after the transmission is finished.
1096  *
1097  * Returns the advanced size if successful, or a negative error code on failure.
1098  */
1099 int snd_rawmidi_transmit_ack(struct snd_rawmidi_substream *substream, int count)
1100 {
1101         unsigned long flags;
1102         struct snd_rawmidi_runtime *runtime = substream->runtime;
1103
1104         if (runtime->buffer == NULL) {
1105                 snd_printd("snd_rawmidi_transmit_ack: output is not active!!!\n");
1106                 return -EINVAL;
1107         }
1108         spin_lock_irqsave(&runtime->lock, flags);
1109         snd_BUG_ON(runtime->avail + count > runtime->buffer_size);
1110         runtime->hw_ptr += count;
1111         runtime->hw_ptr %= runtime->buffer_size;
1112         runtime->avail += count;
1113         substream->bytes += count;
1114         if (count > 0) {
1115                 if (runtime->drain || snd_rawmidi_ready(substream))
1116                         wake_up(&runtime->sleep);
1117         }
1118         spin_unlock_irqrestore(&runtime->lock, flags);
1119         return count;
1120 }
1121
1122 /**
1123  * snd_rawmidi_transmit - copy from the buffer to the device
1124  * @substream: the rawmidi substream
1125  * @buffer: the buffer pointer
1126  * @count: the data size to transfer
1127  * 
1128  * Copies data from the buffer to the device and advances the pointer.
1129  *
1130  * Returns the copied size if successful, or a negative error code on failure.
1131  */
1132 int snd_rawmidi_transmit(struct snd_rawmidi_substream *substream,
1133                          unsigned char *buffer, int count)
1134 {
1135         if (!substream->opened)
1136                 return -EBADFD;
1137         count = snd_rawmidi_transmit_peek(substream, buffer, count);
1138         if (count < 0)
1139                 return count;
1140         return snd_rawmidi_transmit_ack(substream, count);
1141 }
1142
1143 static long snd_rawmidi_kernel_write1(struct snd_rawmidi_substream *substream,
1144                                       const unsigned char __user *userbuf,
1145                                       const unsigned char *kernelbuf,
1146                                       long count)
1147 {
1148         unsigned long flags;
1149         long count1, result;
1150         struct snd_rawmidi_runtime *runtime = substream->runtime;
1151
1152         if (snd_BUG_ON(!kernelbuf && !userbuf))
1153                 return -EINVAL;
1154         if (snd_BUG_ON(!runtime->buffer))
1155                 return -EINVAL;
1156
1157         result = 0;
1158         spin_lock_irqsave(&runtime->lock, flags);
1159         if (substream->append) {
1160                 if ((long)runtime->avail < count) {
1161                         spin_unlock_irqrestore(&runtime->lock, flags);
1162                         return -EAGAIN;
1163                 }
1164         }
1165         while (count > 0 && runtime->avail > 0) {
1166                 count1 = runtime->buffer_size - runtime->appl_ptr;
1167                 if (count1 > count)
1168                         count1 = count;
1169                 if (count1 > (long)runtime->avail)
1170                         count1 = runtime->avail;
1171                 if (kernelbuf)
1172                         memcpy(runtime->buffer + runtime->appl_ptr,
1173                                kernelbuf + result, count1);
1174                 else if (userbuf) {
1175                         spin_unlock_irqrestore(&runtime->lock, flags);
1176                         if (copy_from_user(runtime->buffer + runtime->appl_ptr,
1177                                            userbuf + result, count1)) {
1178                                 spin_lock_irqsave(&runtime->lock, flags);
1179                                 result = result > 0 ? result : -EFAULT;
1180                                 goto __end;
1181                         }
1182                         spin_lock_irqsave(&runtime->lock, flags);
1183                 }
1184                 runtime->appl_ptr += count1;
1185                 runtime->appl_ptr %= runtime->buffer_size;
1186                 runtime->avail -= count1;
1187                 result += count1;
1188                 count -= count1;
1189         }
1190       __end:
1191         count1 = runtime->avail < runtime->buffer_size;
1192         spin_unlock_irqrestore(&runtime->lock, flags);
1193         if (count1)
1194                 snd_rawmidi_output_trigger(substream, 1);
1195         return result;
1196 }
1197
1198 long snd_rawmidi_kernel_write(struct snd_rawmidi_substream *substream,
1199                               const unsigned char *buf, long count)
1200 {
1201         return snd_rawmidi_kernel_write1(substream, NULL, buf, count);
1202 }
1203
1204 static ssize_t snd_rawmidi_write(struct file *file, const char __user *buf,
1205                                  size_t count, loff_t *offset)
1206 {
1207         long result, timeout;
1208         int count1;
1209         struct snd_rawmidi_file *rfile;
1210         struct snd_rawmidi_runtime *runtime;
1211         struct snd_rawmidi_substream *substream;
1212
1213         rfile = file->private_data;
1214         substream = rfile->output;
1215         runtime = substream->runtime;
1216         /* we cannot put an atomic message to our buffer */
1217         if (substream->append && count > runtime->buffer_size)
1218                 return -EIO;
1219         result = 0;
1220         while (count > 0) {
1221                 spin_lock_irq(&runtime->lock);
1222                 while (!snd_rawmidi_ready_append(substream, count)) {
1223                         wait_queue_t wait;
1224                         if (file->f_flags & O_NONBLOCK) {
1225                                 spin_unlock_irq(&runtime->lock);
1226                                 return result > 0 ? result : -EAGAIN;
1227                         }
1228                         init_waitqueue_entry(&wait, current);
1229                         add_wait_queue(&runtime->sleep, &wait);
1230                         set_current_state(TASK_INTERRUPTIBLE);
1231                         spin_unlock_irq(&runtime->lock);
1232                         timeout = schedule_timeout(30 * HZ);
1233                         remove_wait_queue(&runtime->sleep, &wait);
1234                         if (signal_pending(current))
1235                                 return result > 0 ? result : -ERESTARTSYS;
1236                         if (!runtime->avail && !timeout)
1237                                 return result > 0 ? result : -EIO;
1238                         spin_lock_irq(&runtime->lock);
1239                 }
1240                 spin_unlock_irq(&runtime->lock);
1241                 count1 = snd_rawmidi_kernel_write1(substream, buf, NULL, count);
1242                 if (count1 < 0)
1243                         return result > 0 ? result : count1;
1244                 result += count1;
1245                 buf += count1;
1246                 if ((size_t)count1 < count && (file->f_flags & O_NONBLOCK))
1247                         break;
1248                 count -= count1;
1249         }
1250         if (file->f_flags & O_SYNC) {
1251                 spin_lock_irq(&runtime->lock);
1252                 while (runtime->avail != runtime->buffer_size) {
1253                         wait_queue_t wait;
1254                         unsigned int last_avail = runtime->avail;
1255                         init_waitqueue_entry(&wait, current);
1256                         add_wait_queue(&runtime->sleep, &wait);
1257                         set_current_state(TASK_INTERRUPTIBLE);
1258                         spin_unlock_irq(&runtime->lock);
1259                         timeout = schedule_timeout(30 * HZ);
1260                         remove_wait_queue(&runtime->sleep, &wait);
1261                         if (signal_pending(current))
1262                                 return result > 0 ? result : -ERESTARTSYS;
1263                         if (runtime->avail == last_avail && !timeout)
1264                                 return result > 0 ? result : -EIO;
1265                         spin_lock_irq(&runtime->lock);
1266                 }
1267                 spin_unlock_irq(&runtime->lock);
1268         }
1269         return result;
1270 }
1271
1272 static unsigned int snd_rawmidi_poll(struct file *file, poll_table * wait)
1273 {
1274         struct snd_rawmidi_file *rfile;
1275         struct snd_rawmidi_runtime *runtime;
1276         unsigned int mask;
1277
1278         rfile = file->private_data;
1279         if (rfile->input != NULL) {
1280                 runtime = rfile->input->runtime;
1281                 snd_rawmidi_input_trigger(rfile->input, 1);
1282                 poll_wait(file, &runtime->sleep, wait);
1283         }
1284         if (rfile->output != NULL) {
1285                 runtime = rfile->output->runtime;
1286                 poll_wait(file, &runtime->sleep, wait);
1287         }
1288         mask = 0;
1289         if (rfile->input != NULL) {
1290                 if (snd_rawmidi_ready(rfile->input))
1291                         mask |= POLLIN | POLLRDNORM;
1292         }
1293         if (rfile->output != NULL) {
1294                 if (snd_rawmidi_ready(rfile->output))
1295                         mask |= POLLOUT | POLLWRNORM;
1296         }
1297         return mask;
1298 }
1299
1300 /*
1301  */
1302 #ifdef CONFIG_COMPAT
1303 #include "rawmidi_compat.c"
1304 #else
1305 #define snd_rawmidi_ioctl_compat        NULL
1306 #endif
1307
1308 /*
1309
1310  */
1311
1312 static void snd_rawmidi_proc_info_read(struct snd_info_entry *entry,
1313                                        struct snd_info_buffer *buffer)
1314 {
1315         struct snd_rawmidi *rmidi;
1316         struct snd_rawmidi_substream *substream;
1317         struct snd_rawmidi_runtime *runtime;
1318
1319         rmidi = entry->private_data;
1320         snd_iprintf(buffer, "%s\n\n", rmidi->name);
1321         mutex_lock(&rmidi->open_mutex);
1322         if (rmidi->info_flags & SNDRV_RAWMIDI_INFO_OUTPUT) {
1323                 list_for_each_entry(substream,
1324                                     &rmidi->streams[SNDRV_RAWMIDI_STREAM_OUTPUT].substreams,
1325                                     list) {
1326                         snd_iprintf(buffer,
1327                                     "Output %d\n"
1328                                     "  Tx bytes     : %lu\n",
1329                                     substream->number,
1330                                     (unsigned long) substream->bytes);
1331                         if (substream->opened) {
1332                                 runtime = substream->runtime;
1333                                 snd_iprintf(buffer,
1334                                     "  Mode         : %s\n"
1335                                     "  Buffer size  : %lu\n"
1336                                     "  Avail        : %lu\n",
1337                                     runtime->oss ? "OSS compatible" : "native",
1338                                     (unsigned long) runtime->buffer_size,
1339                                     (unsigned long) runtime->avail);
1340                         }
1341                 }
1342         }
1343         if (rmidi->info_flags & SNDRV_RAWMIDI_INFO_INPUT) {
1344                 list_for_each_entry(substream,
1345                                     &rmidi->streams[SNDRV_RAWMIDI_STREAM_INPUT].substreams,
1346                                     list) {
1347                         snd_iprintf(buffer,
1348                                     "Input %d\n"
1349                                     "  Rx bytes     : %lu\n",
1350                                     substream->number,
1351                                     (unsigned long) substream->bytes);
1352                         if (substream->opened) {
1353                                 runtime = substream->runtime;
1354                                 snd_iprintf(buffer,
1355                                             "  Buffer size  : %lu\n"
1356                                             "  Avail        : %lu\n"
1357                                             "  Overruns     : %lu\n",
1358                                             (unsigned long) runtime->buffer_size,
1359                                             (unsigned long) runtime->avail,
1360                                             (unsigned long) runtime->xruns);
1361                         }
1362                 }
1363         }
1364         mutex_unlock(&rmidi->open_mutex);
1365 }
1366
1367 /*
1368  *  Register functions
1369  */
1370
1371 static const struct file_operations snd_rawmidi_f_ops =
1372 {
1373         .owner =        THIS_MODULE,
1374         .read =         snd_rawmidi_read,
1375         .write =        snd_rawmidi_write,
1376         .open =         snd_rawmidi_open,
1377         .release =      snd_rawmidi_release,
1378         .poll =         snd_rawmidi_poll,
1379         .unlocked_ioctl =       snd_rawmidi_ioctl,
1380         .compat_ioctl = snd_rawmidi_ioctl_compat,
1381 };
1382
1383 static int snd_rawmidi_alloc_substreams(struct snd_rawmidi *rmidi,
1384                                         struct snd_rawmidi_str *stream,
1385                                         int direction,
1386                                         int count)
1387 {
1388         struct snd_rawmidi_substream *substream;
1389         int idx;
1390
1391         for (idx = 0; idx < count; idx++) {
1392                 substream = kzalloc(sizeof(*substream), GFP_KERNEL);
1393                 if (substream == NULL) {
1394                         snd_printk(KERN_ERR "rawmidi: cannot allocate substream\n");
1395                         return -ENOMEM;
1396                 }
1397                 substream->stream = direction;
1398                 substream->number = idx;
1399                 substream->rmidi = rmidi;
1400                 substream->pstr = stream;
1401                 list_add_tail(&substream->list, &stream->substreams);
1402                 stream->substream_count++;
1403         }
1404         return 0;
1405 }
1406
1407 /**
1408  * snd_rawmidi_new - create a rawmidi instance
1409  * @card: the card instance
1410  * @id: the id string
1411  * @device: the device index
1412  * @output_count: the number of output streams
1413  * @input_count: the number of input streams
1414  * @rrawmidi: the pointer to store the new rawmidi instance
1415  *
1416  * Creates a new rawmidi instance.
1417  * Use snd_rawmidi_set_ops() to set the operators to the new instance.
1418  *
1419  * Returns zero if successful, or a negative error code on failure.
1420  */
1421 int snd_rawmidi_new(struct snd_card *card, char *id, int device,
1422                     int output_count, int input_count,
1423                     struct snd_rawmidi ** rrawmidi)
1424 {
1425         struct snd_rawmidi *rmidi;
1426         int err;
1427         static struct snd_device_ops ops = {
1428                 .dev_free = snd_rawmidi_dev_free,
1429                 .dev_register = snd_rawmidi_dev_register,
1430                 .dev_disconnect = snd_rawmidi_dev_disconnect,
1431         };
1432
1433         if (snd_BUG_ON(!card))
1434                 return -ENXIO;
1435         if (rrawmidi)
1436                 *rrawmidi = NULL;
1437         rmidi = kzalloc(sizeof(*rmidi), GFP_KERNEL);
1438         if (rmidi == NULL) {
1439                 snd_printk(KERN_ERR "rawmidi: cannot allocate\n");
1440                 return -ENOMEM;
1441         }
1442         rmidi->card = card;
1443         rmidi->device = device;
1444         mutex_init(&rmidi->open_mutex);
1445         init_waitqueue_head(&rmidi->open_wait);
1446         INIT_LIST_HEAD(&rmidi->streams[SNDRV_RAWMIDI_STREAM_INPUT].substreams);
1447         INIT_LIST_HEAD(&rmidi->streams[SNDRV_RAWMIDI_STREAM_OUTPUT].substreams);
1448
1449         if (id != NULL)
1450                 strlcpy(rmidi->id, id, sizeof(rmidi->id));
1451         if ((err = snd_rawmidi_alloc_substreams(rmidi,
1452                                                 &rmidi->streams[SNDRV_RAWMIDI_STREAM_INPUT],
1453                                                 SNDRV_RAWMIDI_STREAM_INPUT,
1454                                                 input_count)) < 0) {
1455                 snd_rawmidi_free(rmidi);
1456                 return err;
1457         }
1458         if ((err = snd_rawmidi_alloc_substreams(rmidi,
1459                                                 &rmidi->streams[SNDRV_RAWMIDI_STREAM_OUTPUT],
1460                                                 SNDRV_RAWMIDI_STREAM_OUTPUT,
1461                                                 output_count)) < 0) {
1462                 snd_rawmidi_free(rmidi);
1463                 return err;
1464         }
1465         if ((err = snd_device_new(card, SNDRV_DEV_RAWMIDI, rmidi, &ops)) < 0) {
1466                 snd_rawmidi_free(rmidi);
1467                 return err;
1468         }
1469         if (rrawmidi)
1470                 *rrawmidi = rmidi;
1471         return 0;
1472 }
1473
1474 static void snd_rawmidi_free_substreams(struct snd_rawmidi_str *stream)
1475 {
1476         struct snd_rawmidi_substream *substream;
1477
1478         while (!list_empty(&stream->substreams)) {
1479                 substream = list_entry(stream->substreams.next, struct snd_rawmidi_substream, list);
1480                 list_del(&substream->list);
1481                 kfree(substream);
1482         }
1483 }
1484
1485 static int snd_rawmidi_free(struct snd_rawmidi *rmidi)
1486 {
1487         if (!rmidi)
1488                 return 0;
1489
1490         snd_info_free_entry(rmidi->proc_entry);
1491         rmidi->proc_entry = NULL;
1492         mutex_lock(&register_mutex);
1493         if (rmidi->ops && rmidi->ops->dev_unregister)
1494                 rmidi->ops->dev_unregister(rmidi);
1495         mutex_unlock(&register_mutex);
1496
1497         snd_rawmidi_free_substreams(&rmidi->streams[SNDRV_RAWMIDI_STREAM_INPUT]);
1498         snd_rawmidi_free_substreams(&rmidi->streams[SNDRV_RAWMIDI_STREAM_OUTPUT]);
1499         if (rmidi->private_free)
1500                 rmidi->private_free(rmidi);
1501         kfree(rmidi);
1502         return 0;
1503 }
1504
1505 static int snd_rawmidi_dev_free(struct snd_device *device)
1506 {
1507         struct snd_rawmidi *rmidi = device->device_data;
1508         return snd_rawmidi_free(rmidi);
1509 }
1510
1511 #if defined(CONFIG_SND_SEQUENCER) || (defined(MODULE) && defined(CONFIG_SND_SEQUENCER_MODULE))
1512 static void snd_rawmidi_dev_seq_free(struct snd_seq_device *device)
1513 {
1514         struct snd_rawmidi *rmidi = device->private_data;
1515         rmidi->seq_dev = NULL;
1516 }
1517 #endif
1518
1519 static int snd_rawmidi_dev_register(struct snd_device *device)
1520 {
1521         int err;
1522         struct snd_info_entry *entry;
1523         char name[16];
1524         struct snd_rawmidi *rmidi = device->device_data;
1525
1526         if (rmidi->device >= SNDRV_RAWMIDI_DEVICES)
1527                 return -ENOMEM;
1528         mutex_lock(&register_mutex);
1529         if (snd_rawmidi_search(rmidi->card, rmidi->device)) {
1530                 mutex_unlock(&register_mutex);
1531                 return -EBUSY;
1532         }
1533         list_add_tail(&rmidi->list, &snd_rawmidi_devices);
1534         sprintf(name, "midiC%iD%i", rmidi->card->number, rmidi->device);
1535         if ((err = snd_register_device(SNDRV_DEVICE_TYPE_RAWMIDI,
1536                                        rmidi->card, rmidi->device,
1537                                        &snd_rawmidi_f_ops, rmidi, name)) < 0) {
1538                 snd_printk(KERN_ERR "unable to register rawmidi device %i:%i\n", rmidi->card->number, rmidi->device);
1539                 list_del(&rmidi->list);
1540                 mutex_unlock(&register_mutex);
1541                 return err;
1542         }
1543         if (rmidi->ops && rmidi->ops->dev_register &&
1544             (err = rmidi->ops->dev_register(rmidi)) < 0) {
1545                 snd_unregister_device(SNDRV_DEVICE_TYPE_RAWMIDI, rmidi->card, rmidi->device);
1546                 list_del(&rmidi->list);
1547                 mutex_unlock(&register_mutex);
1548                 return err;
1549         }
1550 #ifdef CONFIG_SND_OSSEMUL
1551         rmidi->ossreg = 0;
1552         if ((int)rmidi->device == midi_map[rmidi->card->number]) {
1553                 if (snd_register_oss_device(SNDRV_OSS_DEVICE_TYPE_MIDI,
1554                                             rmidi->card, 0, &snd_rawmidi_f_ops,
1555                                             rmidi, name) < 0) {
1556                         snd_printk(KERN_ERR "unable to register OSS rawmidi device %i:%i\n", rmidi->card->number, 0);
1557                 } else {
1558                         rmidi->ossreg++;
1559 #ifdef SNDRV_OSS_INFO_DEV_MIDI
1560                         snd_oss_info_register(SNDRV_OSS_INFO_DEV_MIDI, rmidi->card->number, rmidi->name);
1561 #endif
1562                 }
1563         }
1564         if ((int)rmidi->device == amidi_map[rmidi->card->number]) {
1565                 if (snd_register_oss_device(SNDRV_OSS_DEVICE_TYPE_MIDI,
1566                                             rmidi->card, 1, &snd_rawmidi_f_ops,
1567                                             rmidi, name) < 0) {
1568                         snd_printk(KERN_ERR "unable to register OSS rawmidi device %i:%i\n", rmidi->card->number, 1);
1569                 } else {
1570                         rmidi->ossreg++;
1571                 }
1572         }
1573 #endif /* CONFIG_SND_OSSEMUL */
1574         mutex_unlock(&register_mutex);
1575         sprintf(name, "midi%d", rmidi->device);
1576         entry = snd_info_create_card_entry(rmidi->card, name, rmidi->card->proc_root);
1577         if (entry) {
1578                 entry->private_data = rmidi;
1579                 entry->c.text.read = snd_rawmidi_proc_info_read;
1580                 if (snd_info_register(entry) < 0) {
1581                         snd_info_free_entry(entry);
1582                         entry = NULL;
1583                 }
1584         }
1585         rmidi->proc_entry = entry;
1586 #if defined(CONFIG_SND_SEQUENCER) || (defined(MODULE) && defined(CONFIG_SND_SEQUENCER_MODULE))
1587         if (!rmidi->ops || !rmidi->ops->dev_register) { /* own registration mechanism */
1588                 if (snd_seq_device_new(rmidi->card, rmidi->device, SNDRV_SEQ_DEV_ID_MIDISYNTH, 0, &rmidi->seq_dev) >= 0) {
1589                         rmidi->seq_dev->private_data = rmidi;
1590                         rmidi->seq_dev->private_free = snd_rawmidi_dev_seq_free;
1591                         sprintf(rmidi->seq_dev->name, "MIDI %d-%d", rmidi->card->number, rmidi->device);
1592                         snd_device_register(rmidi->card, rmidi->seq_dev);
1593                 }
1594         }
1595 #endif
1596         return 0;
1597 }
1598
1599 static int snd_rawmidi_dev_disconnect(struct snd_device *device)
1600 {
1601         struct snd_rawmidi *rmidi = device->device_data;
1602
1603         mutex_lock(&register_mutex);
1604         list_del_init(&rmidi->list);
1605 #ifdef CONFIG_SND_OSSEMUL
1606         if (rmidi->ossreg) {
1607                 if ((int)rmidi->device == midi_map[rmidi->card->number]) {
1608                         snd_unregister_oss_device(SNDRV_OSS_DEVICE_TYPE_MIDI, rmidi->card, 0);
1609 #ifdef SNDRV_OSS_INFO_DEV_MIDI
1610                         snd_oss_info_unregister(SNDRV_OSS_INFO_DEV_MIDI, rmidi->card->number);
1611 #endif
1612                 }
1613                 if ((int)rmidi->device == amidi_map[rmidi->card->number])
1614                         snd_unregister_oss_device(SNDRV_OSS_DEVICE_TYPE_MIDI, rmidi->card, 1);
1615                 rmidi->ossreg = 0;
1616         }
1617 #endif /* CONFIG_SND_OSSEMUL */
1618         snd_unregister_device(SNDRV_DEVICE_TYPE_RAWMIDI, rmidi->card, rmidi->device);
1619         mutex_unlock(&register_mutex);
1620         return 0;
1621 }
1622
1623 /**
1624  * snd_rawmidi_set_ops - set the rawmidi operators
1625  * @rmidi: the rawmidi instance
1626  * @stream: the stream direction, SNDRV_RAWMIDI_STREAM_XXX
1627  * @ops: the operator table
1628  *
1629  * Sets the rawmidi operators for the given stream direction.
1630  */
1631 void snd_rawmidi_set_ops(struct snd_rawmidi *rmidi, int stream,
1632                          struct snd_rawmidi_ops *ops)
1633 {
1634         struct snd_rawmidi_substream *substream;
1635         
1636         list_for_each_entry(substream, &rmidi->streams[stream].substreams, list)
1637                 substream->ops = ops;
1638 }
1639
1640 /*
1641  *  ENTRY functions
1642  */
1643
1644 static int __init alsa_rawmidi_init(void)
1645 {
1646
1647         snd_ctl_register_ioctl(snd_rawmidi_control_ioctl);
1648         snd_ctl_register_ioctl_compat(snd_rawmidi_control_ioctl);
1649 #ifdef CONFIG_SND_OSSEMUL
1650         { int i;
1651         /* check device map table */
1652         for (i = 0; i < SNDRV_CARDS; i++) {
1653                 if (midi_map[i] < 0 || midi_map[i] >= SNDRV_RAWMIDI_DEVICES) {
1654                         snd_printk(KERN_ERR "invalid midi_map[%d] = %d\n", i, midi_map[i]);
1655                         midi_map[i] = 0;
1656                 }
1657                 if (amidi_map[i] < 0 || amidi_map[i] >= SNDRV_RAWMIDI_DEVICES) {
1658                         snd_printk(KERN_ERR "invalid amidi_map[%d] = %d\n", i, amidi_map[i]);
1659                         amidi_map[i] = 1;
1660                 }
1661         }
1662         }
1663 #endif /* CONFIG_SND_OSSEMUL */
1664         return 0;
1665 }
1666
1667 static void __exit alsa_rawmidi_exit(void)
1668 {
1669         snd_ctl_unregister_ioctl(snd_rawmidi_control_ioctl);
1670         snd_ctl_unregister_ioctl_compat(snd_rawmidi_control_ioctl);
1671 }
1672
1673 module_init(alsa_rawmidi_init)
1674 module_exit(alsa_rawmidi_exit)
1675
1676 EXPORT_SYMBOL(snd_rawmidi_output_params);
1677 EXPORT_SYMBOL(snd_rawmidi_input_params);
1678 EXPORT_SYMBOL(snd_rawmidi_drop_output);
1679 EXPORT_SYMBOL(snd_rawmidi_drain_output);
1680 EXPORT_SYMBOL(snd_rawmidi_drain_input);
1681 EXPORT_SYMBOL(snd_rawmidi_receive);
1682 EXPORT_SYMBOL(snd_rawmidi_transmit_empty);
1683 EXPORT_SYMBOL(snd_rawmidi_transmit_peek);
1684 EXPORT_SYMBOL(snd_rawmidi_transmit_ack);
1685 EXPORT_SYMBOL(snd_rawmidi_transmit);
1686 EXPORT_SYMBOL(snd_rawmidi_new);
1687 EXPORT_SYMBOL(snd_rawmidi_set_ops);
1688 EXPORT_SYMBOL(snd_rawmidi_info_select);
1689 EXPORT_SYMBOL(snd_rawmidi_kernel_open);
1690 EXPORT_SYMBOL(snd_rawmidi_kernel_release);
1691 EXPORT_SYMBOL(snd_rawmidi_kernel_read);
1692 EXPORT_SYMBOL(snd_rawmidi_kernel_write);