[alsa-devel] [PATCH 23/24] ALSA: ctl: replacement for compat ELEM_READ/ELEM_WRITE operation for modern 32 bit ABI
Takashi Sakamoto
o-takashi at sakamocchi.jp
Sat Nov 25 10:20:05 CET 2017
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 at 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;
--
2.14.1
More information about the Alsa-devel
mailing list