diff options
Diffstat (limited to 'sound/core')
-rw-r--r-- | sound/core/compress_offload.c | 99 | ||||
-rw-r--r-- | sound/core/init.c | 3 | ||||
-rw-r--r-- | sound/core/oss/mixer_oss.c | 8 | ||||
-rw-r--r-- | sound/core/oss/pcm_oss.c | 10 | ||||
-rw-r--r-- | sound/core/pcm_native.c | 26 | ||||
-rw-r--r-- | sound/core/seq/oss/seq_oss.c | 7 | ||||
-rw-r--r-- | sound/core/seq/seq_clientmgr.c | 2 | ||||
-rw-r--r-- | sound/core/seq/seq_queue.c | 2 | ||||
-rw-r--r-- | sound/core/seq/seq_virmidi.c | 2 | ||||
-rw-r--r-- | sound/core/timer.c | 76 |
10 files changed, 180 insertions, 55 deletions
diff --git a/sound/core/compress_offload.c b/sound/core/compress_offload.c index b123c42e7dc8..18b8dc45bb8f 100644 --- a/sound/core/compress_offload.c +++ b/sound/core/compress_offload.c @@ -38,8 +38,10 @@ #include <linux/uio.h> #include <linux/uaccess.h> #include <linux/module.h> +#include <linux/compat.h> #include <sound/core.h> #include <sound/initval.h> +#include <sound/info.h> #include <sound/compress_params.h> #include <sound/compress_offload.h> #include <sound/compress_driver.h> @@ -847,6 +849,15 @@ static long snd_compr_ioctl(struct file *f, unsigned int cmd, unsigned long arg) return retval; } +/* support of 32bit userspace on 64bit platforms */ +#ifdef CONFIG_COMPAT +static long snd_compr_ioctl_compat(struct file *file, unsigned int cmd, + unsigned long arg) +{ + return snd_compr_ioctl(file, cmd, (unsigned long)compat_ptr(arg)); +} +#endif + static const struct file_operations snd_compr_file_ops = { .owner = THIS_MODULE, .open = snd_compr_open, @@ -854,6 +865,9 @@ static const struct file_operations snd_compr_file_ops = { .write = snd_compr_write, .read = snd_compr_read, .unlocked_ioctl = snd_compr_ioctl, +#ifdef CONFIG_COMPAT + .compat_ioctl = snd_compr_ioctl_compat, +#endif .mmap = snd_compr_mmap, .poll = snd_compr_poll, }; @@ -891,11 +905,85 @@ static int snd_compress_dev_disconnect(struct snd_device *device) return 0; } +#ifdef CONFIG_SND_VERBOSE_PROCFS +static void snd_compress_proc_info_read(struct snd_info_entry *entry, + struct snd_info_buffer *buffer) +{ + struct snd_compr *compr = (struct snd_compr *)entry->private_data; + + snd_iprintf(buffer, "card: %d\n", compr->card->number); + snd_iprintf(buffer, "device: %d\n", compr->device); + snd_iprintf(buffer, "stream: %s\n", + compr->direction == SND_COMPRESS_PLAYBACK + ? "PLAYBACK" : "CAPTURE"); + snd_iprintf(buffer, "id: %s\n", compr->id); +} + +static int snd_compress_proc_init(struct snd_compr *compr) +{ + struct snd_info_entry *entry; + char name[16]; + + sprintf(name, "compr%i", compr->device); + entry = snd_info_create_card_entry(compr->card, name, + compr->card->proc_root); + if (!entry) + return -ENOMEM; + entry->mode = S_IFDIR | S_IRUGO | S_IXUGO; + if (snd_info_register(entry) < 0) { + snd_info_free_entry(entry); + return -ENOMEM; + } + compr->proc_root = entry; + + entry = snd_info_create_card_entry(compr->card, "info", + compr->proc_root); + if (entry) { + snd_info_set_text_ops(entry, compr, + snd_compress_proc_info_read); + if (snd_info_register(entry) < 0) { + snd_info_free_entry(entry); + entry = NULL; + } + } + compr->proc_info_entry = entry; + + return 0; +} + +static void snd_compress_proc_done(struct snd_compr *compr) +{ + snd_info_free_entry(compr->proc_info_entry); + compr->proc_info_entry = NULL; + snd_info_free_entry(compr->proc_root); + compr->proc_root = NULL; +} + +static inline void snd_compress_set_id(struct snd_compr *compr, const char *id) +{ + strlcpy(compr->id, id, sizeof(compr->id)); +} +#else +static inline int snd_compress_proc_init(struct snd_compr *compr) +{ + return 0; +} + +static inline void snd_compress_proc_done(struct snd_compr *compr) +{ +} + +static inline void snd_compress_set_id(struct snd_compr *compr, const char *id) +{ +} +#endif + static int snd_compress_dev_free(struct snd_device *device) { struct snd_compr *compr; compr = device->device_data; + snd_compress_proc_done(compr); put_device(&compr->dev); return 0; } @@ -908,22 +996,29 @@ static int snd_compress_dev_free(struct snd_device *device) * @compr: compress device pointer */ int snd_compress_new(struct snd_card *card, int device, - int dirn, struct snd_compr *compr) + int dirn, const char *id, struct snd_compr *compr) { static struct snd_device_ops ops = { .dev_free = snd_compress_dev_free, .dev_register = snd_compress_dev_register, .dev_disconnect = snd_compress_dev_disconnect, }; + int ret; compr->card = card; compr->device = device; compr->direction = dirn; + snd_compress_set_id(compr, id); + snd_device_initialize(&compr->dev, card); dev_set_name(&compr->dev, "comprC%iD%i", card->number, device); - return snd_device_new(card, SNDRV_DEV_COMPRESS, compr, &ops); + ret = snd_device_new(card, SNDRV_DEV_COMPRESS, compr, &ops); + if (ret == 0) + snd_compress_proc_init(compr); + + return ret; } EXPORT_SYMBOL_GPL(snd_compress_new); diff --git a/sound/core/init.c b/sound/core/init.c index 20f37fb3800e..6bda8436d765 100644 --- a/sound/core/init.c +++ b/sound/core/init.c @@ -268,6 +268,9 @@ int snd_card_new(struct device *parent, int idx, const char *xid, if (err < 0) goto __error; + snprintf(card->irq_descr, sizeof(card->irq_descr), "%s:%s", + dev_driver_string(card->dev), dev_name(&card->card_dev)); + /* the control interface cannot be accessed from the user space until */ /* snd_cards_bitmask and snd_cards are set with snd_card_register */ err = snd_ctl_create(card); diff --git a/sound/core/oss/mixer_oss.c b/sound/core/oss/mixer_oss.c index 7a8c79dd9734..2ff9c12d664a 100644 --- a/sound/core/oss/mixer_oss.c +++ b/sound/core/oss/mixer_oss.c @@ -24,6 +24,7 @@ #include <linux/time.h> #include <linux/string.h> #include <linux/module.h> +#include <linux/compat.h> #include <sound/core.h> #include <sound/minors.h> #include <sound/control.h> @@ -397,7 +398,12 @@ int snd_mixer_oss_ioctl_card(struct snd_card *card, unsigned int cmd, unsigned l #ifdef CONFIG_COMPAT /* all compatible */ -#define snd_mixer_oss_ioctl_compat snd_mixer_oss_ioctl +static long snd_mixer_oss_ioctl_compat(struct file *file, unsigned int cmd, + unsigned long arg) +{ + return snd_mixer_oss_ioctl1(file->private_data, cmd, + (unsigned long)compat_ptr(arg)); +} #else #define snd_mixer_oss_ioctl_compat NULL #endif diff --git a/sound/core/oss/pcm_oss.c b/sound/core/oss/pcm_oss.c index 58550cc93f28..0e73d03b30e3 100644 --- a/sound/core/oss/pcm_oss.c +++ b/sound/core/oss/pcm_oss.c @@ -33,6 +33,7 @@ #include <linux/module.h> #include <linux/math64.h> #include <linux/string.h> +#include <linux/compat.h> #include <sound/core.h> #include <sound/minors.h> #include <sound/pcm.h> @@ -850,7 +851,7 @@ static int snd_pcm_oss_change_params(struct snd_pcm_substream *substream) if (mutex_lock_interruptible(&runtime->oss.params_lock)) return -EINTR; - sw_params = kmalloc(sizeof(*sw_params), GFP_KERNEL); + sw_params = kzalloc(sizeof(*sw_params), GFP_KERNEL); params = kmalloc(sizeof(*params), GFP_KERNEL); sparams = kmalloc(sizeof(*sparams), GFP_KERNEL); if (!sw_params || !params || !sparams) { @@ -988,7 +989,6 @@ static int snd_pcm_oss_change_params(struct snd_pcm_substream *substream) goto failure; } - memset(sw_params, 0, sizeof(*sw_params)); if (runtime->oss.trigger) { sw_params->start_threshold = 1; } else { @@ -2648,7 +2648,11 @@ static long snd_pcm_oss_ioctl(struct file *file, unsigned int cmd, unsigned long #ifdef CONFIG_COMPAT /* all compatible */ -#define snd_pcm_oss_ioctl_compat snd_pcm_oss_ioctl +static long snd_pcm_oss_ioctl_compat(struct file *file, unsigned int cmd, + unsigned long arg) +{ + return snd_pcm_oss_ioctl(file, cmd, (unsigned long)compat_ptr(arg)); +} #else #define snd_pcm_oss_ioctl_compat NULL #endif diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c index a8b27cdc2844..fadd3eb8e8bb 100644 --- a/sound/core/pcm_native.c +++ b/sound/core/pcm_native.c @@ -875,7 +875,7 @@ struct action_ops { * Note: the stream state might be changed also on failure * Note2: call with calling stream lock + link lock */ -static int snd_pcm_action_group(struct action_ops *ops, +static int snd_pcm_action_group(const struct action_ops *ops, struct snd_pcm_substream *substream, int state, int do_lock) { @@ -932,7 +932,7 @@ static int snd_pcm_action_group(struct action_ops *ops, /* * Note: call with stream lock */ -static int snd_pcm_action_single(struct action_ops *ops, +static int snd_pcm_action_single(const struct action_ops *ops, struct snd_pcm_substream *substream, int state) { @@ -952,7 +952,7 @@ static int snd_pcm_action_single(struct action_ops *ops, /* * Note: call with stream lock */ -static int snd_pcm_action(struct action_ops *ops, +static int snd_pcm_action(const struct action_ops *ops, struct snd_pcm_substream *substream, int state) { @@ -984,7 +984,7 @@ static int snd_pcm_action(struct action_ops *ops, /* * Note: don't use any locks before */ -static int snd_pcm_action_lock_irq(struct action_ops *ops, +static int snd_pcm_action_lock_irq(const struct action_ops *ops, struct snd_pcm_substream *substream, int state) { @@ -998,7 +998,7 @@ static int snd_pcm_action_lock_irq(struct action_ops *ops, /* */ -static int snd_pcm_action_nonatomic(struct action_ops *ops, +static int snd_pcm_action_nonatomic(const struct action_ops *ops, struct snd_pcm_substream *substream, int state) { @@ -1056,7 +1056,7 @@ static void snd_pcm_post_start(struct snd_pcm_substream *substream, int state) snd_pcm_timer_notify(substream, SNDRV_TIMER_EVENT_MSTART); } -static struct action_ops snd_pcm_action_start = { +static const struct action_ops snd_pcm_action_start = { .pre_action = snd_pcm_pre_start, .do_action = snd_pcm_do_start, .undo_action = snd_pcm_undo_start, @@ -1107,7 +1107,7 @@ static void snd_pcm_post_stop(struct snd_pcm_substream *substream, int state) wake_up(&runtime->tsleep); } -static struct action_ops snd_pcm_action_stop = { +static const struct action_ops snd_pcm_action_stop = { .pre_action = snd_pcm_pre_stop, .do_action = snd_pcm_do_stop, .post_action = snd_pcm_post_stop @@ -1224,7 +1224,7 @@ static void snd_pcm_post_pause(struct snd_pcm_substream *substream, int push) } } -static struct action_ops snd_pcm_action_pause = { +static const struct action_ops snd_pcm_action_pause = { .pre_action = snd_pcm_pre_pause, .do_action = snd_pcm_do_pause, .undo_action = snd_pcm_undo_pause, @@ -1273,7 +1273,7 @@ static void snd_pcm_post_suspend(struct snd_pcm_substream *substream, int state) wake_up(&runtime->tsleep); } -static struct action_ops snd_pcm_action_suspend = { +static const struct action_ops snd_pcm_action_suspend = { .pre_action = snd_pcm_pre_suspend, .do_action = snd_pcm_do_suspend, .post_action = snd_pcm_post_suspend @@ -1375,7 +1375,7 @@ static void snd_pcm_post_resume(struct snd_pcm_substream *substream, int state) snd_pcm_timer_notify(substream, SNDRV_TIMER_EVENT_MRESUME); } -static struct action_ops snd_pcm_action_resume = { +static const struct action_ops snd_pcm_action_resume = { .pre_action = snd_pcm_pre_resume, .do_action = snd_pcm_do_resume, .undo_action = snd_pcm_undo_resume, @@ -1478,7 +1478,7 @@ static void snd_pcm_post_reset(struct snd_pcm_substream *substream, int state) snd_pcm_playback_silence(substream, ULONG_MAX); } -static struct action_ops snd_pcm_action_reset = { +static const struct action_ops snd_pcm_action_reset = { .pre_action = snd_pcm_pre_reset, .do_action = snd_pcm_do_reset, .post_action = snd_pcm_post_reset @@ -1522,7 +1522,7 @@ static void snd_pcm_post_prepare(struct snd_pcm_substream *substream, int state) snd_pcm_set_state(substream, SNDRV_PCM_STATE_PREPARED); } -static struct action_ops snd_pcm_action_prepare = { +static const struct action_ops snd_pcm_action_prepare = { .pre_action = snd_pcm_pre_prepare, .do_action = snd_pcm_do_prepare, .post_action = snd_pcm_post_prepare @@ -1618,7 +1618,7 @@ static void snd_pcm_post_drain_init(struct snd_pcm_substream *substream, int sta { } -static struct action_ops snd_pcm_action_drain_init = { +static const struct action_ops snd_pcm_action_drain_init = { .pre_action = snd_pcm_pre_drain_init, .do_action = snd_pcm_do_drain_init, .post_action = snd_pcm_post_drain_init diff --git a/sound/core/seq/oss/seq_oss.c b/sound/core/seq/oss/seq_oss.c index 7354b8bed860..8db156b207f1 100644 --- a/sound/core/seq/oss/seq_oss.c +++ b/sound/core/seq/oss/seq_oss.c @@ -23,6 +23,7 @@ #include <linux/init.h> #include <linux/module.h> #include <linux/mutex.h> +#include <linux/compat.h> #include <sound/core.h> #include <sound/minors.h> #include <sound/initval.h> @@ -189,7 +190,11 @@ odev_ioctl(struct file *file, unsigned int cmd, unsigned long arg) } #ifdef CONFIG_COMPAT -#define odev_ioctl_compat odev_ioctl +static long odev_ioctl_compat(struct file *file, unsigned int cmd, + unsigned long arg) +{ + return odev_ioctl(file, cmd, (unsigned long)compat_ptr(arg)); +} #else #define odev_ioctl_compat NULL #endif diff --git a/sound/core/seq/seq_clientmgr.c b/sound/core/seq/seq_clientmgr.c index b64f20deba90..13cfa815732d 100644 --- a/sound/core/seq/seq_clientmgr.c +++ b/sound/core/seq/seq_clientmgr.c @@ -1962,7 +1962,7 @@ static int snd_seq_ioctl_remove_events(struct snd_seq_client *client, * No restrictions so for a user client we can clear * the whole fifo */ - if (client->type == USER_CLIENT) + if (client->type == USER_CLIENT && client->data.user.fifo) snd_seq_fifo_clear(client->data.user.fifo); } diff --git a/sound/core/seq/seq_queue.c b/sound/core/seq/seq_queue.c index 7dfd0f429410..0bec02e89d51 100644 --- a/sound/core/seq/seq_queue.c +++ b/sound/core/seq/seq_queue.c @@ -142,8 +142,10 @@ static struct snd_seq_queue *queue_new(int owner, int locked) static void queue_delete(struct snd_seq_queue *q) { /* stop and release the timer */ + mutex_lock(&q->timer_mutex); snd_seq_timer_stop(q->timer); snd_seq_timer_close(q); + mutex_unlock(&q->timer_mutex); /* wait until access free */ snd_use_lock_sync(&q->use_lock); /* release resources... */ diff --git a/sound/core/seq/seq_virmidi.c b/sound/core/seq/seq_virmidi.c index 56e0f4cd3f82..3da2d48610b3 100644 --- a/sound/core/seq/seq_virmidi.c +++ b/sound/core/seq/seq_virmidi.c @@ -468,7 +468,7 @@ static int snd_virmidi_dev_unregister(struct snd_rawmidi *rmidi) /* * */ -static struct snd_rawmidi_global_ops snd_virmidi_global_ops = { +static const struct snd_rawmidi_global_ops snd_virmidi_global_ops = { .dev_register = snd_virmidi_dev_register, .dev_unregister = snd_virmidi_dev_unregister, }; diff --git a/sound/core/timer.c b/sound/core/timer.c index 31f40f03e5b7..cb25aded5349 100644 --- a/sound/core/timer.c +++ b/sound/core/timer.c @@ -73,7 +73,7 @@ struct snd_timer_user { struct timespec tstamp; /* trigger tstamp */ wait_queue_head_t qchange_sleep; struct fasync_struct *fasync; - struct mutex tread_sem; + struct mutex ioctl_lock; }; /* list of timers */ @@ -215,11 +215,13 @@ static void snd_timer_check_master(struct snd_timer_instance *master) slave->slave_id == master->slave_id) { list_move_tail(&slave->open_list, &master->slave_list_head); spin_lock_irq(&slave_active_lock); + spin_lock(&master->timer->lock); slave->master = master; slave->timer = master->timer; if (slave->flags & SNDRV_TIMER_IFLG_RUNNING) list_add_tail(&slave->active_list, &master->slave_active_head); + spin_unlock(&master->timer->lock); spin_unlock_irq(&slave_active_lock); } } @@ -299,8 +301,7 @@ int snd_timer_open(struct snd_timer_instance **ti, return 0; } -static int _snd_timer_stop(struct snd_timer_instance *timeri, - int keep_flag, int event); +static int _snd_timer_stop(struct snd_timer_instance *timeri, int event); /* * close a timer instance @@ -342,19 +343,22 @@ int snd_timer_close(struct snd_timer_instance *timeri) spin_unlock_irq(&timer->lock); mutex_lock(®ister_mutex); list_del(&timeri->open_list); - if (timer && list_empty(&timer->open_list_head) && + if (list_empty(&timer->open_list_head) && timer->hw.close) timer->hw.close(timer); /* remove slave links */ + spin_lock_irq(&slave_active_lock); + spin_lock(&timer->lock); list_for_each_entry_safe(slave, tmp, &timeri->slave_list_head, open_list) { - spin_lock_irq(&slave_active_lock); - _snd_timer_stop(slave, 1, SNDRV_TIMER_EVENT_RESOLUTION); list_move_tail(&slave->open_list, &snd_timer_slave_list); slave->master = NULL; slave->timer = NULL; - spin_unlock_irq(&slave_active_lock); + list_del_init(&slave->ack_list); + list_del_init(&slave->active_list); } + spin_unlock(&timer->lock); + spin_unlock_irq(&slave_active_lock); mutex_unlock(®ister_mutex); } out: @@ -441,9 +445,12 @@ static int snd_timer_start_slave(struct snd_timer_instance *timeri) spin_lock_irqsave(&slave_active_lock, flags); timeri->flags |= SNDRV_TIMER_IFLG_RUNNING; - if (timeri->master) + if (timeri->master && timeri->timer) { + spin_lock(&timeri->timer->lock); list_add_tail(&timeri->active_list, &timeri->master->slave_active_head); + spin_unlock(&timeri->timer->lock); + } spin_unlock_irqrestore(&slave_active_lock, flags); return 1; /* delayed start */ } @@ -476,8 +483,7 @@ int snd_timer_start(struct snd_timer_instance *timeri, unsigned int ticks) return result; } -static int _snd_timer_stop(struct snd_timer_instance * timeri, - int keep_flag, int event) +static int _snd_timer_stop(struct snd_timer_instance *timeri, int event) { struct snd_timer *timer; unsigned long flags; @@ -486,11 +492,11 @@ static int _snd_timer_stop(struct snd_timer_instance * timeri, return -ENXIO; if (timeri->flags & SNDRV_TIMER_IFLG_SLAVE) { - if (!keep_flag) { - spin_lock_irqsave(&slave_active_lock, flags); - timeri->flags &= ~SNDRV_TIMER_IFLG_RUNNING; - spin_unlock_irqrestore(&slave_active_lock, flags); - } + spin_lock_irqsave(&slave_active_lock, flags); + timeri->flags &= ~SNDRV_TIMER_IFLG_RUNNING; + list_del_init(&timeri->ack_list); + list_del_init(&timeri->active_list); + spin_unlock_irqrestore(&slave_active_lock, flags); goto __end; } timer = timeri->timer; @@ -511,9 +517,7 @@ static int _snd_timer_stop(struct snd_timer_instance * timeri, } } } - if (!keep_flag) - timeri->flags &= - ~(SNDRV_TIMER_IFLG_RUNNING | SNDRV_TIMER_IFLG_START); + timeri->flags &= ~(SNDRV_TIMER_IFLG_RUNNING | SNDRV_TIMER_IFLG_START); spin_unlock_irqrestore(&timer->lock, flags); __end: if (event != SNDRV_TIMER_EVENT_RESOLUTION) @@ -532,7 +536,7 @@ int snd_timer_stop(struct snd_timer_instance *timeri) unsigned long flags; int err; - err = _snd_timer_stop(timeri, 0, SNDRV_TIMER_EVENT_STOP); + err = _snd_timer_stop(timeri, SNDRV_TIMER_EVENT_STOP); if (err < 0) return err; timer = timeri->timer; @@ -576,7 +580,7 @@ int snd_timer_continue(struct snd_timer_instance *timeri) */ int snd_timer_pause(struct snd_timer_instance * timeri) { - return _snd_timer_stop(timeri, 0, SNDRV_TIMER_EVENT_PAUSE); + return _snd_timer_stop(timeri, SNDRV_TIMER_EVENT_PAUSE); } /* @@ -694,7 +698,7 @@ void snd_timer_interrupt(struct snd_timer * timer, unsigned long ticks_left) } else { ti->flags &= ~SNDRV_TIMER_IFLG_RUNNING; if (--timer->running) - list_del(&ti->active_list); + list_del_init(&ti->active_list); } if ((timer->hw.flags & SNDRV_TIMER_HW_TASKLET) || (ti->flags & SNDRV_TIMER_IFLG_FAST)) @@ -1253,7 +1257,7 @@ static int snd_timer_user_open(struct inode *inode, struct file *file) return -ENOMEM; spin_lock_init(&tu->qlock); init_waitqueue_head(&tu->qchange_sleep); - mutex_init(&tu->tread_sem); + mutex_init(&tu->ioctl_lock); tu->ticks = 1; tu->queue_size = 128; tu->queue = kmalloc(tu->queue_size * sizeof(struct snd_timer_read), @@ -1273,8 +1277,10 @@ static int snd_timer_user_release(struct inode *inode, struct file *file) if (file->private_data) { tu = file->private_data; file->private_data = NULL; + mutex_lock(&tu->ioctl_lock); if (tu->timeri) snd_timer_close(tu->timeri); + mutex_unlock(&tu->ioctl_lock); kfree(tu->queue); kfree(tu->tqueue); kfree(tu); @@ -1512,7 +1518,6 @@ static int snd_timer_user_tselect(struct file *file, int err = 0; tu = file->private_data; - mutex_lock(&tu->tread_sem); if (tu->timeri) { snd_timer_close(tu->timeri); tu->timeri = NULL; @@ -1556,7 +1561,6 @@ static int snd_timer_user_tselect(struct file *file, } __err: - mutex_unlock(&tu->tread_sem); return err; } @@ -1769,7 +1773,7 @@ enum { SNDRV_TIMER_IOCTL_PAUSE_OLD = _IO('T', 0x23), }; -static long snd_timer_user_ioctl(struct file *file, unsigned int cmd, +static long __snd_timer_user_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { struct snd_timer_user *tu; @@ -1786,17 +1790,11 @@ static long snd_timer_user_ioctl(struct file *file, unsigned int cmd, { int xarg; - mutex_lock(&tu->tread_sem); - if (tu->timeri) { /* too late */ - mutex_unlock(&tu->tread_sem); + if (tu->timeri) /* too late */ return -EBUSY; - } - if (get_user(xarg, p)) { - mutex_unlock(&tu->tread_sem); + if (get_user(xarg, p)) return -EFAULT; - } tu->tread = xarg ? 1 : 0; - mutex_unlock(&tu->tread_sem); return 0; } case SNDRV_TIMER_IOCTL_GINFO: @@ -1829,6 +1827,18 @@ static long snd_timer_user_ioctl(struct file *file, unsigned int cmd, return -ENOTTY; } +static long snd_timer_user_ioctl(struct file *file, unsigned int cmd, + unsigned long arg) +{ + struct snd_timer_user *tu = file->private_data; + long ret; + + mutex_lock(&tu->ioctl_lock); + ret = __snd_timer_user_ioctl(file, cmd, arg); + mutex_unlock(&tu->ioctl_lock); + return ret; +} + static int snd_timer_user_fasync(int fd, struct file * file, int on) { struct snd_timer_user *tu; |