This commit obsoletes old implementation for compat ELEM_READ/ELEM_WRITE operation for modern 32 bit ABI with a renewal way.
Signed-off-by: Takashi Sakamoto o-takashi@sakamocchi.jp --- sound/core/control_compat.c | 218 ++++---------------------------------------- 1 file changed, 20 insertions(+), 198 deletions(-)
diff --git a/sound/core/control_compat.c b/sound/core/control_compat.c index 430f178aa4d8..bbda8eabf18f 100644 --- a/sound/core/control_compat.c +++ b/sound/core/control_compat.c @@ -397,194 +397,6 @@ static int __maybe_unused serialize_to_elem_value_i386( return 0; }
-/* read / write */ -struct snd_ctl_elem_value32 { - struct snd_ctl_elem_id id; - unsigned int indirect; /* bit-field causes misalignment */ - union { - s32 integer[128]; - unsigned char data[512]; - s64 integer64[64]; - } value; - unsigned char reserved[128]; -}; - -/* get the value type and count of the control */ -static int get_ctl_type(struct snd_card *card, struct snd_ctl_elem_id *id, - int *countp) -{ - struct snd_kcontrol *kctl; - struct snd_ctl_elem_info *info; - int err; - - down_read(&card->controls_rwsem); - kctl = snd_ctl_find_id(card, id); - if (! kctl) { - up_read(&card->controls_rwsem); - return -ENOENT; - } - info = kzalloc(sizeof(*info), GFP_KERNEL); - if (info == NULL) { - up_read(&card->controls_rwsem); - return -ENOMEM; - } - info->id = *id; - err = kctl->info(kctl, info); - up_read(&card->controls_rwsem); - if (err >= 0) { - err = info->type; - *countp = info->count; - } - kfree(info); - return err; -} - -static int get_elem_size(int type, int count) -{ - switch (type) { - case SNDRV_CTL_ELEM_TYPE_INTEGER64: - return sizeof(s64) * count; - case SNDRV_CTL_ELEM_TYPE_ENUMERATED: - return sizeof(int) * count; - case SNDRV_CTL_ELEM_TYPE_BYTES: - return 512; - case SNDRV_CTL_ELEM_TYPE_IEC958: - return sizeof(struct snd_aes_iec958); - default: - return -1; - } -} - -static int copy_ctl_value_from_user(struct snd_card *card, - struct snd_ctl_elem_value *data, - void __user *userdata, - void __user *valuep, - int *typep, int *countp) -{ - struct snd_ctl_elem_value32 __user *data32 = userdata; - int i, type, size; - int uninitialized_var(count); - unsigned int indirect; - - if (copy_from_user(&data->id, &data32->id, sizeof(data->id))) - return -EFAULT; - if (get_user(indirect, &data32->indirect)) - return -EFAULT; - if (indirect) - return -EINVAL; - type = get_ctl_type(card, &data->id, &count); - if (type < 0) - return type; - - if (type == SNDRV_CTL_ELEM_TYPE_BOOLEAN || - type == SNDRV_CTL_ELEM_TYPE_INTEGER) { - for (i = 0; i < count; i++) { - s32 __user *intp = valuep; - int val; - if (get_user(val, &intp[i])) - return -EFAULT; - data->value.integer.value[i] = val; - } - } else { - size = get_elem_size(type, count); - if (size < 0) { - dev_err(card->dev, "snd_ioctl32_ctl_elem_value: unknown type %d\n", type); - return -EINVAL; - } - if (copy_from_user(data->value.bytes.data, valuep, size)) - return -EFAULT; - } - - *typep = type; - *countp = count; - return 0; -} - -/* restore the value to 32bit */ -static int copy_ctl_value_to_user(void __user *userdata, - void __user *valuep, - struct snd_ctl_elem_value *data, - int type, int count) -{ - int i, size; - - if (type == SNDRV_CTL_ELEM_TYPE_BOOLEAN || - type == SNDRV_CTL_ELEM_TYPE_INTEGER) { - for (i = 0; i < count; i++) { - s32 __user *intp = valuep; - int val; - val = data->value.integer.value[i]; - if (put_user(val, &intp[i])) - return -EFAULT; - } - } else { - size = get_elem_size(type, count); - if (copy_to_user(valuep, data->value.bytes.data, size)) - return -EFAULT; - } - return 0; -} - -static int ctl_elem_read_user(struct snd_ctl_file *ctl_file, - void __user *userdata, void __user *valuep) -{ - struct snd_ctl_elem_value *data; - int err, type, count; - - data = kzalloc(sizeof(*data), GFP_KERNEL); - if (data == NULL) - return -ENOMEM; - - err = copy_ctl_value_from_user(ctl_file->card, data, userdata, valuep, - &type, &count); - if (err < 0) - goto error; - - err = snd_ctl_elem_read(ctl_file, data); - if (err < 0) - goto error; - err = copy_ctl_value_to_user(userdata, valuep, data, type, count); - error: - kfree(data); - return err; -} - -static int ctl_elem_write_user(struct snd_ctl_file *ctl_file, - void __user *userdata, void __user *valuep) -{ - struct snd_ctl_elem_value *data; - int err, type, count; - - data = kzalloc(sizeof(*data), GFP_KERNEL); - if (data == NULL) - return -ENOMEM; - - err = copy_ctl_value_from_user(ctl_file->card, data, userdata, valuep, - &type, &count); - if (err < 0) - goto error; - - err = snd_ctl_elem_write(ctl_file, data); - if (err < 0) - goto error; - err = copy_ctl_value_to_user(userdata, valuep, data, type, count); - error: - kfree(data); - return err; -} - -static int snd_ctl_elem_read_user_compat(struct snd_ctl_file *ctl_file, - struct snd_ctl_elem_value32 __user *data32) -{ - return ctl_elem_read_user(ctl_file, data32, &data32->value); -} - -static int snd_ctl_elem_write_user_compat(struct snd_ctl_file *file, - struct snd_ctl_elem_value32 __user *data32) -{ - return ctl_elem_write_user(file, data32, &data32->value); -} - static int ctl_compat_ioctl_elem_list_32(struct snd_ctl_file *ctl_file, void *buf) { @@ -638,12 +450,14 @@ enum { _IOWR('U', 0x10, struct snd_ctl_elem_list_32), SNDRV_CTL_IOCTL_ELEM_INFO_32 = _IOWR('U', 0x11, struct snd_ctl_elem_info_32), - SNDRV_CTL_IOCTL_ELEM_READ32 = _IOWR('U', 0x12, struct snd_ctl_elem_value32), - SNDRV_CTL_IOCTL_ELEM_WRITE32 = _IOWR('U', 0x13, struct snd_ctl_elem_value32), SNDRV_CTL_IOCTL_ELEM_ADD_32 = _IOWR('U', 0x17, struct snd_ctl_elem_info_32), SNDRV_CTL_IOCTL_ELEM_REPLACE_32 = _IOWR('U', 0x18, struct snd_ctl_elem_info_32), + SNDRV_CTL_IOCTL_ELEM_READ_32 = + _IOWR('U', 0x12, struct snd_ctl_elem_value_32), + SNDRV_CTL_IOCTL_ELEM_WRITE_32 = + _IOWR('U', 0x13, struct snd_ctl_elem_value_32), SNDRV_CTL_IOCTL_ELEM_READ_I386 = _IOWR('U', 0x12, struct snd_ctl_elem_value_i386), SNDRV_CTL_IOCTL_ELEM_WRITE_I386 = @@ -690,6 +504,22 @@ static long snd_ctl_ioctl_compat(struct file *file, unsigned int cmd, serialize_to_elem_info_32, SNDRV_CTL_IOCTL_ELEM_REPLACE, }, +#if !defined(CONFIG_X86_64) || defined(CONFIG_X86_X32) + { + SNDRV_CTL_IOCTL_ELEM_READ_32, + deserialize_from_elem_value_32, + ctl_compat_ioctl_elem_read_32, + serialize_to_elem_value_32, + SNDRV_CTL_IOCTL_ELEM_READ, + }, + { + SNDRV_CTL_IOCTL_ELEM_WRITE_32, + deserialize_from_elem_value_32, + ctl_compat_ioctl_elem_write_32, + serialize_to_elem_value_32, + SNDRV_CTL_IOCTL_ELEM_WRITE, + }, +#endif #ifdef CONFIG_X86_64 { SNDRV_CTL_IOCTL_ELEM_READ_I386, @@ -708,7 +538,6 @@ static long snd_ctl_ioctl_compat(struct file *file, unsigned int cmd, #endif }; struct snd_ctl_file *ctl; - void __user *argp = compat_ptr(arg); void *buf, *data; unsigned int size; int i; @@ -718,13 +547,6 @@ static long snd_ctl_ioctl_compat(struct file *file, unsigned int cmd, if (snd_BUG_ON(!ctl || !ctl->card)) return -ENXIO;
- switch (cmd) { - case SNDRV_CTL_IOCTL_ELEM_READ32: - return snd_ctl_elem_read_user_compat(ctl, argp); - case SNDRV_CTL_IOCTL_ELEM_WRITE32: - return snd_ctl_elem_write_user_compat(ctl, argp); - } - for (i = 0; i < ARRAY_SIZE(handlers); ++i) { if (handlers[i].cmd == cmd) break;