#include <linux/kerneld.h>
#endif
-#if !defined(CONFIG_SND_RTCTIMER) && !defined(CONFIG_SND_RTCTIMER_MODULE)
-#define DEFAULT_TIMER_LIMIT 1
-#else
+#if defined(CONFIG_SND_HPET) || defined(CONFIG_SND_HPET_MODULE)
+#define DEFAULT_TIMER_LIMIT 3
+#elif defined(CONFIG_SND_RTCTIMER) || defined(CONFIG_SND_RTCTIMER_MODULE)
#define DEFAULT_TIMER_LIMIT 2
+#else
+#define DEFAULT_TIMER_LIMIT 1
#endif
static int timer_limit = DEFAULT_TIMER_LIMIT;
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);
static int snd_timer_user_ginfo(struct file *file, snd_timer_ginfo_t __user *_ginfo)
{
- snd_timer_ginfo_t ginfo;
+ snd_timer_ginfo_t *ginfo;
snd_timer_id_t tid;
snd_timer_t *t;
struct list_head *p;
int err = 0;
- if (copy_from_user(&ginfo, _ginfo, sizeof(ginfo)))
+ ginfo = kmalloc(sizeof(*ginfo), GFP_KERNEL);
+ if (! ginfo)
+ return -ENOMEM;
+ if (copy_from_user(ginfo, _ginfo, sizeof(*ginfo))) {
+ kfree(ginfo);
return -EFAULT;
- tid = ginfo.tid;
- memset(&ginfo, 0, sizeof(ginfo));
- ginfo.tid = tid;
+ }
+ tid = ginfo->tid;
+ memset(ginfo, 0, sizeof(*ginfo));
+ ginfo->tid = tid;
down(®ister_mutex);
t = snd_timer_find(&tid);
if (t != NULL) {
- ginfo.card = t->card ? t->card->number : -1;
+ ginfo->card = t->card ? t->card->number : -1;
if (t->hw.flags & SNDRV_TIMER_HW_SLAVE)
- ginfo.flags |= SNDRV_TIMER_FLG_SLAVE;
- strlcpy(ginfo.id, t->id, sizeof(ginfo.id));
- strlcpy(ginfo.name, t->name, sizeof(ginfo.name));
- ginfo.resolution = t->hw.resolution;
+ ginfo->flags |= SNDRV_TIMER_FLG_SLAVE;
+ strlcpy(ginfo->id, t->id, sizeof(ginfo->id));
+ strlcpy(ginfo->name, t->name, sizeof(ginfo->name));
+ ginfo->resolution = t->hw.resolution;
if (t->hw.resolution_min > 0) {
- ginfo.resolution_min = t->hw.resolution_min;
- ginfo.resolution_max = t->hw.resolution_max;
+ ginfo->resolution_min = t->hw.resolution_min;
+ ginfo->resolution_max = t->hw.resolution_max;
}
list_for_each(p, &t->open_list_head) {
- ginfo.clients++;
+ ginfo->clients++;
}
} else {
err = -ENODEV;
}
up(®ister_mutex);
- if (err >= 0 && copy_to_user(_ginfo, &ginfo, sizeof(ginfo)))
+ if (err >= 0 && copy_to_user(_ginfo, ginfo, sizeof(*ginfo)))
err = -EFAULT;
+ kfree(ginfo);
return err;
}
static int snd_timer_user_info(struct file *file, snd_timer_info_t __user *_info)
{
snd_timer_user_t *tu;
- snd_timer_info_t info;
+ snd_timer_info_t *info;
snd_timer_t *t;
+ int err = 0;
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;
+
+ info = kcalloc(1, sizeof(*info), GFP_KERNEL);
+ if (! info)
+ return -ENOMEM;
+ 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;
+ 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)))
+ err = -EFAULT;
+ kfree(info);
+ return err;
}
static int snd_timer_user_params(struct file *file, snd_timer_params_t __user *_params)
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;
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;
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,
.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,
};