Commit e41ecb2c authored by Jaroslav Kysela's avatar Jaroslav Kysela Committed by Linus Torvalds

[PATCH] ALSA update [1/10] - 2002/06/24

  - ioctl32 emulation update
  - intel8x0 driver
    - fixed PCI ID of AMD8111
  - compilation fixes for HDSP
  - fixes for PCI memory allocation
parent 233da397
...@@ -257,7 +257,7 @@ struct sndrv_seq_ev_raw32 { ...@@ -257,7 +257,7 @@ struct sndrv_seq_ev_raw32 {
struct sndrv_seq_ev_ext { struct sndrv_seq_ev_ext {
unsigned int len; /* length of data */ unsigned int len; /* length of data */
void *ptr; /* pointer to data (note: maybe 64-bit) */ void *ptr; /* pointer to data (note: maybe 64-bit) */
}; } __attribute__((packed));
/* Instrument cluster type */ /* Instrument cluster type */
typedef unsigned int sndrv_seq_instr_cluster_t; typedef unsigned int sndrv_seq_instr_cluster_t;
...@@ -373,7 +373,7 @@ struct sndrv_seq_ev_quote { ...@@ -373,7 +373,7 @@ struct sndrv_seq_ev_quote {
struct sndrv_seq_addr origin; /* original sender */ struct sndrv_seq_addr origin; /* original sender */
unsigned short value; /* optional data */ unsigned short value; /* optional data */
struct sndrv_seq_event *event; /* quoted event */ struct sndrv_seq_event *event; /* quoted event */
}; } __attribute__((packed));
/* sequencer event */ /* sequencer event */
...@@ -486,6 +486,16 @@ struct sndrv_seq_system_info { ...@@ -486,6 +486,16 @@ struct sndrv_seq_system_info {
}; };
/* system running information */
struct sndrv_seq_running_info {
unsigned char client; /* client id */
unsigned char big_endian; /* 1 = big-endian */
unsigned char cpu_mode; /* 4 = 32bit, 8 = 64bit */
unsigned char pad; /* reserved */
unsigned char reserved[12];
};
/* known client numbers */ /* known client numbers */
#define SNDRV_SEQ_CLIENT_SYSTEM 0 #define SNDRV_SEQ_CLIENT_SYSTEM 0
#define SNDRV_SEQ_CLIENT_DUMMY 62 /* dummy ports */ #define SNDRV_SEQ_CLIENT_DUMMY 62 /* dummy ports */
...@@ -609,7 +619,6 @@ struct sndrv_seq_port_info { ...@@ -609,7 +619,6 @@ struct sndrv_seq_port_info {
int write_use; /* R/O: subscribers for input (to this port) */ int write_use; /* R/O: subscribers for input (to this port) */
void *kernel; /* reserved for kernel use (must be NULL) */ void *kernel; /* reserved for kernel use (must be NULL) */
unsigned int flags; /* misc. conditioning */ unsigned int flags; /* misc. conditioning */
char reserved[60]; /* for future use */ char reserved[60]; /* for future use */
}; };
...@@ -853,6 +862,7 @@ struct sndrv_seq_instr_cluster_get { ...@@ -853,6 +862,7 @@ struct sndrv_seq_instr_cluster_get {
#define SNDRV_SEQ_IOCTL_PVERSION _IOR ('S', 0x00, int) #define SNDRV_SEQ_IOCTL_PVERSION _IOR ('S', 0x00, int)
#define SNDRV_SEQ_IOCTL_CLIENT_ID _IOR ('S', 0x01, int) #define SNDRV_SEQ_IOCTL_CLIENT_ID _IOR ('S', 0x01, int)
#define SNDRV_SEQ_IOCTL_SYSTEM_INFO _IOWR('S', 0x02, struct sndrv_seq_system_info) #define SNDRV_SEQ_IOCTL_SYSTEM_INFO _IOWR('S', 0x02, struct sndrv_seq_system_info)
#define SNDRV_SEQ_IOCTL_RUNNING_MODE _IOWR('S', 0x03, struct sndrv_seq_running_info)
#define SNDRV_SEQ_IOCTL_GET_CLIENT_INFO _IOWR('S', 0x10, struct sndrv_seq_client_info) #define SNDRV_SEQ_IOCTL_GET_CLIENT_INFO _IOWR('S', 0x10, struct sndrv_seq_client_info)
#define SNDRV_SEQ_IOCTL_SET_CLIENT_INFO _IOW ('S', 0x11, struct sndrv_seq_client_info) #define SNDRV_SEQ_IOCTL_SET_CLIENT_INFO _IOW ('S', 0x11, struct sndrv_seq_client_info)
......
...@@ -50,7 +50,7 @@ ...@@ -50,7 +50,7 @@
*/ */
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 4, 0) #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 4, 0)
#if defined(__i386__) || defined(__ppc__) #if defined(__i386__) || defined(__ppc__) || defined(__x86_64__)
/* /*
* Here a dirty hack for 2.4 kernels.. See sound/core/memory.c. * Here a dirty hack for 2.4 kernels.. See sound/core/memory.c.
*/ */
......
/* include/version.h. Generated automatically by configure. */ /* include/version.h. Generated automatically by configure. */
#define CONFIG_SND_VERSION "0.9.0rc2" #define CONFIG_SND_VERSION "0.9.0rc2"
#define CONFIG_SND_DATE " (Wed Jun 19 08:56:25 2002 UTC)" #define CONFIG_SND_DATE " (Fri Jun 21 12:21:17 2002 UTC)"
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
# #
snd-ioctl32-objs := ioctl32.o pcm32.o rawmidi32.o timer32.o hwdep32.o snd-ioctl32-objs := ioctl32.o pcm32.o rawmidi32.o timer32.o hwdep32.o
ifeq ($(CONFIG_SND_SEQUENCER),y) ifneq ($(CONFIG_SND_SEQUENCER),n)
snd-ioctl32-objs += seq32.o snd-ioctl32-objs += seq32.o
endif endif
......
...@@ -21,6 +21,7 @@ ...@@ -21,6 +21,7 @@
#define __NO_VERSION__ #define __NO_VERSION__
#include <sound/driver.h> #include <sound/driver.h>
#include <linux/smp_lock.h> #include <linux/smp_lock.h>
#include <linux/init.h>
#include <linux/time.h> #include <linux/time.h>
#include <sound/core.h> #include <sound/core.h>
#include <sound/control.h> #include <sound/control.h>
...@@ -32,6 +33,10 @@ ...@@ -32,6 +33,10 @@
* exported for other modules * 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 register_ioctl32_conversion(unsigned int cmd, int (*handler)(unsigned int, unsigned int, unsigned long, struct file *));
int unregister_ioctl32_conversion(unsigned int cmd); int unregister_ioctl32_conversion(unsigned int cmd);
...@@ -79,7 +84,7 @@ struct sndrv_ctl_elem_list32 { ...@@ -79,7 +84,7 @@ struct sndrv_ctl_elem_list32 {
u32 count; u32 count;
u32 pids; u32 pids;
unsigned char reserved[50]; unsigned char reserved[50];
}; } /* don't set packed attribute here */;
#define CVT_sndrv_ctl_elem_list()\ #define CVT_sndrv_ctl_elem_list()\
{\ {\
...@@ -90,8 +95,43 @@ struct sndrv_ctl_elem_list32 { ...@@ -90,8 +95,43 @@ struct sndrv_ctl_elem_list32 {
CPTR(pids);\ CPTR(pids);\
} }
DEFINE_ALSA_IOCTL(ctl_elem_list); static int _snd_ioctl32_ctl_elem_list(unsigned int fd, unsigned int cmd, unsigned long arg, struct file *file, unsigned int native_ctl)
{
struct sndrv_ctl_elem_list32 data32;
struct sndrv_ctl_elem_list data;
mm_segment_t oldseg = get_fs();
int err;
set_fs(KERNEL_DS);
if (copy_from_user(&data32, (void*)arg, sizeof(data32))) {
err = -EFAULT;
goto __err;
}
memset(&data, 0, sizeof(data));
data.offset = data32.offset;
data.space = data32.space;
data.used = data32.used;
data.count = data32.count;
data.pids = A(data32.pids);
err = file->f_op->ioctl(file->f_dentry->d_inode, file, native_ctl, (unsigned long)&data);
if (err < 0)
goto __err;
/* copy the result */
data32.offset = data.offset;
data32.space = data.space;
data32.used = data.used;
data32.count = data.count;
//data.pids = data.pids;
if (copy_to_user((void*)arg, &data32, sizeof(data32))) {
err = -EFAULT;
goto __err;
}
__err:
set_fs(oldseg);
return err;
}
DEFINE_ALSA_IOCTL_ENTRY(ctl_elem_list, ctl_elem_list, SNDRV_CTL_IOCTL_ELEM_LIST);
/* /*
* control element info * control element info
...@@ -123,22 +163,31 @@ struct sndrv_ctl_elem_info32 { ...@@ -123,22 +163,31 @@ struct sndrv_ctl_elem_info32 {
unsigned char reserved[128]; unsigned char reserved[128];
} value; } value;
unsigned char reserved[64]; unsigned char reserved[64];
}; } __attribute__((packed));
static int snd_ioctl32_ctl_elem_info(unsigned int fd, unsigned int cmd, unsigned long arg, struct file *file) static 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 data; struct sndrv_ctl_elem_info data;
struct sndrv_ctl_elem_info32 data32; struct sndrv_ctl_elem_info32 data32;
int err; int err;
mm_segment_t oldseg = get_fs();
if (copy_from_user(&data32, (void*)arg, sizeof(data32))) set_fs(KERNEL_DS);
return -EFAULT; if (copy_from_user(&data32, (void*)arg, sizeof(data32))) {
err = -EFAULT;
goto __err;
}
memset(&data, 0, sizeof(data)); memset(&data, 0, sizeof(data));
data.id = data32.id; data.id = data32.id;
err = file->f_op->ioctl(file->f_dentry->d_inode, file, cmd, (unsigned long)&data); /* we need to copy the item index.
* hope this doesn't break anything..
*/
data.value.enumerated.item = data32.value.enumerated.item;
err = file->f_op->ioctl(file->f_dentry->d_inode, file, native_ctl, (unsigned long)&data);
if (err < 0) if (err < 0)
return err; goto __err;
/* restore info to 32bit */ /* restore info to 32bit */
data32.id = data.id;
data32.type = data.type; data32.type = data.type;
data32.access = data.access; data32.access = data.access;
data32.count = data.count; data32.count = data.count;
...@@ -147,12 +196,12 @@ static int snd_ioctl32_ctl_elem_info(unsigned int fd, unsigned int cmd, unsigned ...@@ -147,12 +196,12 @@ static int snd_ioctl32_ctl_elem_info(unsigned int fd, unsigned int cmd, unsigned
case SNDRV_CTL_ELEM_TYPE_BOOLEAN: case SNDRV_CTL_ELEM_TYPE_BOOLEAN:
case SNDRV_CTL_ELEM_TYPE_INTEGER: case SNDRV_CTL_ELEM_TYPE_INTEGER:
data32.value.integer.min = data.value.integer.min; data32.value.integer.min = data.value.integer.min;
data32.value.integer.max = data.value.integer.min; data32.value.integer.max = data.value.integer.max;
data32.value.integer.step = data.value.integer.step; data32.value.integer.step = data.value.integer.step;
break; break;
case SNDRV_CTL_ELEM_TYPE_INTEGER64: case SNDRV_CTL_ELEM_TYPE_INTEGER64:
data32.value.integer64.min = data.value.integer64.min; data32.value.integer64.min = data.value.integer64.min;
data32.value.integer64.max = data.value.integer64.min; data32.value.integer64.max = data.value.integer64.max;
data32.value.integer64.step = data.value.integer64.step; data32.value.integer64.step = data.value.integer64.step;
break; break;
case SNDRV_CTL_ELEM_TYPE_ENUMERATED: case SNDRV_CTL_ELEM_TYPE_ENUMERATED:
...@@ -165,14 +214,17 @@ static int snd_ioctl32_ctl_elem_info(unsigned int fd, unsigned int cmd, unsigned ...@@ -165,14 +214,17 @@ static int snd_ioctl32_ctl_elem_info(unsigned int fd, unsigned int cmd, unsigned
break; break;
} }
if (copy_to_user((void*)arg, &data32, sizeof(data32))) if (copy_to_user((void*)arg, &data32, sizeof(data32)))
return -EFAULT; err = -EFAULT;
__err:
set_fs(oldseg);
return err; return err;
} }
DEFINE_ALSA_IOCTL_ENTRY(ctl_elem_info, ctl_elem_info, SNDRV_CTL_IOCTL_ELEM_INFO);
struct sndrv_ctl_elem_value32 { struct sndrv_ctl_elem_value32 {
struct sndrv_ctl_elem_id id; struct sndrv_ctl_elem_id id;
unsigned int indirect: 1; unsigned int indirect; /* bit-field causes misalignment */
union { union {
union { union {
s32 value[128]; s32 value[128];
...@@ -193,7 +245,7 @@ struct sndrv_ctl_elem_value32 { ...@@ -193,7 +245,7 @@ struct sndrv_ctl_elem_value32 {
struct sndrv_aes_iec958 iec958; struct sndrv_aes_iec958 iec958;
} value; } value;
unsigned char reserved[128]; unsigned char reserved[128];
}; } __attribute__((packed));
/* hmm, it's so hard to retrieve the value type from the control id.. */ /* hmm, it's so hard to retrieve the value type from the control id.. */
...@@ -221,25 +273,33 @@ static int get_ctl_type(struct file *file, snd_ctl_elem_id_t *id) ...@@ -221,25 +273,33 @@ static int get_ctl_type(struct file *file, snd_ctl_elem_id_t *id)
} }
static int snd_ioctl32_ctl_elem_value(unsigned int fd, unsigned int cmd, unsigned long arg, struct file *file) static int _snd_ioctl32_ctl_elem_value(unsigned int fd, unsigned int cmd, unsigned long arg, struct file *file, unsigned int native_ctl)
{ {
// too big? // too big?
struct sndrv_ctl_elem_value data; struct sndrv_ctl_elem_value data;
struct sndrv_ctl_elem_value32 data32; struct sndrv_ctl_elem_value32 data32;
int err, i; int err, i;
int type; int type;
mm_segment_t oldseg = get_fs();
set_fs(KERNEL_DS);
/* FIXME: check the sane ioctl.. */ /* FIXME: check the sane ioctl.. */
if (copy_from_user(&data32, (void*)arg, sizeof(data32))) if (copy_from_user(&data32, (void*)arg, sizeof(data32))) {
return -EFAULT; err = -EFAULT;
goto __err;
}
memset(&data, 0, sizeof(data)); memset(&data, 0, sizeof(data));
data.id = data32.id; data.id = data32.id;
data.indirect = data32.indirect; data.indirect = data32.indirect;
if (data.indirect) /* FIXME: this is not correct for long arrays */ if (data.indirect) /* FIXME: this is not correct for long arrays */
data.value.integer.value_ptr = (void*)TO_PTR(data32.value.integer.value_ptr); data.value.integer.value_ptr = (void*)TO_PTR(data32.value.integer.value_ptr);
type = get_ctl_type(file, &data.id); type = get_ctl_type(file, &data.id);
if (type < 0) if (type < 0) {
return type; err = type;
goto __err;
}
if (! data.indirect) { if (! data.indirect) {
switch (type) { switch (type) {
case SNDRV_CTL_ELEM_TYPE_BOOLEAN: case SNDRV_CTL_ELEM_TYPE_BOOLEAN:
...@@ -263,45 +323,50 @@ static int snd_ioctl32_ctl_elem_value(unsigned int fd, unsigned int cmd, unsigne ...@@ -263,45 +323,50 @@ static int snd_ioctl32_ctl_elem_value(unsigned int fd, unsigned int cmd, unsigne
data.value.iec958 = data32.value.iec958; data.value.iec958 = data32.value.iec958;
break; break;
default: default:
printk("unknown type %d\n", type);
break; break;
} }
} }
err = file->f_op->ioctl(file->f_dentry->d_inode, file, cmd, (unsigned long)&data); err = file->f_op->ioctl(file->f_dentry->d_inode, file, native_ctl, (unsigned long)&data);
if (err < 0) if (err < 0)
return err; goto __err;
/* restore info to 32bit */ /* restore info to 32bit */
if (! data.indirect) { if (! data.indirect) {
switch (type) { switch (type) {
case SNDRV_CTL_ELEM_TYPE_BOOLEAN: case SNDRV_CTL_ELEM_TYPE_BOOLEAN:
case SNDRV_CTL_ELEM_TYPE_INTEGER: case SNDRV_CTL_ELEM_TYPE_INTEGER:
for (i = 0; i < 128; i++) for (i = 0; i < 128; i++)
data.value.integer.value[i] = data32.value.integer.value[i]; data32.value.integer.value[i] = data.value.integer.value[i];
break; break;
case SNDRV_CTL_ELEM_TYPE_INTEGER64: case SNDRV_CTL_ELEM_TYPE_INTEGER64:
for (i = 0; i < 64; i++) for (i = 0; i < 64; i++)
data.value.integer64.value[i] = data32.value.integer64.value[i]; data32.value.integer64.value[i] = data.value.integer64.value[i];
break; break;
case SNDRV_CTL_ELEM_TYPE_ENUMERATED: case SNDRV_CTL_ELEM_TYPE_ENUMERATED:
for (i = 0; i < 128; i++) for (i = 0; i < 128; i++)
data.value.enumerated.item[i] = data32.value.enumerated.item[i]; data32.value.enumerated.item[i] = data.value.enumerated.item[i];
break; break;
case SNDRV_CTL_ELEM_TYPE_BYTES: case SNDRV_CTL_ELEM_TYPE_BYTES:
memcpy(data.value.bytes.data, data32.value.bytes.data, memcpy(data32.value.bytes.data, data.value.bytes.data,
sizeof(data.value.bytes.data)); sizeof(data.value.bytes.data));
break; break;
case SNDRV_CTL_ELEM_TYPE_IEC958: case SNDRV_CTL_ELEM_TYPE_IEC958:
data.value.iec958 = data32.value.iec958; data32.value.iec958 = data.value.iec958;
break; break;
default: default:
break; break;
} }
} }
if (copy_to_user((void*)arg, &data32, sizeof(data32))) if (copy_to_user((void*)arg, &data32, sizeof(data32)))
return -EFAULT; err = -EFAULT;
__err:
set_fs(oldseg);
return err; 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);
/* /*
*/ */
...@@ -321,8 +386,8 @@ static struct ioctl32_mapper control_mappers[] = { ...@@ -321,8 +386,8 @@ static struct ioctl32_mapper control_mappers[] = {
{ SNDRV_CTL_IOCTL_CARD_INFO , NULL }, { SNDRV_CTL_IOCTL_CARD_INFO , NULL },
{ SNDRV_CTL_IOCTL_ELEM_LIST32, AP(ctl_elem_list) }, { SNDRV_CTL_IOCTL_ELEM_LIST32, AP(ctl_elem_list) },
{ SNDRV_CTL_IOCTL_ELEM_INFO32, AP(ctl_elem_info) }, { SNDRV_CTL_IOCTL_ELEM_INFO32, AP(ctl_elem_info) },
{ SNDRV_CTL_IOCTL_ELEM_READ32, AP(ctl_elem_value) }, { SNDRV_CTL_IOCTL_ELEM_READ32, AP(ctl_elem_read) },
{ SNDRV_CTL_IOCTL_ELEM_WRITE32, AP(ctl_elem_value) }, { SNDRV_CTL_IOCTL_ELEM_WRITE32, AP(ctl_elem_write) },
{ SNDRV_CTL_IOCTL_ELEM_LOCK, NULL }, { SNDRV_CTL_IOCTL_ELEM_LOCK, NULL },
{ SNDRV_CTL_IOCTL_ELEM_UNLOCK, NULL }, { SNDRV_CTL_IOCTL_ELEM_UNLOCK, NULL },
{ SNDRV_CTL_IOCTL_SUBSCRIBE_EVENTS, NULL }, { SNDRV_CTL_IOCTL_SUBSCRIBE_EVENTS, NULL },
...@@ -393,6 +458,7 @@ static int __init snd_ioctl32_init(void) ...@@ -393,6 +458,7 @@ static int __init snd_ioctl32_init(void)
return err; return err;
} }
#endif #endif
return 0;
} }
module_init(snd_ioctl32_init) module_init(snd_ioctl32_init)
......
...@@ -26,6 +26,15 @@ ...@@ -26,6 +26,15 @@
#ifndef __ALSA_IOCTL32_H #ifndef __ALSA_IOCTL32_H
#define __ALSA_IOCTL32_H #define __ALSA_IOCTL32_H
#ifndef A
#ifdef CONFIG_PPC64
#include <asm/ppc32.h>
#else
/* x86-64, sparc64 */
#define A(__x) ((void *)(unsigned long)(__x))
#endif
#endif
#define TO_PTR(x) A(x) #define TO_PTR(x) A(x)
#define COPY(x) (dst->x = src->x) #define COPY(x) (dst->x = src->x)
...@@ -47,26 +56,39 @@ ...@@ -47,26 +56,39 @@
#define DEFINE_ALSA_IOCTL(type) \ #define DEFINE_ALSA_IOCTL(type) \
static int snd_ioctl32_##type(unsigned int fd, unsigned int cmd, unsigned long arg, struct file *file)\ static int _snd_ioctl32_##type(unsigned int fd, unsigned int cmd, unsigned long arg, struct file *file, unsigned int native_ctl)\
{\ {\
struct sndrv_##type##32 data32;\ struct sndrv_##type##32 data32;\
struct sndrv_##type data;\ struct sndrv_##type data;\
mm_segment_t oldseg = get_fs();\
int err;\ int err;\
if (copy_from_user(&data32, (void*)arg, sizeof(data32)))\ set_fs(KERNEL_DS);\
return -EFAULT;\ if (copy_from_user(&data32, (void*)arg, sizeof(data32))) {\
err = -EFAULT;\
goto __err;\
}\
memset(&data, 0, sizeof(data));\ memset(&data, 0, sizeof(data));\
convert_from_32(type, &data, &data32);\ convert_from_32(type, &data, &data32);\
err = file->f_op->ioctl(file->f_dentry->d_inode, file, cmd, (unsigned long)&data);\ err = file->f_op->ioctl(file->f_dentry->d_inode, file, native_ctl, (unsigned long)&data);\
if (err < 0)\ if (err < 0) \
return err;\ goto __err;\
if (cmd & (_IOC_READ << _IOC_DIRSHIFT)) {\ if (native_ctl & (_IOC_READ << _IOC_DIRSHIFT)) {\
convert_to_32(type, &data32, &data);\ convert_to_32(type, &data32, &data);\
if (copy_to_user((void*)arg, &data32, sizeof(data32)))\ if (copy_to_user((void*)arg, &data32, sizeof(data32))) {\
return -EFAULT;\ err = -EFAULT;\
goto __err;\
}\
}\ }\
__err: set_fs(oldseg);\
return err;\ return err;\
} }
#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);\
}
struct ioctl32_mapper { struct ioctl32_mapper {
unsigned int cmd; unsigned int cmd;
int (*handler)(unsigned int, unsigned int, unsigned long, struct file * filp); int (*handler)(unsigned int, unsigned int, unsigned long, struct file * filp);
......
...@@ -54,7 +54,7 @@ struct sndrv_interval32 { ...@@ -54,7 +54,7 @@ struct sndrv_interval32 {
struct sndrv_pcm_hw_params32 { struct sndrv_pcm_hw_params32 {
u32 flags; u32 flags;
u32 masks[SNDRV_PCM_HW_PARAM_LAST_MASK - SNDRV_PCM_HW_PARAM_FIRST_MASK + 1]; struct sndrv_mask masks[SNDRV_PCM_HW_PARAM_LAST_MASK - SNDRV_PCM_HW_PARAM_FIRST_MASK + 1]; /* this must be identical */
struct sndrv_interval32 intervals[SNDRV_PCM_HW_PARAM_LAST_INTERVAL - SNDRV_PCM_HW_PARAM_FIRST_INTERVAL + 1]; struct sndrv_interval32 intervals[SNDRV_PCM_HW_PARAM_LAST_INTERVAL - SNDRV_PCM_HW_PARAM_FIRST_INTERVAL + 1];
u32 rmask; u32 rmask;
u32 cmask; u32 cmask;
...@@ -64,7 +64,7 @@ struct sndrv_pcm_hw_params32 { ...@@ -64,7 +64,7 @@ struct sndrv_pcm_hw_params32 {
u32 rate_den; u32 rate_den;
u32 fifo_size; u32 fifo_size;
unsigned char reserved[64]; unsigned char reserved[64];
}; } __attribute__((packed));
#define numberof(array) (sizeof(array)/sizeof(array[0])) #define numberof(array) (sizeof(array)/sizeof(array[0]))
...@@ -103,7 +103,7 @@ struct sndrv_pcm_sw_params32 { ...@@ -103,7 +103,7 @@ struct sndrv_pcm_sw_params32 {
u32 silence_size; u32 silence_size;
u32 boundary; u32 boundary;
unsigned char reserved[64]; unsigned char reserved[64];
}; } __attribute__((packed));
#define CVT_sndrv_pcm_sw_params()\ #define CVT_sndrv_pcm_sw_params()\
{\ {\
...@@ -124,7 +124,7 @@ struct sndrv_pcm_channel_info32 { ...@@ -124,7 +124,7 @@ struct sndrv_pcm_channel_info32 {
u32 offset; u32 offset;
u32 first; u32 first;
u32 step; u32 step;
}; } __attribute__((packed));
#define CVT_sndrv_pcm_channel_info()\ #define CVT_sndrv_pcm_channel_info()\
{\ {\
...@@ -137,7 +137,7 @@ struct sndrv_pcm_channel_info32 { ...@@ -137,7 +137,7 @@ struct sndrv_pcm_channel_info32 {
struct timeval32 { struct timeval32 {
s32 tv_sec; s32 tv_sec;
s32 tv_usec; s32 tv_usec;
}; } __attribute__((packed));
struct sndrv_pcm_status32 { struct sndrv_pcm_status32 {
s32 state; s32 state;
...@@ -151,7 +151,7 @@ struct sndrv_pcm_status32 { ...@@ -151,7 +151,7 @@ struct sndrv_pcm_status32 {
u32 overrange; u32 overrange;
s32 suspended_state; s32 suspended_state;
unsigned char reserved[60]; unsigned char reserved[60];
}; } __attribute__((packed));
#define CVT_sndrv_pcm_status()\ #define CVT_sndrv_pcm_status()\
{\ {\
...@@ -169,33 +169,58 @@ struct sndrv_pcm_status32 { ...@@ -169,33 +169,58 @@ struct sndrv_pcm_status32 {
COPY(suspended_state);\ COPY(suspended_state);\
} }
DEFINE_ALSA_IOCTL(pcm_uframes_str);
DEFINE_ALSA_IOCTL(pcm_sframes_str);
DEFINE_ALSA_IOCTL(pcm_hw_params);
DEFINE_ALSA_IOCTL(pcm_sw_params);
DEFINE_ALSA_IOCTL(pcm_channel_info);
DEFINE_ALSA_IOCTL(pcm_status);
/*
*/
struct sndrv_xferi32 { struct sndrv_xferi32 {
s32 result; s32 result;
u32 buf; u32 buf;
u32 frames; u32 frames;
}; } __attribute__((packed));
#define CVT_sndrv_xferi()\ static int _snd_ioctl32_xferi(unsigned int fd, unsigned int cmd, unsigned long arg, struct file *file, unsigned int native_ctl)
{\ {
COPY(result);\ struct sndrv_xferi32 data32;
CPTR(buf);\ struct sndrv_xferi data;
COPY(frames);\ mm_segment_t oldseg = get_fs();
int err;
set_fs(KERNEL_DS);
if (copy_from_user(&data32, (void*)arg, sizeof(data32))) {
err = -EFAULT;
goto __err;
}
memset(&data, 0, sizeof(data));
data.result = data32.result;
data.buf = A(data32.buf);
data.frames = data32.frames;
err = file->f_op->ioctl(file->f_dentry->d_inode, file, native_ctl, (unsigned long)&data);
if (err < 0)
goto __err;
/* copy the result */
data32.result = data.result;
if (copy_to_user((void*)arg, &data32, sizeof(data32))) {
err = -EFAULT;
goto __err;
}
__err:
set_fs(oldseg);
return err;
} }
DEFINE_ALSA_IOCTL(pcm_uframes_str);
DEFINE_ALSA_IOCTL(pcm_sframes_str);
DEFINE_ALSA_IOCTL(pcm_hw_params);
DEFINE_ALSA_IOCTL(pcm_sw_params);
DEFINE_ALSA_IOCTL(pcm_channel_info);
DEFINE_ALSA_IOCTL(pcm_status);
DEFINE_ALSA_IOCTL(xferi);
/* snd_xfern needs remapping of bufs */ /* snd_xfern needs remapping of bufs */
struct sndrv_xfern32 { struct sndrv_xfern32 {
s32 result; s32 result;
u32 bufs; /* this is void **; */ u32 bufs; /* this is void **; */
u32 frames; u32 frames;
}; } __attribute__((packed));
/* /*
* xfern ioctl nees to copy (up to) 128 pointers on stack. * xfern ioctl nees to copy (up to) 128 pointers on stack.
...@@ -203,7 +228,7 @@ struct sndrv_xfern32 { ...@@ -203,7 +228,7 @@ struct sndrv_xfern32 {
* handler there expands again the same 128 pointers on stack, so it is better * 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. * 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) 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_file_t *pcm_file;
snd_pcm_substream_t *substream; snd_pcm_substream_t *substream;
...@@ -211,6 +236,9 @@ static int snd_ioctl32_xfern(unsigned int fd, unsigned int cmd, unsigned long ar ...@@ -211,6 +236,9 @@ static int snd_ioctl32_xfern(unsigned int fd, unsigned int cmd, unsigned long ar
void *bufs[128]; void *bufs[128];
int err = 0, ch, i; int err = 0, ch, i;
u32 *bufptr; u32 *bufptr;
mm_segment_t oldseg = get_fs();
set_fs(KERNEL_DS);
/* FIXME: need to check whether fop->ioctl is sane */ /* FIXME: need to check whether fop->ioctl is sane */
...@@ -219,31 +247,44 @@ static int snd_ioctl32_xfern(unsigned int fd, unsigned int cmd, unsigned long ar ...@@ -219,31 +247,44 @@ static int snd_ioctl32_xfern(unsigned int fd, unsigned int cmd, unsigned long ar
snd_assert(substream != NULL && substream->runtime, return -ENXIO); snd_assert(substream != NULL && substream->runtime, return -ENXIO);
/* check validty of the command */ /* check validty of the command */
switch (cmd) { switch (native_ctl) {
case SNDRV_PCM_IOCTL_WRITEN_FRAMES: case SNDRV_PCM_IOCTL_WRITEN_FRAMES:
if (substream->stream != SNDRV_PCM_STREAM_PLAYBACK) if (substream->stream != SNDRV_PCM_STREAM_PLAYBACK) {
return -EINVAL; err = -EINVAL;
if (substream->runtime->status->state == SNDRV_PCM_STATE_OPEN) goto __err;
return -EBADFD; }
if (substream->runtime->status->state == SNDRV_PCM_STATE_OPEN) {
err = -EBADFD;
goto __err;
}
break;
case SNDRV_PCM_IOCTL_READN_FRAMES: case SNDRV_PCM_IOCTL_READN_FRAMES:
if (substream->stream != SNDRV_PCM_STREAM_CAPTURE) if (substream->stream != SNDRV_PCM_STREAM_CAPTURE) {
return -EINVAL; err = -EINVAL;
goto __err;
}
break; break;
} }
if ((ch = substream->runtime->channels) > 128) if ((ch = substream->runtime->channels) > 128) {
return -EINVAL; err = -EINVAL;
if (get_user(data32.frames, &srcptr->frames)) goto __err;
return -EFAULT; }
if (get_user(data32.frames, &srcptr->frames)) {
err = -EFAULT;
goto __err;
}
__get_user(data32.bufs, &srcptr->bufs); __get_user(data32.bufs, &srcptr->bufs);
bufptr = (u32*)TO_PTR(data32.bufs); bufptr = (u32*)TO_PTR(data32.bufs);
for (i = 0; i < ch; i++) { for (i = 0; i < ch; i++) {
u32 ptr; u32 ptr;
if (get_user(ptr, bufptr)) if (get_user(ptr, bufptr)) {
return -EFAULT; err = -EFAULT;
goto __err;
}
bufs[ch] = (void*)TO_PTR(ptr); bufs[ch] = (void*)TO_PTR(ptr);
bufptr++; bufptr++;
} }
switch (cmd) { switch (native_ctl) {
case SNDRV_PCM_IOCTL_WRITEN_FRAMES: case SNDRV_PCM_IOCTL_WRITEN_FRAMES:
err = snd_pcm_lib_writev(substream, bufs, data32.frames); err = snd_pcm_lib_writev(substream, bufs, data32.frames);
break; break;
...@@ -253,13 +294,33 @@ static int snd_ioctl32_xfern(unsigned int fd, unsigned int cmd, unsigned long ar ...@@ -253,13 +294,33 @@ static int snd_ioctl32_xfern(unsigned int fd, unsigned int cmd, unsigned long ar
} }
if (err < 0) if (err < 0)
return err; goto __err;
if (put_user(err, &srcptr->result)) if (put_user(err, &srcptr->result))
return -EFAULT; err = -EFAULT;
__err:
set_fs(oldseg);
return err < 0 ? err : 0; return err < 0 ? err : 0;
} }
/*
*/
DEFINE_ALSA_IOCTL_ENTRY(pcm_hw_refine, pcm_hw_params, SNDRV_PCM_IOCTL_HW_REFINE);
DEFINE_ALSA_IOCTL_ENTRY(pcm_sw_params, pcm_sw_params, SNDRV_PCM_IOCTL_SW_PARAMS);
DEFINE_ALSA_IOCTL_ENTRY(pcm_hw_params, pcm_hw_params, SNDRV_PCM_IOCTL_HW_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_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 AP(x) snd_ioctl32_##x #define AP(x) snd_ioctl32_##x
enum { enum {
...@@ -279,12 +340,12 @@ enum { ...@@ -279,12 +340,12 @@ enum {
struct ioctl32_mapper pcm_mappers[] = { struct ioctl32_mapper pcm_mappers[] = {
{ SNDRV_PCM_IOCTL_PVERSION, NULL }, { SNDRV_PCM_IOCTL_PVERSION, NULL },
{ SNDRV_PCM_IOCTL_INFO, NULL }, { SNDRV_PCM_IOCTL_INFO, NULL },
{ SNDRV_PCM_IOCTL_HW_REFINE32, AP(pcm_hw_params) }, { SNDRV_PCM_IOCTL_HW_REFINE32, AP(pcm_hw_refine) },
{ SNDRV_PCM_IOCTL_HW_PARAMS32, AP(pcm_hw_params) }, { SNDRV_PCM_IOCTL_HW_PARAMS32, AP(pcm_hw_params) },
{ SNDRV_PCM_IOCTL_HW_FREE, NULL }, { SNDRV_PCM_IOCTL_HW_FREE, NULL },
{ SNDRV_PCM_IOCTL_SW_PARAMS32, AP(pcm_sw_params) }, { SNDRV_PCM_IOCTL_SW_PARAMS32, AP(pcm_sw_params) },
{ SNDRV_PCM_IOCTL_STATUS32, AP(pcm_status) }, { SNDRV_PCM_IOCTL_STATUS32, AP(pcm_status) },
{ SNDRV_PCM_IOCTL_DELAY32, AP(pcm_sframes_str) }, { SNDRV_PCM_IOCTL_DELAY32, AP(pcm_delay) },
{ SNDRV_PCM_IOCTL_CHANNEL_INFO32, AP(pcm_channel_info) }, { SNDRV_PCM_IOCTL_CHANNEL_INFO32, AP(pcm_channel_info) },
{ SNDRV_PCM_IOCTL_PREPARE, NULL }, { SNDRV_PCM_IOCTL_PREPARE, NULL },
{ SNDRV_PCM_IOCTL_RESET, NULL }, { SNDRV_PCM_IOCTL_RESET, NULL },
...@@ -292,13 +353,13 @@ struct ioctl32_mapper pcm_mappers[] = { ...@@ -292,13 +353,13 @@ struct ioctl32_mapper pcm_mappers[] = {
{ SNDRV_PCM_IOCTL_DROP, NULL }, { SNDRV_PCM_IOCTL_DROP, NULL },
{ SNDRV_PCM_IOCTL_DRAIN, NULL }, { SNDRV_PCM_IOCTL_DRAIN, NULL },
{ SNDRV_PCM_IOCTL_PAUSE, NULL }, { SNDRV_PCM_IOCTL_PAUSE, NULL },
{ SNDRV_PCM_IOCTL_REWIND32, AP(pcm_uframes_str) }, { SNDRV_PCM_IOCTL_REWIND32, AP(pcm_rewind) },
{ SNDRV_PCM_IOCTL_RESUME, NULL }, { SNDRV_PCM_IOCTL_RESUME, NULL },
{ SNDRV_PCM_IOCTL_XRUN, NULL }, { SNDRV_PCM_IOCTL_XRUN, NULL },
{ SNDRV_PCM_IOCTL_WRITEI_FRAMES32, AP(xferi) }, { SNDRV_PCM_IOCTL_WRITEI_FRAMES32, AP(pcm_writei) },
{ SNDRV_PCM_IOCTL_READI_FRAMES32, AP(xferi) }, { SNDRV_PCM_IOCTL_READI_FRAMES32, AP(pcm_readi) },
{ SNDRV_PCM_IOCTL_WRITEN_FRAMES32, AP(xfern) }, { SNDRV_PCM_IOCTL_WRITEN_FRAMES32, AP(pcm_writen) },
{ SNDRV_PCM_IOCTL_READN_FRAMES32, AP(xfern) }, { SNDRV_PCM_IOCTL_READN_FRAMES32, AP(pcm_readn) },
{ SNDRV_PCM_IOCTL_LINK, NULL }, { SNDRV_PCM_IOCTL_LINK, NULL },
{ SNDRV_PCM_IOCTL_UNLINK, NULL }, { SNDRV_PCM_IOCTL_UNLINK, NULL },
......
...@@ -30,9 +30,9 @@ struct sndrv_rawmidi_params32 { ...@@ -30,9 +30,9 @@ struct sndrv_rawmidi_params32 {
s32 stream; s32 stream;
u32 buffer_size; u32 buffer_size;
u32 avail_min; u32 avail_min;
unsigned int no_active_sensing: 1; unsigned int no_active_sensing; /* avoid bit-field */
unsigned char reserved[16]; unsigned char reserved[16];
}; } __attribute__((packed));
#define CVT_sndrv_rawmidi_params()\ #define CVT_sndrv_rawmidi_params()\
{\ {\
...@@ -45,7 +45,7 @@ struct sndrv_rawmidi_params32 { ...@@ -45,7 +45,7 @@ struct sndrv_rawmidi_params32 {
struct timeval32 { struct timeval32 {
s32 tv_sec; s32 tv_sec;
s32 tv_usec; s32 tv_usec;
}; } __attribute__((packed));
struct sndrv_rawmidi_status32 { struct sndrv_rawmidi_status32 {
s32 stream; s32 stream;
...@@ -53,7 +53,7 @@ struct sndrv_rawmidi_status32 { ...@@ -53,7 +53,7 @@ struct sndrv_rawmidi_status32 {
u32 avail; u32 avail;
u32 xruns; u32 xruns;
unsigned char reserved[16]; unsigned char reserved[16];
}; } __attribute__((packed));
#define CVT_sndrv_rawmidi_status()\ #define CVT_sndrv_rawmidi_status()\
{\ {\
...@@ -67,6 +67,8 @@ struct sndrv_rawmidi_status32 { ...@@ -67,6 +67,8 @@ struct sndrv_rawmidi_status32 {
DEFINE_ALSA_IOCTL(rawmidi_params); DEFINE_ALSA_IOCTL(rawmidi_params);
DEFINE_ALSA_IOCTL(rawmidi_status); 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 #define AP(x) snd_ioctl32_##x
......
...@@ -27,16 +27,67 @@ ...@@ -27,16 +27,67 @@
#include <sound/asequencer.h> #include <sound/asequencer.h>
#include "ioctl32.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 */
char reserved[60]; /* for future use */
};
#define CVT_sndrv_seq_port_info()\
{\
COPY(addr);\
memcpy(dst->name, src->name, sizeof(dst->name));\
COPY(capability);\
COPY(type);\
COPY(midi_channels);\
COPY(midi_voices);\
COPY(synth_voices);\
COPY(read_use);\
COPY(write_use);\
COPY(flags);\
}
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[] = { struct ioctl32_mapper seq_mappers[] = {
{ SNDRV_SEQ_IOCTL_PVERSION, NULL }, { SNDRV_SEQ_IOCTL_PVERSION, NULL },
{ SNDRV_SEQ_IOCTL_CLIENT_ID, NULL }, { SNDRV_SEQ_IOCTL_CLIENT_ID, NULL },
{ SNDRV_SEQ_IOCTL_SYSTEM_INFO, NULL }, { SNDRV_SEQ_IOCTL_SYSTEM_INFO, NULL },
{ SNDRV_SEQ_IOCTL_GET_CLIENT_INFO, NULL }, { SNDRV_SEQ_IOCTL_GET_CLIENT_INFO, NULL },
{ SNDRV_SEQ_IOCTL_SET_CLIENT_INFO, NULL }, { SNDRV_SEQ_IOCTL_SET_CLIENT_INFO, NULL },
{ SNDRV_SEQ_IOCTL_CREATE_PORT, NULL }, { SNDRV_SEQ_IOCTL_CREATE_PORT32, AP(create_port) },
{ SNDRV_SEQ_IOCTL_DELETE_PORT, NULL }, { SNDRV_SEQ_IOCTL_DELETE_PORT32, AP(delete_port) },
{ SNDRV_SEQ_IOCTL_GET_PORT_INFO, NULL }, { SNDRV_SEQ_IOCTL_GET_PORT_INFO32, AP(get_port_info) },
{ SNDRV_SEQ_IOCTL_SET_PORT_INFO, NULL }, { SNDRV_SEQ_IOCTL_SET_PORT_INFO32, AP(set_port_info) },
{ SNDRV_SEQ_IOCTL_SUBSCRIBE_PORT, NULL }, { SNDRV_SEQ_IOCTL_SUBSCRIBE_PORT, NULL },
{ SNDRV_SEQ_IOCTL_UNSUBSCRIBE_PORT, NULL }, { SNDRV_SEQ_IOCTL_UNSUBSCRIBE_PORT, NULL },
{ SNDRV_SEQ_IOCTL_CREATE_QUEUE, NULL }, { SNDRV_SEQ_IOCTL_CREATE_QUEUE, NULL },
...@@ -47,8 +98,6 @@ struct ioctl32_mapper seq_mappers[] = { ...@@ -47,8 +98,6 @@ struct ioctl32_mapper seq_mappers[] = {
{ SNDRV_SEQ_IOCTL_GET_QUEUE_STATUS, NULL }, { SNDRV_SEQ_IOCTL_GET_QUEUE_STATUS, NULL },
{ SNDRV_SEQ_IOCTL_GET_QUEUE_TEMPO, NULL }, { SNDRV_SEQ_IOCTL_GET_QUEUE_TEMPO, NULL },
{ SNDRV_SEQ_IOCTL_SET_QUEUE_TEMPO, NULL }, { SNDRV_SEQ_IOCTL_SET_QUEUE_TEMPO, NULL },
{ SNDRV_SEQ_IOCTL_GET_QUEUE_OWNER, NULL },
{ SNDRV_SEQ_IOCTL_SET_QUEUE_OWNER, NULL },
{ SNDRV_SEQ_IOCTL_GET_QUEUE_TIMER, NULL }, { SNDRV_SEQ_IOCTL_GET_QUEUE_TIMER, NULL },
{ SNDRV_SEQ_IOCTL_SET_QUEUE_TIMER, NULL }, { SNDRV_SEQ_IOCTL_SET_QUEUE_TIMER, NULL },
{ SNDRV_SEQ_IOCTL_GET_QUEUE_CLIENT, NULL }, { SNDRV_SEQ_IOCTL_GET_QUEUE_CLIENT, NULL },
...@@ -59,6 +108,7 @@ struct ioctl32_mapper seq_mappers[] = { ...@@ -59,6 +108,7 @@ struct ioctl32_mapper seq_mappers[] = {
{ SNDRV_SEQ_IOCTL_QUERY_SUBS, NULL }, { SNDRV_SEQ_IOCTL_QUERY_SUBS, NULL },
{ SNDRV_SEQ_IOCTL_GET_SUBSCRIPTION, NULL }, { SNDRV_SEQ_IOCTL_GET_SUBSCRIPTION, NULL },
{ SNDRV_SEQ_IOCTL_QUERY_NEXT_CLIENT, NULL }, { SNDRV_SEQ_IOCTL_QUERY_NEXT_CLIENT, NULL },
{ SNDRV_SEQ_IOCTL_QUERY_NEXT_PORT, NULL }, { SNDRV_SEQ_IOCTL_QUERY_NEXT_PORT32, AP(query_next_port) },
{ SNDRV_SEQ_IOCTL_RUNNING_MODE, NULL },
{ 0 }, { 0 },
}; };
...@@ -73,6 +73,8 @@ struct sndrv_timer_status32 { ...@@ -73,6 +73,8 @@ struct sndrv_timer_status32 {
DEFINE_ALSA_IOCTL(timer_info); DEFINE_ALSA_IOCTL(timer_info);
DEFINE_ALSA_IOCTL(timer_status); 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);
/* /*
*/ */
......
...@@ -439,7 +439,7 @@ int copy_to_user_fromio(void *dst, unsigned long src, size_t count) ...@@ -439,7 +439,7 @@ int copy_to_user_fromio(void *dst, unsigned long src, size_t count)
size_t c = count; size_t c = count;
if (c > sizeof(buf)) if (c > sizeof(buf))
c = sizeof(buf); c = sizeof(buf);
memcpy_fromio(buf, src, c); memcpy_fromio(buf, (void*)src, c);
if (copy_to_user(dst, buf, c)) if (copy_to_user(dst, buf, c))
return -EFAULT; return -EFAULT;
count -= c; count -= c;
...@@ -462,7 +462,7 @@ int copy_from_user_toio(unsigned long dst, const void *src, size_t count) ...@@ -462,7 +462,7 @@ int copy_from_user_toio(unsigned long dst, const void *src, size_t count)
c = sizeof(buf); c = sizeof(buf);
if (copy_from_user(buf, src, c)) if (copy_from_user(buf, src, c))
return -EFAULT; return -EFAULT;
memcpy_toio(dst, buf, c); memcpy_toio((void*)dst, buf, c);
count -= c; count -= c;
dst += c; dst += c;
src += c; src += c;
...@@ -484,7 +484,7 @@ int copy_from_user_toio(unsigned long dst, const void *src, size_t count) ...@@ -484,7 +484,7 @@ int copy_from_user_toio(unsigned long dst, const void *src, size_t count)
*/ */
#ifdef __i386__ #ifdef __i386__
#define get_phys_addr(x) virt_to_phys(x) #define get_phys_addr(x) virt_to_phys(x)
#else /* ppc */ #else /* ppc and x86-64 */
#define get_phys_addr(x) virt_to_bus(x) #define get_phys_addr(x) virt_to_bus(x)
#endif #endif
void *snd_pci_hack_alloc_consistent(struct pci_dev *hwdev, size_t size, void *snd_pci_hack_alloc_consistent(struct pci_dev *hwdev, size_t size,
......
...@@ -37,6 +37,9 @@ ...@@ -37,6 +37,9 @@
#include "seq_info.h" #include "seq_info.h"
#include "seq_system.h" #include "seq_system.h"
#include <sound/seq_device.h> #include <sound/seq_device.h>
#if defined(CONFIG_SND_BIT32_EMUL) || defined(CONFIG_SND_BIT32_EMUL_MODULE)
#include "../ioctl32/ioctl32.h"
#endif
/* Client Manager /* Client Manager
...@@ -1018,6 +1021,13 @@ static ssize_t snd_seq_write(struct file *file, const char *buf, size_t count, l ...@@ -1018,6 +1021,13 @@ static ssize_t snd_seq_write(struct file *file, const char *buf, size_t count, l
event.data.ext.len = extlen | SNDRV_SEQ_EXT_USRPTR; event.data.ext.len = extlen | SNDRV_SEQ_EXT_USRPTR;
event.data.ext.ptr = (char*)buf + sizeof(snd_seq_event_t); event.data.ext.ptr = (char*)buf + sizeof(snd_seq_event_t);
len += extlen; /* increment data length */ len += extlen; /* increment data length */
} else {
#if defined(CONFIG_SND_BIT32_EMUL) || defined(CONFIG_SND_BIT32_EMUL_MODULE)
if (client->convert32 && snd_seq_ev_is_varusr(&event)) {
void *ptr = (void*)A(event.data.raw32.d[1]);
event.data.ext.ptr = ptr;
}
#endif
} }
/* ok, enqueue it */ /* ok, enqueue it */
...@@ -1092,6 +1102,43 @@ static int snd_seq_ioctl_system_info(client_t *client, unsigned long arg) ...@@ -1092,6 +1102,43 @@ static int snd_seq_ioctl_system_info(client_t *client, unsigned long arg)
} }
/* RUNNING_MODE ioctl() */
static int snd_seq_ioctl_running_mode(client_t *client, unsigned long arg)
{
struct sndrv_seq_running_info info;
client_t *cptr;
int err = 0;
if (copy_from_user(&info, (void*)arg, sizeof(info)))
return -EFAULT;
/* requested client number */
cptr = snd_seq_client_use_ptr(info.client);
if (cptr == NULL)
return -ENOENT; /* don't change !!! */
#ifdef SNDRV_BIG_ENDIAN
if (! info.big_endian) {
err = -EINVAL;
goto __err;
}
#else
if (info.big_endian) {
err = -EINVAL;
goto __err;
}
#endif
if (info.cpu_mode > sizeof(long)) {
err = -EINVAL;
goto __err;
}
cptr->convert32 = (info.cpu_mode < sizeof(long));
__err:
snd_seq_client_unlock(cptr);
return err;
}
/* CLIENT_INFO ioctl() */ /* CLIENT_INFO ioctl() */
static void get_client_info(client_t *cptr, snd_seq_client_info_t *info) static void get_client_info(client_t *cptr, snd_seq_client_info_t *info)
{ {
...@@ -2042,6 +2089,7 @@ static struct seq_ioctl_table { ...@@ -2042,6 +2089,7 @@ static struct seq_ioctl_table {
int (*func)(client_t *client, unsigned long arg); int (*func)(client_t *client, unsigned long arg);
} ioctl_tables[] = { } ioctl_tables[] = {
{ SNDRV_SEQ_IOCTL_SYSTEM_INFO, snd_seq_ioctl_system_info }, { SNDRV_SEQ_IOCTL_SYSTEM_INFO, snd_seq_ioctl_system_info },
{ SNDRV_SEQ_IOCTL_RUNNING_MODE, snd_seq_ioctl_running_mode },
{ SNDRV_SEQ_IOCTL_GET_CLIENT_INFO, snd_seq_ioctl_get_client_info }, { SNDRV_SEQ_IOCTL_GET_CLIENT_INFO, snd_seq_ioctl_get_client_info },
{ SNDRV_SEQ_IOCTL_SET_CLIENT_INFO, snd_seq_ioctl_set_client_info }, { SNDRV_SEQ_IOCTL_SET_CLIENT_INFO, snd_seq_ioctl_set_client_info },
{ SNDRV_SEQ_IOCTL_CREATE_PORT, snd_seq_ioctl_create_port }, { SNDRV_SEQ_IOCTL_CREATE_PORT, snd_seq_ioctl_create_port },
......
...@@ -61,6 +61,7 @@ struct _snd_seq_client { ...@@ -61,6 +61,7 @@ struct _snd_seq_client {
struct list_head ports_list_head; struct list_head ports_list_head;
rwlock_t ports_lock; rwlock_t ports_lock;
struct semaphore ports_mutex; struct semaphore ports_mutex;
int convert32; /* convert 32->64bit */
/* output pool */ /* output pool */
pool_t *pool; /* memory pool for this client */ pool_t *pool; /* memory pool for this client */
......
...@@ -293,7 +293,7 @@ static struct pci_device_id snd_intel8x0_ids[] __devinitdata = { ...@@ -293,7 +293,7 @@ static struct pci_device_id snd_intel8x0_ids[] __devinitdata = {
{ 0x8086, 0x7195, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL }, /* 440MX */ { 0x8086, 0x7195, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL }, /* 440MX */
{ 0x1039, 0x7012, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_SIS }, /* SI7012 */ { 0x1039, 0x7012, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_SIS }, /* SI7012 */
{ 0x10de, 0x01b1, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL }, /* NFORCE */ { 0x10de, 0x01b1, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL }, /* NFORCE */
{ 0x1022, 0x764d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL }, /* AMD8111 */ { 0x1022, 0x746d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL }, /* AMD8111 */
{ 0x1022, 0x7445, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL }, /* AMD768 */ { 0x1022, 0x7445, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL }, /* AMD768 */
{ 0, } { 0, }
}; };
...@@ -1233,7 +1233,10 @@ static void __devinit intel8x0_measure_ac97_clock(intel8x0_t *chip) ...@@ -1233,7 +1233,10 @@ static void __devinit intel8x0_measure_ac97_clock(intel8x0_t *chip)
chip->playback.substream = NULL; /* don't process interrupts */ chip->playback.substream = NULL; /* don't process interrupts */
/* set rate */ /* set rate */
snd_ac97_set_rate(chip->ac97, AC97_PCM_FRONT_DAC_RATE, 48000); if (snd_ac97_set_rate(chip->ac97, AC97_PCM_FRONT_DAC_RATE, 48000) < 0) {
snd_printk(KERN_ERR "cannot set ac97 rate: clock = %d\n", chip->ac97->clock);
return;
}
snd_intel8x0_setup_periods(chip, &chip->playback); snd_intel8x0_setup_periods(chip, &chip->playback);
port = chip->bmport + chip->playback.reg_offset; port = chip->bmport + chip->playback.reg_offset;
spin_lock_irqsave(&chip->reg_lock, flags); spin_lock_irqsave(&chip->reg_lock, flags);
...@@ -1412,7 +1415,7 @@ static struct shortname_table { ...@@ -1412,7 +1415,7 @@ static struct shortname_table {
{ PCI_DEVICE_ID_INTEL_ICH4, "Intel 82801DB-ICH4" }, { PCI_DEVICE_ID_INTEL_ICH4, "Intel 82801DB-ICH4" },
{ PCI_DEVICE_ID_SI_7012, "SiS SI7012" }, { PCI_DEVICE_ID_SI_7012, "SiS SI7012" },
{ PCI_DEVICE_ID_NVIDIA_MCP_AUDIO, "NVidia NForce" }, { PCI_DEVICE_ID_NVIDIA_MCP_AUDIO, "NVidia NForce" },
{ 0x764d, "AMD AMD8111" }, { 0x746d, "AMD AMD8111" },
{ 0x7445, "AMD AMD768" }, { 0x7445, "AMD AMD768" },
{ 0, 0 }, { 0, 0 },
}; };
......
...@@ -25,6 +25,7 @@ ...@@ -25,6 +25,7 @@
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/pci.h>
#include <sound/core.h> #include <sound/core.h>
#include <sound/control.h> #include <sound/control.h>
#include <sound/pcm.h> #include <sound/pcm.h>
......
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