Commit a1066453 authored by Takashi Iwai's avatar Takashi Iwai

ALSA: control: Fix power_ref lock order for compat code, too

In the previous change for swapping the power_ref and controls_rwsem
lock order, the code path for the compat layer was forgotten.
This patch covers the remaining code.

Fixes: fcc62b19 ("ALSA: control: Take power_ref lock primarily")
Link: https://patch.msgid.link/20240808163128.20383-1-tiwai@suse.deSigned-off-by: default avatarTakashi Iwai <tiwai@suse.de>
parent c37f7cd7
......@@ -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 */
......@@ -175,10 +180,7 @@ static int get_ctl_type(struct snd_card *card, struct snd_ctl_elem_id *id,
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)
{
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment