Update of /cvsroot/alsa/alsa-kernel/core/ioctl32
In directory usw-pr-cvs1:/tmp/cvs-serv29536

Modified Files:
        ioctl32.c ioctl32.h pcm32.c 
Log Message:
Use kcallocated structures to reduce heap usage

Index: ioctl32.c
===================================================================
RCS file: /cvsroot/alsa/alsa-kernel/core/ioctl32/ioctl32.c,v
retrieving revision 1.10
retrieving revision 1.11
diff -u -r1.10 -r1.11
--- ioctl32.c   29 Aug 2002 16:23:05 -0000      1.10
+++ ioctl32.c   12 Oct 2002 13:08:50 -0000      1.11
@@ -264,46 +264,56 @@
 
 static int _snd_ioctl32_ctl_elem_value(unsigned int fd, unsigned int cmd, unsigned 
long arg, struct file *file, unsigned int native_ctl)
 {
-       // too big?
-       struct sndrv_ctl_elem_value data;
-       struct sndrv_ctl_elem_value32 data32;
+       struct sndrv_ctl_elem_value *data;
+       struct sndrv_ctl_elem_value32 *data32;
        int err, i;
        int type;
        mm_segment_t oldseg;
 
        /* FIXME: check the sane ioctl.. */
 
-       if (copy_from_user(&data32, (void*)arg, sizeof(data32)))
-               return -EFAULT;
-       memset(&data, 0, sizeof(data));
-       data.id = data32.id;
-       data.indirect = data32.indirect;
-       if (data.indirect) /* FIXME: this is not correct for long arrays */
-               data.value.integer.value_ptr = 
(void*)TO_PTR(data32.value.integer.value_ptr);
-       type = get_ctl_type(file, &data.id);
-       if (type < 0)
-               return type;
+       data = kmalloc(sizeof(*data), GFP_KERNEL);
+       data32 = kmalloc(sizeof(*data32), GFP_KERNEL);
+       if (data == NULL || data32 == NULL) {
+               err = -ENOMEM;
+               goto __end;
+       }
+
+       if (copy_from_user(data32, (void*)arg, sizeof(*data32))) {
+               err = -EFAULT;
+               goto __end;
+       }
+       memset(data, 0, sizeof(*data));
+       data->id = data32->id;
+       data->indirect = data32->indirect;
+       if (data->indirect) /* FIXME: this is not correct for long arrays */
+               data.value.integer.value_ptr = 
+(void*)TO_PTR(data32->value.integer.value_ptr);
+       type = get_ctl_type(file, &data->id);
+       if (type < 0) {
+               err = type;
+               goto __end;
+       }
        if (! data.indirect) {
                switch (type) {
                case SNDRV_CTL_ELEM_TYPE_BOOLEAN:
                case SNDRV_CTL_ELEM_TYPE_INTEGER:
                        for (i = 0; i < 128; i++)
-                               data.value.integer.value[i] = 
data32.value.integer.value[i];
+                               data->value.integer.value[i] = 
+data32->value.integer.value[i];
                        break;
                case SNDRV_CTL_ELEM_TYPE_INTEGER64:
                        for (i = 0; i < 64; i++)
-                               data.value.integer64.value[i] = 
data32.value.integer64.value[i];
+                               data->value.integer64.value[i] = 
+data32->value.integer64.value[i];
                        break;
                case SNDRV_CTL_ELEM_TYPE_ENUMERATED:
                        for (i = 0; i < 128; i++)
-                               data.value.enumerated.item[i] = 
data32.value.enumerated.item[i];
+                               data->value.enumerated.item[i] = 
+data32->value.enumerated.item[i];
                        break;
                case SNDRV_CTL_ELEM_TYPE_BYTES:
-                       memcpy(data.value.bytes.data, data32.value.bytes.data,
-                              sizeof(data.value.bytes.data));
+                       memcpy(data->value.bytes.data, data32->value.bytes.data,
+                              sizeof(data->value.bytes.data));
                        break;
                case SNDRV_CTL_ELEM_TYPE_IEC958:
-                       data.value.iec958 = data32.value.iec958;
+                       data->value.iec958 = data32->value.iec958;
                        break;
                default:
                        printk("unknown type %d\n", type);
@@ -313,40 +323,46 @@
 
        oldseg = get_fs();
        set_fs(KERNEL_DS);
-       err = file->f_op->ioctl(file->f_dentry->d_inode, file, native_ctl, (unsigned 
long)&data);
+       err = file->f_op->ioctl(file->f_dentry->d_inode, file, native_ctl, (unsigned 
+long)data);
        set_fs(oldseg);
        if (err < 0)
-               return err;
+               goto __end;
        /* restore info to 32bit */
        if (! data.indirect) {
                switch (type) {
                case SNDRV_CTL_ELEM_TYPE_BOOLEAN:
                case SNDRV_CTL_ELEM_TYPE_INTEGER:
                        for (i = 0; i < 128; i++)
-                               data32.value.integer.value[i] = 
data.value.integer.value[i];
+                               data32->value.integer.value[i] = 
+data->value.integer.value[i];
                        break;
                case SNDRV_CTL_ELEM_TYPE_INTEGER64:
                        for (i = 0; i < 64; i++)
-                               data32.value.integer64.value[i] = 
data.value.integer64.value[i];
+                               data32->value.integer64.value[i] = 
+data->value.integer64.value[i];
                        break;
                case SNDRV_CTL_ELEM_TYPE_ENUMERATED:
                        for (i = 0; i < 128; i++)
-                               data32.value.enumerated.item[i] = 
data.value.enumerated.item[i];
+                               data32->value.enumerated.item[i] = 
+data->value.enumerated.item[i];
                        break;
                case SNDRV_CTL_ELEM_TYPE_BYTES:
-                       memcpy(data32.value.bytes.data, data.value.bytes.data,
-                              sizeof(data.value.bytes.data));
+                       memcpy(data32->value.bytes.data, data->value.bytes.data,
+                              sizeof(data->value.bytes.data));
                        break;
                case SNDRV_CTL_ELEM_TYPE_IEC958:
-                       data32.value.iec958 = data.value.iec958;
+                       data32->value.iec958 = data->value.iec958;
                        break;
                default:
                        break;
                }
        }
-       if (copy_to_user((void*)arg, &data32, sizeof(data32)))
-               return -EFAULT;
-       return 0;
+       err = 0;
+       if (copy_to_user((void*)arg, data32, sizeof(*data32)))
+               err = -EFAULT;
+      __end:
+       if (data32)
+               free(data32);
+       if (data)
+               free(data);
+       return err;
 }
 
 DEFINE_ALSA_IOCTL_ENTRY(ctl_elem_read, ctl_elem_value, SNDRV_CTL_IOCTL_ELEM_READ);

Index: ioctl32.h
===================================================================
RCS file: /cvsroot/alsa/alsa-kernel/core/ioctl32/ioctl32.h,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -r1.7 -r1.8
--- ioctl32.h   1 Oct 2002 05:54:43 -0000       1.7
+++ ioctl32.h   12 Oct 2002 13:08:50 -0000      1.8
@@ -79,6 +79,44 @@
        return 0;\
 }
 
+#define DEFINE_ALSA_IOCTL_BIG(type) \
+static int _snd_ioctl32_##type(unsigned int fd, unsigned int cmd, unsigned long arg, 
+struct file *file, unsigned int native_ctl)\
+{\
+       struct sndrv_##type##32 *data32;\
+       struct sndrv_##type *data;\
+       mm_segment_t oldseg;\
+       int err;\
+       data32 = kcalloc(sizeof(*data32), GFP_KERNEL); \
+       data = kcalloc(sizeof(*data), GFP_KERNEL); \
+       if (data32 == NULL || data == NULL) { \
+               err = -ENOMEM; \
+               goto __end; \
+       }
+       if (copy_from_user(data32, (void*)arg, sizeof(*data32))) { \
+               err = -EFAULT; \
+               goto __end; \
+       }
+       memset(data, 0, sizeof(*data));\
+       convert_from_32(type, data, data32);\
+       oldseg = get_fs();\
+       set_fs(KERNEL_DS);\
+       err = file->f_op->ioctl(file->f_dentry->d_inode, file, native_ctl, (unsigned 
+long)data);\
+       if (err < 0) \
+               goto __end;\
+       err = 0;\
+       if (native_ctl & (_IOC_READ << _IOC_DIRSHIFT)) {\
+               convert_to_32(type, data32, data);\
+               if (copy_to_user((void*)arg, data32, sizeof(*data32)))\
+                       err = -EFAULT;\
+       }\
+      __end:\
+       if (data)\
+               free(data);\
+       if (data32)\
+               free(data32);\
+       return err;\
+}
+
 #define DEFINE_ALSA_IOCTL_ENTRY(name,type,native_ctl) \
 static int snd_ioctl32_##name(unsigned int fd, unsigned int cmd, unsigned long arg, 
struct file *file) {\
        return _snd_ioctl32_##type(fd, cmd, arg, file, native_ctl);\

Index: pcm32.c
===================================================================
RCS file: /cvsroot/alsa/alsa-kernel/core/ioctl32/pcm32.c,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -r1.7 -r1.8
--- pcm32.c     29 Aug 2002 16:23:05 -0000      1.7
+++ pcm32.c     12 Oct 2002 13:08:50 -0000      1.8
@@ -172,7 +172,7 @@
 
 DEFINE_ALSA_IOCTL(pcm_uframes_str);
 DEFINE_ALSA_IOCTL(pcm_sframes_str);
-DEFINE_ALSA_IOCTL(pcm_hw_params);
+DEFINE_ALSA_IOCTL_BIG(pcm_hw_params);
 DEFINE_ALSA_IOCTL(pcm_sw_params);
 DEFINE_ALSA_IOCTL(pcm_channel_info);
 DEFINE_ALSA_IOCTL(pcm_status);
@@ -230,7 +230,7 @@
        snd_pcm_file_t *pcm_file;
        snd_pcm_substream_t *substream;
        struct sndrv_xfern32 data32, *srcptr = (struct sndrv_xfern32*)arg;
-       void *bufs[128];
+       void *bufs[] = NULL;
        int err = 0, ch, i;
        u32 *bufptr;
        mm_segment_t oldseg;
@@ -260,6 +260,9 @@
                return -EFAULT;
        __get_user(data32.bufs, &srcptr->bufs);
        bufptr = (u32*)TO_PTR(data32.bufs);
+       bufs = kmalloc(sizeof(void *) * 128, GFP_KERNEL)
+       if (bufs == NULL)
+               return -ENOMEM;
        for (i = 0; i < ch; i++) {
                u32 ptr;
                if (get_user(ptr, bufptr))
@@ -278,10 +281,11 @@
                break;
        }
        set_fs(oldseg);
-       if (err < 0)
-               return err;
-       if (put_user(err, &srcptr->result))
-               return -EFAULT;
+       if (err >= 0) {
+               if (put_user(err, &srcptr->result))
+                       err = -EFAULT;
+       }
+       free(bufs);
        return 0;
 }
 
@@ -343,24 +347,38 @@
 
 static int _snd_ioctl32_pcm_hw_params_old(unsigned int fd, unsigned int cmd, unsigned 
long arg, struct file *file, unsigned int native_ctl)
 {
-       struct sndrv_pcm_hw_params_old32 data32;
-       struct sndrv_pcm_hw_params data;
+       struct sndrv_pcm_hw_params_old32 *data32;
+       struct sndrv_pcm_hw_params *data;
        mm_segment_t oldseg;
        int err;
 
-       if (copy_from_user(&data32, (void*)arg, sizeof(data32)))
-               return -EFAULT;
-       snd_pcm_hw_convert_from_old_params(&data, &data32);
+       data32 = kcalloc(sizeof(*data32), GFP_KERNEL);
+       data = kcalloc(sizeof(*data), GFP_KERNEL);
+       if (data32 == NULL || data == NULL) {
+               err = -ENOMEM;
+               goto __end;
+       }
+       if (copy_from_user(data32, (void*)arg, sizeof(*data32))) {
+               err = -EFAULT;
+               goto __end;
+       }
+       snd_pcm_hw_convert_from_old_params(data, data32);
        oldseg = get_fs();
        set_fs(KERNEL_DS);
-       err = file->f_op->ioctl(file->f_dentry->d_inode, file, native_ctl, (unsigned 
long)&data);
+       err = file->f_op->ioctl(file->f_dentry->d_inode, file, native_ctl, (unsigned 
+long)data);
        set_fs(oldseg);
        if (err < 0)
-               return err;
-       snd_pcm_hw_convert_to_old_params(&data32, &data);
-       if (copy_to_user((void*)arg, &data32, sizeof(data32)))
-               return  -EFAULT;
-       return 0;
+               goto __end;
+       snd_pcm_hw_convert_to_old_params(data32, data);
+       err = 0;
+       if (copy_to_user((void*)arg, data32, sizeof(*data32)))
+               err = -EFAULT;
+      __end:
+       if (data)
+               free(data);
+       if (data32)
+               free(data32);
+       return err;
 }
 
 



-------------------------------------------------------
This sf.net email is sponsored by:ThinkGeek
Welcome to geek heaven.
http://thinkgeek.com/sf
_______________________________________________
Alsa-cvslog mailing list
[EMAIL PROTECTED]
https://lists.sourceforge.net/lists/listinfo/alsa-cvslog

Reply via email to