summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeremy Huddleston <eradicator@gentoo.org>2004-11-26 20:23:51 +0000
committerJeremy Huddleston <eradicator@gentoo.org>2004-11-26 20:23:51 +0000
commit148425dd41f2ce0e93f83e2cd04e0afbfc825c91 (patch)
tree0c500d3023a4ebbf0ae25f77116a5814a3cf20f9 /media-sound/alsa-driver
parentVersion bump closes bug #68617. (Manifest recommit) (diff)
downloadgentoo-2-148425dd41f2ce0e93f83e2cd04e0afbfc825c91.tar.gz
gentoo-2-148425dd41f2ce0e93f83e2cd04e0afbfc825c91.tar.bz2
gentoo-2-148425dd41f2ce0e93f83e2cd04e0afbfc825c91.zip
Updating upstream ioctl32 patch.
Diffstat (limited to 'media-sound/alsa-driver')
-rw-r--r--media-sound/alsa-driver/ChangeLog6
-rw-r--r--media-sound/alsa-driver/files/alsa-driver-1.0.7-ioctl32.patch-r1434
2 files changed, 375 insertions, 65 deletions
diff --git a/media-sound/alsa-driver/ChangeLog b/media-sound/alsa-driver/ChangeLog
index 27beba5aa698..1416e3d9885b 100644
--- a/media-sound/alsa-driver/ChangeLog
+++ b/media-sound/alsa-driver/ChangeLog
@@ -1,6 +1,10 @@
# ChangeLog for media-sound/alsa-driver
# Copyright 2002-2004 Gentoo Foundation; Distributed under the GPL v2
-# $Header: /var/cvsroot/gentoo-x86/media-sound/alsa-driver/ChangeLog,v 1.109 2004/11/26 06:53:30 eradicator Exp $
+# $Header: /var/cvsroot/gentoo-x86/media-sound/alsa-driver/ChangeLog,v 1.110 2004/11/26 20:23:51 eradicator Exp $
+
+ 26 Nov 2004; Jeremy Huddleston <eradicator@gentoo.org>
+ files/alsa-driver-1.0.7-ioctl32.patch-r1:
+ Updating upstream ioctl32 patch.
25 Nov 2004; Jeremy Huddleston <eradicator@gentoo.org>
+files/alsa-driver-1.0.7-audigy71.patch,
diff --git a/media-sound/alsa-driver/files/alsa-driver-1.0.7-ioctl32.patch-r1 b/media-sound/alsa-driver/files/alsa-driver-1.0.7-ioctl32.patch-r1
index 97a066faab04..c8fbb767e216 100644
--- a/media-sound/alsa-driver/files/alsa-driver-1.0.7-ioctl32.patch-r1
+++ b/media-sound/alsa-driver/files/alsa-driver-1.0.7-ioctl32.patch-r1
@@ -1,3 +1,176 @@
+Index: alsa-kernel/core/control.c
+===================================================================
+RCS file: /suse/tiwai/cvs/alsa/alsa-kernel/core/control.c,v
+retrieving revision 1.42
+diff -u -r1.42 control.c
+--- alsa-kernel/core/control.c 16 Jul 2004 16:50:36 -0000 1.42
++++ alsa-kernel/core/control.c 26 Nov 2004 14:05:44 -0000
+@@ -635,19 +635,13 @@
+ return result;
+ }
+
+-static int snd_ctl_elem_read(snd_card_t *card, snd_ctl_elem_value_t __user *_control)
++int snd_ctl_elem_read(snd_card_t *card, snd_ctl_elem_value_t *control)
+ {
+- snd_ctl_elem_value_t *control;
+ snd_kcontrol_t *kctl;
+ snd_kcontrol_volatile_t *vd;
+ unsigned int index_offset;
+ int result, indirect;
+-
+- control = kmalloc(sizeof(*control), GFP_KERNEL);
+- if (control == NULL)
+- return -ENOMEM;
+- if (copy_from_user(control, _control, sizeof(*control)))
+- return -EFAULT;
++
+ down_read(&card->controls_rwsem);
+ kctl = snd_ctl_find_id(card, &control->id);
+ if (kctl == NULL) {
+@@ -668,27 +662,37 @@
+ }
+ }
+ up_read(&card->controls_rwsem);
++ return result;
++}
++
++static int snd_ctl_elem_read_user(snd_card_t *card, snd_ctl_elem_value_t __user *_control)
++{
++ snd_ctl_elem_value_t *control;
++ int result;
++
++ control = kmalloc(sizeof(*control), GFP_KERNEL);
++ if (control == NULL)
++ return -ENOMEM;
++ if (copy_from_user(control, _control, sizeof(*control))) {
++ kfree(control);
++ return -EFAULT;
++ }
++ result = snd_ctl_elem_read(card, control);
+ if (result >= 0)
+ if (copy_to_user(_control, control, sizeof(*control)))
+- return -EFAULT;
++ result = -EFAULT;
+ kfree(control);
+ return result;
+ }
+
+-static int snd_ctl_elem_write(snd_ctl_file_t *file, snd_ctl_elem_value_t __user *_control)
++int snd_ctl_elem_write(snd_ctl_file_t *file, snd_ctl_elem_value_t *control)
+ {
+ snd_card_t *card = file->card;
+- snd_ctl_elem_value_t *control;
+ snd_kcontrol_t *kctl;
+ snd_kcontrol_volatile_t *vd;
+ unsigned int index_offset;
+ int result, indirect;
+
+- control = kmalloc(sizeof(*control), GFP_KERNEL);
+- if (control == NULL)
+- return -ENOMEM;
+- if (copy_from_user(control, _control, sizeof(*control)))
+- return -EFAULT;
+ down_read(&card->controls_rwsem);
+ kctl = snd_ctl_find_id(card, &control->id);
+ if (kctl == NULL) {
+@@ -711,16 +715,30 @@
+ if (result > 0) {
+ up_read(&card->controls_rwsem);
+ snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_VALUE, &control->id);
+- result = 0;
+- goto __unlocked;
++ return 0;
+ }
+ }
+ }
+ up_read(&card->controls_rwsem);
+- __unlocked:
++ return result;
++}
++
++static int snd_ctl_elem_write_user(snd_ctl_file_t *file, snd_ctl_elem_value_t __user *_control)
++{
++ snd_ctl_elem_value_t *control;
++ int result;
++
++ control = kmalloc(sizeof(*control), GFP_KERNEL);
++ if (control == NULL)
++ return -ENOMEM;
++ if (copy_from_user(control, _control, sizeof(*control))) {
++ kfree(control);
++ return -EFAULT;
++ }
++ result = snd_ctl_elem_write(file, control);
+ if (result >= 0)
+ if (copy_to_user(_control, control, sizeof(*control)))
+- return -EFAULT;
++ result = -EFAULT;
+ kfree(control);
+ return result;
+ }
+@@ -1045,9 +1063,9 @@
+ case SNDRV_CTL_IOCTL_ELEM_INFO:
+ return snd_ctl_elem_info(ctl, argp);
+ case SNDRV_CTL_IOCTL_ELEM_READ:
+- return snd_ctl_elem_read(ctl->card, argp);
++ return snd_ctl_elem_read_user(ctl->card, argp);
+ case SNDRV_CTL_IOCTL_ELEM_WRITE:
+- return snd_ctl_elem_write(ctl, argp);
++ return snd_ctl_elem_write_user(ctl, argp);
+ case SNDRV_CTL_IOCTL_ELEM_LOCK:
+ return snd_ctl_elem_lock(ctl, argp);
+ case SNDRV_CTL_IOCTL_ELEM_UNLOCK:
+Index: alsa-kernel/core/pcm_lib.c
+===================================================================
+RCS file: /suse/tiwai/cvs/alsa/alsa-kernel/core/pcm_lib.c,v
+retrieving revision 1.57
+diff -u -r1.57 pcm_lib.c
+--- alsa-kernel/core/pcm_lib.c 24 Sep 2004 13:55:54 -0000 1.57
++++ alsa-kernel/core/pcm_lib.c 26 Nov 2004 13:42:21 -0000
+@@ -2660,6 +2660,7 @@
+ EXPORT_SYMBOL(snd_pcm_hw_param_near);
+ EXPORT_SYMBOL(snd_pcm_hw_param_set);
+ EXPORT_SYMBOL(snd_pcm_hw_refine);
++EXPORT_SYMBOL(snd_pcm_hw_params);
+ EXPORT_SYMBOL(snd_pcm_hw_constraints_init);
+ EXPORT_SYMBOL(snd_pcm_hw_constraints_complete);
+ EXPORT_SYMBOL(snd_pcm_hw_constraint_list);
+Index: alsa-kernel/core/pcm_native.c
+===================================================================
+RCS file: /suse/tiwai/cvs/alsa/alsa-kernel/core/pcm_native.c,v
+retrieving revision 1.85
+diff -u -r1.85 pcm_native.c
+--- alsa-kernel/core/pcm_native.c 16 Nov 2004 15:17:15 -0000 1.85
++++ alsa-kernel/core/pcm_native.c 26 Nov 2004 13:34:12 -0000
+@@ -329,8 +329,8 @@
+ return err;
+ }
+
+-static int snd_pcm_hw_params(snd_pcm_substream_t *substream,
+- snd_pcm_hw_params_t *params)
++int snd_pcm_hw_params(snd_pcm_substream_t *substream,
++ snd_pcm_hw_params_t *params)
+ {
+ snd_pcm_runtime_t *runtime;
+ int err;
+Index: alsa-kernel/core/sound.c
+===================================================================
+RCS file: /suse/tiwai/cvs/alsa/alsa-kernel/core/sound.c,v
+retrieving revision 1.62
+diff -u -r1.62 sound.c
+--- alsa-kernel/core/sound.c 8 Nov 2004 11:37:34 -0000 1.62
++++ alsa-kernel/core/sound.c 26 Nov 2004 14:06:50 -0000
+@@ -475,6 +475,10 @@
+ EXPORT_SYMBOL(snd_ctl_notify);
+ EXPORT_SYMBOL(snd_ctl_register_ioctl);
+ EXPORT_SYMBOL(snd_ctl_unregister_ioctl);
++#ifdef CONFIG_COMPAT
++EXPORT_SYMBOL(snd_ctl_elem_read);
++EXPORT_SYMBOL(snd_ctl_elem_write);
++#endif
+ /* misc.c */
+ EXPORT_SYMBOL(snd_task_name);
+ #ifdef CONFIG_SND_VERBOSE_PRINTK
Index: alsa-kernel/core/ioctl32/hwdep32.c
===================================================================
RCS file: /suse/tiwai/cvs/alsa/alsa-kernel/core/ioctl32/hwdep32.c,v
@@ -52,7 +225,7 @@ RCS file: /suse/tiwai/cvs/alsa/alsa-kernel/core/ioctl32/ioctl32.c,v
retrieving revision 1.27
diff -u -r1.27 ioctl32.c
--- alsa-kernel/core/ioctl32/ioctl32.c 18 Oct 2004 14:31:33 -0000 1.27
-+++ alsa-kernel/core/ioctl32/ioctl32.c 24 Nov 2004 13:48:10 -0000
++++ alsa-kernel/core/ioctl32/ioctl32.c 26 Nov 2004 14:11:08 -0000
@@ -30,6 +30,23 @@
#include <asm/uaccess.h>
#include "ioctl32.h"
@@ -105,7 +278,7 @@ diff -u -r1.27 ioctl32.c
+ data = compat_alloc_user_space(sizeof(*data));
+
+ /* offset, space, used, count */
-+ if (copy_in_user(data, data32, 4 * 4))
++ if (copy_in_user(data, data32, 4 * sizeof(u32)))
return -EFAULT;
- memset(&data, 0, sizeof(data));
- data.offset = data32.offset;
@@ -131,11 +304,11 @@ diff -u -r1.27 ioctl32.c
- data32.count = data.count;
- //data.pids = data.pids;
- if (copy_to_user((void __user *)arg, &data32, sizeof(data32)))
-+ if (copy_in_user(data32, data, 4 * 4))
++ if (copy_in_user(data32, data, 4 * sizeof(u32)))
return -EFAULT;
return 0;
}
-@@ -170,54 +172,57 @@
+@@ -170,54 +172,59 @@
static inline int _snd_ioctl32_ctl_elem_info(unsigned int fd, unsigned int cmd, unsigned long arg, struct file *file, unsigned int native_ctl)
{
@@ -165,7 +338,8 @@ diff -u -r1.27 ioctl32.c
- err = file->f_op->ioctl(file->f_dentry->d_inode, file, native_ctl, (unsigned long)&data);
- set_fs(oldseg);
+ if (copy_in_user(&data->value.enumerated.item,
-+ &data32->value.enumerated.item, 4))
++ &data32->value.enumerated.item,
++ sizeof(data->value.enumerated.item)))
+ return -EFAULT;
+ err = file->f_op->ioctl(file->f_dentry->d_inode, file, native_ctl, (unsigned long)data);
if (err < 0)
@@ -177,12 +351,13 @@ diff -u -r1.27 ioctl32.c
- data32.count = data.count;
- data32.owner = data.owner;
- switch (data.type) {
-+ /* id, type, access, count */
-+ if (copy_in_user(data32, data, 4 * 4))
-+ return -EFAULT;
+ /* for COPY_CVT macro */
+ src = data;
+ dst = data32;
++ /* id, type, access, count */
++ if (copy_in_user(&data32->id, &data->id, sizeof(data->id)) ||
++ copy_in_user(&data32->type, &data->type, 3 * sizeof(u32)))
++ return -EFAULT;
+ COPY_CVT(owner);
+ __get_user(type, &data->type);
+ switch (type) {
@@ -222,18 +397,50 @@ diff -u -r1.27 ioctl32.c
return 0;
}
-@@ -277,60 +282,85 @@
+@@ -250,24 +257,21 @@
+
+
+ /* hmm, it's so hard to retrieve the value type from the control id.. */
+-static int get_ctl_type(struct file *file, snd_ctl_elem_id_t *id)
++static int get_ctl_type(snd_card_t *card, snd_ctl_elem_id_t *id)
+ {
+- snd_ctl_file_t *ctl;
+ snd_kcontrol_t *kctl;
+ snd_ctl_elem_info_t info;
+ int err;
+
+- ctl = file->private_data;
+-
+- down_read(&ctl->card->controls_rwsem);
+- kctl = snd_ctl_find_id(ctl->card, id);
++ down_read(&card->controls_rwsem);
++ kctl = snd_ctl_find_id(card, id);
+ if (! kctl) {
+- up_read(&ctl->card->controls_rwsem);
++ up_read(&card->controls_rwsem);
+ return -ENXIO;
+ }
+ info.id = *id;
+ err = kctl->info(kctl, &info);
+- up_read(&ctl->card->controls_rwsem);
++ up_read(&card->controls_rwsem);
+ if (err >= 0)
+ err = info.type;
+ return err;
+@@ -277,101 +281,142 @@
static inline int _snd_ioctl32_ctl_elem_value(unsigned int fd, unsigned int cmd, unsigned long arg, struct file *file, unsigned int native_ctl)
{
struct sndrv_ctl_elem_value *data;
- struct sndrv_ctl_elem_value32 *data32;
+ struct sndrv_ctl_elem_value32 __user *data32;
-+ mm_segment_t oldseg;
++ snd_ctl_file_t *ctl = ctl = file->private_data;
int err, i;
int type;
- mm_segment_t oldseg;
- /* FIXME: check the sane ioctl.. */
+- /* FIXME: check the sane ioctl.. */
++ if (ctl == NULL)
++ return -ENXIO;
+ data32 = compat_ptr(arg);
data = kmalloc(sizeof(*data), GFP_KERNEL);
@@ -243,7 +450,7 @@ diff -u -r1.27 ioctl32.c
+ if (data == NULL)
+ return -ENOMEM;
+
-+ if (copy_from_user(&data->id, &data32->id, 4)) {
++ if (copy_from_user(&data->id, &data32->id, sizeof(data->id))) {
+ err = -EFAULT;
goto __end;
}
@@ -258,12 +465,13 @@ diff -u -r1.27 ioctl32.c
- data->indirect = data32->indirect;
- if (data->indirect) /* FIXME: this is not correct for long arrays */
- data->value.integer.value_ptr = compat_ptr(data32->value.integer.value_ptr);
+- type = get_ctl_type(file, &data->id);
+ /* FIXME: indirect access is not supported */
+ if (data->indirect) {
+ err = -EINVAL;
+ goto __end;
+ }
- type = get_ctl_type(file, &data->id);
++ type = get_ctl_type(ctl->card, &data->id);
if (type < 0) {
err = type;
goto __end;
@@ -320,7 +528,7 @@ diff -u -r1.27 ioctl32.c
+ sizeof(data32->value.enumerated.item))) {
+ err = -EFAULT;
+ goto __end;
- }
++ }
+ break;
+ case SNDRV_CTL_ELEM_TYPE_BYTES:
+ if (__copy_from_user(data->value.bytes.data,
@@ -336,7 +544,7 @@ diff -u -r1.27 ioctl32.c
+ sizeof(data32->value.iec958))) {
+ err = -EFAULT;
+ goto __end;
-+ }
+ }
+ break;
+ default:
+ printk(KERN_ERR "snd_ioctl32_ctl_elem_value: unknown type %d\n", type);
@@ -344,8 +552,14 @@ diff -u -r1.27 ioctl32.c
+ goto __end;
}
- oldseg = get_fs();
-@@ -340,38 +370,53 @@
+- 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 (native_ctl == SNDRV_CTL_IOCTL_ELEM_READ)
++ err = snd_ctl_elem_read(ctl->card, data);
++ else
++ err = snd_ctl_elem_write(ctl, data);
if (err < 0)
goto __end;
/* restore info to 32bit */
@@ -391,7 +605,7 @@ diff -u -r1.27 ioctl32.c
+ sizeof(data32->value.integer64.value))) {
+ err = -EFAULT;
+ goto __end;
- }
++ }
+ break;
+ case SNDRV_CTL_ELEM_TYPE_ENUMERATED:
+ if (__copy_to_user(data32->value.enumerated.item,
@@ -407,7 +621,7 @@ diff -u -r1.27 ioctl32.c
+ sizeof(data32->value.bytes.data))) {
+ err = -EFAULT;
+ goto __end;
-+ }
+ }
+ break;
+ case SNDRV_CTL_ELEM_TYPE_IEC958:
+ if (__copy_to_user(&data32->value.iec958,
@@ -433,7 +647,7 @@ RCS file: /suse/tiwai/cvs/alsa/alsa-kernel/core/ioctl32/ioctl32.h,v
retrieving revision 1.14
diff -u -r1.14 ioctl32.h
--- alsa-kernel/core/ioctl32/ioctl32.h 18 Oct 2004 14:31:33 -0000 1.14
-+++ alsa-kernel/core/ioctl32/ioctl32.h 24 Nov 2004 13:49:00 -0000
++++ alsa-kernel/core/ioctl32/ioctl32.h 25 Nov 2004 10:53:58 -0000
@@ -28,20 +28,37 @@
#include <linux/compat.h>
@@ -569,8 +783,8 @@ RCS file: /suse/tiwai/cvs/alsa/alsa-kernel/core/ioctl32/pcm32.c,v
retrieving revision 1.25
diff -u -r1.25 pcm32.c
--- alsa-kernel/core/ioctl32/pcm32.c 18 Oct 2004 14:36:00 -0000 1.25
-+++ alsa-kernel/core/ioctl32/pcm32.c 23 Nov 2004 14:15:56 -0000
-@@ -41,16 +41,13 @@
++++ alsa-kernel/core/ioctl32/pcm32.c 26 Nov 2004 13:47:57 -0000
+@@ -41,23 +41,15 @@
u32 val;
};
@@ -580,20 +794,31 @@ diff -u -r1.25 pcm32.c
+#define CVT_sndrv_pcm_uframes_str() { COPY_CVT(val); }
- struct sndrv_interval32 {
- u32 min, max;
+-struct sndrv_interval32 {
+- u32 min, max;
- unsigned int openmin:1,
- openmax:1,
- integer:1,
- empty:1;
-+ u32 flags; /* bit fields */
- };
-
+-};
+-
struct sndrv_pcm_hw_params32 {
-@@ -73,25 +70,9 @@
+ u32 flags;
+ struct sndrv_mask masks[SNDRV_PCM_HW_PARAM_LAST_MASK - SNDRV_PCM_HW_PARAM_FIRST_MASK + 1]; /* this must be identical */
+ struct sndrv_mask mres[5]; /* reserved masks */
+- struct sndrv_interval32 intervals[SNDRV_PCM_HW_PARAM_LAST_INTERVAL - SNDRV_PCM_HW_PARAM_FIRST_INTERVAL + 1];
++ struct sndrv_interval intervals[SNDRV_PCM_HW_PARAM_LAST_INTERVAL - SNDRV_PCM_HW_PARAM_FIRST_INTERVAL + 1];
+ struct sndrv_interval ires[9]; /* reserved intervals */
+ u32 rmask;
+ u32 cmask;
+@@ -69,31 +61,6 @@
+ unsigned char reserved[64];
+ } __attribute__((packed));
- #define CVT_sndrv_pcm_hw_params()\
- {\
+-#define numberof(array) ARRAY_SIZE(array)
+-
+-#define CVT_sndrv_pcm_hw_params()\
+-{\
- unsigned int i;\
- COPY(flags);\
- for (i = 0; i < numberof(dst->masks); i++)\
@@ -613,13 +838,12 @@ diff -u -r1.25 pcm32.c
- COPY(rate_num);\
- COPY(rate_den);\
- COPY(fifo_size);\
-+ if (copy_in_user(dst, src, sizeof(snd_pcm_hw_params_t) - sizeof(sndrv_pcm_uframes_t) - 64)) \
-+ return -EFAULT;\
-+ COPY_CVT(fifo_size);\
- }
-
+-}
+-
struct sndrv_pcm_sw_params32 {
-@@ -113,13 +94,13 @@
+ s32 tstamp_mode;
+ u32 period_step;
+@@ -113,13 +80,13 @@
COPY(tstamp_mode);\
COPY(period_step);\
COPY(sleep_min);\
@@ -640,7 +864,7 @@ diff -u -r1.25 pcm32.c
}
struct sndrv_pcm_channel_info32 {
-@@ -132,7 +113,7 @@
+@@ -132,7 +99,7 @@
#define CVT_sndrv_pcm_channel_info()\
{\
COPY(channel);\
@@ -649,7 +873,7 @@ diff -u -r1.25 pcm32.c
COPY(first);\
COPY(step);\
}
-@@ -154,16 +135,16 @@
+@@ -154,16 +121,16 @@
#define CVT_sndrv_pcm_status()\
{\
COPY(state);\
@@ -676,42 +900,87 @@ diff -u -r1.25 pcm32.c
COPY(suspended_state);\
}
-@@ -194,41 +175,19 @@
+@@ -173,61 +140,60 @@
+ DEFINE_ALSA_IOCTL(pcm_channel_info);
+ DEFINE_ALSA_IOCTL(pcm_status);
++int snd_pcm_hw_refine(snd_pcm_substream_t *substream, snd_pcm_hw_params_t *params);
++int snd_pcm_hw_params(snd_pcm_substream_t *substream, snd_pcm_hw_params_t *params);
++
+ /* recalcuate the boundary within 32bit */
+-static void recalculate_boundary(struct file *file)
++static void recalculate_boundary(snd_pcm_runtime_t *runtime)
+ {
+- snd_pcm_file_t *pcm_file;
+- snd_pcm_substream_t *substream;
+- snd_pcm_runtime_t *runtime;
+-
+- /* FIXME: need to check whether fop->ioctl is sane */
+- if (! (pcm_file = file->private_data))
+- return;
+- if (! (substream = pcm_file->substream))
+- return;
+- if (! (runtime = substream->runtime))
++ if (! runtime->buffer_size)
+ return;
+ runtime->boundary = runtime->buffer_size;
+ while (runtime->boundary * 2 <= 0x7fffffffUL - runtime->buffer_size)
+ runtime->boundary *= 2;
+ }
+
++/* both for HW_PARAMS and HW_REFINE */
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;
+ struct sndrv_pcm_hw_params32 __user *data32;
-+ struct sndrv_pcm_hw_params __user *data;
+ struct sndrv_pcm_hw_params *data;
+- mm_segment_t oldseg;
++ snd_pcm_file_t *pcm_file;
++ snd_pcm_substream_t *substream;
++ snd_pcm_runtime_t *runtime;
int err;
- data32 = kmalloc(sizeof(*data32), GFP_KERNEL);
-- data = kmalloc(sizeof(*data), GFP_KERNEL);
++ if (! (pcm_file = file->private_data))
++ return -ENXIO;
++ if (! (substream = pcm_file->substream))
++ return -ENXIO;
++ if (! (runtime = substream->runtime))
++ return -ENXIO;
++
++ data32 = compat_ptr(arg);
+ 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;
++ if (data == NULL)
++ return -ENOMEM;
++ if (copy_from_user(data, data32, sizeof(*data32))) {
+ err = -EFAULT;
- goto __end;
-- }
++ goto error;
+ }
- memset(data, 0, sizeof(*data));
-+ data32 = compat_ptr(arg);
-+ data = compat_alloc_user_space(sizeof(*data));
- convert_from_32(pcm_hw_params, data, data32);
+- 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);
+- err = file->f_op->ioctl(file->f_dentry->d_inode, file, native_ctl, (unsigned long)data);
- set_fs(oldseg);
++ if (native_ctl == SNDRV_PCM_IOCTL_HW_REFINE)
++ err = snd_pcm_hw_refine(substream, data);
++ else
++ err = snd_pcm_hw_params(substream, data);
if (err < 0)
- goto __end;
- err = 0;
-+ return err;
- convert_to_32(pcm_hw_params, data32, data);
+- convert_to_32(pcm_hw_params, data32, data);
- if (copy_to_user((void __user *)arg, data32, sizeof(*data32)))
-- err = -EFAULT;
++ goto error;
++ if (copy_to_user(data32, data, sizeof(*data32)) ||
++ __put_user((u32)data->fifo_size, &data32->fifo_size)) {
+ err = -EFAULT;
- else
- recalculate_boundary(file);
- __end:
@@ -719,13 +988,17 @@ diff -u -r1.25 pcm32.c
- kfree(data);
- if (data32)
- kfree(data32);
-- return err;
-+ recalculate_boundary(file);
-+ return 0;
++ goto error;
++ }
++
++ if (native_ctl == SNDRV_PCM_IOCTL_HW_PARAMS)
++ recalculate_boundary(runtime);
++ error:
++ kfree(data);
+ return err;
}
-
-@@ -243,24 +202,24 @@
+@@ -243,24 +209,24 @@
static inline int _snd_ioctl32_xferi(unsigned int fd, unsigned int cmd, unsigned long arg, struct file *file, unsigned int native_ctl)
{
struct sndrv_xferi32 data32;
@@ -761,7 +1034,7 @@ diff -u -r1.25 pcm32.c
if (copy_to_user((void __user *)arg, &data32, sizeof(data32)))
return -EFAULT;
return 0;
-@@ -284,12 +243,11 @@
+@@ -284,12 +250,11 @@
{
snd_pcm_file_t *pcm_file;
snd_pcm_substream_t *substream;
@@ -776,7 +1049,7 @@ diff -u -r1.25 pcm32.c
/* FIXME: need to check whether fop->ioctl is sane */
-@@ -312,22 +270,21 @@
+@@ -312,22 +277,21 @@
}
if ((ch = substream->runtime->channels) > 128)
return -EINVAL;
@@ -804,7 +1077,7 @@ diff -u -r1.25 pcm32.c
switch (native_ctl) {
case SNDRV_PCM_IOCTL_WRITEN_FRAMES:
err = snd_pcm_lib_writev(substream, bufs, data32.frames);
-@@ -336,109 +293,15 @@
+@@ -336,109 +300,15 @@
err = snd_pcm_lib_readv(substream, bufs, data32.frames);
break;
}
@@ -915,7 +1188,7 @@ diff -u -r1.25 pcm32.c
struct sndrv_pcm_mmap_status32 {
s32 state;
s32 pad1;
-@@ -469,15 +332,15 @@
+@@ -469,15 +339,15 @@
COPY(flags);\
COPY(s.status.state);\
COPY(s.status.pad1);\
@@ -937,7 +1210,7 @@ diff -u -r1.25 pcm32.c
/*
*/
-@@ -485,8 +348,6 @@
+@@ -485,8 +355,6 @@
DEFINE_ALSA_IOCTL_ENTRY(pcm_hw_refine, pcm_hw_params, SNDRV_PCM_IOCTL_HW_REFINE);
DEFINE_ALSA_IOCTL_ENTRY(pcm_hw_params, pcm_hw_params, SNDRV_PCM_IOCTL_HW_PARAMS);
DEFINE_ALSA_IOCTL_ENTRY(pcm_sw_params, pcm_sw_params, SNDRV_PCM_IOCTL_SW_PARAMS);
@@ -946,7 +1219,7 @@ diff -u -r1.25 pcm32.c
DEFINE_ALSA_IOCTL_ENTRY(pcm_status, pcm_status, SNDRV_PCM_IOCTL_STATUS);
DEFINE_ALSA_IOCTL_ENTRY(pcm_delay, pcm_sframes_str, SNDRV_PCM_IOCTL_DELAY);
DEFINE_ALSA_IOCTL_ENTRY(pcm_channel_info, pcm_channel_info, SNDRV_PCM_IOCTL_CHANNEL_INFO);
-@@ -538,8 +399,6 @@
+@@ -538,8 +406,6 @@
SNDRV_PCM_IOCTL_READI_FRAMES32 = _IOR('A', 0x51, struct sndrv_xferi32),
SNDRV_PCM_IOCTL_WRITEN_FRAMES32 = _IOW('A', 0x52, struct sndrv_xfern32),
SNDRV_PCM_IOCTL_READN_FRAMES32 = _IOR('A', 0x53, struct sndrv_xfern32),
@@ -955,7 +1228,7 @@ diff -u -r1.25 pcm32.c
SNDRV_PCM_IOCTL_SYNC_PTR32 = _IOWR('A', 0x23, struct sndrv_pcm_sync_ptr32),
};
-@@ -551,8 +410,6 @@
+@@ -551,8 +417,6 @@
MAP_COMPAT(SNDRV_PCM_IOCTL_TSTAMP),
{ SNDRV_PCM_IOCTL_HW_REFINE32, AP(pcm_hw_refine) },
{ SNDRV_PCM_IOCTL_HW_PARAMS32, AP(pcm_hw_params) },
@@ -1064,3 +1337,36 @@ diff -u -r1.8 timer32.c
COPY(resolution);\
COPY(lost);\
COPY(overrun);\
+Index: alsa-kernel/include/control.h
+===================================================================
+RCS file: /suse/tiwai/cvs/alsa/alsa-kernel/include/control.h,v
+retrieving revision 1.9
+diff -u -r1.9 control.h
+--- alsa-kernel/include/control.h 29 Jun 2004 16:01:15 -0000 1.9
++++ alsa-kernel/include/control.h 26 Nov 2004 14:06:21 -0000
+@@ -122,6 +122,10 @@
+ int snd_ctl_register_ioctl(snd_kctl_ioctl_func_t fcn);
+ int snd_ctl_unregister_ioctl(snd_kctl_ioctl_func_t fcn);
+
++/* for ioctl32 */
++int snd_ctl_elem_read(snd_card_t *card, snd_ctl_elem_value_t *control);
++int snd_ctl_elem_write(snd_ctl_file_t *file, snd_ctl_elem_value_t *control);
++
+ static inline unsigned int snd_ctl_get_ioffnum(snd_kcontrol_t *kctl, snd_ctl_elem_id_t *id)
+ {
+ return id->numid - kctl->id.numid;
+Index: alsa-kernel/include/pcm.h
+===================================================================
+RCS file: /suse/tiwai/cvs/alsa/alsa-kernel/include/pcm.h,v
+retrieving revision 1.51
+diff -u -r1.51 pcm.h
+--- alsa-kernel/include/pcm.h 8 Nov 2004 11:39:35 -0000 1.51
++++ alsa-kernel/include/pcm.h 26 Nov 2004 13:41:20 -0000
+@@ -810,6 +810,7 @@
+ int snd_pcm_hw_params_choose(snd_pcm_substream_t *substream, snd_pcm_hw_params_t *params);
+
+ int snd_pcm_hw_refine(snd_pcm_substream_t *substream, snd_pcm_hw_params_t *params);
++int snd_pcm_hw_params(snd_pcm_substream_t *substream, snd_pcm_hw_params_t *params);
+
+ int snd_pcm_hw_constraints_init(snd_pcm_substream_t *substream);
+ int snd_pcm_hw_constraints_complete(snd_pcm_substream_t *substream);