diff options
author | Jeremy Huddleston <eradicator@gentoo.org> | 2004-11-21 23:07:53 +0000 |
---|---|---|
committer | Jeremy Huddleston <eradicator@gentoo.org> | 2004-11-21 23:07:53 +0000 |
commit | bb99479ea3cadbc2263a1df1fdaeb4010e473625 (patch) | |
tree | 31331892e95afada28fc13565d59caaee3b6158c /media-sound/alsa-driver/files | |
parent | Version bump to fix #71035. (diff) | |
download | gentoo-2-bb99479ea3cadbc2263a1df1fdaeb4010e473625.tar.gz gentoo-2-bb99479ea3cadbc2263a1df1fdaeb4010e473625.tar.bz2 gentoo-2-bb99479ea3cadbc2263a1df1fdaeb4010e473625.zip |
Added patch to ioctl32 support to get it to work on sparc... still needs testing... See bug #55465.
Diffstat (limited to 'media-sound/alsa-driver/files')
-rw-r--r-- | media-sound/alsa-driver/files/alsa-driver-1.0.7-ioctl32.patch | 329 |
1 files changed, 329 insertions, 0 deletions
diff --git a/media-sound/alsa-driver/files/alsa-driver-1.0.7-ioctl32.patch b/media-sound/alsa-driver/files/alsa-driver-1.0.7-ioctl32.patch new file mode 100644 index 000000000000..e5ddc81776c7 --- /dev/null +++ b/media-sound/alsa-driver/files/alsa-driver-1.0.7-ioctl32.patch @@ -0,0 +1,329 @@ +diff -Naur alsa-driver-1.0.7.orig/sound/core/ioctl32/hwdep32.c alsa-driver-1.0.7/sound/core/ioctl32/hwdep32.c +--- alsa-driver-1.0.7.orig/sound/core/ioctl32/hwdep32.c 2004-10-18 07:55:51.000000000 -0700 ++++ alsa-driver-1.0.7/sound/core/ioctl32/hwdep32.c 2004-11-21 15:03:41.306477719 -0800 +@@ -39,20 +39,26 @@ + struct sndrv_hwdep_dsp_image data; + struct sndrv_hwdep_dsp_image32 data32; + mm_segment_t oldseg; +- int err; ++ int err = 0; + +- if (copy_from_user(&data32, (void __user *)arg, sizeof(data32))) ++ if (copy_from_user(&data32, (void __user *)arg, sizeof(data32))) { + return -EFAULT; ++ } + memset(&data, 0, sizeof(data)); + data.index = data32.index; + memcpy(data.name, data32.name, sizeof(data.name)); +- data.image = compat_ptr(data32.image); ++ data.image = kmalloc(data32.length, GFP_KERNEL); ++ if (data.image == NULL) { ++ return -ENOMEM; ++ } + data.length = data32.length; + data.driver_data = data32.driver_data; + oldseg = get_fs(); + set_fs(KERNEL_DS); + err = file->f_op->ioctl(file->f_dentry->d_inode, file, native_ctl, (unsigned long)&data); + set_fs(oldseg); ++ ++ kfree(data.image); + return err; + } + +diff -Naur alsa-driver-1.0.7.orig/sound/core/ioctl32/ioctl32.c alsa-driver-1.0.7/sound/core/ioctl32/ioctl32.c +--- alsa-driver-1.0.7.orig/sound/core/ioctl32/ioctl32.c 2004-10-18 07:55:51.000000000 -0700 ++++ alsa-driver-1.0.7/sound/core/ioctl32/ioctl32.c 2004-11-21 15:03:41.299478783 -0800 +@@ -93,45 +93,54 @@ + unsigned char reserved[50]; + } /* don't set packed attribute here */; + +-#define CVT_sndrv_ctl_elem_list()\ +-{\ +- COPY(offset);\ +- COPY(space);\ +- COPY(used);\ +- COPY(count);\ +- CPTR(pids);\ +-} +- + static inline int _snd_ioctl32_ctl_elem_list(unsigned int fd, unsigned int cmd, unsigned long arg, struct file *file, unsigned int native_ctl) + { + struct sndrv_ctl_elem_list32 data32; + struct sndrv_ctl_elem_list data; + mm_segment_t oldseg; +- int err; ++ int err = 0; + + if (copy_from_user(&data32, (void __user *)arg, sizeof(data32))) + return -EFAULT; + memset(&data, 0, sizeof(data)); ++ ++ /* Copy over W data */ + data.offset = data32.offset; + data.space = data32.space; +- data.used = data32.used; +- data.count = data32.count; +- data.pids = compat_ptr(data32.pids); ++ ++ data.pids = kmalloc(sizeof(*data.pids) * data.space, GFP_KERNEL); ++ if (data.pids == NULL) { ++ err = -ENOMEM; ++ goto __list_end; ++ } ++ ++ /* ioctl call */ + oldseg = get_fs(); + set_fs(KERNEL_DS); + 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 __list_end; ++ + /* copy the result */ +- data32.offset = data.offset; +- data32.space = data.space; + data32.used = data.used; + data32.count = data.count; +- //data.pids = data.pids; ++ ++ if (data.used > 0 && ++ copy_to_user((void __user *)compat_ptr(data32.pids), data.pids, sizeof(*data.pids) * data.used)) { ++ err = -EFAULT; ++ goto __list_end; ++ } ++ + if (copy_to_user((void __user *)arg, &data32, sizeof(data32))) +- return -EFAULT; +- return 0; ++ err = -EFAULT; ++ ++__list_end: ++ if (data.pids) { ++ kfree(data.pids); ++ } ++ return err; + } + + DEFINE_ALSA_IOCTL_ENTRY(ctl_elem_list, ctl_elem_list, SNDRV_CTL_IOCTL_ELEM_LIST); +@@ -298,8 +307,21 @@ + memset(data, 0, sizeof(*data)); + data->id = data32->id; + data->indirect = data32->indirect; +- if (data->indirect) /* FIXME: this is not correct for long arrays */ ++ if (data->indirect) { /* FIXME: this is not correct for long arrays */ ++#if defined(__sparc__) ++ err = -EINVAL; ++ goto __end; ++ ++ /* Is this the correct way to handle indirect? */ ++ data->value.integer.value_ptr = kmalloc(sizeof(u32), GFP_KERNEL); ++ if (data->value.integer.value_ptr == NULL) { ++ err = -ENOMEM; ++ goto __end; ++ } ++#else + data->value.integer.value_ptr = compat_ptr(data32->value.integer.value_ptr); ++#endif ++ } + type = get_ctl_type(file, &data->id); + if (type < 0) { + err = type; +@@ -370,10 +392,16 @@ + if (copy_to_user((void __user *)arg, data32, sizeof(*data32))) + err = -EFAULT; + __end: ++#if defined(__sparc__) ++ if (data->indirect) { ++ kfree(data->value.integer.value_ptr); ++ } ++#endif + if (data32) + kfree(data32); + if (data) + kfree(data); ++ + return err; + } + +diff -Naur alsa-driver-1.0.7.orig/sound/core/ioctl32/pcm32.c alsa-driver-1.0.7/sound/core/ioctl32/pcm32.c +--- alsa-driver-1.0.7.orig/sound/core/ioctl32/pcm32.c 2004-10-18 07:55:51.000000000 -0700 ++++ alsa-driver-1.0.7/sound/core/ioctl32/pcm32.c 2004-11-21 15:03:41.305477871 -0800 +@@ -169,6 +169,7 @@ + + DEFINE_ALSA_IOCTL(pcm_uframes_str); + DEFINE_ALSA_IOCTL(pcm_sframes_str); ++DEFINE_ALSA_IOCTL_BIG(pcm_hw_params); + DEFINE_ALSA_IOCTL(pcm_sw_params); + DEFINE_ALSA_IOCTL(pcm_channel_info); + DEFINE_ALSA_IOCTL(pcm_status); +@@ -192,46 +193,6 @@ + runtime->boundary *= 2; + } + +-static inline int _snd_ioctl32_pcm_hw_params(unsigned int fd, unsigned int cmd, unsigned long arg, struct file *file, unsigned int native_ctl) +-{ +- struct sndrv_pcm_hw_params32 *data32; +- struct sndrv_pcm_hw_params *data; +- mm_segment_t oldseg; +- int err; +- +- data32 = kmalloc(sizeof(*data32), GFP_KERNEL); +- data = kmalloc(sizeof(*data), GFP_KERNEL); +- if (data32 == NULL || data == NULL) { +- err = -ENOMEM; +- goto __end; +- } +- if (copy_from_user(data32, (void __user *)arg, sizeof(*data32))) { +- err = -EFAULT; +- goto __end; +- } +- memset(data, 0, sizeof(*data)); +- convert_from_32(pcm_hw_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); +- set_fs(oldseg); +- if (err < 0) +- goto __end; +- err = 0; +- convert_to_32(pcm_hw_params, data32, data); +- if (copy_to_user((void __user *)arg, data32, sizeof(*data32))) +- err = -EFAULT; +- else +- recalculate_boundary(file); +- __end: +- if (data) +- kfree(data); +- if (data32) +- kfree(data32); +- return err; +-} +- +- + /* + */ + struct sndrv_xferi32 { +@@ -245,25 +206,54 @@ + struct sndrv_xferi32 data32; + struct sndrv_xferi data; + mm_segment_t oldseg; +- int err; ++ int err = 0; ++ size_t size; ++ ++ snd_pcm_substream_t *substream; ++ snd_pcm_runtime_t *runtime; ++ ++ substream = ((snd_pcm_file_t *)file->private_data)->substream; ++ snd_assert(substream != NULL, return -ENXIO); ++ runtime = substream->runtime; + + if (copy_from_user(&data32, (void __user *)arg, sizeof(data32))) + return -EFAULT; + memset(&data, 0, sizeof(data)); ++ ++ size = frames_to_bytes(runtime, data32.frames); ++ data.buf = kmalloc(size, GFP_KERNEL); ++ if (data.buf == NULL) { ++ return -ENOMEM; ++ } ++ ++ if (copy_from_user(data.buf, (void __user *)compat_ptr(data32.buf), size)) { ++ err = -EFAULT; ++ goto __xferi_end; ++ } + data.result = data32.result; +- data.buf = compat_ptr(data32.buf); + data.frames = data32.frames; ++ + oldseg = get_fs(); + set_fs(KERNEL_DS); + 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 __xferi_end; ++ + /* copy the result */ + data32.result = data.result; ++ data32.frames = data.frames; ++ if (copy_to_user((void __user *)compat_ptr(data32.buf), data.buf, size)) { ++ err = -EFAULT; ++ goto __xferi_end; ++ } + if (copy_to_user((void __user *)arg, &data32, sizeof(data32))) +- return -EFAULT; +- return 0; ++ err = -EFAULT; ++ ++__xferi_end: ++ if(data.buf) ++ kfree(data.buf); ++ return err; + } + + +@@ -287,12 +277,12 @@ + struct sndrv_xfern32 data32; + struct sndrv_xfern32 __user *srcptr = (void __user *)arg; + void __user **bufs = NULL; +- int err = 0, ch, i; ++ int err = 0, ch, i, cp = 0; + u32 __user *bufptr; + mm_segment_t oldseg; ++ size_t size; + + /* FIXME: need to check whether fop->ioctl is sane */ +- + pcm_file = file->private_data; + substream = pcm_file->substream; + snd_assert(substream != NULL && substream->runtime, return -ENXIO); +@@ -319,11 +309,27 @@ + bufs = kmalloc(sizeof(void *) * 128, GFP_KERNEL); + if (bufs == NULL) + return -ENOMEM; ++ size = frames_to_bytes(substream->runtime , data32.frames); + for (i = 0; i < ch; i++) { + u32 ptr; +- if (get_user(ptr, bufptr)) +- return -EFAULT; +- bufs[ch] = compat_ptr(ptr); ++ if (get_user(ptr, bufptr)) { ++ err = -EFAULT; ++ goto __xfern_out; ++ } ++ ++ bufs[i] = kmalloc(size, GFP_KERNEL); ++ if (bufs[i] == NULL) { ++ err = -ENOMEM; ++ goto __xfern_out; ++ } ++ ++ cp++; ++ ++ if (copy_from_user(bufs[i], (void __user *)compat_ptr(ptr), size)) { ++ err = -EFAULT; ++ goto __xfern_out; ++ } ++ + bufptr++; + } + oldseg = get_fs(); +@@ -341,8 +347,13 @@ + if (put_user(err, &srcptr->result)) + err = -EFAULT; + } ++ ++__xfern_out: ++ for (i = 0; i < cp; i++) { ++ kfree(bufs[i]); ++ } + kfree(bufs); +- return 0; ++ return err; + } + + |