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