Commit 5c9b7198 authored by Jaroslav Kysela's avatar Jaroslav Kysela

[ALSA] remove obsolete sound/core/ioctl32 directory

The compatibility layer is integrated to ALSA midlevel code now.
parent 5b0bebdc
/* include/version.h. Generated by configure. */
#define CONFIG_SND_VERSION "1.0.8rc2"
#define CONFIG_SND_DATE " (Wed Jan 05 06:44:40 2005 UTC)"
#
# Makefile for ALSA
# Copyright (c) 1999 by Jaroslav Kysela <perex@suse.cz>
#
snd-ioctl32-objs := ioctl32.o pcm32.o rawmidi32.o timer32.o hwdep32.o
ifneq ($(CONFIG_SND_SEQUENCER),n)
snd-ioctl32-objs += seq32.o
endif
obj-$(CONFIG_SND_BIT32_EMUL) += snd-ioctl32.o
/*
* 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
*
*/
#include <sound/driver.h>
#include <linux/time.h>
#include <linux/fs.h>
#include <sound/core.h>
#include <sound/hwdep.h>
#include <asm/uaccess.h>
#include "ioctl32.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 inline int _snd_ioctl32_hwdep_dsp_image(unsigned int fd, unsigned int cmd, unsigned long arg, struct file *file, unsigned int native_ctl)
{
struct sndrv_hwdep_dsp_image __user *data, *dst;
struct sndrv_hwdep_dsp_image32 __user *data32, *src;
compat_caddr_t ptr;
data32 = compat_ptr(arg);
data = compat_alloc_user_space(sizeof(*data));
/* index and name */
if (copy_in_user(data, data32, 4 + 64))
return -EFAULT;
if (__get_user(ptr, &data32->image) ||
__put_user(compat_ptr(ptr), &data->image))
return -EFAULT;
src = data32;
dst = data;
COPY_CVT(length);
COPY_CVT(driver_data);
return file->f_op->ioctl(file->f_dentry->d_inode, file, native_ctl, (unsigned long)data);
}
DEFINE_ALSA_IOCTL_ENTRY(hwdep_dsp_image, hwdep_dsp_image, SNDRV_HWDEP_IOCTL_DSP_LOAD);
#define AP(x) snd_ioctl32_##x
enum {
SNDRV_HWDEP_IOCTL_DSP_LOAD32 = _IOW('H', 0x03, struct sndrv_hwdep_dsp_image32)
};
struct ioctl32_mapper hwdep_mappers[] = {
MAP_COMPAT(SNDRV_HWDEP_IOCTL_PVERSION),
MAP_COMPAT(SNDRV_HWDEP_IOCTL_INFO),
MAP_COMPAT(SNDRV_HWDEP_IOCTL_DSP_STATUS),
{ SNDRV_HWDEP_IOCTL_DSP_LOAD32, AP(hwdep_dsp_image) },
{ 0 },
};
/*
* 32bit -> 64bit ioctl wrapper for control 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
*
*/
#include <sound/driver.h>
#include <linux/sched.h>
#include <linux/smp_lock.h>
#include <linux/init.h>
#include <linux/time.h>
#include <linux/slab.h>
#include <linux/fs.h>
#include <sound/core.h>
#include <sound/control.h>
#include <sound/minors.h>
#include <asm/uaccess.h>
#include "ioctl32.h"
/*
* register/unregister mappers
* exported for other modules
*/
MODULE_AUTHOR("Takashi Iwai <tiwai@suse.de>");
MODULE_DESCRIPTION("ioctl32 wrapper for ALSA");
MODULE_LICENSE("GPL");
int register_ioctl32_conversion(unsigned int cmd, int (*handler)(unsigned int, unsigned int, unsigned long, struct file *));
int unregister_ioctl32_conversion(unsigned int cmd);
int snd_ioctl32_register(struct ioctl32_mapper *mappers)
{
int err;
struct ioctl32_mapper *m;
for (m = mappers; m->cmd; m++) {
err = register_ioctl32_conversion(m->cmd, m->handler);
if (err >= 0)
m->registered++;
}
return 0;
}
void snd_ioctl32_unregister(struct ioctl32_mapper *mappers)
{
struct ioctl32_mapper *m;
for (m = mappers; m->cmd; m++) {
if (m->registered) {
unregister_ioctl32_conversion(m->cmd);
m->registered = 0;
}
}
}
/*
* compatible wrapper
*/
int snd_ioctl32_compat(unsigned int fd, unsigned int cmd, unsigned long arg, struct file *filp)
{
if (! filp->f_op || ! filp->f_op->ioctl)
return -ENOTTY;
return filp->f_op->ioctl(filp->f_dentry->d_inode, filp, cmd, arg);
}
/*
* Controls
*/
struct sndrv_ctl_elem_list32 {
u32 offset;
u32 space;
u32 used;
u32 count;
u32 pids;
unsigned char reserved[50];
} /* don't set packed attribute here */;
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 __user *data32;
struct sndrv_ctl_elem_list __user *data;
compat_caddr_t ptr;
int err;
data32 = compat_ptr(arg);
data = compat_alloc_user_space(sizeof(*data));
/* offset, space, used, count */
if (copy_in_user(data, data32, 4 * sizeof(u32)))
return -EFAULT;
/* pids */
if (__get_user(ptr, &data32->pids) ||
__put_user(compat_ptr(ptr), &data->pids))
return -EFAULT;
err = file->f_op->ioctl(file->f_dentry->d_inode, file, native_ctl, (unsigned long)data);
if (err < 0)
return err;
/* copy the result */
if (copy_in_user(data32, data, 4 * sizeof(u32)))
return -EFAULT;
return 0;
}
DEFINE_ALSA_IOCTL_ENTRY(ctl_elem_list, ctl_elem_list, SNDRV_CTL_IOCTL_ELEM_LIST);
/*
* control element info
* it uses union, so the things are not easy..
*/
struct sndrv_ctl_elem_info32 {
struct sndrv_ctl_elem_id id; // the size of struct is same
s32 type;
u32 access;
u32 count;
s32 owner;
union {
struct {
s32 min;
s32 max;
s32 step;
} integer;
struct {
u64 min;
u64 max;
u64 step;
} integer64;
struct {
u32 items;
u32 item;
char name[64];
} enumerated;
unsigned char reserved[128];
} value;
unsigned char reserved[64];
} __attribute__((packed));
static inline int _snd_ioctl32_ctl_elem_info(unsigned int fd, unsigned int cmd, unsigned long arg, struct file *file, unsigned int native_ctl)
{
struct sndrv_ctl_elem_info __user *data, *src;
struct sndrv_ctl_elem_info32 __user *data32, *dst;
unsigned int type;
int err;
data32 = compat_ptr(arg);
data = compat_alloc_user_space(sizeof(*data));
/* copy id */
if (copy_in_user(&data->id, &data32->id, sizeof(data->id)))
return -EFAULT;
/* we need to copy the item index.
* hope this doesn't break anything..
*/
if (copy_in_user(&data->value.enumerated.item,
&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)
return err;
/* restore info to 32bit */
/* 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) {
case SNDRV_CTL_ELEM_TYPE_BOOLEAN:
case SNDRV_CTL_ELEM_TYPE_INTEGER:
COPY_CVT(value.integer.min);
COPY_CVT(value.integer.max);
COPY_CVT(value.integer.step);
break;
case SNDRV_CTL_ELEM_TYPE_INTEGER64:
if (copy_in_user(&data32->value.integer64,
&data->value.integer64,
sizeof(data->value.integer64)))
return -EFAULT;
break;
case SNDRV_CTL_ELEM_TYPE_ENUMERATED:
if (copy_in_user(&data32->value.enumerated,
&data->value.enumerated,
sizeof(data->value.enumerated)))
return -EFAULT;
break;
default:
break;
}
return 0;
}
DEFINE_ALSA_IOCTL_ENTRY(ctl_elem_info, ctl_elem_info, SNDRV_CTL_IOCTL_ELEM_INFO);
struct sndrv_ctl_elem_value32 {
struct sndrv_ctl_elem_id id;
unsigned int indirect; /* bit-field causes misalignment */
union {
s32 integer[128]; /* integer and boolean need conversion */
#ifndef CONFIG_X86_64
s64 integer64[64]; /* for alignment */
#endif
unsigned char data[512]; /* others should be compatible */
} value;
unsigned char reserved[128]; /* not used */
};
/* hmm, it's so hard to retrieve the value type from the control id.. */
static int get_ctl_type(snd_card_t *card, snd_ctl_elem_id_t *id)
{
snd_kcontrol_t *kctl;
snd_ctl_elem_info_t info;
int err;
down_read(&card->controls_rwsem);
kctl = snd_ctl_find_id(card, id);
if (! kctl) {
up_read(&card->controls_rwsem);
return -ENXIO;
}
info.id = *id;
err = kctl->info(kctl, &info);
up_read(&card->controls_rwsem);
if (err >= 0)
err = info.type;
return err;
}
extern int snd_major;
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 __user *data32;
snd_ctl_file_t *ctl;
int err, i, indirect;
int type;
/* sanity check */
if (imajor(file->f_dentry->d_inode) != snd_major ||
SNDRV_MINOR_DEVICE(iminor(file->f_dentry->d_inode)) != SNDRV_MINOR_CONTROL)
return -ENOTTY;
if ((ctl = file->private_data) == NULL)
return -ENOTTY;
data32 = compat_ptr(arg);
data = kcalloc(1, sizeof(*data), GFP_KERNEL);
if (data == NULL)
return -ENOMEM;
if (copy_from_user(&data->id, &data32->id, sizeof(data->id))) {
err = -EFAULT;
goto __end;
}
if (__get_user(indirect, &data32->indirect)) {
err = -EFAULT;
goto __end;
}
/* FIXME: indirect access is not supported */
if (indirect) {
err = -EINVAL;
goto __end;
}
type = get_ctl_type(ctl->card, &data->id);
if (type < 0) {
err = type;
goto __end;
}
switch (type) {
case SNDRV_CTL_ELEM_TYPE_BOOLEAN:
case SNDRV_CTL_ELEM_TYPE_INTEGER:
for (i = 0; i < 128; i++) {
int val;
if (__get_user(val, &data32->value.integer[i])) {
err = -EFAULT;
goto __end;
}
data->value.integer.value[i] = val;
}
break;
case SNDRV_CTL_ELEM_TYPE_INTEGER64:
case SNDRV_CTL_ELEM_TYPE_ENUMERATED:
case SNDRV_CTL_ELEM_TYPE_BYTES:
case SNDRV_CTL_ELEM_TYPE_IEC958:
if (__copy_from_user(data->value.bytes.data,
data32->value.data,
sizeof(data32->value.data))) {
err = -EFAULT;
goto __end;
}
break;
default:
printk(KERN_ERR "snd_ioctl32_ctl_elem_value: unknown type %d\n", type);
err = -EINVAL;
goto __end;
}
if (native_ctl == SNDRV_CTL_IOCTL_ELEM_READ)
err = snd_ctl_elem_read(ctl->card, data);
else
err = snd_ctl_elem_write(ctl->card, ctl, data);
if (err < 0)
goto __end;
/* restore info to 32bit */
switch (type) {
case SNDRV_CTL_ELEM_TYPE_BOOLEAN:
case SNDRV_CTL_ELEM_TYPE_INTEGER:
for (i = 0; i < 128; i++) {
int val;
val = data->value.integer.value[i];
if (__put_user(val, &data32->value.integer[i])) {
err = -EFAULT;
goto __end;
}
}
break;
default:
if (__copy_to_user(data32->value.data,
data->value.bytes.data,
sizeof(data32->value.data))) {
err = -EFAULT;
goto __end;
}
break;
break;
}
err = 0;
__end:
kfree(data);
return err;
}
DEFINE_ALSA_IOCTL_ENTRY(ctl_elem_read, ctl_elem_value, SNDRV_CTL_IOCTL_ELEM_READ);
DEFINE_ALSA_IOCTL_ENTRY(ctl_elem_write, ctl_elem_value, SNDRV_CTL_IOCTL_ELEM_WRITE);
/*
*/
#define AP(x) snd_ioctl32_##x
enum {
SNDRV_CTL_IOCTL_ELEM_LIST32 = _IOWR('U', 0x10, struct sndrv_ctl_elem_list32),
SNDRV_CTL_IOCTL_ELEM_INFO32 = _IOWR('U', 0x11, struct sndrv_ctl_elem_info32),
SNDRV_CTL_IOCTL_ELEM_READ32 = _IOWR('U', 0x12, struct sndrv_ctl_elem_value32),
SNDRV_CTL_IOCTL_ELEM_WRITE32 = _IOWR('U', 0x13, struct sndrv_ctl_elem_value32),
};
static struct ioctl32_mapper control_mappers[] = {
/* controls (without rawmidi, hwdep, timer releated ones) */
MAP_COMPAT(SNDRV_CTL_IOCTL_PVERSION),
MAP_COMPAT(SNDRV_CTL_IOCTL_CARD_INFO),
{ SNDRV_CTL_IOCTL_ELEM_LIST32, AP(ctl_elem_list) },
{ SNDRV_CTL_IOCTL_ELEM_INFO32, AP(ctl_elem_info) },
{ SNDRV_CTL_IOCTL_ELEM_READ32, AP(ctl_elem_read) },
{ SNDRV_CTL_IOCTL_ELEM_WRITE32, AP(ctl_elem_write) },
MAP_COMPAT(SNDRV_CTL_IOCTL_ELEM_LOCK),
MAP_COMPAT(SNDRV_CTL_IOCTL_ELEM_UNLOCK),
MAP_COMPAT(SNDRV_CTL_IOCTL_SUBSCRIBE_EVENTS),
MAP_COMPAT(SNDRV_CTL_IOCTL_HWDEP_INFO),
MAP_COMPAT(SNDRV_CTL_IOCTL_HWDEP_NEXT_DEVICE),
MAP_COMPAT(SNDRV_CTL_IOCTL_PCM_NEXT_DEVICE),
MAP_COMPAT(SNDRV_CTL_IOCTL_PCM_INFO),
MAP_COMPAT(SNDRV_CTL_IOCTL_PCM_PREFER_SUBDEVICE),
MAP_COMPAT(SNDRV_CTL_IOCTL_POWER),
MAP_COMPAT(SNDRV_CTL_IOCTL_POWER_STATE),
{ 0 }
};
/*
*/
extern struct ioctl32_mapper pcm_mappers[];
extern struct ioctl32_mapper rawmidi_mappers[];
extern struct ioctl32_mapper timer_mappers[];
extern struct ioctl32_mapper hwdep_mappers[];
#if defined(CONFIG_SND_SEQUENCER) || (defined(MODULE) && defined(CONFIG_SND_SEQUENCER_MODULE))
extern struct ioctl32_mapper seq_mappers[];
#endif
static void snd_ioctl32_done(void)
{
#if defined(CONFIG_SND_SEQUENCER) || (defined(MODULE) && defined(CONFIG_SND_SEQUENCER_MODULE))
snd_ioctl32_unregister(seq_mappers);
#endif
snd_ioctl32_unregister(hwdep_mappers);
snd_ioctl32_unregister(timer_mappers);
snd_ioctl32_unregister(rawmidi_mappers);
snd_ioctl32_unregister(pcm_mappers);
snd_ioctl32_unregister(control_mappers);
}
static int __init snd_ioctl32_init(void)
{
snd_ioctl32_register(control_mappers);
snd_ioctl32_register(pcm_mappers);
snd_ioctl32_register(rawmidi_mappers);
snd_ioctl32_register(timer_mappers);
snd_ioctl32_register(hwdep_mappers);
#if defined(CONFIG_SND_SEQUENCER) || (defined(MODULE) && defined(CONFIG_SND_SEQUENCER_MODULE))
snd_ioctl32_register(seq_mappers);
#endif
return 0;
}
module_init(snd_ioctl32_init)
module_exit(snd_ioctl32_done)
/*
* 32bit -> 64bit ioctl helpers
* 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 registers the converters from 32-bit ioctls to 64-bit ones.
* The converter assumes that a 32-bit user-pointer can be casted by compat_ptr(x)
* macro to a valid 64-bit pointer which is accessible via copy_from/to_user.
*
*/
#ifndef __ALSA_IOCTL32_H
#define __ALSA_IOCTL32_H
#include <linux/compat.h>
#define COPY(x) \
do { \
if (copy_in_user(&dst->x, &src->x, sizeof(dst->x))) \
return -EFAULT; \
} while (0)
#define COPY_ARRAY(x) \
do { \
if (copy_in_user(dst->x, src->x, sizeof(dst->x))) \
return -EFAULT; \
} while (0)
#define COPY_CVT(x) \
do { \
__typeof__(src->x) __val_tmp; \
if (get_user(__val_tmp, &src->x) || \
put_user(__val_tmp, &dst->x))\
return -EFAULT; \
} while (0)
#define convert_from_32(type, dstp, srcp)\
{\
struct sndrv_##type __user *dst = dstp;\
struct sndrv_##type##32 __user *src = srcp;\
CVT_##sndrv_##type();\
}
#define convert_to_32(type, dstp, srcp)\
{\
struct sndrv_##type __user *src = srcp;\
struct sndrv_##type##32 __user *dst = dstp;\
CVT_##sndrv_##type();\
}
#define DEFINE_ALSA_IOCTL(type) \
static inline int _snd_ioctl32_##type(unsigned int fd, unsigned int cmd, unsigned long arg, struct file *file, unsigned int native_ctl)\
{\
struct sndrv_##type##32 __user *data32;\
struct sndrv_##type __user *data;\
int err;\
data32 = compat_ptr(arg);\
data = compat_alloc_user_space(sizeof(*data));\
convert_from_32(type, data, data32);\
err = file->f_op->ioctl(file->f_dentry->d_inode, file, native_ctl, (unsigned long)data);\
if (err < 0) \
return err;\
if (native_ctl & (_IOC_READ << _IOC_DIRSHIFT)) {\
convert_to_32(type, data32, data);\
}\
return 0;\
}
#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);\
}
#define MAP_COMPAT(ctl) { ctl, snd_ioctl32_compat }
struct ioctl32_mapper {
unsigned int cmd;
int (*handler)(unsigned int, unsigned int, unsigned long, struct file * filp);
int registered;
};
int snd_ioctl32_compat(unsigned int, unsigned int, unsigned long, struct file *);
int snd_ioctl32_register(struct ioctl32_mapper *mappers);
void snd_ioctl32_unregister(struct ioctl32_mapper *mappers);
#endif /* __ALSA_IOCTL32_H */
/*
* 32bit -> 64bit ioctl wrapper for PCM 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
*
*/
#include <sound/driver.h>
#include <linux/time.h>
#include <linux/slab.h>
#include <linux/compat.h>
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/minors.h>
#include "ioctl32.h"
/* wrapper for sndrv_pcm_[us]frames */
struct sndrv_pcm_sframes_str {
sndrv_pcm_sframes_t val;
};
struct sndrv_pcm_sframes_str32 {
s32 val;
};
struct sndrv_pcm_uframes_str {
sndrv_pcm_uframes_t val;
};
struct sndrv_pcm_uframes_str32 {
u32 val;
};
#define CVT_sndrv_pcm_sframes_str() { COPY_CVT(val); }
#define CVT_sndrv_pcm_uframes_str() { COPY_CVT(val); }
struct sndrv_pcm_hw_params32 {
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_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;
u32 info;
u32 msbits;
u32 rate_num;
u32 rate_den;
u32 fifo_size;
unsigned char reserved[64];
} __attribute__((packed));
struct sndrv_pcm_sw_params32 {
s32 tstamp_mode;
u32 period_step;
u32 sleep_min;
u32 avail_min;
u32 xfer_align;
u32 start_threshold;
u32 stop_threshold;
u32 silence_threshold;
u32 silence_size;
u32 boundary;
unsigned char reserved[64];
} __attribute__((packed));
#define CVT_sndrv_pcm_sw_params()\
{\
COPY(tstamp_mode);\
COPY(period_step);\
COPY(sleep_min);\
COPY_CVT(avail_min);\
COPY_CVT(xfer_align);\
COPY_CVT(start_threshold);\
COPY_CVT(stop_threshold);\
COPY_CVT(silence_threshold);\
COPY_CVT(silence_size);\
COPY_CVT(boundary);\
}
struct sndrv_pcm_channel_info32 {
u32 channel;
u32 offset;
u32 first;
u32 step;
} __attribute__((packed));
#define CVT_sndrv_pcm_channel_info()\
{\
COPY(channel);\
COPY_CVT(offset);\
COPY(first);\
COPY(step);\
}
struct sndrv_pcm_status32 {
s32 state;
struct compat_timespec trigger_tstamp;
struct compat_timespec tstamp;
u32 appl_ptr;
u32 hw_ptr;
s32 delay;
u32 avail;
u32 avail_max;
u32 overrange;
s32 suspended_state;
unsigned char reserved[60];
} __attribute__((packed));
#define CVT_sndrv_pcm_status()\
{\
COPY(state);\
COPY_CVT(trigger_tstamp.tv_sec);\
COPY_CVT(trigger_tstamp.tv_nsec);\
COPY_CVT(tstamp.tv_sec);\
COPY_CVT(tstamp.tv_nsec);\
COPY_CVT(appl_ptr);\
COPY_CVT(hw_ptr);\
COPY_CVT(delay);\
COPY_CVT(avail);\
COPY_CVT(avail_max);\
COPY_CVT(overrange);\
COPY(suspended_state);\
}
DEFINE_ALSA_IOCTL(pcm_uframes_str);
DEFINE_ALSA_IOCTL(pcm_sframes_str);
DEFINE_ALSA_IOCTL(pcm_sw_params);
DEFINE_ALSA_IOCTL(pcm_channel_info);
DEFINE_ALSA_IOCTL(pcm_status);
/* sanity device check */
extern int snd_major;
static int sanity_check_pcm(struct file *file)
{
unsigned short minor;
if (imajor(file->f_dentry->d_inode) != snd_major)
return -ENOTTY;
minor = iminor(file->f_dentry->d_inode);
if (minor >= 256 ||
minor % SNDRV_MINOR_DEVICES < SNDRV_MINOR_PCM_PLAYBACK)
return -ENOTTY;
return 0;
}
/* recalcuate the boundary within 32bit */
static void recalculate_boundary(snd_pcm_runtime_t *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 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 __user *data32;
struct sndrv_pcm_hw_params *data;
snd_pcm_file_t *pcm_file;
snd_pcm_substream_t *substream;
snd_pcm_runtime_t *runtime;
int err;
if (sanity_check_pcm(file))
return -ENOTTY;
if (! (pcm_file = file->private_data))
return -ENOTTY;
if (! (substream = pcm_file->substream))
return -ENOTTY;
if (! (runtime = substream->runtime))
return -ENOTTY;
data32 = compat_ptr(arg);
data = kmalloc(sizeof(*data), GFP_KERNEL);
if (data == NULL)
return -ENOMEM;
if (copy_from_user(data, data32, sizeof(*data32))) {
err = -EFAULT;
goto error;
}
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 error;
if (copy_to_user(data32, data, sizeof(*data32)) ||
__put_user((u32)data->fifo_size, &data32->fifo_size)) {
err = -EFAULT;
goto error;
}
if (native_ctl == SNDRV_PCM_IOCTL_HW_PARAMS)
recalculate_boundary(runtime);
error:
kfree(data);
return err;
}
/*
*/
struct sndrv_xferi32 {
s32 result;
u32 buf;
u32 frames;
} __attribute__((packed));
static int _snd_ioctl32_xferi(unsigned int fd, unsigned int cmd, unsigned long arg, struct file *file, unsigned int native_ctl)
{
struct sndrv_xferi32 data32;
struct sndrv_xferi __user *data;
snd_pcm_sframes_t result;
int err;
if (copy_from_user(&data32, (void __user *)arg, sizeof(data32)))
return -EFAULT;
data = compat_alloc_user_space(sizeof(*data));
if (put_user((snd_pcm_sframes_t)data32.result, &data->result) ||
__put_user(compat_ptr(data32.buf), &data->buf) ||
__put_user((snd_pcm_uframes_t)data32.frames, &data->frames))
return -EFAULT;
err = file->f_op->ioctl(file->f_dentry->d_inode, file, native_ctl, (unsigned long)data);
if (err < 0)
return err;
/* copy the result */
if (__get_user(result, &data->result))
return -EFAULT;
data32.result = result;
if (copy_to_user((void __user *)arg, &data32, sizeof(data32)))
return -EFAULT;
return 0;
}
/* snd_xfern needs remapping of bufs */
struct sndrv_xfern32 {
s32 result;
u32 bufs; /* this is void **; */
u32 frames;
} __attribute__((packed));
/*
* xfern ioctl nees to copy (up to) 128 pointers on stack.
* although we may pass the copied pointers through f_op->ioctl, but the ioctl
* handler there expands again the same 128 pointers on stack, so it is better
* to handle the function (calling pcm_readv/writev) directly in this handler.
*/
static int _snd_ioctl32_xfern(unsigned int fd, unsigned int cmd, unsigned long arg, struct file *file, unsigned int native_ctl)
{
snd_pcm_file_t *pcm_file;
snd_pcm_substream_t *substream;
struct sndrv_xfern32 __user *srcptr = compat_ptr(arg);
struct sndrv_xfern32 data32;
void __user **bufs;
int err = 0, ch, i;
u32 __user *bufptr;
if (sanity_check_pcm(file))
return -ENOTTY;
if (! (pcm_file = file->private_data))
return -ENOTTY;
if (! (substream = pcm_file->substream))
return -ENOTTY;
if (! substream->runtime)
return -ENOTTY;
/* check validty of the command */
switch (native_ctl) {
case SNDRV_PCM_IOCTL_WRITEN_FRAMES:
if (substream->stream != SNDRV_PCM_STREAM_PLAYBACK)
return -EINVAL;
if (substream->runtime->status->state == SNDRV_PCM_STATE_OPEN)
return -EBADFD;
break;
case SNDRV_PCM_IOCTL_READN_FRAMES:
if (substream->stream != SNDRV_PCM_STREAM_CAPTURE)
return -EINVAL;
break;
}
if ((ch = substream->runtime->channels) > 128)
return -EINVAL;
if (copy_from_user(&data32, (void __user *)arg, sizeof(data32)))
return -EFAULT;
bufptr = compat_ptr(data32.bufs);
bufs = kmalloc(sizeof(void __user *) * ch, GFP_KERNEL);
if (bufs == NULL)
return -ENOMEM;
for (i = 0; i < ch; i++) {
u32 ptr;
if (get_user(ptr, bufptr)) {
kfree(bufs);
return -EFAULT;
}
bufs[ch] = compat_ptr(ptr);
bufptr++;
}
switch (native_ctl) {
case SNDRV_PCM_IOCTL_WRITEN_FRAMES:
err = snd_pcm_lib_writev(substream, bufs, data32.frames);
break;
case SNDRV_PCM_IOCTL_READN_FRAMES:
err = snd_pcm_lib_readv(substream, bufs, data32.frames);
break;
}
if (err >= 0) {
if (put_user(err, &srcptr->result))
err = -EFAULT;
}
kfree(bufs);
return err;
}
struct sndrv_pcm_mmap_status32 {
s32 state;
s32 pad1;
u32 hw_ptr;
struct compat_timespec tstamp;
s32 suspended_state;
} __attribute__((packed));
struct sndrv_pcm_mmap_control32 {
u32 appl_ptr;
u32 avail_min;
} __attribute__((packed));
struct sndrv_pcm_sync_ptr32 {
u32 flags;
union {
struct sndrv_pcm_mmap_status32 status;
unsigned char reserved[64];
} s;
union {
struct sndrv_pcm_mmap_control32 control;
unsigned char reserved[64];
} c;
} __attribute__((packed));
#define CVT_sndrv_pcm_sync_ptr()\
{\
COPY(flags);\
COPY(s.status.state);\
COPY(s.status.pad1);\
COPY_CVT(s.status.hw_ptr);\
COPY_CVT(s.status.tstamp.tv_sec);\
COPY_CVT(s.status.tstamp.tv_nsec);\
COPY(s.status.suspended_state);\
COPY_CVT(c.control.appl_ptr);\
COPY_CVT(c.control.avail_min);\
}
DEFINE_ALSA_IOCTL(pcm_sync_ptr);
/*
*/
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);
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);
DEFINE_ALSA_IOCTL_ENTRY(pcm_rewind, pcm_uframes_str, SNDRV_PCM_IOCTL_REWIND);
DEFINE_ALSA_IOCTL_ENTRY(pcm_forward, pcm_uframes_str, SNDRV_PCM_IOCTL_FORWARD);
DEFINE_ALSA_IOCTL_ENTRY(pcm_readi, xferi, SNDRV_PCM_IOCTL_READI_FRAMES);
DEFINE_ALSA_IOCTL_ENTRY(pcm_writei, xferi, SNDRV_PCM_IOCTL_WRITEI_FRAMES);
DEFINE_ALSA_IOCTL_ENTRY(pcm_readn, xfern, SNDRV_PCM_IOCTL_READN_FRAMES);
DEFINE_ALSA_IOCTL_ENTRY(pcm_writen, xfern, SNDRV_PCM_IOCTL_WRITEN_FRAMES);
DEFINE_ALSA_IOCTL_ENTRY(pcm_sync_ptr, pcm_sync_ptr, SNDRV_PCM_IOCTL_SYNC_PTR);
/*
* When PCM is used on 32bit mode, we need to disable
* mmap of PCM status/control records because of the size
* incompatibility.
*
* Since INFO ioctl is always called at first, we mark the
* mmap-disabling in this ioctl wrapper.
*/
static int snd_pcm_info_ioctl32(unsigned int fd, unsigned int cmd, unsigned long arg, struct file *filp)
{
snd_pcm_file_t *pcm_file;
snd_pcm_substream_t *substream;
if (! filp->f_op || ! filp->f_op->ioctl)
return -ENOTTY;
pcm_file = filp->private_data;
if (! pcm_file)
return -ENOTTY;
substream = pcm_file->substream;
if (! substream)
return -ENOTTY;
substream->no_mmap_ctrl = 1;
return filp->f_op->ioctl(filp->f_dentry->d_inode, filp, cmd, arg);
}
/*
*/
#define AP(x) snd_ioctl32_##x
enum {
SNDRV_PCM_IOCTL_HW_REFINE32 = _IOWR('A', 0x10, struct sndrv_pcm_hw_params32),
SNDRV_PCM_IOCTL_HW_PARAMS32 = _IOWR('A', 0x11, struct sndrv_pcm_hw_params32),
SNDRV_PCM_IOCTL_SW_PARAMS32 = _IOWR('A', 0x13, struct sndrv_pcm_sw_params32),
SNDRV_PCM_IOCTL_STATUS32 = _IOR('A', 0x20, struct sndrv_pcm_status32),
SNDRV_PCM_IOCTL_DELAY32 = _IOR('A', 0x21, s32),
SNDRV_PCM_IOCTL_CHANNEL_INFO32 = _IOR('A', 0x32, struct sndrv_pcm_channel_info32),
SNDRV_PCM_IOCTL_REWIND32 = _IOW('A', 0x46, u32),
SNDRV_PCM_IOCTL_FORWARD32 = _IOW('A', 0x49, u32),
SNDRV_PCM_IOCTL_WRITEI_FRAMES32 = _IOW('A', 0x50, struct sndrv_xferi32),
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),
SNDRV_PCM_IOCTL_SYNC_PTR32 = _IOWR('A', 0x23, struct sndrv_pcm_sync_ptr32),
};
struct ioctl32_mapper pcm_mappers[] = {
MAP_COMPAT(SNDRV_PCM_IOCTL_PVERSION),
/* MAP_COMPAT(SNDRV_PCM_IOCTL_INFO), */
{ SNDRV_PCM_IOCTL_INFO, snd_pcm_info_ioctl32 },
MAP_COMPAT(SNDRV_PCM_IOCTL_TSTAMP),
{ SNDRV_PCM_IOCTL_HW_REFINE32, AP(pcm_hw_refine) },
{ SNDRV_PCM_IOCTL_HW_PARAMS32, AP(pcm_hw_params) },
MAP_COMPAT(SNDRV_PCM_IOCTL_HW_FREE),
{ SNDRV_PCM_IOCTL_SW_PARAMS32, AP(pcm_sw_params) },
{ SNDRV_PCM_IOCTL_STATUS32, AP(pcm_status) },
{ SNDRV_PCM_IOCTL_DELAY32, AP(pcm_delay) },
MAP_COMPAT(SNDRV_PCM_IOCTL_HWSYNC),
{ SNDRV_PCM_IOCTL_SYNC_PTR32, AP(pcm_sync_ptr) },
{ SNDRV_PCM_IOCTL_CHANNEL_INFO32, AP(pcm_channel_info) },
MAP_COMPAT(SNDRV_PCM_IOCTL_PREPARE),
MAP_COMPAT(SNDRV_PCM_IOCTL_RESET),
MAP_COMPAT(SNDRV_PCM_IOCTL_START),
MAP_COMPAT(SNDRV_PCM_IOCTL_DROP),
MAP_COMPAT(SNDRV_PCM_IOCTL_DRAIN),
MAP_COMPAT(SNDRV_PCM_IOCTL_PAUSE),
{ SNDRV_PCM_IOCTL_REWIND32, AP(pcm_rewind) },
MAP_COMPAT(SNDRV_PCM_IOCTL_RESUME),
MAP_COMPAT(SNDRV_PCM_IOCTL_XRUN),
{ SNDRV_PCM_IOCTL_FORWARD32, AP(pcm_forward) },
{ SNDRV_PCM_IOCTL_WRITEI_FRAMES32, AP(pcm_writei) },
{ SNDRV_PCM_IOCTL_READI_FRAMES32, AP(pcm_readi) },
{ SNDRV_PCM_IOCTL_WRITEN_FRAMES32, AP(pcm_writen) },
{ SNDRV_PCM_IOCTL_READN_FRAMES32, AP(pcm_readn) },
MAP_COMPAT(SNDRV_PCM_IOCTL_LINK),
MAP_COMPAT(SNDRV_PCM_IOCTL_UNLINK),
{ 0 },
};
/*
* 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
*
*/
#include <sound/driver.h>
#include <linux/time.h>
#include <linux/fs.h>
#include <linux/compat.h>
#include <sound/core.h>
#include <sound/rawmidi.h>
#include <asm/uaccess.h>
#include "ioctl32.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));
#define CVT_sndrv_rawmidi_params()\
{\
COPY(stream);\
COPY_CVT(buffer_size);\
COPY_CVT(avail_min);\
if (copy_in_user(((size_t __user *)&dst->avail_min + 1),\
((size_t __user *)&src->avail_min + 1), 4)) \
return -EFAULT;\
}
struct sndrv_rawmidi_status32 {
s32 stream;
struct compat_timespec tstamp;
u32 avail;
u32 xruns;
unsigned char reserved[16];
} __attribute__((packed));
#define CVT_sndrv_rawmidi_status()\
{\
COPY(stream);\
COPY_CVT(tstamp.tv_sec);\
COPY_CVT(tstamp.tv_nsec);\
COPY_CVT(avail);\
COPY_CVT(xruns);\
}
DEFINE_ALSA_IOCTL(rawmidi_params);
DEFINE_ALSA_IOCTL(rawmidi_status);
DEFINE_ALSA_IOCTL_ENTRY(rawmidi_params, rawmidi_params, SNDRV_RAWMIDI_IOCTL_PARAMS);
DEFINE_ALSA_IOCTL_ENTRY(rawmidi_status, rawmidi_status, SNDRV_RAWMIDI_IOCTL_STATUS);
#define AP(x) snd_ioctl32_##x
enum {
SNDRV_RAWMIDI_IOCTL_PARAMS32 = _IOWR('W', 0x10, struct sndrv_rawmidi_params32),
SNDRV_RAWMIDI_IOCTL_STATUS32 = _IOWR('W', 0x20, struct sndrv_rawmidi_status32),
};
struct ioctl32_mapper rawmidi_mappers[] = {
MAP_COMPAT(SNDRV_RAWMIDI_IOCTL_PVERSION),
MAP_COMPAT(SNDRV_RAWMIDI_IOCTL_INFO),
{ SNDRV_RAWMIDI_IOCTL_PARAMS32, AP(rawmidi_params) },
{ SNDRV_RAWMIDI_IOCTL_STATUS32, AP(rawmidi_status) },
MAP_COMPAT(SNDRV_RAWMIDI_IOCTL_DROP),
MAP_COMPAT(SNDRV_RAWMIDI_IOCTL_DRAIN),
MAP_COMPAT(SNDRV_CTL_IOCTL_RAWMIDI_NEXT_DEVICE),
MAP_COMPAT(SNDRV_CTL_IOCTL_RAWMIDI_INFO),
MAP_COMPAT(SNDRV_CTL_IOCTL_RAWMIDI_PREFER_SUBDEVICE),
{ 0 },
};
/*
* 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
*
*/
#include <sound/driver.h>
#include <linux/time.h>
#include <linux/fs.h>
#include <sound/core.h>
#include <sound/timer.h>
#include <asm/uaccess.h>
#include <sound/asequencer.h>
#include "ioctl32.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 */
};
#define CVT_sndrv_seq_port_info()\
{\
COPY(addr);\
COPY_ARRAY(name);\
COPY(capability);\
COPY(type);\
COPY(midi_channels);\
COPY(midi_voices);\
COPY(synth_voices);\
COPY(read_use);\
COPY(write_use);\
COPY(flags);\
COPY(time_queue);\
}
DEFINE_ALSA_IOCTL(seq_port_info);
DEFINE_ALSA_IOCTL_ENTRY(create_port, seq_port_info, SNDRV_SEQ_IOCTL_CREATE_PORT);
DEFINE_ALSA_IOCTL_ENTRY(delete_port, seq_port_info, SNDRV_SEQ_IOCTL_DELETE_PORT);
DEFINE_ALSA_IOCTL_ENTRY(get_port_info, seq_port_info, SNDRV_SEQ_IOCTL_GET_PORT_INFO);
DEFINE_ALSA_IOCTL_ENTRY(set_port_info, seq_port_info, SNDRV_SEQ_IOCTL_SET_PORT_INFO);
DEFINE_ALSA_IOCTL_ENTRY(query_next_port, seq_port_info, SNDRV_SEQ_IOCTL_QUERY_NEXT_PORT);
/*
*/
#define AP(x) snd_ioctl32_##x
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),
};
struct ioctl32_mapper seq_mappers[] = {
MAP_COMPAT(SNDRV_SEQ_IOCTL_PVERSION),
MAP_COMPAT(SNDRV_SEQ_IOCTL_CLIENT_ID),
MAP_COMPAT(SNDRV_SEQ_IOCTL_SYSTEM_INFO),
MAP_COMPAT(SNDRV_SEQ_IOCTL_GET_CLIENT_INFO),
MAP_COMPAT(SNDRV_SEQ_IOCTL_SET_CLIENT_INFO),
{ SNDRV_SEQ_IOCTL_CREATE_PORT32, AP(create_port) },
{ SNDRV_SEQ_IOCTL_DELETE_PORT32, AP(delete_port) },
{ SNDRV_SEQ_IOCTL_GET_PORT_INFO32, AP(get_port_info) },
{ SNDRV_SEQ_IOCTL_SET_PORT_INFO32, AP(set_port_info) },
MAP_COMPAT(SNDRV_SEQ_IOCTL_SUBSCRIBE_PORT),
MAP_COMPAT(SNDRV_SEQ_IOCTL_UNSUBSCRIBE_PORT),
MAP_COMPAT(SNDRV_SEQ_IOCTL_CREATE_QUEUE),
MAP_COMPAT(SNDRV_SEQ_IOCTL_DELETE_QUEUE),
MAP_COMPAT(SNDRV_SEQ_IOCTL_GET_QUEUE_INFO),
MAP_COMPAT(SNDRV_SEQ_IOCTL_SET_QUEUE_INFO),
MAP_COMPAT(SNDRV_SEQ_IOCTL_GET_NAMED_QUEUE),
MAP_COMPAT(SNDRV_SEQ_IOCTL_GET_QUEUE_STATUS),
MAP_COMPAT(SNDRV_SEQ_IOCTL_GET_QUEUE_TEMPO),
MAP_COMPAT(SNDRV_SEQ_IOCTL_SET_QUEUE_TEMPO),
MAP_COMPAT(SNDRV_SEQ_IOCTL_GET_QUEUE_TIMER),
MAP_COMPAT(SNDRV_SEQ_IOCTL_SET_QUEUE_TIMER),
MAP_COMPAT(SNDRV_SEQ_IOCTL_GET_QUEUE_CLIENT),
MAP_COMPAT(SNDRV_SEQ_IOCTL_SET_QUEUE_CLIENT),
MAP_COMPAT(SNDRV_SEQ_IOCTL_GET_CLIENT_POOL),
MAP_COMPAT(SNDRV_SEQ_IOCTL_SET_CLIENT_POOL),
MAP_COMPAT(SNDRV_SEQ_IOCTL_REMOVE_EVENTS),
MAP_COMPAT(SNDRV_SEQ_IOCTL_QUERY_SUBS),
MAP_COMPAT(SNDRV_SEQ_IOCTL_GET_SUBSCRIPTION),
MAP_COMPAT(SNDRV_SEQ_IOCTL_QUERY_NEXT_CLIENT),
{ SNDRV_SEQ_IOCTL_QUERY_NEXT_PORT32, AP(query_next_port) },
MAP_COMPAT(SNDRV_SEQ_IOCTL_RUNNING_MODE),
{ 0 },
};
/*
* 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
*
*/
#include <sound/driver.h>
#include <linux/time.h>
#include <linux/fs.h>
#include <linux/compat.h>
#include <sound/core.h>
#include <sound/timer.h>
#include <asm/uaccess.h>
#include "ioctl32.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];
};
#define CVT_sndrv_timer_info()\
{\
COPY(flags);\
COPY(card);\
COPY_ARRAY(id);\
COPY_ARRAY(name);\
COPY_CVT(resolution);\
}
struct sndrv_timer_status32 {
struct compat_timespec tstamp;
u32 resolution;
u32 lost;
u32 overrun;
u32 queue;
unsigned char reserved[64];
};
#define CVT_sndrv_timer_status()\
{\
COPY_CVT(tstamp.tv_sec);\
COPY_CVT(tstamp.tv_nsec);\
COPY(resolution);\
COPY(lost);\
COPY(overrun);\
COPY(queue);\
}
DEFINE_ALSA_IOCTL(timer_info);
DEFINE_ALSA_IOCTL(timer_status);
DEFINE_ALSA_IOCTL_ENTRY(timer_info, timer_info, SNDRV_TIMER_IOCTL_INFO);
DEFINE_ALSA_IOCTL_ENTRY(timer_status, timer_status, SNDRV_TIMER_IOCTL_STATUS);
/*
*/
#define AP(x) snd_ioctl32_##x
enum {
SNDRV_TIMER_IOCTL_INFO32 = _IOR('T', 0x11, struct sndrv_timer_info32),
SNDRV_TIMER_IOCTL_STATUS32 = _IOW('T', 0x14, struct sndrv_timer_status32),
};
struct ioctl32_mapper timer_mappers[] = {
MAP_COMPAT(SNDRV_TIMER_IOCTL_PVERSION),
MAP_COMPAT(SNDRV_TIMER_IOCTL_NEXT_DEVICE),
MAP_COMPAT(SNDRV_TIMER_IOCTL_SELECT),
{ SNDRV_TIMER_IOCTL_INFO32, AP(timer_info) },
MAP_COMPAT(SNDRV_TIMER_IOCTL_PARAMS),
{ SNDRV_TIMER_IOCTL_STATUS32, AP(timer_status) },
#if 0
/* ** FIXME **
* The following four entries are disabled because they conflict
* with the TCOC* definitions.
* Unfortunately, the current ioctl32 wrapper uses a single
* hash table for all devices. Once when the wrapper is fixed
* with the table based on devices, they'll be back again.
*/
MAP_COMPAT(SNDRV_TIMER_IOCTL_START),
MAP_COMPAT(SNDRV_TIMER_IOCTL_STOP),
MAP_COMPAT(SNDRV_TIMER_IOCTL_CONTINUE),
MAP_COMPAT(SNDRV_TIMER_IOCTL_PAUSE),
#endif
{ 0 },
};
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment