X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=sound%2Fcore%2Frawmidi.c;h=0f055bfcbdac3b305e78c80fc6f0f01e0d21f56c;hb=a2f44b27303a5353859d77a3e96a1d3f33f56ab7;hp=d4d124e21924835ee6f10b3cc34afec7d8a6632c;hpb=134734d875a0a48d994ef20b9905209b4b8b6f75;p=linux-2.6.git diff --git a/sound/core/rawmidi.c b/sound/core/rawmidi.c index d4d124e21..0f055bfcb 100644 --- a/sound/core/rawmidi.c +++ b/sound/core/rawmidi.c @@ -28,6 +28,7 @@ #include #include #include +#include #include #include #include @@ -42,7 +43,7 @@ MODULE_DESCRIPTION("Midlevel RawMidi code for ALSA."); MODULE_LICENSE("GPL"); #ifdef CONFIG_SND_OSSEMUL -static int midi_map[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS-1)] = 0}; +static int midi_map[SNDRV_CARDS]; static int amidi_map[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS-1)] = 1}; module_param_array(midi_map, int, NULL, 0444); MODULE_PARM_DESC(midi_map, "Raw MIDI device number assigned to 1st OSS device."); @@ -54,10 +55,9 @@ static int snd_rawmidi_free(struct snd_rawmidi *rawmidi); static int snd_rawmidi_dev_free(struct snd_device *device); static int snd_rawmidi_dev_register(struct snd_device *device); static int snd_rawmidi_dev_disconnect(struct snd_device *device); -static int snd_rawmidi_dev_unregister(struct snd_device *device); static LIST_HEAD(snd_rawmidi_devices); -static DECLARE_MUTEX(register_mutex); +static DEFINE_MUTEX(register_mutex); static struct snd_rawmidi *snd_rawmidi_search(struct snd_card *card, int device) { @@ -237,9 +237,9 @@ int snd_rawmidi_kernel_open(struct snd_card *card, int device, int subdevice, if (rfile) rfile->input = rfile->output = NULL; - down(®ister_mutex); + mutex_lock(®ister_mutex); rmidi = snd_rawmidi_search(card, device); - up(®ister_mutex); + mutex_unlock(®ister_mutex); if (rmidi == NULL) { err = -ENODEV; goto __error1; @@ -249,7 +249,7 @@ int snd_rawmidi_kernel_open(struct snd_card *card, int device, int subdevice, goto __error1; } if (!(mode & SNDRV_RAWMIDI_LFLG_NOOPENLOCK)) - down(&rmidi->open_mutex); + mutex_lock(&rmidi->open_mutex); if (mode & SNDRV_RAWMIDI_LFLG_INPUT) { if (!(rmidi->info_flags & SNDRV_RAWMIDI_INFO_INPUT)) { err = -ENXIO; @@ -359,7 +359,7 @@ int snd_rawmidi_kernel_open(struct snd_card *card, int device, int subdevice, soutput = NULL; } if (!(mode & SNDRV_RAWMIDI_LFLG_NOOPENLOCK)) - up(&rmidi->open_mutex); + mutex_unlock(&rmidi->open_mutex); if (rfile) { rfile->rmidi = rmidi; rfile->input = sinput; @@ -374,7 +374,7 @@ int snd_rawmidi_kernel_open(struct snd_card *card, int device, int subdevice, snd_rawmidi_runtime_free(soutput); module_put(rmidi->card->module); if (!(mode & SNDRV_RAWMIDI_LFLG_NOOPENLOCK)) - up(&rmidi->open_mutex); + mutex_unlock(&rmidi->open_mutex); __error1: return err; } @@ -422,7 +422,7 @@ static int snd_rawmidi_open(struct inode *inode, struct file *file) } init_waitqueue_entry(&wait, current); add_wait_queue(&rmidi->open_wait, &wait); - down(&rmidi->open_mutex); + mutex_lock(&rmidi->open_mutex); while (1) { subdevice = -1; down_read(&card->controls_rwsem); @@ -430,7 +430,8 @@ static int snd_rawmidi_open(struct inode *inode, struct file *file) kctl = snd_ctl_file(list); if (kctl->pid == current->pid) { subdevice = kctl->prefer_rawmidi_subdevice; - break; + if (subdevice != -1) + break; } } up_read(&card->controls_rwsem); @@ -446,9 +447,9 @@ static int snd_rawmidi_open(struct inode *inode, struct file *file) } else break; set_current_state(TASK_INTERRUPTIBLE); - up(&rmidi->open_mutex); + mutex_unlock(&rmidi->open_mutex); schedule(); - down(&rmidi->open_mutex); + mutex_lock(&rmidi->open_mutex); if (signal_pending(current)) { err = -ERESTARTSYS; break; @@ -467,7 +468,7 @@ static int snd_rawmidi_open(struct inode *inode, struct file *file) snd_card_file_remove(card, file); kfree(rawmidi_file); } - up(&rmidi->open_mutex); + mutex_unlock(&rmidi->open_mutex); return err; } @@ -480,7 +481,7 @@ int snd_rawmidi_kernel_release(struct snd_rawmidi_file * rfile) snd_assert(rfile != NULL, return -ENXIO); snd_assert(rfile->input != NULL || rfile->output != NULL, return -ENXIO); rmidi = rfile->rmidi; - down(&rmidi->open_mutex); + mutex_lock(&rmidi->open_mutex); if (rfile->input != NULL) { substream = rfile->input; rfile->input = NULL; @@ -514,7 +515,7 @@ int snd_rawmidi_kernel_release(struct snd_rawmidi_file * rfile) } rmidi->streams[SNDRV_RAWMIDI_STREAM_OUTPUT].substream_opened--; } - up(&rmidi->open_mutex); + mutex_unlock(&rmidi->open_mutex); module_put(rmidi->card->module); return 0; } @@ -576,9 +577,9 @@ int snd_rawmidi_info_select(struct snd_card *card, struct snd_rawmidi_info *info struct snd_rawmidi_substream *substream; struct list_head *list; - down(®ister_mutex); + mutex_lock(®ister_mutex); rmidi = snd_rawmidi_search(card, info->device); - up(®ister_mutex); + mutex_unlock(®ister_mutex); if (!rmidi) return -ENXIO; if (info->stream < 0 || info->stream > 1) @@ -630,7 +631,8 @@ int snd_rawmidi_output_params(struct snd_rawmidi_substream *substream, return -EINVAL; } if (params->buffer_size != runtime->buffer_size) { - if ((newbuf = (char *) kmalloc(params->buffer_size, GFP_KERNEL)) == NULL) + newbuf = kmalloc(params->buffer_size, GFP_KERNEL); + if (!newbuf) return -ENOMEM; kfree(runtime->buffer); runtime->buffer = newbuf; @@ -656,7 +658,8 @@ int snd_rawmidi_input_params(struct snd_rawmidi_substream *substream, return -EINVAL; } if (params->buffer_size != runtime->buffer_size) { - if ((newbuf = (char *) kmalloc(params->buffer_size, GFP_KERNEL)) == NULL) + newbuf = kmalloc(params->buffer_size, GFP_KERNEL); + if (!newbuf) return -ENOMEM; kfree(runtime->buffer); runtime->buffer = newbuf; @@ -818,7 +821,7 @@ static int snd_rawmidi_control_ioctl(struct snd_card *card, if (get_user(device, (int __user *)argp)) return -EFAULT; - down(®ister_mutex); + mutex_lock(®ister_mutex); device = device < 0 ? 0 : device + 1; while (device < SNDRV_RAWMIDI_DEVICES) { if (snd_rawmidi_search(card, device)) @@ -827,7 +830,7 @@ static int snd_rawmidi_control_ioctl(struct snd_card *card, } if (device == SNDRV_RAWMIDI_DEVICES) device = -1; - up(®ister_mutex); + mutex_unlock(®ister_mutex); if (put_user(device, (int __user *)argp)) return -EFAULT; return 0; @@ -1314,7 +1317,7 @@ static void snd_rawmidi_proc_info_read(struct snd_info_entry *entry, rmidi = entry->private_data; snd_iprintf(buffer, "%s\n\n", rmidi->name); - down(&rmidi->open_mutex); + mutex_lock(&rmidi->open_mutex); if (rmidi->info_flags & SNDRV_RAWMIDI_INFO_OUTPUT) { list_for_each(list, &rmidi->streams[SNDRV_RAWMIDI_STREAM_OUTPUT].substreams) { substream = list_entry(list, struct snd_rawmidi_substream, list); @@ -1355,7 +1358,7 @@ static void snd_rawmidi_proc_info_read(struct snd_info_entry *entry, } } } - up(&rmidi->open_mutex); + mutex_unlock(&rmidi->open_mutex); } /* @@ -1382,7 +1385,6 @@ static int snd_rawmidi_alloc_substreams(struct snd_rawmidi *rmidi, struct snd_rawmidi_substream *substream; int idx; - INIT_LIST_HEAD(&stream->substreams); for (idx = 0; idx < count; idx++) { substream = kzalloc(sizeof(*substream), GFP_KERNEL); if (substream == NULL) { @@ -1423,7 +1425,6 @@ int snd_rawmidi_new(struct snd_card *card, char *id, int device, .dev_free = snd_rawmidi_dev_free, .dev_register = snd_rawmidi_dev_register, .dev_disconnect = snd_rawmidi_dev_disconnect, - .dev_unregister = snd_rawmidi_dev_unregister }; snd_assert(rrawmidi != NULL, return -EINVAL); @@ -1436,8 +1437,11 @@ int snd_rawmidi_new(struct snd_card *card, char *id, int device, } rmidi->card = card; rmidi->device = device; - init_MUTEX(&rmidi->open_mutex); + mutex_init(&rmidi->open_mutex); init_waitqueue_head(&rmidi->open_wait); + INIT_LIST_HEAD(&rmidi->streams[SNDRV_RAWMIDI_STREAM_INPUT].substreams); + INIT_LIST_HEAD(&rmidi->streams[SNDRV_RAWMIDI_STREAM_OUTPUT].substreams); + if (id != NULL) strlcpy(rmidi->id, id, sizeof(rmidi->id)); if ((err = snd_rawmidi_alloc_substreams(rmidi, @@ -1476,6 +1480,14 @@ static void snd_rawmidi_free_substreams(struct snd_rawmidi_str *stream) static int snd_rawmidi_free(struct snd_rawmidi *rmidi) { snd_assert(rmidi != NULL, return -ENXIO); + + snd_info_free_entry(rmidi->proc_entry); + rmidi->proc_entry = NULL; + mutex_lock(®ister_mutex); + if (rmidi->ops && rmidi->ops->dev_unregister) + rmidi->ops->dev_unregister(rmidi); + mutex_unlock(®ister_mutex); + snd_rawmidi_free_substreams(&rmidi->streams[SNDRV_RAWMIDI_STREAM_INPUT]); snd_rawmidi_free_substreams(&rmidi->streams[SNDRV_RAWMIDI_STREAM_OUTPUT]); if (rmidi->private_free) @@ -1507,9 +1519,9 @@ static int snd_rawmidi_dev_register(struct snd_device *device) if (rmidi->device >= SNDRV_RAWMIDI_DEVICES) return -ENOMEM; - down(®ister_mutex); + mutex_lock(®ister_mutex); if (snd_rawmidi_search(rmidi->card, rmidi->device)) { - up(®ister_mutex); + mutex_unlock(®ister_mutex); return -EBUSY; } list_add_tail(&rmidi->list, &snd_rawmidi_devices); @@ -1519,14 +1531,14 @@ static int snd_rawmidi_dev_register(struct snd_device *device) &snd_rawmidi_f_ops, rmidi, name)) < 0) { snd_printk(KERN_ERR "unable to register rawmidi device %i:%i\n", rmidi->card->number, rmidi->device); list_del(&rmidi->list); - up(®ister_mutex); + mutex_unlock(®ister_mutex); return err; } if (rmidi->ops && rmidi->ops->dev_register && (err = rmidi->ops->dev_register(rmidi)) < 0) { snd_unregister_device(SNDRV_DEVICE_TYPE_RAWMIDI, rmidi->card, rmidi->device); list_del(&rmidi->list); - up(®ister_mutex); + mutex_unlock(®ister_mutex); return err; } #ifdef CONFIG_SND_OSSEMUL @@ -1553,12 +1565,11 @@ static int snd_rawmidi_dev_register(struct snd_device *device) } } #endif /* CONFIG_SND_OSSEMUL */ - up(®ister_mutex); + mutex_unlock(®ister_mutex); sprintf(name, "midi%d", rmidi->device); entry = snd_info_create_card_entry(rmidi->card, name, rmidi->card->proc_root); if (entry) { entry->private_data = rmidi; - entry->c.text.read_size = 1024; entry->c.text.read = snd_rawmidi_proc_info_read; if (snd_info_register(entry) < 0) { snd_info_free_entry(entry); @@ -1583,23 +1594,8 @@ static int snd_rawmidi_dev_disconnect(struct snd_device *device) { struct snd_rawmidi *rmidi = device->device_data; - down(®ister_mutex); + mutex_lock(®ister_mutex); list_del_init(&rmidi->list); - up(®ister_mutex); - return 0; -} - -static int snd_rawmidi_dev_unregister(struct snd_device *device) -{ - struct snd_rawmidi *rmidi = device->device_data; - - snd_assert(rmidi != NULL, return -ENXIO); - down(®ister_mutex); - list_del(&rmidi->list); - if (rmidi->proc_entry) { - snd_info_unregister(rmidi->proc_entry); - rmidi->proc_entry = NULL; - } #ifdef CONFIG_SND_OSSEMUL if (rmidi->ossreg) { if ((int)rmidi->device == midi_map[rmidi->card->number]) { @@ -1613,17 +1609,9 @@ static int snd_rawmidi_dev_unregister(struct snd_device *device) rmidi->ossreg = 0; } #endif /* CONFIG_SND_OSSEMUL */ - if (rmidi->ops && rmidi->ops->dev_unregister) - rmidi->ops->dev_unregister(rmidi); snd_unregister_device(SNDRV_DEVICE_TYPE_RAWMIDI, rmidi->card, rmidi->device); - up(®ister_mutex); -#if defined(CONFIG_SND_SEQUENCER) || (defined(MODULE) && defined(CONFIG_SND_SEQUENCER_MODULE)) - if (rmidi->seq_dev) { - snd_device_free(rmidi->card, rmidi->seq_dev); - rmidi->seq_dev = NULL; - } -#endif - return snd_rawmidi_free(rmidi); + mutex_unlock(®ister_mutex); + return 0; } /**