From: Takashi Iwai <tiwai@suse.de>
To: akpm@osdl.org
Cc: linux-kernel@vger.kernel.org, ak@suse.de, perex@suse.cz
Subject: [PATCH 3/3] Conversion to compat_ioctl for ALSA drivers
Date: Tue, 18 Jan 2005 17:37:22 +0100 [thread overview]
Message-ID: <s5hbrbmwv5p.wl@alsa2.suse.de> (raw)
In-Reply-To: s5hd5w2wv7o.wl@alsa2.suse.de
The last patch covers the rest of ALSA APIs: hwdep, rawmidi, timer and
seq. Also it covers the OSS emulation modules.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
--- linux/sound/core/hwdep.c 30 Nov 2004 19:58:21 -0000 1.24
+++ linux/sound/core/hwdep.c 18 Jan 2005 14:52:43 -0000
@@ -232,8 +232,7 @@
return 0;
}
-static inline int _snd_hwdep_ioctl(struct inode *inode, struct file * file,
- unsigned int cmd, unsigned long arg)
+static long snd_hwdep_ioctl(struct file * file, unsigned int cmd, unsigned long arg)
{
snd_hwdep_t *hw = file->private_data;
void __user *argp = (void __user *)arg;
@@ -252,17 +251,6 @@
return -ENOTTY;
}
-/* FIXME: need to unlock BKL to allow preemption */
-static int snd_hwdep_ioctl(struct inode *inode, struct file * file,
- unsigned int cmd, unsigned long arg)
-{
- int err;
- unlock_kernel();
- err = _snd_hwdep_ioctl(inode, file, cmd, arg);
- lock_kernel();
- return err;
-}
-
static int snd_hwdep_mmap(struct file * file, struct vm_area_struct * vma)
{
snd_hwdep_t *hw = file->private_data;
@@ -315,6 +303,12 @@
return -ENOIOCTLCMD;
}
+#ifdef CONFIG_COMPAT
+#include "hwdep_compat.c"
+#else
+#define snd_hwdep_ioctl_compat NULL
+#endif
+
/*
*/
@@ -328,7 +322,8 @@
.open = snd_hwdep_open,
.release = snd_hwdep_release,
.poll = snd_hwdep_poll,
- .ioctl = snd_hwdep_ioctl,
+ .unlocked_ioctl = snd_hwdep_ioctl,
+ .compat_ioctl = snd_hwdep_ioctl_compat,
.mmap = snd_hwdep_mmap,
};
@@ -509,12 +504,14 @@
}
snd_hwdep_proc_entry = entry;
snd_ctl_register_ioctl(snd_hwdep_control_ioctl);
+ snd_ctl_register_ioctl_compat(snd_hwdep_control_ioctl);
return 0;
}
static void __exit alsa_hwdep_exit(void)
{
snd_ctl_unregister_ioctl(snd_hwdep_control_ioctl);
+ snd_ctl_unregister_ioctl_compat(snd_hwdep_control_ioctl);
if (snd_hwdep_proc_entry) {
snd_info_unregister(snd_hwdep_proc_entry);
snd_hwdep_proc_entry = NULL;
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ linux/sound/core/hwdep_compat.c 18 Jan 2005 14:52:14 -0000
@@ -0,0 +1,77 @@
+/*
+ * 32bit -> 64bit ioctl wrapper for hwdep API
+ * Copyright (c) by Takashi Iwai <tiwai@suse.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+/* This file is included from hwdep.c */
+
+#include <linux/compat.h>
+
+struct sndrv_hwdep_dsp_image32 {
+ u32 index;
+ unsigned char name[64];
+ u32 image; /* pointer */
+ u32 length;
+ u32 driver_data;
+} /* don't set packed attribute here */;
+
+static int snd_hwdep_dsp_load_compat(snd_hwdep_t *hw,
+ struct sndrv_hwdep_dsp_image32 __user *src)
+{
+ struct sndrv_hwdep_dsp_image *dst;
+ compat_caddr_t ptr;
+ u32 val;
+
+ dst = compat_alloc_user_space(sizeof(*dst));
+
+ /* index and name */
+ if (copy_in_user(dst, src, 4 + 64))
+ return -EFAULT;
+ if (get_user(ptr, &src->image) ||
+ put_user(compat_ptr(ptr), &dst->image))
+ return -EFAULT;
+ if (get_user(val, &src->length) ||
+ put_user(val, &dst->length))
+ return -EFAULT;
+ if (get_user(val, &src->driver_data) ||
+ put_user(val, &dst->driver_data))
+ return -EFAULT;
+
+ return snd_hwdep_dsp_load(hw, dst);
+}
+
+enum {
+ SNDRV_HWDEP_IOCTL_DSP_LOAD32 = _IOW('H', 0x03, struct sndrv_hwdep_dsp_image32)
+};
+
+static long snd_hwdep_ioctl_compat(struct file * file, unsigned int cmd, unsigned long arg)
+{
+ snd_hwdep_t *hw = file->private_data;
+ void __user *argp = compat_ptr(arg);
+ switch (cmd) {
+ case SNDRV_HWDEP_IOCTL_PVERSION:
+ case SNDRV_HWDEP_IOCTL_INFO:
+ case SNDRV_HWDEP_IOCTL_DSP_STATUS:
+ return snd_hwdep_ioctl(file, cmd, (unsigned long)argp);
+ case SNDRV_HWDEP_IOCTL_DSP_LOAD32:
+ return snd_hwdep_dsp_load_compat(hw, argp);
+ }
+ if (hw->ops.ioctl_compat)
+ return hw->ops.ioctl_compat(hw, file, cmd, arg);
+ return -ENOIOCTLCMD;
+}
--- linux/sound/core/rawmidi.c 5 Jan 2005 21:55:20 -0000 1.46
+++ linux/sound/core/rawmidi.c 18 Jan 2005 14:52:43 -0000
@@ -673,8 +673,7 @@
return 0;
}
-static inline int _snd_rawmidi_ioctl(struct inode *inode, struct file *file,
- unsigned int cmd, unsigned long arg)
+static long snd_rawmidi_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
snd_rawmidi_file_t *rfile;
void __user *argp = (void __user *)arg;
@@ -784,17 +783,6 @@
return -ENOTTY;
}
-/* FIXME: need to unlock BKL to allow preemption */
-static int snd_rawmidi_ioctl(struct inode *inode, struct file *file,
- unsigned int cmd, unsigned long arg)
-{
- int err;
- unlock_kernel();
- err = _snd_rawmidi_ioctl(inode, file, cmd, arg);
- lock_kernel();
- return err;
-}
-
static int snd_rawmidi_control_ioctl(snd_card_t * card,
snd_ctl_file_t * control,
unsigned int cmd,
@@ -1278,6 +1266,14 @@
}
/*
+ */
+#ifdef CONFIG_COMPAT
+#include "rawmidi_compat.c"
+#else
+#define snd_rawmidi_ioctl_comapt NULL
+#endif
+
+/*
*/
@@ -1347,7 +1343,8 @@
.open = snd_rawmidi_open,
.release = snd_rawmidi_release,
.poll = snd_rawmidi_poll,
- .ioctl = snd_rawmidi_ioctl,
+ .unlocked_ioctl = snd_rawmidi_ioctl,
+ .compat_ioctl = snd_rawmidi_ioctl_compat,
};
static snd_minor_t snd_rawmidi_reg =
@@ -1628,6 +1625,7 @@
{
snd_ctl_register_ioctl(snd_rawmidi_control_ioctl);
+ snd_ctl_register_ioctl_compat(snd_rawmidi_control_ioctl);
#ifdef CONFIG_SND_OSSEMUL
{ int i;
/* check device map table */
@@ -1649,6 +1647,7 @@
static void __exit alsa_rawmidi_exit(void)
{
snd_ctl_unregister_ioctl(snd_rawmidi_control_ioctl);
+ snd_ctl_unregister_ioctl_compat(snd_rawmidi_control_ioctl);
}
module_init(alsa_rawmidi_init)
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ linux/sound/core/rawmidi_compat.c 18 Jan 2005 14:52:14 -0000
@@ -0,0 +1,120 @@
+/*
+ * 32bit -> 64bit ioctl wrapper for raw MIDI API
+ * Copyright (c) by Takashi Iwai <tiwai@suse.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+/* This file included from rawmidi.c */
+
+#include <linux/compat.h>
+
+struct sndrv_rawmidi_params32 {
+ s32 stream;
+ u32 buffer_size;
+ u32 avail_min;
+ unsigned int no_active_sensing; /* avoid bit-field */
+ unsigned char reserved[16];
+} __attribute__((packed));
+
+static int snd_rawmidi_ioctl_params_compat(snd_rawmidi_file_t *rfile,
+ struct sndrv_rawmidi_params32 __user *src)
+{
+ snd_rawmidi_params_t params;
+ unsigned int val;
+
+ if (rfile->output == NULL)
+ return -EINVAL;
+ if (get_user(params.stream, &src->stream) ||
+ get_user(params.buffer_size, &src->buffer_size) ||
+ get_user(params.avail_min, &src->avail_min) ||
+ get_user(val, &src->no_active_sensing))
+ return -EFAULT;
+ params.no_active_sensing = val;
+ switch (params.stream) {
+ case SNDRV_RAWMIDI_STREAM_OUTPUT:
+ return snd_rawmidi_output_params(rfile->output, ¶ms);
+ case SNDRV_RAWMIDI_STREAM_INPUT:
+ return snd_rawmidi_input_params(rfile->input, ¶ms);
+ }
+ return -EINVAL;
+}
+
+struct sndrv_rawmidi_status32 {
+ s32 stream;
+ struct compat_timespec tstamp;
+ u32 avail;
+ u32 xruns;
+ unsigned char reserved[16];
+} __attribute__((packed));
+
+static int snd_rawmidi_ioctl_status_compat(snd_rawmidi_file_t *rfile,
+ struct sndrv_rawmidi_status32 __user *src)
+{
+ int err;
+ snd_rawmidi_status_t status;
+
+ if (rfile->output == NULL)
+ return -EINVAL;
+ if (get_user(status.stream, &src->stream))
+ return -EFAULT;
+
+ switch (status.stream) {
+ case SNDRV_RAWMIDI_STREAM_OUTPUT:
+ err = snd_rawmidi_output_status(rfile->output, &status);
+ break;
+ case SNDRV_RAWMIDI_STREAM_INPUT:
+ err = snd_rawmidi_input_status(rfile->input, &status);
+ break;
+ default:
+ return -EINVAL;
+ }
+ if (err < 0)
+ return err;
+
+ if (put_user(status.tstamp.tv_sec, &src->tstamp.tv_sec) ||
+ put_user(status.tstamp.tv_nsec, &src->tstamp.tv_nsec) ||
+ put_user(status.avail, &src->avail) ||
+ put_user(status.xruns, &src->xruns))
+ return -EFAULT;
+
+ return 0;
+}
+
+enum {
+ SNDRV_RAWMIDI_IOCTL_PARAMS32 = _IOWR('W', 0x10, struct sndrv_rawmidi_params32),
+ SNDRV_RAWMIDI_IOCTL_STATUS32 = _IOWR('W', 0x20, struct sndrv_rawmidi_status32),
+};
+
+static long snd_rawmidi_ioctl_compat(struct file *file, unsigned int cmd, unsigned long arg)
+{
+ snd_rawmidi_file_t *rfile;
+ void __user *argp = compat_ptr(arg);
+
+ rfile = file->private_data;
+ switch (cmd) {
+ case SNDRV_RAWMIDI_IOCTL_PVERSION:
+ case SNDRV_RAWMIDI_IOCTL_INFO:
+ case SNDRV_RAWMIDI_IOCTL_DROP:
+ case SNDRV_RAWMIDI_IOCTL_DRAIN:
+ return snd_rawmidi_ioctl(file, cmd, (unsigned long)argp);
+ case SNDRV_RAWMIDI_IOCTL_PARAMS32:
+ return snd_rawmidi_ioctl_params_compat(rfile, argp);
+ case SNDRV_RAWMIDI_IOCTL_STATUS32:
+ return snd_rawmidi_ioctl_status_compat(rfile, argp);
+ }
+ return -ENOIOCTLCMD;
+}
--- linux/sound/core/timer.c 29 Nov 2004 14:03:52 -0000 1.48
+++ linux/sound/core/timer.c 18 Jan 2005 14:52:43 -0000
@@ -76,7 +76,7 @@
static LIST_HEAD(snd_timer_slave_list);
/* lock for slave active lists */
-static spinlock_t slave_active_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(slave_active_lock);
static DECLARE_MUTEX(register_mutex);
@@ -1653,8 +1653,7 @@
return (err = snd_timer_continue(tu->timeri)) < 0 ? err : 0;
}
-static inline int _snd_timer_user_ioctl(struct inode *inode, struct file *file,
- unsigned int cmd, unsigned long arg)
+static long snd_timer_user_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
snd_timer_user_t *tu;
void __user *argp = (void __user *)arg;
@@ -1701,17 +1700,6 @@
return -ENOTTY;
}
-/* FIXME: need to unlock BKL to allow preemption */
-static int snd_timer_user_ioctl(struct inode *inode, struct file * file,
- unsigned int cmd, unsigned long arg)
-{
- int err;
- unlock_kernel();
- err = _snd_timer_user_ioctl(inode, file, cmd, arg);
- lock_kernel();
- return err;
-}
-
static int snd_timer_user_fasync(int fd, struct file * file, int on)
{
snd_timer_user_t *tu;
@@ -1803,6 +1791,12 @@
return mask;
}
+#ifdef CONFIG_COMPAT
+#include "timer_compat.c"
+#else
+#define snd_timer_user_ioctl_compat NULL
+#endif
+
static struct file_operations snd_timer_f_ops =
{
.owner = THIS_MODULE,
@@ -1810,7 +1804,8 @@
.open = snd_timer_user_open,
.release = snd_timer_user_release,
.poll = snd_timer_user_poll,
- .ioctl = snd_timer_user_ioctl,
+ .unlocked_ioctl = snd_timer_user_ioctl,
+ .compat_ioctl = snd_timer_user_ioctl_compat,
.fasync = snd_timer_user_fasync,
};
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ linux/sound/core/timer_compat.c 18 Jan 2005 14:52:14 -0000
@@ -0,0 +1,119 @@
+/*
+ * 32bit -> 64bit ioctl wrapper for timer API
+ * Copyright (c) by Takashi Iwai <tiwai@suse.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+/* This file included from timer.c */
+
+#include <linux/compat.h>
+
+struct sndrv_timer_info32 {
+ u32 flags;
+ s32 card;
+ unsigned char id[64];
+ unsigned char name[80];
+ u32 reserved0;
+ u32 resolution;
+ unsigned char reserved[64];
+};
+
+static int snd_timer_user_info_compat(struct file *file,
+ struct sndrv_timer_info32 __user *_info)
+{
+ snd_timer_user_t *tu;
+ struct sndrv_timer_info32 info;
+ snd_timer_t *t;
+
+ tu = file->private_data;
+ snd_assert(tu->timeri != NULL, return -ENXIO);
+ t = tu->timeri->timer;
+ snd_assert(t != NULL, return -ENXIO);
+ memset(&info, 0, sizeof(info));
+ info.card = t->card ? t->card->number : -1;
+ if (t->hw.flags & SNDRV_TIMER_HW_SLAVE)
+ info.flags |= SNDRV_TIMER_FLG_SLAVE;
+ strlcpy(info.id, t->id, sizeof(info.id));
+ strlcpy(info.name, t->name, sizeof(info.name));
+ info.resolution = t->hw.resolution;
+ if (copy_to_user(_info, &info, sizeof(*_info)))
+ return -EFAULT;
+ return 0;
+}
+
+struct sndrv_timer_status32 {
+ struct compat_timespec tstamp;
+ u32 resolution;
+ u32 lost;
+ u32 overrun;
+ u32 queue;
+ unsigned char reserved[64];
+};
+
+static int snd_timer_user_status_compat(struct file *file,
+ struct sndrv_timer_status32 __user *_status)
+{
+ snd_timer_user_t *tu;
+ snd_timer_status_t status;
+
+ tu = file->private_data;
+ snd_assert(tu->timeri != NULL, return -ENXIO);
+ memset(&status, 0, sizeof(status));
+ status.tstamp = tu->tstamp;
+ status.resolution = snd_timer_resolution(tu->timeri);
+ status.lost = tu->timeri->lost;
+ status.overrun = tu->overrun;
+ spin_lock_irq(&tu->qlock);
+ status.queue = tu->qused;
+ spin_unlock_irq(&tu->qlock);
+ if (copy_to_user(_status, &status, sizeof(status)))
+ return -EFAULT;
+ return 0;
+}
+
+/*
+ */
+
+enum {
+ SNDRV_TIMER_IOCTL_INFO32 = _IOR('T', 0x11, struct sndrv_timer_info32),
+ SNDRV_TIMER_IOCTL_STATUS32 = _IOW('T', 0x14, struct sndrv_timer_status32),
+};
+
+static long snd_timer_user_ioctl_compat(struct file *file, unsigned int cmd, unsigned long arg)
+{
+ void __user *argp = compat_ptr(arg);
+
+ switch (cmd) {
+ case SNDRV_TIMER_IOCTL_PVERSION:
+ case SNDRV_TIMER_IOCTL_TREAD:
+ case SNDRV_TIMER_IOCTL_GINFO:
+ case SNDRV_TIMER_IOCTL_GPARAMS:
+ case SNDRV_TIMER_IOCTL_GSTATUS:
+ case SNDRV_TIMER_IOCTL_SELECT:
+ case SNDRV_TIMER_IOCTL_PARAMS:
+ case SNDRV_TIMER_IOCTL_START:
+ case SNDRV_TIMER_IOCTL_STOP:
+ case SNDRV_TIMER_IOCTL_CONTINUE:
+ case SNDRV_TIMER_IOCTL_NEXT_DEVICE:
+ return snd_timer_user_ioctl(file, cmd, (unsigned long)argp);
+ case SNDRV_TIMER_IOCTL_INFO32:
+ return snd_timer_user_info_compat(file, argp);
+ case SNDRV_TIMER_IOCTL_STATUS32:
+ return snd_timer_user_status_compat(file, argp);
+ }
+ return -ENOIOCTLCMD;
+}
--- linux/sound/core/oss/mixer_oss.c 30 Nov 2004 19:58:22 -0000 1.33
+++ linux/sound/core/oss/mixer_oss.c 18 Jan 2005 14:44:19 -0000
@@ -359,16 +359,9 @@
return -ENXIO;
}
-/* FIXME: need to unlock BKL to allow preemption */
-static int snd_mixer_oss_ioctl(struct inode *inode, struct file *file,
- unsigned int cmd, unsigned long arg)
+static long snd_mixer_oss_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
- int err;
- /* FIXME: need to unlock BKL to allow preemption */
- unlock_kernel();
- err = snd_mixer_oss_ioctl1((snd_mixer_oss_file_t *) file->private_data, cmd, arg);
- lock_kernel();
- return err;
+ return snd_mixer_oss_ioctl1((snd_mixer_oss_file_t *) file->private_data, cmd, arg);
}
int snd_mixer_oss_ioctl_card(snd_card_t *card, unsigned int cmd, unsigned long arg)
@@ -384,6 +377,13 @@
return snd_mixer_oss_ioctl1(&fmixer, cmd, arg);
}
+#ifdef CONFIG_COMPAT
+/* all compatible */
+#define snd_mixer_oss_ioctl_compat snd_mixer_oss_ioctl
+#else
+#define snd_mixer_oss_ioctl_compat NULL
+#endif
+
/*
* REGISTRATION PART
*/
@@ -393,7 +393,8 @@
.owner = THIS_MODULE,
.open = snd_mixer_oss_open,
.release = snd_mixer_oss_release,
- .ioctl = snd_mixer_oss_ioctl,
+ .unlocked_ioctl = snd_mixer_oss_ioctl,
+ .compat_ioctl = snd_mixer_oss_ioctl_compat,
};
static snd_minor_t snd_mixer_oss_reg =
--- linux/sound/core/oss/pcm_oss.c 30 Nov 2004 19:58:22 -0000 1.68
+++ linux/sound/core/oss/pcm_oss.c 18 Jan 2005 14:45:08 -0000
@@ -1913,8 +1913,7 @@
return 0;
}
-static inline int _snd_pcm_oss_ioctl(struct inode *inode, struct file *file,
- unsigned int cmd, unsigned long arg)
+static long snd_pcm_oss_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
snd_pcm_oss_file_t *pcm_oss_file;
int __user *p = (int __user *)arg;
@@ -2073,16 +2072,12 @@
return -EINVAL;
}
-/* FIXME: need to unlock BKL to allow preemption */
-static int snd_pcm_oss_ioctl(struct inode *inode, struct file *file,
- unsigned int cmd, unsigned long arg)
-{
- int err;
- unlock_kernel();
- err = _snd_pcm_oss_ioctl(inode, file, cmd, arg);
- lock_kernel();
- return err;
-}
+#ifdef CONFIG_COMPAT
+/* all compatible */
+#define snd_pcm_oss_ioctl_compat snd_pcm_oss_ioctl
+#else
+#define snd_pcm_oss_ioctl_compat NULL
+#endif
static ssize_t snd_pcm_oss_read(struct file *file, char __user *buf, size_t count, loff_t *offset)
{
@@ -2410,7 +2405,8 @@
.open = snd_pcm_oss_open,
.release = snd_pcm_oss_release,
.poll = snd_pcm_oss_poll,
- .ioctl = snd_pcm_oss_ioctl,
+ .unlocked_ioctl = snd_pcm_oss_ioctl,
+ .compat_ioctl = snd_pcm_oss_ioctl_compat,
.mmap = snd_pcm_oss_mmap,
};
--- linux/sound/core/seq/seq_clientmgr.c 30 Nov 2004 19:58:22 -0000 1.40
+++ linux/sound/core/seq/seq_clientmgr.c 18 Jan 2005 14:52:51 -0000
@@ -51,7 +51,7 @@
#define SNDRV_SEQ_LFLG_OUTPUT 0x0002
#define SNDRV_SEQ_LFLG_OPEN (SNDRV_SEQ_LFLG_INPUT|SNDRV_SEQ_LFLG_OUTPUT)
-static spinlock_t clients_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(clients_lock);
static DECLARE_MUTEX(register_mutex);
/*
@@ -2131,21 +2131,20 @@
}
-static int snd_seq_ioctl(struct inode *inode, struct file *file,
- unsigned int cmd, unsigned long arg)
+static long snd_seq_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
client_t *client = (client_t *) file->private_data;
- int err;
snd_assert(client != NULL, return -ENXIO);
- /* FIXME: need to unlock BKL to allow preemption */
- unlock_kernel();
- err = snd_seq_do_ioctl(client, cmd, (void __user *) arg);
- lock_kernel();
- return err;
+ return snd_seq_do_ioctl(client, cmd, (void __user *) arg);
}
+#ifdef CONFIG_COMPAT
+#include "seq_compat.c"
+#else
+#define snd_seq_ioctl_compat NULL
+#endif
/* -------------------------------------------------------- */
@@ -2462,7 +2461,8 @@
.open = snd_seq_open,
.release = snd_seq_release,
.poll = snd_seq_poll,
- .ioctl = snd_seq_ioctl,
+ .unlocked_ioctl = snd_seq_ioctl,
+ .compat_ioctl = snd_seq_ioctl_compat,
};
static snd_minor_t snd_seq_reg =
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ linux/sound/core/seq/seq_compat.c 18 Jan 2005 15:37:41 -0000
@@ -0,0 +1,137 @@
+/*
+ * 32bit -> 64bit ioctl wrapper for sequencer API
+ * Copyright (c) by Takashi Iwai <tiwai@suse.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+/* This file included from seq.c */
+
+#include <linux/compat.h>
+
+struct sndrv_seq_port_info32 {
+ struct sndrv_seq_addr addr; /* client/port numbers */
+ char name[64]; /* port name */
+
+ u32 capability; /* port capability bits */
+ u32 type; /* port type bits */
+ s32 midi_channels; /* channels per MIDI port */
+ s32 midi_voices; /* voices per MIDI port */
+ s32 synth_voices; /* voices per SYNTH port */
+
+ s32 read_use; /* R/O: subscribers for output (from this port) */
+ s32 write_use; /* R/O: subscribers for input (to this port) */
+
+ u32 kernel; /* reserved for kernel use (must be NULL) */
+ u32 flags; /* misc. conditioning */
+ unsigned char time_queue; /* queue # for timestamping */
+ char reserved[59]; /* for future use */
+};
+
+static int snd_seq_call_port_info_ioctl(client_t *client, unsigned int cmd,
+ struct sndrv_seq_port_info32 __user *data32)
+{
+ int err = -EFAULT;
+ snd_seq_port_info_t *data;
+ mm_segment_t fs;
+
+ data = kmalloc(sizeof(*data), GFP_KERNEL);
+ if (! data)
+ return -ENOMEM;
+
+ if (copy_from_user(data, data32, sizeof(*data32)) ||
+ get_user(data->flags, &data32->flags) ||
+ get_user(data->time_queue, &data32->time_queue))
+ goto error;
+ data->kernel = NULL;
+
+ fs = snd_enter_user();
+ err = snd_seq_do_ioctl(client, cmd, data);
+ snd_leave_user(fs);
+ if (err < 0)
+ goto error;
+
+ if (copy_to_user(data32, data, sizeof(*data32)) ||
+ put_user(data->flags, &data32->flags) ||
+ put_user(data->time_queue, &data32->time_queue))
+ err = -EFAULT;
+
+ error:
+ kfree(data);
+ return err;
+}
+
+
+
+/*
+ */
+
+enum {
+ SNDRV_SEQ_IOCTL_CREATE_PORT32 = _IOWR('S', 0x20, struct sndrv_seq_port_info32),
+ SNDRV_SEQ_IOCTL_DELETE_PORT32 = _IOW ('S', 0x21, struct sndrv_seq_port_info32),
+ SNDRV_SEQ_IOCTL_GET_PORT_INFO32 = _IOWR('S', 0x22, struct sndrv_seq_port_info32),
+ SNDRV_SEQ_IOCTL_SET_PORT_INFO32 = _IOW ('S', 0x23, struct sndrv_seq_port_info32),
+ SNDRV_SEQ_IOCTL_QUERY_NEXT_PORT32 = _IOWR('S', 0x52, struct sndrv_seq_port_info32),
+};
+
+static long snd_seq_ioctl_compat(struct file *file, unsigned int cmd, unsigned long arg)
+{
+ client_t *client = (client_t *) file->private_data;
+ void __user *argp = compat_ptr(arg);
+
+ snd_assert(client != NULL, return -ENXIO);
+
+ switch (cmd) {
+ case SNDRV_SEQ_IOCTL_PVERSION:
+ case SNDRV_SEQ_IOCTL_CLIENT_ID:
+ case SNDRV_SEQ_IOCTL_SYSTEM_INFO:
+ case SNDRV_SEQ_IOCTL_GET_CLIENT_INFO:
+ case SNDRV_SEQ_IOCTL_SET_CLIENT_INFO:
+ case SNDRV_SEQ_IOCTL_SUBSCRIBE_PORT:
+ case SNDRV_SEQ_IOCTL_UNSUBSCRIBE_PORT:
+ case SNDRV_SEQ_IOCTL_CREATE_QUEUE:
+ case SNDRV_SEQ_IOCTL_DELETE_QUEUE:
+ case SNDRV_SEQ_IOCTL_GET_QUEUE_INFO:
+ case SNDRV_SEQ_IOCTL_SET_QUEUE_INFO:
+ case SNDRV_SEQ_IOCTL_GET_NAMED_QUEUE:
+ case SNDRV_SEQ_IOCTL_GET_QUEUE_STATUS:
+ case SNDRV_SEQ_IOCTL_GET_QUEUE_TEMPO:
+ case SNDRV_SEQ_IOCTL_SET_QUEUE_TEMPO:
+ case SNDRV_SEQ_IOCTL_GET_QUEUE_TIMER:
+ case SNDRV_SEQ_IOCTL_SET_QUEUE_TIMER:
+ case SNDRV_SEQ_IOCTL_GET_QUEUE_CLIENT:
+ case SNDRV_SEQ_IOCTL_SET_QUEUE_CLIENT:
+ case SNDRV_SEQ_IOCTL_GET_CLIENT_POOL:
+ case SNDRV_SEQ_IOCTL_SET_CLIENT_POOL:
+ case SNDRV_SEQ_IOCTL_REMOVE_EVENTS:
+ case SNDRV_SEQ_IOCTL_QUERY_SUBS:
+ case SNDRV_SEQ_IOCTL_GET_SUBSCRIPTION:
+ case SNDRV_SEQ_IOCTL_QUERY_NEXT_CLIENT:
+ case SNDRV_SEQ_IOCTL_RUNNING_MODE:
+ return snd_seq_do_ioctl(client, cmd, argp);
+ case SNDRV_SEQ_IOCTL_CREATE_PORT32:
+ return snd_seq_call_port_info_ioctl(client, SNDRV_SEQ_IOCTL_CREATE_PORT, argp);
+ case SNDRV_SEQ_IOCTL_DELETE_PORT32:
+ return snd_seq_call_port_info_ioctl(client, SNDRV_SEQ_IOCTL_DELETE_PORT, argp);
+ case SNDRV_SEQ_IOCTL_GET_PORT_INFO32:
+ return snd_seq_call_port_info_ioctl(client, SNDRV_SEQ_IOCTL_GET_PORT_INFO, argp);
+ case SNDRV_SEQ_IOCTL_SET_PORT_INFO32:
+ return snd_seq_call_port_info_ioctl(client, SNDRV_SEQ_IOCTL_SET_PORT_INFO, argp);
+ case SNDRV_SEQ_IOCTL_QUERY_NEXT_PORT32:
+ return snd_seq_call_port_info_ioctl(client, SNDRV_SEQ_IOCTL_QUERY_NEXT_PORT, argp);
+ }
+ return -ENOIOCTLCMD;
+}
--- linux/sound/core/seq/oss/seq_oss.c 4 Oct 2004 10:06:21 -0000 1.14
+++ linux/sound/core/seq/oss/seq_oss.c 18 Jan 2005 14:49:15 -0000
@@ -59,7 +59,7 @@
static int odev_release(struct inode *inode, struct file *file);
static ssize_t odev_read(struct file *file, char __user *buf, size_t count, loff_t *offset);
static ssize_t odev_write(struct file *file, const char __user *buf, size_t count, loff_t *offset);
-static int odev_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg);
+static long odev_ioctl(struct file *file, unsigned int cmd, unsigned long arg);
static unsigned int odev_poll(struct file *file, poll_table * wait);
#ifdef CONFIG_PROC_FS
static void info_read(snd_info_entry_t *entry, snd_info_buffer_t *buf);
@@ -177,20 +177,20 @@
return snd_seq_oss_write(dp, buf, count, file);
}
-static int
-odev_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
+static long
+odev_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
seq_oss_devinfo_t *dp;
- int err;
dp = file->private_data;
snd_assert(dp != NULL, return -EIO);
- /* FIXME: need to unlock BKL to allow preemption */
- unlock_kernel();
- err = snd_seq_oss_ioctl(dp, cmd, arg);
- lock_kernel();
- return err;
+ return snd_seq_oss_ioctl(dp, cmd, arg);
}
+#ifdef CONFIG_COMPAT
+#define odev_ioctl_compat odev_ioctl
+#else
+#define odev_ioctl_compat NULL
+#endif
static unsigned int
odev_poll(struct file *file, poll_table * wait)
@@ -213,7 +213,8 @@
.open = odev_open,
.release = odev_release,
.poll = odev_poll,
- .ioctl = odev_ioctl,
+ .unlocked_ioctl = odev_ioctl,
+ .compat_ioctl = odev_ioctl_compat,
};
static snd_minor_t seq_oss_reg = {
--- linux/include/sound/hwdep.h 23 Jun 2004 13:34:03 -0000 1.5
+++ linux/include/sound/hwdep.h 18 Jan 2005 14:53:20 -0000
@@ -38,6 +38,7 @@
int (*release) (snd_hwdep_t * hw, struct file * file);
unsigned int (*poll) (snd_hwdep_t * hw, struct file * file, poll_table * wait);
int (*ioctl) (snd_hwdep_t * hw, struct file * file, unsigned int cmd, unsigned long arg);
+ int (*ioctl_compat) (snd_hwdep_t * hw, struct file * file, unsigned int cmd, unsigned long arg);
int (*mmap) (snd_hwdep_t * hw, struct file * file, struct vm_area_struct * vma);
int (*dsp_status) (snd_hwdep_t * hw, snd_hwdep_dsp_status_t * status);
int (*dsp_load) (snd_hwdep_t * hw, snd_hwdep_dsp_image_t * image);
next prev parent reply other threads:[~2005-01-18 16:46 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2005-01-18 16:32 [PATCH 0/3] Conversion to compat_ioctl for ALSA drivers Takashi Iwai
2005-01-18 16:35 ` [PATCH 1/3] " Takashi Iwai
2005-01-18 16:36 ` [PATCH 2/3] " Takashi Iwai
2005-01-18 16:37 ` Takashi Iwai [this message]
2005-01-18 18:51 ` [PATCH 3/3] Resend: " Takashi Iwai
2005-01-30 18:02 ` [PATCH 0/3] " Brian Gerst
2005-01-31 13:39 ` Takashi Iwai
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=s5hbrbmwv5p.wl@alsa2.suse.de \
--to=tiwai@suse.de \
--cc=ak@suse.de \
--cc=akpm@osdl.org \
--cc=linux-kernel@vger.kernel.org \
--cc=perex@suse.cz \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.