X-Git-Url: http://pilppa.org/gitweb/gitweb.cgi?a=blobdiff_plain;f=sound%2Fcore%2Frawmidi.c;h=d14dcbb6dbca70a6789b0b56144cd1d99f85f361;hb=7eaa943c8ed8e91e05d0f5d0dc7a18e3319b45cf;hp=269c467ca9bb2ba76f3c001f1d824414ccb5bd07;hpb=e823aff2d6eb43083abcc75a32ddfb167c324089;p=linux-2.6-omap-h63xx.git diff --git a/sound/core/rawmidi.c b/sound/core/rawmidi.c index 269c467ca9b..c4995c9f573 100644 --- a/sound/core/rawmidi.c +++ b/sound/core/rawmidi.c @@ -1,6 +1,6 @@ /* * Abstract layer for MIDI v1.0 stream - * Copyright (c) by Jaroslav Kysela + * Copyright (c) by Jaroslav Kysela * * * This program is free software; you can redistribute it and/or modify @@ -19,11 +19,9 @@ * */ -#include #include #include #include -#include #include #include #include @@ -31,14 +29,13 @@ #include #include #include -#include #include #include #include #include #include -MODULE_AUTHOR("Jaroslav Kysela "); +MODULE_AUTHOR("Jaroslav Kysela "); MODULE_DESCRIPTION("Midlevel RawMidi code for ALSA."); MODULE_LICENSE("GPL"); @@ -61,14 +58,11 @@ static DEFINE_MUTEX(register_mutex); static struct snd_rawmidi *snd_rawmidi_search(struct snd_card *card, int device) { - struct list_head *p; struct snd_rawmidi *rawmidi; - list_for_each(p, &snd_rawmidi_devices) { - rawmidi = list_entry(p, struct snd_rawmidi, list); + list_for_each_entry(rawmidi, &snd_rawmidi_devices, list) if (rawmidi->card == card && rawmidi->device == device) return rawmidi; - } return NULL; } @@ -389,7 +383,6 @@ static int snd_rawmidi_open(struct inode *inode, struct file *file) struct snd_rawmidi *rmidi; struct snd_rawmidi_file *rawmidi_file; wait_queue_t wait; - struct list_head *list; struct snd_ctl_file *kctl; if (maj == snd_major) { @@ -425,16 +418,15 @@ static int snd_rawmidi_open(struct inode *inode, struct file *file) mutex_lock(&rmidi->open_mutex); while (1) { subdevice = -1; - down_read(&card->controls_rwsem); - list_for_each(list, &card->ctl_files) { - kctl = snd_ctl_file(list); + read_lock(&card->ctl_files_rwlock); + list_for_each_entry(kctl, &card->ctl_files, list) { if (kctl->pid == current->pid) { subdevice = kctl->prefer_rawmidi_subdevice; if (subdevice != -1) break; } } - up_read(&card->controls_rwsem); + read_unlock(&card->ctl_files_rwlock); err = snd_rawmidi_kernel_open(rmidi->card, rmidi->device, subdevice, fflags, rawmidi_file); if (err >= 0) @@ -478,8 +470,8 @@ int snd_rawmidi_kernel_release(struct snd_rawmidi_file * rfile) struct snd_rawmidi_substream *substream; struct snd_rawmidi_runtime *runtime; - snd_assert(rfile != NULL, return -ENXIO); - snd_assert(rfile->input != NULL || rfile->output != NULL, return -ENXIO); + if (snd_BUG_ON(!rfile)) + return -ENXIO; rmidi = rfile->rmidi; mutex_lock(&rmidi->open_mutex); if (rfile->input != NULL) { @@ -575,7 +567,6 @@ int snd_rawmidi_info_select(struct snd_card *card, struct snd_rawmidi_info *info struct snd_rawmidi *rmidi; struct snd_rawmidi_str *pstr; struct snd_rawmidi_substream *substream; - struct list_head *list; mutex_lock(®ister_mutex); rmidi = snd_rawmidi_search(card, info->device); @@ -589,8 +580,7 @@ int snd_rawmidi_info_select(struct snd_card *card, struct snd_rawmidi_info *info return -ENOENT; if (info->subdevice >= pstr->substream_count) return -ENXIO; - list_for_each(list, &pstr->substreams) { - substream = list_entry(list, struct snd_rawmidi_substream, list); + list_for_each_entry(substream, &pstr->substreams, list) { if ((unsigned int)substream->number == info->subdevice) return snd_rawmidi_info(substream, info); } @@ -921,7 +911,8 @@ int snd_rawmidi_receive(struct snd_rawmidi_substream *substream, } static long snd_rawmidi_kernel_read1(struct snd_rawmidi_substream *substream, - unsigned char *buf, long count, int kernel) + unsigned char __user *userbuf, + unsigned char *kernelbuf, long count) { unsigned long flags; long result = 0, count1; @@ -934,11 +925,11 @@ static long snd_rawmidi_kernel_read1(struct snd_rawmidi_substream *substream, spin_lock_irqsave(&runtime->lock, flags); if (count1 > (int)runtime->avail) count1 = runtime->avail; - if (kernel) { - memcpy(buf + result, runtime->buffer + runtime->appl_ptr, count1); - } else { + if (kernelbuf) + memcpy(kernelbuf + result, runtime->buffer + runtime->appl_ptr, count1); + if (userbuf) { spin_unlock_irqrestore(&runtime->lock, flags); - if (copy_to_user((char __user *)buf + result, + if (copy_to_user(userbuf + result, runtime->buffer + runtime->appl_ptr, count1)) { return result > 0 ? result : -EFAULT; } @@ -958,7 +949,7 @@ long snd_rawmidi_kernel_read(struct snd_rawmidi_substream *substream, unsigned char *buf, long count) { snd_rawmidi_input_trigger(substream, 1); - return snd_rawmidi_kernel_read1(substream, buf, count, 1); + return snd_rawmidi_kernel_read1(substream, NULL/*userbuf*/, buf, count); } static ssize_t snd_rawmidi_read(struct file *file, char __user *buf, size_t count, @@ -999,8 +990,9 @@ static ssize_t snd_rawmidi_read(struct file *file, char __user *buf, size_t coun } spin_unlock_irq(&runtime->lock); count1 = snd_rawmidi_kernel_read1(substream, - (unsigned char __force *)buf, - count, 0); + (unsigned char __user *)buf, + NULL/*kernelbuf*/, + count); if (count1 < 0) return result > 0 ? result : count1; result += count1; @@ -1108,7 +1100,7 @@ int snd_rawmidi_transmit_ack(struct snd_rawmidi_substream *substream, int count) return -EINVAL; } spin_lock_irqsave(&runtime->lock, flags); - snd_assert(runtime->avail + count <= runtime->buffer_size, ); + snd_BUG_ON(runtime->avail + count > runtime->buffer_size); runtime->hw_ptr += count; runtime->hw_ptr %= runtime->buffer_size; runtime->avail += count; @@ -1141,14 +1133,18 @@ int snd_rawmidi_transmit(struct snd_rawmidi_substream *substream, } static long snd_rawmidi_kernel_write1(struct snd_rawmidi_substream *substream, - const unsigned char *buf, long count, int kernel) + const unsigned char __user *userbuf, + const unsigned char *kernelbuf, + long count) { unsigned long flags; long count1, result; struct snd_rawmidi_runtime *runtime = substream->runtime; - snd_assert(buf != NULL, return -EINVAL); - snd_assert(runtime->buffer != NULL, return -EINVAL); + if (snd_BUG_ON(!kernelbuf && !userbuf)) + return -EINVAL; + if (snd_BUG_ON(!runtime->buffer)) + return -EINVAL; result = 0; spin_lock_irqsave(&runtime->lock, flags); @@ -1164,12 +1160,13 @@ static long snd_rawmidi_kernel_write1(struct snd_rawmidi_substream *substream, count1 = count; if (count1 > (long)runtime->avail) count1 = runtime->avail; - if (kernel) { - memcpy(runtime->buffer + runtime->appl_ptr, buf, count1); - } else { + if (kernelbuf) + memcpy(runtime->buffer + runtime->appl_ptr, + kernelbuf + result, count1); + else if (userbuf) { spin_unlock_irqrestore(&runtime->lock, flags); if (copy_from_user(runtime->buffer + runtime->appl_ptr, - (char __user *)buf, count1)) { + userbuf + result, count1)) { spin_lock_irqsave(&runtime->lock, flags); result = result > 0 ? result : -EFAULT; goto __end; @@ -1180,7 +1177,6 @@ static long snd_rawmidi_kernel_write1(struct snd_rawmidi_substream *substream, runtime->appl_ptr %= runtime->buffer_size; runtime->avail -= count1; result += count1; - buf += count1; count -= count1; } __end: @@ -1194,7 +1190,7 @@ static long snd_rawmidi_kernel_write1(struct snd_rawmidi_substream *substream, long snd_rawmidi_kernel_write(struct snd_rawmidi_substream *substream, const unsigned char *buf, long count) { - return snd_rawmidi_kernel_write1(substream, buf, count, 1); + return snd_rawmidi_kernel_write1(substream, NULL, buf, count); } static ssize_t snd_rawmidi_write(struct file *file, const char __user *buf, @@ -1234,9 +1230,7 @@ static ssize_t snd_rawmidi_write(struct file *file, const char __user *buf, spin_lock_irq(&runtime->lock); } spin_unlock_irq(&runtime->lock); - count1 = snd_rawmidi_kernel_write1(substream, - (unsigned char __force *)buf, - count, 0); + count1 = snd_rawmidi_kernel_write1(substream, buf, NULL, count); if (count1 < 0) return result > 0 ? result : count1; result += count1; @@ -1313,14 +1307,14 @@ static void snd_rawmidi_proc_info_read(struct snd_info_entry *entry, struct snd_rawmidi *rmidi; struct snd_rawmidi_substream *substream; struct snd_rawmidi_runtime *runtime; - struct list_head *list; rmidi = entry->private_data; snd_iprintf(buffer, "%s\n\n", rmidi->name); 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); + list_for_each_entry(substream, + &rmidi->streams[SNDRV_RAWMIDI_STREAM_OUTPUT].substreams, + list) { snd_iprintf(buffer, "Output %d\n" " Tx bytes : %lu\n", @@ -1339,8 +1333,9 @@ static void snd_rawmidi_proc_info_read(struct snd_info_entry *entry, } } if (rmidi->info_flags & SNDRV_RAWMIDI_INFO_INPUT) { - list_for_each(list, &rmidi->streams[SNDRV_RAWMIDI_STREAM_INPUT].substreams) { - substream = list_entry(list, struct snd_rawmidi_substream, list); + list_for_each_entry(substream, + &rmidi->streams[SNDRV_RAWMIDI_STREAM_INPUT].substreams, + list) { snd_iprintf(buffer, "Input %d\n" " Rx bytes : %lu\n", @@ -1365,7 +1360,7 @@ static void snd_rawmidi_proc_info_read(struct snd_info_entry *entry, * Register functions */ -static struct file_operations snd_rawmidi_f_ops = +static const struct file_operations snd_rawmidi_f_ops = { .owner = THIS_MODULE, .read = snd_rawmidi_read, @@ -1385,7 +1380,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) { @@ -1428,9 +1422,10 @@ int snd_rawmidi_new(struct snd_card *card, char *id, int device, .dev_disconnect = snd_rawmidi_dev_disconnect, }; - snd_assert(rrawmidi != NULL, return -EINVAL); - *rrawmidi = NULL; - snd_assert(card != NULL, return -ENXIO); + if (snd_BUG_ON(!card)) + return -ENXIO; + if (rrawmidi) + *rrawmidi = NULL; rmidi = kzalloc(sizeof(*rmidi), GFP_KERNEL); if (rmidi == NULL) { snd_printk(KERN_ERR "rawmidi: cannot allocate\n"); @@ -1440,6 +1435,9 @@ int snd_rawmidi_new(struct snd_card *card, char *id, int device, rmidi->device = device; 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, @@ -1460,7 +1458,8 @@ int snd_rawmidi_new(struct snd_card *card, char *id, int device, snd_rawmidi_free(rmidi); return err; } - *rrawmidi = rmidi; + if (rrawmidi) + *rrawmidi = rmidi; return 0; } @@ -1477,7 +1476,8 @@ 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); + if (!rmidi) + return 0; snd_info_free_entry(rmidi->proc_entry); rmidi->proc_entry = NULL; @@ -1623,13 +1623,10 @@ static int snd_rawmidi_dev_disconnect(struct snd_device *device) void snd_rawmidi_set_ops(struct snd_rawmidi *rmidi, int stream, struct snd_rawmidi_ops *ops) { - struct list_head *list; struct snd_rawmidi_substream *substream; - list_for_each(list, &rmidi->streams[stream].substreams) { - substream = list_entry(list, struct snd_rawmidi_substream, list); + list_for_each_entry(substream, &rmidi->streams[stream].substreams, list) substream->ops = ops; - } } /*