Lines Matching +full:signal +full:- +full:guard
1 // SPDX-License-Identifier: GPL-2.0-or-later
10 #include <linux/sched/signal.h>
32 static int amidi_map[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS-1)] = 1};
47 dev_err((rmidi)->dev, fmt, ##args)
49 dev_warn((rmidi)->dev, fmt, ##args)
51 dev_dbg((rmidi)->dev, fmt, ##args)
77 (IS_ENABLED(CONFIG_SND_UMP) && ((rmidi)->info_flags & SNDRV_RAWMIDI_INFO_UMP))
84 if (rawmidi->card == card && rawmidi->device == device) in snd_rawmidi_search()
91 switch (file->f_mode & (FMODE_READ | FMODE_WRITE)) { in snd_rawmidi_file_flags()
103 return runtime->avail >= runtime->avail_min; in __snd_rawmidi_ready()
108 guard(spinlock_irqsave)(&substream->lock); in snd_rawmidi_ready()
109 return __snd_rawmidi_ready(substream->runtime); in snd_rawmidi_ready()
115 struct snd_rawmidi_runtime *runtime = substream->runtime; in snd_rawmidi_ready_append()
117 return runtime->avail >= runtime->avail_min && in snd_rawmidi_ready_append()
118 (!substream->append || runtime->avail >= count); in snd_rawmidi_ready_append()
126 if (runtime->event) in snd_rawmidi_input_event_work()
127 runtime->event(runtime->substream); in snd_rawmidi_input_event_work()
130 /* buffer refcount management: call with substream->lock held */
133 runtime->buffer_ref++; in snd_rawmidi_buffer_ref()
138 runtime->buffer_ref--; in snd_rawmidi_buffer_unref()
145 spin_lock_irq(&substream->lock); in snd_rawmidi_buffer_ref_sync()
146 while (substream->runtime->buffer_ref) { in snd_rawmidi_buffer_ref_sync()
147 spin_unlock_irq(&substream->lock); in snd_rawmidi_buffer_ref_sync()
148 if (!--loop) { in snd_rawmidi_buffer_ref_sync()
149 rmidi_err(substream->rmidi, "Buffer ref sync timeout\n"); in snd_rawmidi_buffer_ref_sync()
153 spin_lock_irq(&substream->lock); in snd_rawmidi_buffer_ref_sync()
155 spin_unlock_irq(&substream->lock); in snd_rawmidi_buffer_ref_sync()
164 return -ENOMEM; in snd_rawmidi_runtime_create()
165 runtime->substream = substream; in snd_rawmidi_runtime_create()
166 init_waitqueue_head(&runtime->sleep); in snd_rawmidi_runtime_create()
167 INIT_WORK(&runtime->event_work, snd_rawmidi_input_event_work); in snd_rawmidi_runtime_create()
168 runtime->event = NULL; in snd_rawmidi_runtime_create()
169 runtime->buffer_size = PAGE_SIZE; in snd_rawmidi_runtime_create()
170 runtime->avail_min = 1; in snd_rawmidi_runtime_create()
171 if (substream->stream == SNDRV_RAWMIDI_STREAM_INPUT) in snd_rawmidi_runtime_create()
172 runtime->avail = 0; in snd_rawmidi_runtime_create()
174 runtime->avail = runtime->buffer_size; in snd_rawmidi_runtime_create()
175 runtime->buffer = kvzalloc(runtime->buffer_size, GFP_KERNEL); in snd_rawmidi_runtime_create()
176 if (!runtime->buffer) { in snd_rawmidi_runtime_create()
178 return -ENOMEM; in snd_rawmidi_runtime_create()
180 runtime->appl_ptr = runtime->hw_ptr = 0; in snd_rawmidi_runtime_create()
181 substream->runtime = runtime; in snd_rawmidi_runtime_create()
182 if (rawmidi_is_ump(substream->rmidi)) in snd_rawmidi_runtime_create()
183 runtime->align = 3; in snd_rawmidi_runtime_create()
191 return runtime->align; in get_align()
201 struct snd_rawmidi_runtime *runtime = substream->runtime; in snd_rawmidi_runtime_free()
203 kvfree(runtime->buffer); in snd_rawmidi_runtime_free()
205 substream->runtime = NULL; in snd_rawmidi_runtime_free()
211 if (!substream->opened) in snd_rawmidi_output_trigger()
213 substream->ops->trigger(substream, up); in snd_rawmidi_output_trigger()
218 if (!substream->opened) in snd_rawmidi_input_trigger()
220 substream->ops->trigger(substream, up); in snd_rawmidi_input_trigger()
222 cancel_work_sync(&substream->runtime->event_work); in snd_rawmidi_input_trigger()
228 runtime->drain = 0; in __reset_runtime_ptrs()
229 runtime->appl_ptr = runtime->hw_ptr = 0; in __reset_runtime_ptrs()
230 runtime->avail = is_input ? 0 : runtime->buffer_size; in __reset_runtime_ptrs()
236 guard(spinlock_irqsave)(&substream->lock); in reset_runtime_ptrs()
237 if (substream->opened && substream->runtime) in reset_runtime_ptrs()
238 __reset_runtime_ptrs(substream->runtime, is_input); in reset_runtime_ptrs()
255 scoped_guard(spinlock_irq, &substream->lock) { in snd_rawmidi_drain_output()
256 runtime = substream->runtime; in snd_rawmidi_drain_output()
257 if (!substream->opened || !runtime || !runtime->buffer) in snd_rawmidi_drain_output()
258 return -EINVAL; in snd_rawmidi_drain_output()
260 runtime->drain = 1; in snd_rawmidi_drain_output()
263 timeout = wait_event_interruptible_timeout(runtime->sleep, in snd_rawmidi_drain_output()
264 (runtime->avail >= runtime->buffer_size), in snd_rawmidi_drain_output()
267 scoped_guard(spinlock_irq, &substream->lock) { in snd_rawmidi_drain_output()
269 err = -ERESTARTSYS; in snd_rawmidi_drain_output()
270 if (runtime->avail < runtime->buffer_size && !timeout) { in snd_rawmidi_drain_output()
271 rmidi_warn(substream->rmidi, in snd_rawmidi_drain_output()
273 (long)runtime->avail, (long)runtime->buffer_size); in snd_rawmidi_drain_output()
274 err = -EIO; in snd_rawmidi_drain_output()
276 runtime->drain = 0; in snd_rawmidi_drain_output()
279 if (err != -ERESTARTSYS) { in snd_rawmidi_drain_output()
281 if (substream->ops->drain) in snd_rawmidi_drain_output()
282 substream->ops->drain(substream); in snd_rawmidi_drain_output()
288 scoped_guard(spinlock_irq, &substream->lock) in snd_rawmidi_drain_output()
311 struct snd_rawmidi_str *s = &rmidi->streams[stream]; in assign_substream()
317 if (!(rmidi->info_flags & info_flags[stream])) in assign_substream()
318 return -ENXIO; in assign_substream()
319 if (subdevice >= 0 && subdevice >= s->substream_count) in assign_substream()
320 return -ENODEV; in assign_substream()
322 list_for_each_entry(substream, &s->substreams, list) { in assign_substream()
323 if (substream->opened) { in assign_substream()
326 !substream->append) in assign_substream()
329 if (subdevice < 0 || subdevice == substream->number) { in assign_substream()
334 return -EAGAIN; in assign_substream()
337 /* open and do ref-counting for the given substream */
344 if (substream->use_count == 0) { in open_substream()
348 err = substream->ops->open(substream); in open_substream()
353 guard(spinlock_irq)(&substream->lock); in open_substream()
354 substream->opened = 1; in open_substream()
355 substream->active_sensing = 0; in open_substream()
357 substream->append = 1; in open_substream()
358 substream->pid = get_pid(task_pid(current)); in open_substream()
359 rmidi->streams[substream->stream].substream_opened++; in open_substream()
361 substream->use_count++; in open_substream()
375 rfile->input = rfile->output = NULL; in rawmidi_open_priv()
405 rfile->rmidi = rmidi; in rawmidi_open_priv()
406 rfile->input = sinput; in rawmidi_open_priv()
407 rfile->output = soutput; in rawmidi_open_priv()
418 return -EINVAL; in snd_rawmidi_kernel_open()
419 if (!try_module_get(rmidi->card->module)) in snd_rawmidi_kernel_open()
420 return -ENXIO; in snd_rawmidi_kernel_open()
422 guard(mutex)(&rmidi->open_mutex); in snd_rawmidi_kernel_open()
425 module_put(rmidi->card->module); in snd_rawmidi_kernel_open()
441 if ((file->f_flags & O_APPEND) && !(file->f_flags & O_NONBLOCK)) in snd_rawmidi_open()
442 return -EINVAL; /* invalid combination */ in snd_rawmidi_open()
457 return -ENXIO; in snd_rawmidi_open()
460 return -ENODEV; in snd_rawmidi_open()
462 if (!try_module_get(rmidi->card->module)) { in snd_rawmidi_open()
463 snd_card_unref(rmidi->card); in snd_rawmidi_open()
464 return -ENXIO; in snd_rawmidi_open()
467 mutex_lock(&rmidi->open_mutex); in snd_rawmidi_open()
468 card = rmidi->card; in snd_rawmidi_open()
473 if ((file->f_flags & O_APPEND) || maj == SOUND_MAJOR) /* OSS emul? */ in snd_rawmidi_open()
477 err = -ENOMEM; in snd_rawmidi_open()
480 rawmidi_file->user_pversion = 0; in snd_rawmidi_open()
482 add_wait_queue(&rmidi->open_wait, &wait); in snd_rawmidi_open()
488 if (err == -EAGAIN) { in snd_rawmidi_open()
489 if (file->f_flags & O_NONBLOCK) { in snd_rawmidi_open()
490 err = -EBUSY; in snd_rawmidi_open()
496 mutex_unlock(&rmidi->open_mutex); in snd_rawmidi_open()
498 mutex_lock(&rmidi->open_mutex); in snd_rawmidi_open()
499 if (rmidi->card->shutdown) { in snd_rawmidi_open()
500 err = -ENODEV; in snd_rawmidi_open()
504 err = -ERESTARTSYS; in snd_rawmidi_open()
508 remove_wait_queue(&rmidi->open_wait, &wait); in snd_rawmidi_open()
514 if (rawmidi_file->input && rawmidi_file->input->runtime) in snd_rawmidi_open()
515 rawmidi_file->input->runtime->oss = (maj == SOUND_MAJOR); in snd_rawmidi_open()
516 if (rawmidi_file->output && rawmidi_file->output->runtime) in snd_rawmidi_open()
517 rawmidi_file->output->runtime->oss = (maj == SOUND_MAJOR); in snd_rawmidi_open()
519 file->private_data = rawmidi_file; in snd_rawmidi_open()
520 mutex_unlock(&rmidi->open_mutex); in snd_rawmidi_open()
521 snd_card_unref(rmidi->card); in snd_rawmidi_open()
527 mutex_unlock(&rmidi->open_mutex); in snd_rawmidi_open()
528 module_put(rmidi->card->module); in snd_rawmidi_open()
529 snd_card_unref(rmidi->card); in snd_rawmidi_open()
537 if (--substream->use_count) in close_substream()
541 if (substream->stream == SNDRV_RAWMIDI_STREAM_INPUT) in close_substream()
544 if (substream->active_sensing) { in close_substream()
551 if (snd_rawmidi_drain_output(substream) == -ERESTARTSYS) in close_substream()
556 scoped_guard(spinlock_irq, &substream->lock) { in close_substream()
557 substream->opened = 0; in close_substream()
558 substream->append = 0; in close_substream()
560 substream->ops->close(substream); in close_substream()
561 if (substream->runtime->private_free) in close_substream()
562 substream->runtime->private_free(substream); in close_substream()
564 put_pid(substream->pid); in close_substream()
565 substream->pid = NULL; in close_substream()
566 rmidi->streams[substream->stream].substream_opened--; in close_substream()
573 rmidi = rfile->rmidi; in rawmidi_release_priv()
574 guard(mutex)(&rmidi->open_mutex); in rawmidi_release_priv()
575 if (rfile->input) { in rawmidi_release_priv()
576 close_substream(rmidi, rfile->input, 1); in rawmidi_release_priv()
577 rfile->input = NULL; in rawmidi_release_priv()
579 if (rfile->output) { in rawmidi_release_priv()
580 close_substream(rmidi, rfile->output, 1); in rawmidi_release_priv()
581 rfile->output = NULL; in rawmidi_release_priv()
583 rfile->rmidi = NULL; in rawmidi_release_priv()
584 wake_up(&rmidi->open_wait); in rawmidi_release_priv()
593 return -ENXIO; in snd_rawmidi_kernel_release()
595 rmidi = rfile->rmidi; in snd_rawmidi_kernel_release()
597 module_put(rmidi->card->module); in snd_rawmidi_kernel_release()
608 rfile = file->private_data; in snd_rawmidi_release()
609 rmidi = rfile->rmidi; in snd_rawmidi_release()
612 module = rmidi->card->module; in snd_rawmidi_release()
613 snd_card_file_remove(rmidi->card, file); in snd_rawmidi_release()
624 return -ENODEV; in snd_rawmidi_info()
625 rmidi = substream->rmidi; in snd_rawmidi_info()
627 info->card = rmidi->card->number; in snd_rawmidi_info()
628 info->device = rmidi->device; in snd_rawmidi_info()
629 info->subdevice = substream->number; in snd_rawmidi_info()
630 info->stream = substream->stream; in snd_rawmidi_info()
631 info->flags = rmidi->info_flags; in snd_rawmidi_info()
632 strcpy(info->id, rmidi->id); in snd_rawmidi_info()
633 strcpy(info->name, rmidi->name); in snd_rawmidi_info()
634 strcpy(info->subname, substream->name); in snd_rawmidi_info()
635 info->subdevices_count = substream->pstr->substream_count; in snd_rawmidi_info()
636 info->subdevices_avail = (substream->pstr->substream_count - in snd_rawmidi_info()
637 substream->pstr->substream_opened); in snd_rawmidi_info()
651 return -EFAULT; in snd_rawmidi_info_user()
662 rmidi = snd_rawmidi_search(card, info->device); in __snd_rawmidi_info_select()
664 return -ENXIO; in __snd_rawmidi_info_select()
665 if (info->stream < 0 || info->stream > 1) in __snd_rawmidi_info_select()
666 return -EINVAL; in __snd_rawmidi_info_select()
667 info->stream = array_index_nospec(info->stream, 2); in __snd_rawmidi_info_select()
668 pstr = &rmidi->streams[info->stream]; in __snd_rawmidi_info_select()
669 if (pstr->substream_count == 0) in __snd_rawmidi_info_select()
670 return -ENOENT; in __snd_rawmidi_info_select()
671 if (info->subdevice >= pstr->substream_count) in __snd_rawmidi_info_select()
672 return -ENXIO; in __snd_rawmidi_info_select()
673 list_for_each_entry(substream, &pstr->substreams, list) { in __snd_rawmidi_info_select()
674 if ((unsigned int)substream->number == info->subdevice) in __snd_rawmidi_info_select()
677 return -ENXIO; in __snd_rawmidi_info_select()
682 guard(mutex)(®ister_mutex); in snd_rawmidi_info_select()
693 if (get_user(info.device, &_info->device)) in snd_rawmidi_info_select_user()
694 return -EFAULT; in snd_rawmidi_info_select_user()
695 if (get_user(info.stream, &_info->stream)) in snd_rawmidi_info_select_user()
696 return -EFAULT; in snd_rawmidi_info_select_user()
697 if (get_user(info.subdevice, &_info->subdevice)) in snd_rawmidi_info_select_user()
698 return -EFAULT; in snd_rawmidi_info_select_user()
703 return -EFAULT; in snd_rawmidi_info_select_user()
711 struct snd_rawmidi_runtime *runtime = substream->runtime; in resize_runtime_buffer()
713 unsigned int framing = params->mode & SNDRV_RAWMIDI_MODE_FRAMING_MASK; in resize_runtime_buffer()
715 if (params->buffer_size < 32 || params->buffer_size > 1024L * 1024L) in resize_runtime_buffer()
716 return -EINVAL; in resize_runtime_buffer()
717 if (framing == SNDRV_RAWMIDI_MODE_FRAMING_TSTAMP && (params->buffer_size & 0x1f) != 0) in resize_runtime_buffer()
718 return -EINVAL; in resize_runtime_buffer()
719 if (params->avail_min < 1 || params->avail_min > params->buffer_size) in resize_runtime_buffer()
720 return -EINVAL; in resize_runtime_buffer()
721 if (params->buffer_size & get_align(runtime)) in resize_runtime_buffer()
722 return -EINVAL; in resize_runtime_buffer()
723 if (params->buffer_size != runtime->buffer_size) { in resize_runtime_buffer()
724 newbuf = kvzalloc(params->buffer_size, GFP_KERNEL); in resize_runtime_buffer()
726 return -ENOMEM; in resize_runtime_buffer()
727 guard(spinlock_irq)(&substream->lock); in resize_runtime_buffer()
728 if (runtime->buffer_ref) { in resize_runtime_buffer()
730 return -EBUSY; in resize_runtime_buffer()
732 oldbuf = runtime->buffer; in resize_runtime_buffer()
733 runtime->buffer = newbuf; in resize_runtime_buffer()
734 runtime->buffer_size = params->buffer_size; in resize_runtime_buffer()
738 runtime->avail_min = params->avail_min; in resize_runtime_buffer()
748 guard(mutex)(&substream->rmidi->open_mutex); in snd_rawmidi_output_params()
749 if (substream->append && substream->use_count > 1) in snd_rawmidi_output_params()
750 return -EBUSY; in snd_rawmidi_output_params()
753 substream->active_sensing = !params->no_active_sensing; in snd_rawmidi_output_params()
761 unsigned int framing = params->mode & SNDRV_RAWMIDI_MODE_FRAMING_MASK; in snd_rawmidi_input_params()
762 unsigned int clock_type = params->mode & SNDRV_RAWMIDI_MODE_CLOCK_MASK; in snd_rawmidi_input_params()
766 guard(mutex)(&substream->rmidi->open_mutex); in snd_rawmidi_input_params()
768 err = -EINVAL; in snd_rawmidi_input_params()
770 err = -EINVAL; in snd_rawmidi_input_params()
772 err = -EINVAL; in snd_rawmidi_input_params()
777 substream->framing = framing; in snd_rawmidi_input_params()
778 substream->clock_type = clock_type; in snd_rawmidi_input_params()
787 struct snd_rawmidi_runtime *runtime = substream->runtime; in snd_rawmidi_output_status()
790 status->stream = SNDRV_RAWMIDI_STREAM_OUTPUT; in snd_rawmidi_output_status()
791 guard(spinlock_irq)(&substream->lock); in snd_rawmidi_output_status()
792 status->avail = runtime->avail; in snd_rawmidi_output_status()
799 struct snd_rawmidi_runtime *runtime = substream->runtime; in snd_rawmidi_input_status()
802 status->stream = SNDRV_RAWMIDI_STREAM_INPUT; in snd_rawmidi_input_status()
803 guard(spinlock_irq)(&substream->lock); in snd_rawmidi_input_status()
804 status->avail = runtime->avail; in snd_rawmidi_input_status()
805 status->xruns = runtime->xruns; in snd_rawmidi_input_status()
806 runtime->xruns = 0; in snd_rawmidi_input_status()
820 return -EFAULT; in snd_rawmidi_ioctl_status32()
824 if (rfile->output == NULL) in snd_rawmidi_ioctl_status32()
825 return -EINVAL; in snd_rawmidi_ioctl_status32()
826 err = snd_rawmidi_output_status(rfile->output, &status64); in snd_rawmidi_ioctl_status32()
829 if (rfile->input == NULL) in snd_rawmidi_ioctl_status32()
830 return -EINVAL; in snd_rawmidi_ioctl_status32()
831 err = snd_rawmidi_input_status(rfile->input, &status64); in snd_rawmidi_ioctl_status32()
834 return -EINVAL; in snd_rawmidi_ioctl_status32()
848 return -EFAULT; in snd_rawmidi_ioctl_status32()
860 return -EFAULT; in snd_rawmidi_ioctl_status64()
864 if (rfile->output == NULL) in snd_rawmidi_ioctl_status64()
865 return -EINVAL; in snd_rawmidi_ioctl_status64()
866 err = snd_rawmidi_output_status(rfile->output, &status); in snd_rawmidi_ioctl_status64()
869 if (rfile->input == NULL) in snd_rawmidi_ioctl_status64()
870 return -EINVAL; in snd_rawmidi_ioctl_status64()
871 err = snd_rawmidi_input_status(rfile->input, &status); in snd_rawmidi_ioctl_status64()
874 return -EINVAL; in snd_rawmidi_ioctl_status64()
880 return -EFAULT; in snd_rawmidi_ioctl_status64()
890 rfile = file->private_data; in snd_rawmidi_ioctl()
892 return -ENOTTY; in snd_rawmidi_ioctl()
895 return put_user(SNDRV_RAWMIDI_VERSION, (int __user *)argp) ? -EFAULT : 0; in snd_rawmidi_ioctl()
901 if (get_user(stream, &info->stream)) in snd_rawmidi_ioctl()
902 return -EFAULT; in snd_rawmidi_ioctl()
905 return snd_rawmidi_info_user(rfile->input, info); in snd_rawmidi_ioctl()
907 return snd_rawmidi_info_user(rfile->output, info); in snd_rawmidi_ioctl()
909 return -EINVAL; in snd_rawmidi_ioctl()
913 if (get_user(rfile->user_pversion, (unsigned int __user *)arg)) in snd_rawmidi_ioctl()
914 return -EFAULT; in snd_rawmidi_ioctl()
922 return -EFAULT; in snd_rawmidi_ioctl()
923 if (rfile->user_pversion < SNDRV_PROTOCOL_VERSION(2, 0, 2)) { in snd_rawmidi_ioctl()
929 if (rfile->output == NULL) in snd_rawmidi_ioctl()
930 return -EINVAL; in snd_rawmidi_ioctl()
931 return snd_rawmidi_output_params(rfile->output, ¶ms); in snd_rawmidi_ioctl()
933 if (rfile->input == NULL) in snd_rawmidi_ioctl()
934 return -EINVAL; in snd_rawmidi_ioctl()
935 return snd_rawmidi_input_params(rfile->input, ¶ms); in snd_rawmidi_ioctl()
937 return -EINVAL; in snd_rawmidi_ioctl()
949 return -EFAULT; in snd_rawmidi_ioctl()
952 if (rfile->output == NULL) in snd_rawmidi_ioctl()
953 return -EINVAL; in snd_rawmidi_ioctl()
954 return snd_rawmidi_drop_output(rfile->output); in snd_rawmidi_ioctl()
956 return -EINVAL; in snd_rawmidi_ioctl()
964 return -EFAULT; in snd_rawmidi_ioctl()
967 if (rfile->output == NULL) in snd_rawmidi_ioctl()
968 return -EINVAL; in snd_rawmidi_ioctl()
969 return snd_rawmidi_drain_output(rfile->output); in snd_rawmidi_ioctl()
971 if (rfile->input == NULL) in snd_rawmidi_ioctl()
972 return -EINVAL; in snd_rawmidi_ioctl()
973 return snd_rawmidi_drain_input(rfile->input); in snd_rawmidi_ioctl()
975 return -EINVAL; in snd_rawmidi_ioctl()
979 rmidi = rfile->rmidi; in snd_rawmidi_ioctl()
980 if (rmidi->ops && rmidi->ops->ioctl) in snd_rawmidi_ioctl()
981 return rmidi->ops->ioctl(rmidi, cmd, argp); in snd_rawmidi_ioctl()
984 return -ENOTTY; in snd_rawmidi_ioctl()
997 return -EFAULT; in snd_rawmidi_next_device()
998 if (device >= SNDRV_RAWMIDI_DEVICES) /* next device is -1 */ in snd_rawmidi_next_device()
999 device = SNDRV_RAWMIDI_DEVICES - 1; in snd_rawmidi_next_device()
1011 device = -1; in snd_rawmidi_next_device()
1014 return -EFAULT; in snd_rawmidi_next_device()
1027 if (get_user(device, &info->device)) in snd_rawmidi_call_ump_ioctl()
1028 return -EFAULT; in snd_rawmidi_call_ump_ioctl()
1029 guard(mutex)(®ister_mutex); in snd_rawmidi_call_ump_ioctl()
1031 if (rmidi && rmidi->ops && rmidi->ops->ioctl) in snd_rawmidi_call_ump_ioctl()
1032 return rmidi->ops->ioctl(rmidi, cmd, argp); in snd_rawmidi_call_ump_ioctl()
1034 return -ENXIO; in snd_rawmidi_call_ump_ioctl()
1061 return -EFAULT; in snd_rawmidi_control_ioctl()
1062 control->preferred_subdevice[SND_CTL_SUBDEV_RAWMIDI] = val; in snd_rawmidi_control_ioctl()
1068 return -ENOIOCTLCMD; in snd_rawmidi_control_ioctl()
1074 struct snd_rawmidi_runtime *runtime = substream->runtime; in receive_with_tstamp_framing()
1076 struct snd_rawmidi_framing_tstamp frame = { .tv_sec = tstamp->tv_sec, .tv_nsec = tstamp->tv_nsec }; in receive_with_tstamp_framing()
1082 if (snd_BUG_ON((runtime->hw_ptr & 0x1f) != 0)) in receive_with_tstamp_framing()
1083 return -EINVAL; in receive_with_tstamp_framing()
1086 if ((int)(runtime->buffer_size - runtime->avail) < frame_size) { in receive_with_tstamp_framing()
1087 runtime->xruns += src_count; in receive_with_tstamp_framing()
1100 src_count -= frame.length; in receive_with_tstamp_framing()
1101 dest_ptr = (struct snd_rawmidi_framing_tstamp *) (runtime->buffer + runtime->hw_ptr); in receive_with_tstamp_framing()
1103 runtime->avail += frame_size; in receive_with_tstamp_framing()
1104 runtime->hw_ptr += frame_size; in receive_with_tstamp_framing()
1105 runtime->hw_ptr %= runtime->buffer_size; in receive_with_tstamp_framing()
1107 return orig_count - src_count; in receive_with_tstamp_framing()
1114 switch (substream->clock_type) { in get_framing_tstamp()
1129 * snd_rawmidi_receive - receive the input data from the device
1145 guard(spinlock_irqsave)(&substream->lock); in snd_rawmidi_receive()
1146 if (!substream->opened) in snd_rawmidi_receive()
1147 return -EBADFD; in snd_rawmidi_receive()
1148 runtime = substream->runtime; in snd_rawmidi_receive()
1149 if (!runtime || !runtime->buffer) { in snd_rawmidi_receive()
1150 rmidi_dbg(substream->rmidi, in snd_rawmidi_receive()
1152 return -EINVAL; in snd_rawmidi_receive()
1159 if (substream->framing == SNDRV_RAWMIDI_MODE_FRAMING_TSTAMP) { in snd_rawmidi_receive()
1162 substream->bytes++; in snd_rawmidi_receive()
1163 if (runtime->avail < runtime->buffer_size) { in snd_rawmidi_receive()
1164 runtime->buffer[runtime->hw_ptr++] = buffer[0]; in snd_rawmidi_receive()
1165 runtime->hw_ptr %= runtime->buffer_size; in snd_rawmidi_receive()
1166 runtime->avail++; in snd_rawmidi_receive()
1169 runtime->xruns++; in snd_rawmidi_receive()
1172 substream->bytes += count; in snd_rawmidi_receive()
1173 count1 = runtime->buffer_size - runtime->hw_ptr; in snd_rawmidi_receive()
1176 if (count1 > (int)(runtime->buffer_size - runtime->avail)) in snd_rawmidi_receive()
1177 count1 = runtime->buffer_size - runtime->avail; in snd_rawmidi_receive()
1181 memcpy(runtime->buffer + runtime->hw_ptr, buffer, count1); in snd_rawmidi_receive()
1182 runtime->hw_ptr += count1; in snd_rawmidi_receive()
1183 runtime->hw_ptr %= runtime->buffer_size; in snd_rawmidi_receive()
1184 runtime->avail += count1; in snd_rawmidi_receive()
1185 count -= count1; in snd_rawmidi_receive()
1190 if (count1 > (int)(runtime->buffer_size - runtime->avail)) { in snd_rawmidi_receive()
1191 count1 = runtime->buffer_size - runtime->avail; in snd_rawmidi_receive()
1192 runtime->xruns += count - count1; in snd_rawmidi_receive()
1195 memcpy(runtime->buffer, buffer, count1); in snd_rawmidi_receive()
1196 runtime->hw_ptr = count1; in snd_rawmidi_receive()
1197 runtime->avail += count1; in snd_rawmidi_receive()
1203 if (runtime->event) in snd_rawmidi_receive()
1204 schedule_work(&runtime->event_work); in snd_rawmidi_receive()
1206 wake_up(&runtime->sleep); in snd_rawmidi_receive()
1218 struct snd_rawmidi_runtime *runtime = substream->runtime; in snd_rawmidi_kernel_read1()
1222 spin_lock_irqsave(&substream->lock, flags); in snd_rawmidi_kernel_read1()
1224 while (count > 0 && runtime->avail) { in snd_rawmidi_kernel_read1()
1225 count1 = runtime->buffer_size - runtime->appl_ptr; in snd_rawmidi_kernel_read1()
1228 if (count1 > (int)runtime->avail) in snd_rawmidi_kernel_read1()
1229 count1 = runtime->avail; in snd_rawmidi_kernel_read1()
1231 /* update runtime->appl_ptr before unlocking for userbuf */ in snd_rawmidi_kernel_read1()
1232 appl_ptr = runtime->appl_ptr; in snd_rawmidi_kernel_read1()
1233 runtime->appl_ptr += count1; in snd_rawmidi_kernel_read1()
1234 runtime->appl_ptr %= runtime->buffer_size; in snd_rawmidi_kernel_read1()
1235 runtime->avail -= count1; in snd_rawmidi_kernel_read1()
1238 memcpy(kernelbuf + result, runtime->buffer + appl_ptr, count1); in snd_rawmidi_kernel_read1()
1240 spin_unlock_irqrestore(&substream->lock, flags); in snd_rawmidi_kernel_read1()
1242 runtime->buffer + appl_ptr, count1)) in snd_rawmidi_kernel_read1()
1243 err = -EFAULT; in snd_rawmidi_kernel_read1()
1244 spin_lock_irqsave(&substream->lock, flags); in snd_rawmidi_kernel_read1()
1249 count -= count1; in snd_rawmidi_kernel_read1()
1253 spin_unlock_irqrestore(&substream->lock, flags); in snd_rawmidi_kernel_read1()
1274 rfile = file->private_data; in snd_rawmidi_read()
1275 substream = rfile->input; in snd_rawmidi_read()
1277 return -EIO; in snd_rawmidi_read()
1278 runtime = substream->runtime; in snd_rawmidi_read()
1282 spin_lock_irq(&substream->lock); in snd_rawmidi_read()
1286 if ((file->f_flags & O_NONBLOCK) != 0 || result > 0) { in snd_rawmidi_read()
1287 spin_unlock_irq(&substream->lock); in snd_rawmidi_read()
1288 return result > 0 ? result : -EAGAIN; in snd_rawmidi_read()
1291 add_wait_queue(&runtime->sleep, &wait); in snd_rawmidi_read()
1293 spin_unlock_irq(&substream->lock); in snd_rawmidi_read()
1295 remove_wait_queue(&runtime->sleep, &wait); in snd_rawmidi_read()
1296 if (rfile->rmidi->card->shutdown) in snd_rawmidi_read()
1297 return -ENODEV; in snd_rawmidi_read()
1299 return result > 0 ? result : -ERESTARTSYS; in snd_rawmidi_read()
1300 spin_lock_irq(&substream->lock); in snd_rawmidi_read()
1301 if (!runtime->avail) { in snd_rawmidi_read()
1302 spin_unlock_irq(&substream->lock); in snd_rawmidi_read()
1303 return result > 0 ? result : -EIO; in snd_rawmidi_read()
1306 spin_unlock_irq(&substream->lock); in snd_rawmidi_read()
1315 count -= count1; in snd_rawmidi_read()
1321 * snd_rawmidi_transmit_empty - check whether the output buffer is empty
1330 guard(spinlock_irqsave)(&substream->lock); in snd_rawmidi_transmit_empty()
1331 runtime = substream->runtime; in snd_rawmidi_transmit_empty()
1332 if (!substream->opened || !runtime || !runtime->buffer) { in snd_rawmidi_transmit_empty()
1333 rmidi_dbg(substream->rmidi, in snd_rawmidi_transmit_empty()
1337 return (runtime->avail >= runtime->buffer_size); in snd_rawmidi_transmit_empty()
1342 * __snd_rawmidi_transmit_peek - copy data from the internal buffer
1353 struct snd_rawmidi_runtime *runtime = substream->runtime; in __snd_rawmidi_transmit_peek()
1355 if (runtime->buffer == NULL) { in __snd_rawmidi_transmit_peek()
1356 rmidi_dbg(substream->rmidi, in __snd_rawmidi_transmit_peek()
1358 return -EINVAL; in __snd_rawmidi_transmit_peek()
1361 if (runtime->avail >= runtime->buffer_size) { in __snd_rawmidi_transmit_peek()
1366 *buffer = runtime->buffer[runtime->hw_ptr]; in __snd_rawmidi_transmit_peek()
1369 count1 = runtime->buffer_size - runtime->hw_ptr; in __snd_rawmidi_transmit_peek()
1372 if (count1 > (int)(runtime->buffer_size - runtime->avail)) in __snd_rawmidi_transmit_peek()
1373 count1 = runtime->buffer_size - runtime->avail; in __snd_rawmidi_transmit_peek()
1377 memcpy(buffer, runtime->buffer + runtime->hw_ptr, count1); in __snd_rawmidi_transmit_peek()
1378 count -= count1; in __snd_rawmidi_transmit_peek()
1381 if (count > (int)(runtime->buffer_size - runtime->avail - count1)) in __snd_rawmidi_transmit_peek()
1382 count = runtime->buffer_size - runtime->avail - count1; in __snd_rawmidi_transmit_peek()
1386 memcpy(buffer + count1, runtime->buffer, count); in __snd_rawmidi_transmit_peek()
1395 * snd_rawmidi_transmit_peek - copy data from the internal buffer
1411 guard(spinlock_irqsave)(&substream->lock); in snd_rawmidi_transmit_peek()
1412 if (!substream->opened || !substream->runtime) in snd_rawmidi_transmit_peek()
1413 return -EBADFD; in snd_rawmidi_transmit_peek()
1419 * __snd_rawmidi_transmit_ack - acknowledge the transmission
1428 struct snd_rawmidi_runtime *runtime = substream->runtime; in __snd_rawmidi_transmit_ack()
1430 if (runtime->buffer == NULL) { in __snd_rawmidi_transmit_ack()
1431 rmidi_dbg(substream->rmidi, in __snd_rawmidi_transmit_ack()
1433 return -EINVAL; in __snd_rawmidi_transmit_ack()
1435 snd_BUG_ON(runtime->avail + count > runtime->buffer_size); in __snd_rawmidi_transmit_ack()
1437 runtime->hw_ptr += count; in __snd_rawmidi_transmit_ack()
1438 runtime->hw_ptr %= runtime->buffer_size; in __snd_rawmidi_transmit_ack()
1439 runtime->avail += count; in __snd_rawmidi_transmit_ack()
1440 substream->bytes += count; in __snd_rawmidi_transmit_ack()
1442 if (runtime->drain || __snd_rawmidi_ready(runtime)) in __snd_rawmidi_transmit_ack()
1443 wake_up(&runtime->sleep); in __snd_rawmidi_transmit_ack()
1449 * snd_rawmidi_transmit_ack - acknowledge the transmission
1461 guard(spinlock_irqsave)(&substream->lock); in snd_rawmidi_transmit_ack()
1462 if (!substream->opened || !substream->runtime) in snd_rawmidi_transmit_ack()
1463 return -EBADFD; in snd_rawmidi_transmit_ack()
1469 * snd_rawmidi_transmit - copy from the buffer to the device
1481 guard(spinlock_irqsave)(&substream->lock); in snd_rawmidi_transmit()
1482 if (!substream->opened) in snd_rawmidi_transmit()
1483 return -EBADFD; in snd_rawmidi_transmit()
1492 * snd_rawmidi_proceed - Discard the all pending bytes and proceed
1502 guard(spinlock_irqsave)(&substream->lock); in snd_rawmidi_proceed()
1503 runtime = substream->runtime; in snd_rawmidi_proceed()
1504 if (substream->opened && runtime && in snd_rawmidi_proceed()
1505 runtime->avail < runtime->buffer_size) { in snd_rawmidi_proceed()
1506 count = runtime->buffer_size - runtime->avail; in snd_rawmidi_proceed()
1520 struct snd_rawmidi_runtime *runtime = substream->runtime; in snd_rawmidi_kernel_write1()
1524 return -EINVAL; in snd_rawmidi_kernel_write1()
1525 if (snd_BUG_ON(!runtime->buffer)) in snd_rawmidi_kernel_write1()
1526 return -EINVAL; in snd_rawmidi_kernel_write1()
1529 spin_lock_irqsave(&substream->lock, flags); in snd_rawmidi_kernel_write1()
1530 if (substream->append) { in snd_rawmidi_kernel_write1()
1531 if ((long)runtime->avail < count) { in snd_rawmidi_kernel_write1()
1532 spin_unlock_irqrestore(&substream->lock, flags); in snd_rawmidi_kernel_write1()
1533 return -EAGAIN; in snd_rawmidi_kernel_write1()
1537 while (count > 0 && runtime->avail > 0) { in snd_rawmidi_kernel_write1()
1538 count1 = runtime->buffer_size - runtime->appl_ptr; in snd_rawmidi_kernel_write1()
1541 if (count1 > (long)runtime->avail) in snd_rawmidi_kernel_write1()
1542 count1 = runtime->avail; in snd_rawmidi_kernel_write1()
1544 /* update runtime->appl_ptr before unlocking for userbuf */ in snd_rawmidi_kernel_write1()
1545 appl_ptr = runtime->appl_ptr; in snd_rawmidi_kernel_write1()
1546 runtime->appl_ptr += count1; in snd_rawmidi_kernel_write1()
1547 runtime->appl_ptr %= runtime->buffer_size; in snd_rawmidi_kernel_write1()
1548 runtime->avail -= count1; in snd_rawmidi_kernel_write1()
1551 memcpy(runtime->buffer + appl_ptr, in snd_rawmidi_kernel_write1()
1554 spin_unlock_irqrestore(&substream->lock, flags); in snd_rawmidi_kernel_write1()
1555 if (copy_from_user(runtime->buffer + appl_ptr, in snd_rawmidi_kernel_write1()
1557 spin_lock_irqsave(&substream->lock, flags); in snd_rawmidi_kernel_write1()
1558 result = result > 0 ? result : -EFAULT; in snd_rawmidi_kernel_write1()
1561 spin_lock_irqsave(&substream->lock, flags); in snd_rawmidi_kernel_write1()
1564 count -= count1; in snd_rawmidi_kernel_write1()
1567 count1 = runtime->avail < runtime->buffer_size; in snd_rawmidi_kernel_write1()
1569 spin_unlock_irqrestore(&substream->lock, flags); in snd_rawmidi_kernel_write1()
1591 rfile = file->private_data; in snd_rawmidi_write()
1592 substream = rfile->output; in snd_rawmidi_write()
1593 runtime = substream->runtime; in snd_rawmidi_write()
1595 if (substream->append && count > runtime->buffer_size) in snd_rawmidi_write()
1596 return -EIO; in snd_rawmidi_write()
1599 spin_lock_irq(&substream->lock); in snd_rawmidi_write()
1603 if (file->f_flags & O_NONBLOCK) { in snd_rawmidi_write()
1604 spin_unlock_irq(&substream->lock); in snd_rawmidi_write()
1605 return result > 0 ? result : -EAGAIN; in snd_rawmidi_write()
1608 add_wait_queue(&runtime->sleep, &wait); in snd_rawmidi_write()
1610 spin_unlock_irq(&substream->lock); in snd_rawmidi_write()
1612 remove_wait_queue(&runtime->sleep, &wait); in snd_rawmidi_write()
1613 if (rfile->rmidi->card->shutdown) in snd_rawmidi_write()
1614 return -ENODEV; in snd_rawmidi_write()
1616 return result > 0 ? result : -ERESTARTSYS; in snd_rawmidi_write()
1617 spin_lock_irq(&substream->lock); in snd_rawmidi_write()
1618 if (!runtime->avail && !timeout) { in snd_rawmidi_write()
1619 spin_unlock_irq(&substream->lock); in snd_rawmidi_write()
1620 return result > 0 ? result : -EIO; in snd_rawmidi_write()
1623 spin_unlock_irq(&substream->lock); in snd_rawmidi_write()
1629 if ((size_t)count1 < count && (file->f_flags & O_NONBLOCK)) in snd_rawmidi_write()
1631 count -= count1; in snd_rawmidi_write()
1633 if (file->f_flags & O_DSYNC) { in snd_rawmidi_write()
1634 spin_lock_irq(&substream->lock); in snd_rawmidi_write()
1635 while (runtime->avail != runtime->buffer_size) { in snd_rawmidi_write()
1637 unsigned int last_avail = runtime->avail; in snd_rawmidi_write()
1640 add_wait_queue(&runtime->sleep, &wait); in snd_rawmidi_write()
1642 spin_unlock_irq(&substream->lock); in snd_rawmidi_write()
1644 remove_wait_queue(&runtime->sleep, &wait); in snd_rawmidi_write()
1646 return result > 0 ? result : -ERESTARTSYS; in snd_rawmidi_write()
1647 if (runtime->avail == last_avail && !timeout) in snd_rawmidi_write()
1648 return result > 0 ? result : -EIO; in snd_rawmidi_write()
1649 spin_lock_irq(&substream->lock); in snd_rawmidi_write()
1651 spin_unlock_irq(&substream->lock); in snd_rawmidi_write()
1662 rfile = file->private_data; in snd_rawmidi_poll()
1663 if (rfile->input != NULL) { in snd_rawmidi_poll()
1664 runtime = rfile->input->runtime; in snd_rawmidi_poll()
1665 snd_rawmidi_input_trigger(rfile->input, 1); in snd_rawmidi_poll()
1666 poll_wait(file, &runtime->sleep, wait); in snd_rawmidi_poll()
1668 if (rfile->output != NULL) { in snd_rawmidi_poll()
1669 runtime = rfile->output->runtime; in snd_rawmidi_poll()
1670 poll_wait(file, &runtime->sleep, wait); in snd_rawmidi_poll()
1673 if (rfile->input != NULL) { in snd_rawmidi_poll()
1674 if (snd_rawmidi_ready(rfile->input)) in snd_rawmidi_poll()
1677 if (rfile->output != NULL) { in snd_rawmidi_poll()
1678 if (snd_rawmidi_ready(rfile->output)) in snd_rawmidi_poll()
1705 rmidi = entry->private_data; in snd_rawmidi_proc_info_read()
1706 snd_iprintf(buffer, "%s\n\n", rmidi->name); in snd_rawmidi_proc_info_read()
1710 if (rmidi->ops && rmidi->ops->proc_read) in snd_rawmidi_proc_info_read()
1711 rmidi->ops->proc_read(entry, buffer); in snd_rawmidi_proc_info_read()
1712 guard(mutex)(&rmidi->open_mutex); in snd_rawmidi_proc_info_read()
1713 if (rmidi->info_flags & SNDRV_RAWMIDI_INFO_OUTPUT) { in snd_rawmidi_proc_info_read()
1715 &rmidi->streams[SNDRV_RAWMIDI_STREAM_OUTPUT].substreams, in snd_rawmidi_proc_info_read()
1720 substream->number, in snd_rawmidi_proc_info_read()
1721 (unsigned long) substream->bytes); in snd_rawmidi_proc_info_read()
1722 if (substream->opened) { in snd_rawmidi_proc_info_read()
1725 pid_vnr(substream->pid)); in snd_rawmidi_proc_info_read()
1726 runtime = substream->runtime; in snd_rawmidi_proc_info_read()
1727 scoped_guard(spinlock_irq, &substream->lock) { in snd_rawmidi_proc_info_read()
1728 buffer_size = runtime->buffer_size; in snd_rawmidi_proc_info_read()
1729 avail = runtime->avail; in snd_rawmidi_proc_info_read()
1735 runtime->oss ? "OSS compatible" : "native", in snd_rawmidi_proc_info_read()
1740 if (rmidi->info_flags & SNDRV_RAWMIDI_INFO_INPUT) { in snd_rawmidi_proc_info_read()
1742 &rmidi->streams[SNDRV_RAWMIDI_STREAM_INPUT].substreams, in snd_rawmidi_proc_info_read()
1747 substream->number, in snd_rawmidi_proc_info_read()
1748 (unsigned long) substream->bytes); in snd_rawmidi_proc_info_read()
1749 if (substream->opened) { in snd_rawmidi_proc_info_read()
1752 pid_vnr(substream->pid)); in snd_rawmidi_proc_info_read()
1753 runtime = substream->runtime; in snd_rawmidi_proc_info_read()
1754 scoped_guard(spinlock_irq, &substream->lock) { in snd_rawmidi_proc_info_read()
1755 buffer_size = runtime->buffer_size; in snd_rawmidi_proc_info_read()
1756 avail = runtime->avail; in snd_rawmidi_proc_info_read()
1757 xruns = runtime->xruns; in snd_rawmidi_proc_info_read()
1764 if (substream->framing == SNDRV_RAWMIDI_MODE_FRAMING_TSTAMP) { in snd_rawmidi_proc_info_read()
1765 clock_type = substream->clock_type >> SNDRV_RAWMIDI_MODE_CLOCK_SHIFT; in snd_rawmidi_proc_info_read()
1803 return -ENOMEM; in snd_rawmidi_alloc_substreams()
1804 substream->stream = direction; in snd_rawmidi_alloc_substreams()
1805 substream->number = idx; in snd_rawmidi_alloc_substreams()
1806 substream->rmidi = rmidi; in snd_rawmidi_alloc_substreams()
1807 substream->pstr = stream; in snd_rawmidi_alloc_substreams()
1808 spin_lock_init(&substream->lock); in snd_rawmidi_alloc_substreams()
1809 list_add_tail(&substream->list, &stream->substreams); in snd_rawmidi_alloc_substreams()
1810 stream->substream_count++; in snd_rawmidi_alloc_substreams()
1828 rmidi->card = card; in snd_rawmidi_init()
1829 rmidi->device = device; in snd_rawmidi_init()
1830 mutex_init(&rmidi->open_mutex); in snd_rawmidi_init()
1831 init_waitqueue_head(&rmidi->open_wait); in snd_rawmidi_init()
1832 INIT_LIST_HEAD(&rmidi->streams[SNDRV_RAWMIDI_STREAM_INPUT].substreams); in snd_rawmidi_init()
1833 INIT_LIST_HEAD(&rmidi->streams[SNDRV_RAWMIDI_STREAM_OUTPUT].substreams); in snd_rawmidi_init()
1834 rmidi->info_flags = info_flags; in snd_rawmidi_init()
1837 strscpy(rmidi->id, id, sizeof(rmidi->id)); in snd_rawmidi_init()
1839 err = snd_device_alloc(&rmidi->dev, card); in snd_rawmidi_init()
1843 dev_set_name(rmidi->dev, "umpC%iD%i", card->number, device); in snd_rawmidi_init()
1845 dev_set_name(rmidi->dev, "midiC%iD%i", card->number, device); in snd_rawmidi_init()
1848 &rmidi->streams[SNDRV_RAWMIDI_STREAM_INPUT], in snd_rawmidi_init()
1854 &rmidi->streams[SNDRV_RAWMIDI_STREAM_OUTPUT], in snd_rawmidi_init()
1867 * snd_rawmidi_new - create a rawmidi instance
1891 return -ENOMEM; in snd_rawmidi_new()
1908 while (!list_empty(&stream->substreams)) { in snd_rawmidi_free_substreams()
1909 substream = list_entry(stream->substreams.next, struct snd_rawmidi_substream, list); in snd_rawmidi_free_substreams()
1910 list_del(&substream->list); in snd_rawmidi_free_substreams()
1921 snd_info_free_entry(rmidi->proc_entry); in snd_rawmidi_free()
1922 rmidi->proc_entry = NULL; in snd_rawmidi_free()
1923 if (rmidi->ops && rmidi->ops->dev_unregister) in snd_rawmidi_free()
1924 rmidi->ops->dev_unregister(rmidi); in snd_rawmidi_free()
1926 snd_rawmidi_free_substreams(&rmidi->streams[SNDRV_RAWMIDI_STREAM_INPUT]); in snd_rawmidi_free()
1927 snd_rawmidi_free_substreams(&rmidi->streams[SNDRV_RAWMIDI_STREAM_OUTPUT]); in snd_rawmidi_free()
1928 if (rmidi->private_free) in snd_rawmidi_free()
1929 rmidi->private_free(rmidi); in snd_rawmidi_free()
1930 put_device(rmidi->dev); in snd_rawmidi_free()
1938 struct snd_rawmidi *rmidi = device->device_data; in snd_rawmidi_dev_free()
1946 struct snd_rawmidi *rmidi = device->private_data; in snd_rawmidi_dev_seq_free()
1948 rmidi->seq_dev = NULL; in snd_rawmidi_dev_seq_free()
1957 struct snd_rawmidi *rmidi = device->device_data; in snd_rawmidi_dev_register()
1959 if (rmidi->device >= SNDRV_RAWMIDI_DEVICES) in snd_rawmidi_dev_register()
1960 return -ENOMEM; in snd_rawmidi_dev_register()
1963 if (snd_rawmidi_search(rmidi->card, rmidi->device)) in snd_rawmidi_dev_register()
1964 err = -EBUSY; in snd_rawmidi_dev_register()
1966 list_add_tail(&rmidi->list, &snd_rawmidi_devices); in snd_rawmidi_dev_register()
1972 rmidi->card, rmidi->device, in snd_rawmidi_dev_register()
1973 &snd_rawmidi_f_ops, rmidi, rmidi->dev); in snd_rawmidi_dev_register()
1978 if (rmidi->ops && rmidi->ops->dev_register) { in snd_rawmidi_dev_register()
1979 err = rmidi->ops->dev_register(rmidi); in snd_rawmidi_dev_register()
1984 rmidi->ossreg = 0; in snd_rawmidi_dev_register()
1986 (int)rmidi->device == midi_map[rmidi->card->number]) { in snd_rawmidi_dev_register()
1988 rmidi->card, 0, &snd_rawmidi_f_ops, in snd_rawmidi_dev_register()
1992 rmidi->card->number, 0); in snd_rawmidi_dev_register()
1994 rmidi->ossreg++; in snd_rawmidi_dev_register()
1996 snd_oss_info_register(SNDRV_OSS_INFO_DEV_MIDI, rmidi->card->number, rmidi->name); in snd_rawmidi_dev_register()
2001 (int)rmidi->device == amidi_map[rmidi->card->number]) { in snd_rawmidi_dev_register()
2003 rmidi->card, 1, &snd_rawmidi_f_ops, in snd_rawmidi_dev_register()
2007 rmidi->card->number, 1); in snd_rawmidi_dev_register()
2009 rmidi->ossreg++; in snd_rawmidi_dev_register()
2013 sprintf(name, "midi%d", rmidi->device); in snd_rawmidi_dev_register()
2014 entry = snd_info_create_card_entry(rmidi->card, name, rmidi->card->proc_root); in snd_rawmidi_dev_register()
2016 entry->private_data = rmidi; in snd_rawmidi_dev_register()
2017 entry->c.text.read = snd_rawmidi_proc_info_read; in snd_rawmidi_dev_register()
2023 rmidi->proc_entry = entry; in snd_rawmidi_dev_register()
2026 if (!rmidi->ops || !rmidi->ops->dev_register) { in snd_rawmidi_dev_register()
2027 …if (snd_seq_device_new(rmidi->card, rmidi->device, SNDRV_SEQ_DEV_ID_MIDISYNTH, 0, &rmidi->seq_dev)… in snd_rawmidi_dev_register()
2028 rmidi->seq_dev->private_data = rmidi; in snd_rawmidi_dev_register()
2029 rmidi->seq_dev->private_free = snd_rawmidi_dev_seq_free; in snd_rawmidi_dev_register()
2030 sprintf(rmidi->seq_dev->name, "MIDI %d-%d", rmidi->card->number, rmidi->device); in snd_rawmidi_dev_register()
2031 snd_device_register(rmidi->card, rmidi->seq_dev); in snd_rawmidi_dev_register()
2038 snd_unregister_device(rmidi->dev); in snd_rawmidi_dev_register()
2041 list_del(&rmidi->list); in snd_rawmidi_dev_register()
2047 struct snd_rawmidi *rmidi = device->device_data; in snd_rawmidi_dev_disconnect()
2050 guard(mutex)(®ister_mutex); in snd_rawmidi_dev_disconnect()
2051 guard(mutex)(&rmidi->open_mutex); in snd_rawmidi_dev_disconnect()
2052 wake_up(&rmidi->open_wait); in snd_rawmidi_dev_disconnect()
2053 list_del_init(&rmidi->list); in snd_rawmidi_dev_disconnect()
2057 list_for_each_entry(s, &rmidi->streams[dir].substreams, list) { in snd_rawmidi_dev_disconnect()
2058 if (s->runtime) in snd_rawmidi_dev_disconnect()
2059 wake_up(&s->runtime->sleep); in snd_rawmidi_dev_disconnect()
2064 if (rmidi->ossreg) { in snd_rawmidi_dev_disconnect()
2065 if ((int)rmidi->device == midi_map[rmidi->card->number]) { in snd_rawmidi_dev_disconnect()
2066 snd_unregister_oss_device(SNDRV_OSS_DEVICE_TYPE_MIDI, rmidi->card, 0); in snd_rawmidi_dev_disconnect()
2068 snd_oss_info_unregister(SNDRV_OSS_INFO_DEV_MIDI, rmidi->card->number); in snd_rawmidi_dev_disconnect()
2071 if ((int)rmidi->device == amidi_map[rmidi->card->number]) in snd_rawmidi_dev_disconnect()
2072 snd_unregister_oss_device(SNDRV_OSS_DEVICE_TYPE_MIDI, rmidi->card, 1); in snd_rawmidi_dev_disconnect()
2073 rmidi->ossreg = 0; in snd_rawmidi_dev_disconnect()
2076 snd_unregister_device(rmidi->dev); in snd_rawmidi_dev_disconnect()
2081 * snd_rawmidi_set_ops - set the rawmidi operators
2093 list_for_each_entry(substream, &rmidi->streams[stream].substreams, list) in snd_rawmidi_set_ops()
2094 substream->ops = ops; in snd_rawmidi_set_ops()