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