diff options
Diffstat (limited to 'sound/core/control_compat.c')
-rw-r--r-- | sound/core/control_compat.c | 47 |
1 files changed, 38 insertions, 9 deletions
diff --git a/sound/core/control_compat.c b/sound/core/control_compat.c index 934bb945e702..6459809ed364 100644 --- a/sound/core/control_compat.c +++ b/sound/core/control_compat.c @@ -79,6 +79,7 @@ struct snd_ctl_elem_info32 { static int snd_ctl_elem_info_compat(struct snd_ctl_file *ctl, struct snd_ctl_elem_info32 __user *data32) { + struct snd_card *card = ctl->card; struct snd_ctl_elem_info *data __free(kfree) = NULL; int err; @@ -95,7 +96,11 @@ static int snd_ctl_elem_info_compat(struct snd_ctl_file *ctl, if (get_user(data->value.enumerated.item, &data32->value.enumerated.item)) return -EFAULT; + err = snd_power_ref_and_wait(card); + if (err < 0) + return err; err = snd_ctl_elem_info(ctl, data); + snd_power_unref(card); if (err < 0) return err; /* restore info to 32bit */ @@ -168,17 +173,14 @@ static int get_ctl_type(struct snd_card *card, struct snd_ctl_elem_id *id, int err; guard(rwsem_read)(&card->controls_rwsem); - kctl = snd_ctl_find_id_locked(card, id); + kctl = snd_ctl_find_id(card, id); if (!kctl) return -ENOENT; info = kzalloc(sizeof(*info), GFP_KERNEL); if (info == NULL) return -ENOMEM; info->id = *id; - err = snd_power_ref_and_wait(card); - if (!err) - err = kctl->info(kctl, info); - snd_power_unref(card); + err = kctl->info(kctl, info); if (err >= 0) { err = info->type; *countp = info->count; @@ -275,8 +277,8 @@ static int copy_ctl_value_to_user(void __user *userdata, return 0; } -static int ctl_elem_read_user(struct snd_card *card, - void __user *userdata, void __user *valuep) +static int __ctl_elem_read_user(struct snd_card *card, + void __user *userdata, void __user *valuep) { struct snd_ctl_elem_value *data __free(kfree) = NULL; int err, type, count; @@ -296,8 +298,21 @@ static int ctl_elem_read_user(struct snd_card *card, return copy_ctl_value_to_user(userdata, valuep, data, type, count); } -static int ctl_elem_write_user(struct snd_ctl_file *file, - void __user *userdata, void __user *valuep) +static int ctl_elem_read_user(struct snd_card *card, + void __user *userdata, void __user *valuep) +{ + int err; + + err = snd_power_ref_and_wait(card); + if (err < 0) + return err; + err = __ctl_elem_read_user(card, userdata, valuep); + snd_power_unref(card); + return err; +} + +static int __ctl_elem_write_user(struct snd_ctl_file *file, + void __user *userdata, void __user *valuep) { struct snd_ctl_elem_value *data __free(kfree) = NULL; struct snd_card *card = file->card; @@ -318,6 +333,20 @@ static int ctl_elem_write_user(struct snd_ctl_file *file, return copy_ctl_value_to_user(userdata, valuep, data, type, count); } +static int ctl_elem_write_user(struct snd_ctl_file *file, + void __user *userdata, void __user *valuep) +{ + struct snd_card *card = file->card; + int err; + + err = snd_power_ref_and_wait(card); + if (err < 0) + return err; + err = __ctl_elem_write_user(file, userdata, valuep); + snd_power_unref(card); + return err; +} + static int snd_ctl_elem_read_user_compat(struct snd_card *card, struct snd_ctl_elem_value32 __user *data32) { |