aboutsummaryrefslogtreecommitdiffstats
path: root/sound/core/control.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/core/control.c')
-rw-r--r--sound/core/control.c39
1 files changed, 29 insertions, 10 deletions
diff --git a/sound/core/control.c b/sound/core/control.c
index 0c29679a8576..574745314e70 100644
--- a/sound/core/control.c
+++ b/sound/core/control.c
@@ -309,28 +309,29 @@ int snd_ctl_add(struct snd_card *card, struct snd_kcontrol *kcontrol)
309{ 309{
310 struct snd_ctl_elem_id id; 310 struct snd_ctl_elem_id id;
311 unsigned int idx; 311 unsigned int idx;
312 int err = -EINVAL;
312 313
313 snd_assert(card != NULL, return -EINVAL);
314 if (! kcontrol) 314 if (! kcontrol)
315 return -EINVAL; 315 return err;
316 snd_assert(kcontrol->info != NULL, return -EINVAL); 316 snd_assert(card != NULL, goto error);
317 snd_assert(kcontrol->info != NULL, goto error);
317 id = kcontrol->id; 318 id = kcontrol->id;
318 down_write(&card->controls_rwsem); 319 down_write(&card->controls_rwsem);
319 if (snd_ctl_find_id(card, &id)) { 320 if (snd_ctl_find_id(card, &id)) {
320 up_write(&card->controls_rwsem); 321 up_write(&card->controls_rwsem);
321 snd_ctl_free_one(kcontrol);
322 snd_printd(KERN_ERR "control %i:%i:%i:%s:%i is already present\n", 322 snd_printd(KERN_ERR "control %i:%i:%i:%s:%i is already present\n",
323 id.iface, 323 id.iface,
324 id.device, 324 id.device,
325 id.subdevice, 325 id.subdevice,
326 id.name, 326 id.name,
327 id.index); 327 id.index);
328 return -EBUSY; 328 err = -EBUSY;
329 goto error;
329 } 330 }
330 if (snd_ctl_find_hole(card, kcontrol->count) < 0) { 331 if (snd_ctl_find_hole(card, kcontrol->count) < 0) {
331 up_write(&card->controls_rwsem); 332 up_write(&card->controls_rwsem);
332 snd_ctl_free_one(kcontrol); 333 err = -ENOMEM;
333 return -ENOMEM; 334 goto error;
334 } 335 }
335 list_add_tail(&kcontrol->list, &card->controls); 336 list_add_tail(&kcontrol->list, &card->controls);
336 card->controls_count += kcontrol->count; 337 card->controls_count += kcontrol->count;
@@ -340,6 +341,10 @@ int snd_ctl_add(struct snd_card *card, struct snd_kcontrol *kcontrol)
340 for (idx = 0; idx < kcontrol->count; idx++, id.index++, id.numid++) 341 for (idx = 0; idx < kcontrol->count; idx++, id.index++, id.numid++)
341 snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_ADD, &id); 342 snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_ADD, &id);
342 return 0; 343 return 0;
344
345 error:
346 snd_ctl_free_one(kcontrol);
347 return err;
343} 348}
344 349
345/** 350/**
@@ -658,7 +663,11 @@ static int snd_ctl_elem_info_user(struct snd_ctl_file *ctl,
658 663
659 if (copy_from_user(&info, _info, sizeof(info))) 664 if (copy_from_user(&info, _info, sizeof(info)))
660 return -EFAULT; 665 return -EFAULT;
661 result = snd_ctl_elem_info(ctl, &info); 666 snd_power_lock(ctl->card);
667 result = snd_power_wait(ctl->card, SNDRV_CTL_POWER_D0, NULL);
668 if (result >= 0)
669 result = snd_ctl_elem_info(ctl, &info);
670 snd_power_unlock(ctl->card);
662 if (result >= 0) 671 if (result >= 0)
663 if (copy_to_user(_info, &info, sizeof(info))) 672 if (copy_to_user(_info, &info, sizeof(info)))
664 return -EFAULT; 673 return -EFAULT;
@@ -708,7 +717,11 @@ static int snd_ctl_elem_read_user(struct snd_card *card,
708 kfree(control); 717 kfree(control);
709 return -EFAULT; 718 return -EFAULT;
710 } 719 }
711 result = snd_ctl_elem_read(card, control); 720 snd_power_lock(card);
721 result = snd_power_wait(card, SNDRV_CTL_POWER_D0, NULL);
722 if (result >= 0)
723 result = snd_ctl_elem_read(card, control);
724 snd_power_unlock(card);
712 if (result >= 0) 725 if (result >= 0)
713 if (copy_to_user(_control, control, sizeof(*control))) 726 if (copy_to_user(_control, control, sizeof(*control)))
714 result = -EFAULT; 727 result = -EFAULT;
@@ -758,6 +771,7 @@ static int snd_ctl_elem_write_user(struct snd_ctl_file *file,
758 struct snd_ctl_elem_value __user *_control) 771 struct snd_ctl_elem_value __user *_control)
759{ 772{
760 struct snd_ctl_elem_value *control; 773 struct snd_ctl_elem_value *control;
774 struct snd_card *card;
761 int result; 775 int result;
762 776
763 control = kmalloc(sizeof(*control), GFP_KERNEL); 777 control = kmalloc(sizeof(*control), GFP_KERNEL);
@@ -767,7 +781,12 @@ static int snd_ctl_elem_write_user(struct snd_ctl_file *file,
767 kfree(control); 781 kfree(control);
768 return -EFAULT; 782 return -EFAULT;
769 } 783 }
770 result = snd_ctl_elem_write(file->card, file, control); 784 card = file->card;
785 snd_power_lock(card);
786 result = snd_power_wait(card, SNDRV_CTL_POWER_D0, NULL);
787 if (result >= 0)
788 result = snd_ctl_elem_write(card, file, control);
789 snd_power_unlock(card);
771 if (result >= 0) 790 if (result >= 0)
772 if (copy_to_user(_control, control, sizeof(*control))) 791 if (copy_to_user(_control, control, sizeof(*control)))
773 result = -EFAULT; 792 result = -EFAULT;