X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=sound%2Fcore%2Fcontrol.c;h=7cc19394dae895155e47a715dd8abaef533d3f3f;hb=9213980e6a70d8473e0ffd4b39ab5b6caaba9ff5;hp=7d2bdb77ab73c7f5a6ad62086389d2185a90e337;hpb=5273a3df6485dc2ad6aa7ddd441b9a21970f003b;p=linux-2.6.git diff --git a/sound/core/control.c b/sound/core/control.c index 7d2bdb77a..7cc19394d 100644 --- a/sound/core/control.c +++ b/sound/core/control.c @@ -512,7 +512,7 @@ snd_kcontrol_t *snd_ctl_find_id(snd_card_t * card, snd_ctl_elem_id_t *id) } static int snd_ctl_card_info(snd_card_t * card, snd_ctl_file_t * ctl, - unsigned int cmd, unsigned long arg) + unsigned int cmd, void __user *arg) { snd_ctl_card_info_t info; @@ -526,12 +526,12 @@ static int snd_ctl_card_info(snd_card_t * card, snd_ctl_file_t * ctl, strlcpy(info.mixername, card->mixername, sizeof(info.mixername)); strlcpy(info.components, card->components, sizeof(info.components)); up_read(&snd_ioctl_rwsem); - if (copy_to_user((void *) arg, &info, sizeof(snd_ctl_card_info_t))) + if (copy_to_user(arg, &info, sizeof(snd_ctl_card_info_t))) return -EFAULT; return 0; } -static int snd_ctl_elem_list(snd_card_t *card, snd_ctl_elem_list_t *_list) +static int snd_ctl_elem_list(snd_card_t *card, snd_ctl_elem_list_t __user *_list) { struct list_head *plist; snd_ctl_elem_list_t list; @@ -593,7 +593,7 @@ static int snd_ctl_elem_list(snd_card_t *card, snd_ctl_elem_list_t *_list) return 0; } -static int snd_ctl_elem_info(snd_ctl_file_t *ctl, snd_ctl_elem_info_t *_info) +static int snd_ctl_elem_info(snd_ctl_file_t *ctl, snd_ctl_elem_info_t __user *_info) { snd_card_t *card = ctl->card; snd_ctl_elem_info_t info; @@ -636,7 +636,7 @@ static int snd_ctl_elem_info(snd_ctl_file_t *ctl, snd_ctl_elem_info_t *_info) return result; } -static int snd_ctl_elem_read(snd_card_t *card, snd_ctl_elem_value_t *_control) +static int snd_ctl_elem_read(snd_card_t *card, snd_ctl_elem_value_t __user *_control) { snd_ctl_elem_value_t *control; snd_kcontrol_t *kctl; @@ -676,7 +676,7 @@ static int snd_ctl_elem_read(snd_card_t *card, snd_ctl_elem_value_t *_control) return result; } -static int snd_ctl_elem_write(snd_ctl_file_t *file, snd_ctl_elem_value_t *_control) +static int snd_ctl_elem_write(snd_ctl_file_t *file, snd_ctl_elem_value_t __user *_control) { snd_card_t *card = file->card; snd_ctl_elem_value_t *control; @@ -726,7 +726,7 @@ static int snd_ctl_elem_write(snd_ctl_file_t *file, snd_ctl_elem_value_t *_contr return result; } -static int snd_ctl_elem_lock(snd_ctl_file_t *file, snd_ctl_elem_id_t *_id) +static int snd_ctl_elem_lock(snd_ctl_file_t *file, snd_ctl_elem_id_t __user *_id) { snd_card_t *card = file->card; snd_ctl_elem_id_t id; @@ -754,7 +754,7 @@ static int snd_ctl_elem_lock(snd_ctl_file_t *file, snd_ctl_elem_id_t *_id) return result; } -static int snd_ctl_elem_unlock(snd_ctl_file_t *file, snd_ctl_elem_id_t *_id) +static int snd_ctl_elem_unlock(snd_ctl_file_t *file, snd_ctl_elem_id_t __user *_id) { snd_card_t *card = file->card; snd_ctl_elem_id_t id; @@ -840,7 +840,7 @@ static void snd_ctl_elem_user_free(snd_kcontrol_t * kcontrol) kfree(kcontrol->private_data); } -static int snd_ctl_elem_add(snd_ctl_file_t *file, snd_ctl_elem_info_t *_info, int replace) +static int snd_ctl_elem_add(snd_ctl_file_t *file, snd_ctl_elem_info_t __user *_info, int replace) { snd_card_t *card = file->card; snd_ctl_elem_info_t info; @@ -965,7 +965,7 @@ static int snd_ctl_elem_add(snd_ctl_file_t *file, snd_ctl_elem_info_t *_info, in return 0; } -static int snd_ctl_elem_remove(snd_ctl_file_t *file, snd_ctl_elem_id_t *_id) +static int snd_ctl_elem_remove(snd_ctl_file_t *file, snd_ctl_elem_id_t __user *_id) { snd_ctl_elem_id_t id; @@ -974,7 +974,7 @@ static int snd_ctl_elem_remove(snd_ctl_file_t *file, snd_ctl_elem_id_t *_id) return snd_ctl_remove_unlocked_id(file, &id); } -static int snd_ctl_subscribe_events(snd_ctl_file_t *file, int *ptr) +static int snd_ctl_subscribe_events(snd_ctl_file_t *file, int __user *ptr) { int subscribe; if (get_user(subscribe, ptr)) @@ -995,6 +995,33 @@ static int snd_ctl_subscribe_events(snd_ctl_file_t *file, int *ptr) return 0; } +#ifdef CONFIG_PM +/* + * change the power state + */ +static int snd_ctl_set_power_state(snd_card_t *card, unsigned int power_state) +{ + switch (power_state) { + case SNDRV_CTL_POWER_D0: + case SNDRV_CTL_POWER_D1: + case SNDRV_CTL_POWER_D2: + if (card->power_state != power_state) + /* FIXME: pass the correct state value */ + card->pm_resume(card, 0); + break; + case SNDRV_CTL_POWER_D3hot: + case SNDRV_CTL_POWER_D3cold: + if (card->power_state != power_state) + /* FIXME: pass the correct state value */ + card->pm_suspend(card, 0); + break; + default: + return -EINVAL; + } + return 0; +} +#endif + static int snd_ctl_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) { @@ -1002,6 +1029,8 @@ static int snd_ctl_ioctl(struct inode *inode, struct file *file, snd_card_t *card; struct list_head *list; snd_kctl_ioctl_t *p; + void __user *argp = (void __user *)arg; + int __user *ip = argp; int err; ctl = snd_magic_cast(snd_ctl_file_t, file->private_data, return -ENXIO); @@ -1009,38 +1038,38 @@ static int snd_ctl_ioctl(struct inode *inode, struct file *file, snd_assert(card != NULL, return -ENXIO); switch (cmd) { case SNDRV_CTL_IOCTL_PVERSION: - return put_user(SNDRV_CTL_VERSION, (int *)arg) ? -EFAULT : 0; + return put_user(SNDRV_CTL_VERSION, ip) ? -EFAULT : 0; case SNDRV_CTL_IOCTL_CARD_INFO: - return snd_ctl_card_info(card, ctl, cmd, arg); + return snd_ctl_card_info(card, ctl, cmd, argp); case SNDRV_CTL_IOCTL_ELEM_LIST: - return snd_ctl_elem_list(ctl->card, (snd_ctl_elem_list_t *) arg); + return snd_ctl_elem_list(ctl->card, argp); case SNDRV_CTL_IOCTL_ELEM_INFO: - return snd_ctl_elem_info(ctl, (snd_ctl_elem_info_t *) arg); + return snd_ctl_elem_info(ctl, argp); case SNDRV_CTL_IOCTL_ELEM_READ: - return snd_ctl_elem_read(ctl->card, (snd_ctl_elem_value_t *) arg); + return snd_ctl_elem_read(ctl->card, argp); case SNDRV_CTL_IOCTL_ELEM_WRITE: - return snd_ctl_elem_write(ctl, (snd_ctl_elem_value_t *) arg); + return snd_ctl_elem_write(ctl, argp); case SNDRV_CTL_IOCTL_ELEM_LOCK: - return snd_ctl_elem_lock(ctl, (snd_ctl_elem_id_t *) arg); + return snd_ctl_elem_lock(ctl, argp); case SNDRV_CTL_IOCTL_ELEM_UNLOCK: - return snd_ctl_elem_unlock(ctl, (snd_ctl_elem_id_t *) arg); + return snd_ctl_elem_unlock(ctl, argp); case SNDRV_CTL_IOCTL_ELEM_ADD: - return snd_ctl_elem_add(ctl, (snd_ctl_elem_info_t *) arg, 0); + return snd_ctl_elem_add(ctl, argp, 0); case SNDRV_CTL_IOCTL_ELEM_REPLACE: - return snd_ctl_elem_add(ctl, (snd_ctl_elem_info_t *) arg, 1); + return snd_ctl_elem_add(ctl, argp, 1); case SNDRV_CTL_IOCTL_ELEM_REMOVE: - return snd_ctl_elem_remove(ctl, (snd_ctl_elem_id_t *) arg); + return snd_ctl_elem_remove(ctl, argp); case SNDRV_CTL_IOCTL_SUBSCRIBE_EVENTS: - return snd_ctl_subscribe_events(ctl, (int *) arg); + return snd_ctl_subscribe_events(ctl, ip); case SNDRV_CTL_IOCTL_POWER: - if (get_user(err, (int *)arg)) + if (get_user(err, ip)) return -EFAULT; if (!capable(CAP_SYS_ADMIN)) return -EPERM; #ifdef CONFIG_PM - if (card->set_power_state) { + if (card->pm_suspend && card->pm_resume) { snd_power_lock(card); - err = card->set_power_state(card, err); + err = snd_ctl_set_power_state(card, err); snd_power_unlock(card); } else #endif @@ -1048,9 +1077,9 @@ static int snd_ctl_ioctl(struct inode *inode, struct file *file, return err; case SNDRV_CTL_IOCTL_POWER_STATE: #ifdef CONFIG_PM - return put_user(card->power_state, (int *)arg) ? -EFAULT : 0; + return put_user(card->power_state, ip) ? -EFAULT : 0; #else - return put_user(SNDRV_CTL_POWER_D0, (int *)arg) ? -EFAULT : 0; + return put_user(SNDRV_CTL_POWER_D0, ip) ? -EFAULT : 0; #endif } down_read(&snd_ioctl_rwsem); @@ -1067,7 +1096,7 @@ static int snd_ctl_ioctl(struct inode *inode, struct file *file, return -ENOTTY; } -static ssize_t snd_ctl_read(struct file *file, char *buffer, size_t count, loff_t * offset) +static ssize_t snd_ctl_read(struct file *file, char __user *buffer, size_t count, loff_t * offset) { snd_ctl_file_t *ctl; int err = 0;