diff options
Diffstat (limited to 'sound/core/control.c')
| -rw-r--r-- | sound/core/control.c | 24 | 
1 files changed, 15 insertions, 9 deletions
| diff --git a/sound/core/control.c b/sound/core/control.c index 50e7ba66f187..82aa1af1d1d8 100644 --- a/sound/core/control.c +++ b/sound/core/control.c @@ -1203,14 +1203,19 @@ static int snd_ctl_elem_read(struct snd_card *card,  	const u32 pattern = 0xdeadbeef;  	int ret; +	down_read(&card->controls_rwsem);  	kctl = snd_ctl_find_id(card, &control->id); -	if (kctl == NULL) -		return -ENOENT; +	if (kctl == NULL) { +		ret = -ENOENT; +		goto unlock; +	}  	index_offset = snd_ctl_get_ioff(kctl, &control->id);  	vd = &kctl->vd[index_offset]; -	if (!(vd->access & SNDRV_CTL_ELEM_ACCESS_READ) || kctl->get == NULL) -		return -EPERM; +	if (!(vd->access & SNDRV_CTL_ELEM_ACCESS_READ) || kctl->get == NULL) { +		ret = -EPERM; +		goto unlock; +	}  	snd_ctl_build_ioff(&control->id, kctl, index_offset); @@ -1220,7 +1225,7 @@ static int snd_ctl_elem_read(struct snd_card *card,  	info.id = control->id;  	ret = __snd_ctl_elem_info(card, kctl, &info, NULL);  	if (ret < 0) -		return ret; +		goto unlock;  #endif  	if (!snd_ctl_skip_validation(&info)) @@ -1230,7 +1235,7 @@ static int snd_ctl_elem_read(struct snd_card *card,  		ret = kctl->get(kctl, control);  	snd_power_unref(card);  	if (ret < 0) -		return ret; +		goto unlock;  	if (!snd_ctl_skip_validation(&info) &&  	    sanity_check_elem_value(card, control, &info, pattern) < 0) {  		dev_err(card->dev, @@ -1238,8 +1243,11 @@ static int snd_ctl_elem_read(struct snd_card *card,  			control->id.iface, control->id.device,  			control->id.subdevice, control->id.name,  			control->id.index); -		return -EINVAL; +		ret = -EINVAL; +		goto unlock;  	} +unlock: +	up_read(&card->controls_rwsem);  	return ret;  } @@ -1253,9 +1261,7 @@ static int snd_ctl_elem_read_user(struct snd_card *card,  	if (IS_ERR(control))  		return PTR_ERR(control); -	down_read(&card->controls_rwsem);  	result = snd_ctl_elem_read(card, control); -	up_read(&card->controls_rwsem);  	if (result < 0)  		goto error; |