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 {
struct sndrv_seq_ev_ext {
unsigned int len; /* length of data */
void *ptr; /* pointer to data (note: maybe 64-bit) */
};
} __attribute__((packed));
/* Instrument cluster type */
typedef unsigned int sndrv_seq_instr_cluster_t;
......@@ -373,7 +373,7 @@ struct sndrv_seq_ev_quote {
struct sndrv_seq_addr origin; /* original sender */
unsigned short value; /* optional data */
struct sndrv_seq_event *event; /* quoted event */
};
} __attribute__((packed));
/* sequencer event */
......@@ -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 */
#define SNDRV_SEQ_CLIENT_SYSTEM 0
#define SNDRV_SEQ_CLIENT_DUMMY 62 /* dummy ports */
......@@ -609,7 +619,6 @@ struct sndrv_seq_port_info {
int write_use; /* R/O: subscribers for input (to this port) */
void *kernel; /* reserved for kernel use (must be NULL) */
unsigned int flags; /* misc. conditioning */
char reserved[60]; /* for future use */
};
......@@ -853,6 +862,7 @@ struct sndrv_seq_instr_cluster_get {
#define SNDRV_SEQ_IOCTL_PVERSION _IOR ('S', 0x00, 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_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_SET_CLIENT_INFO _IOW ('S', 0x11, struct sndrv_seq_client_info)
......
......@@ -50,7 +50,7 @@
*/
#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.
*/
......
/* include/version.h. Generated automatically by configure. */
#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 @@
#
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
endif
......
......@@ -21,6 +21,7 @@
#define __NO_VERSION__
#include <sound/driver.h>
#include <linux/smp_lock.h>
#include <linux/init.h>
#include <linux/time.h>
#include <sound/core.h>
#include <sound/control.h>
......@@ -32,6 +33,10 @@
* 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);
......@@ -79,7 +84,7 @@ struct sndrv_ctl_elem_list32 {
u32 count;
u32 pids;
unsigned char reserved[50];
};
} /* don't set packed attribute here */;
#define CVT_sndrv_ctl_elem_list()\
{\
......@@ -90,8 +95,43 @@ struct sndrv_ctl_elem_list32 {
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
......@@ -123,22 +163,31 @@ struct sndrv_ctl_elem_info32 {
unsigned char reserved[128];
} value;
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_info32 data32;
int err;
mm_segment_t oldseg = get_fs();
if (copy_from_user(&data32, (void*)arg, sizeof(data32)))
return -EFAULT;
set_fs(KERNEL_DS);
if (copy_from_user(&data32, (void*)arg, sizeof(data32))) {
err = -EFAULT;
goto __err;
}
memset(&data, 0, sizeof(data));
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)
return err;
goto __err;
/* restore info to 32bit */
data32.id = data.id;
data32.type = data.type;
data32.access = data.access;
data32.count = data.count;
......@@ -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_INTEGER:
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;
break;
case SNDRV_CTL_ELEM_TYPE_INTEGER64:
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;
break;
case SNDRV_CTL_ELEM_TYPE_ENUMERATED:
......@@ -165,14 +214,17 @@ static int snd_ioctl32_ctl_elem_info(unsigned int fd, unsigned int cmd, unsigned
break;
}
if (copy_to_user((void*)arg, &data32, sizeof(data32)))
return -EFAULT;
err = -EFAULT;
__err:
set_fs(oldseg);
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_id id;
unsigned int indirect: 1;
unsigned int indirect; /* bit-field causes misalignment */
union {
union {
s32 value[128];
......@@ -193,7 +245,7 @@ struct sndrv_ctl_elem_value32 {
struct sndrv_aes_iec958 iec958;
} value;
unsigned char reserved[128];
};
} __attribute__((packed));
/* 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)
}
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?
struct sndrv_ctl_elem_value data;
struct sndrv_ctl_elem_value32 data32;
int err, i;
int type;
mm_segment_t oldseg = get_fs();
set_fs(KERNEL_DS);
/* FIXME: check the sane ioctl.. */
if (copy_from_user(&data32, (void*)arg, sizeof(data32)))
return -EFAULT;
if (copy_from_user(&data32, (void*)arg, sizeof(data32))) {
err = -EFAULT;
goto __err;
}
memset(&data, 0, sizeof(data));
data.id = data32.id;
data.indirect = data32.indirect;
if (data.indirect) /* FIXME: this is not correct for long arrays */
data.value.integer.value_ptr = (void*)TO_PTR(data32.value.integer.value_ptr);
type = get_ctl_type(file, &data.id);
if (type < 0)
return type;
if (type < 0) {
err = type;
goto __err;
}
if (! data.indirect) {
switch (type) {
case SNDRV_CTL_ELEM_TYPE_BOOLEAN:
......@@ -263,45 +323,50 @@ static int snd_ioctl32_ctl_elem_value(unsigned int fd, unsigned int cmd, unsigne
data.value.iec958 = data32.value.iec958;
break;
default:
printk("unknown type %d\n", type);
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)
return err;
goto __err;
/* restore info to 32bit */
if (! data.indirect) {
switch (type) {
case SNDRV_CTL_ELEM_TYPE_BOOLEAN:
case SNDRV_CTL_ELEM_TYPE_INTEGER:
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;
case SNDRV_CTL_ELEM_TYPE_INTEGER64:
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;
case SNDRV_CTL_ELEM_TYPE_ENUMERATED:
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;
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));
break;
case SNDRV_CTL_ELEM_TYPE_IEC958:
data.value.iec958 = data32.value.iec958;
data32.value.iec958 = data.value.iec958;
break;
default:
break;
}
}
if (copy_to_user((void*)arg, &data32, sizeof(data32)))
return -EFAULT;
err = -EFAULT;
__err:
set_fs(oldseg);
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[] = {
{ SNDRV_CTL_IOCTL_CARD_INFO , NULL },
{ 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_value) },
{ SNDRV_CTL_IOCTL_ELEM_WRITE32, AP(ctl_elem_value) },
{ SNDRV_CTL_IOCTL_ELEM_READ32, AP(ctl_elem_read) },
{ SNDRV_CTL_IOCTL_ELEM_WRITE32, AP(ctl_elem_write) },
{ SNDRV_CTL_IOCTL_ELEM_LOCK, NULL },
{ SNDRV_CTL_IOCTL_ELEM_UNLOCK, NULL },
{ SNDRV_CTL_IOCTL_SUBSCRIBE_EVENTS, NULL },
......@@ -393,6 +458,7 @@ static int __init snd_ioctl32_init(void)
return err;
}
#endif
return 0;
}
module_init(snd_ioctl32_init)
......
......@@ -26,6 +26,15 @@
#ifndef __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 COPY(x) (dst->x = src->x)
......@@ -47,26 +56,39 @@
#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 data;\
mm_segment_t oldseg = get_fs();\
int err;\
if (copy_from_user(&data32, (void*)arg, sizeof(data32)))\
return -EFAULT;\
set_fs(KERNEL_DS);\
if (copy_from_user(&data32, (void*)arg, sizeof(data32))) {\
err = -EFAULT;\
goto __err;\
}\
memset(&data, 0, sizeof(data));\
convert_from_32(type, &data, &data32);\
err = file->f_op->ioctl(file->f_dentry->d_inode, file, cmd, (unsigned long)&data);\
if (err < 0)\
return err;\
if (cmd & (_IOC_READ << _IOC_DIRSHIFT)) {\
err = file->f_op->ioctl(file->f_dentry->d_inode, file, native_ctl, (unsigned long)&data);\
if (err < 0) \
goto __err;\
if (native_ctl & (_IOC_READ << _IOC_DIRSHIFT)) {\
convert_to_32(type, &data32, &data);\
if (copy_to_user((void*)arg, &data32, sizeof(data32)))\
return -EFAULT;\
if (copy_to_user((void*)arg, &data32, sizeof(data32))) {\
err = -EFAULT;\
goto __err;\
}\
}\
__err: set_fs(oldseg);\
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 {
unsigned int cmd;
int (*handler)(unsigned int, unsigned int, unsigned long, struct file * filp);
......
......@@ -54,7 +54,7 @@ struct sndrv_interval32 {
struct sndrv_pcm_hw_params32 {
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];
u32 rmask;
u32 cmask;
......@@ -64,7 +64,7 @@ struct sndrv_pcm_hw_params32 {
u32 rate_den;
u32 fifo_size;
unsigned char reserved[64];
};
} __attribute__((packed));
#define numberof(array) (sizeof(array)/sizeof(array[0]))
......@@ -103,7 +103,7 @@ struct sndrv_pcm_sw_params32 {
u32 silence_size;
u32 boundary;
unsigned char reserved[64];
};
} __attribute__((packed));
#define CVT_sndrv_pcm_sw_params()\
{\
......@@ -124,7 +124,7 @@ struct sndrv_pcm_channel_info32 {
u32 offset;
u32 first;
u32 step;
};
} __attribute__((packed));
#define CVT_sndrv_pcm_channel_info()\
{\
......@@ -137,7 +137,7 @@ struct sndrv_pcm_channel_info32 {
struct timeval32 {
s32 tv_sec;
s32 tv_usec;
};
} __attribute__((packed));
struct sndrv_pcm_status32 {
s32 state;
......@@ -151,7 +151,7 @@ struct sndrv_pcm_status32 {
u32 overrange;
s32 suspended_state;
unsigned char reserved[60];
};
} __attribute__((packed));
#define CVT_sndrv_pcm_status()\
{\
......@@ -169,33 +169,58 @@ struct sndrv_pcm_status32 {
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 {
s32 result;
u32 buf;
u32 frames;
};
} __attribute__((packed));
#define CVT_sndrv_xferi()\
{\
COPY(result);\
CPTR(buf);\
COPY(frames);\
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 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.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 */
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.
......@@ -203,7 +228,7 @@ struct sndrv_xfern32 {
* 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)
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;
......@@ -211,6 +236,9 @@ static int snd_ioctl32_xfern(unsigned int fd, unsigned int cmd, unsigned long ar
void *bufs[128];
int err = 0, ch, i;
u32 *bufptr;
mm_segment_t oldseg = get_fs();
set_fs(KERNEL_DS);
/* 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
snd_assert(substream != NULL && substream->runtime, return -ENXIO);
/* check validty of the command */
switch (cmd) {
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;
if (substream->stream != SNDRV_PCM_STREAM_PLAYBACK) {
err = -EINVAL;
goto __err;
}
if (substream->runtime->status->state == SNDRV_PCM_STATE_OPEN) {
err = -EBADFD;
goto __err;
}
break;
case SNDRV_PCM_IOCTL_READN_FRAMES:
if (substream->stream != SNDRV_PCM_STREAM_CAPTURE)
return -EINVAL;
if (substream->stream != SNDRV_PCM_STREAM_CAPTURE) {
err = -EINVAL;
goto __err;
}
break;
}
if ((ch = substream->runtime->channels) > 128)
return -EINVAL;
if (get_user(data32.frames, &srcptr->frames))
return -EFAULT;
if ((ch = substream->runtime->channels) > 128) {
err = -EINVAL;
goto __err;
}
if (get_user(data32.frames, &srcptr->frames)) {
err = -EFAULT;
goto __err;
}
__get_user(data32.bufs, &srcptr->bufs);
bufptr = (u32*)TO_PTR(data32.bufs);
for (i = 0; i < ch; i++) {
u32 ptr;
if (get_user(ptr, bufptr))
return -EFAULT;
if (get_user(ptr, bufptr)) {
err = -EFAULT;
goto __err;
}
bufs[ch] = (void*)TO_PTR(ptr);
bufptr++;
}
switch (cmd) {
switch (native_ctl) {
case SNDRV_PCM_IOCTL_WRITEN_FRAMES:
err = snd_pcm_lib_writev(substream, bufs, data32.frames);
break;
......@@ -253,13 +294,33 @@ static int snd_ioctl32_xfern(unsigned int fd, unsigned int cmd, unsigned long ar
}
if (err < 0)
return err;
goto __err;
if (put_user(err, &srcptr->result))
return -EFAULT;
err = -EFAULT;
__err:
set_fs(oldseg);
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
enum {
......@@ -279,12 +340,12 @@ enum {
struct ioctl32_mapper pcm_mappers[] = {
{ SNDRV_PCM_IOCTL_PVERSION, 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_FREE, NULL },
{ SNDRV_PCM_IOCTL_SW_PARAMS32, AP(pcm_sw_params) },
{ 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_PREPARE, NULL },
{ SNDRV_PCM_IOCTL_RESET, NULL },
......@@ -292,13 +353,13 @@ struct ioctl32_mapper pcm_mappers[] = {
{ SNDRV_PCM_IOCTL_DROP, NULL },
{ SNDRV_PCM_IOCTL_DRAIN, 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_XRUN, NULL },
{ SNDRV_PCM_IOCTL_WRITEI_FRAMES32, AP(xferi) },
{ SNDRV_PCM_IOCTL_READI_FRAMES32, AP(xferi) },
{ SNDRV_PCM_IOCTL_WRITEN_FRAMES32, AP(xfern) },
{ SNDRV_PCM_IOCTL_READN_FRAMES32, AP(xfern) },
{ 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) },
{ SNDRV_PCM_IOCTL_LINK, NULL },
{ SNDRV_PCM_IOCTL_UNLINK, NULL },
......
......@@ -30,9 +30,9 @@ struct sndrv_rawmidi_params32 {
s32 stream;
u32 buffer_size;
u32 avail_min;
unsigned int no_active_sensing: 1;
unsigned int no_active_sensing; /* avoid bit-field */
unsigned char reserved[16];
};
} __attribute__((packed));
#define CVT_sndrv_rawmidi_params()\
{\
......@@ -45,7 +45,7 @@ struct sndrv_rawmidi_params32 {
struct timeval32 {
s32 tv_sec;
s32 tv_usec;
};
} __attribute__((packed));
struct sndrv_rawmidi_status32 {
s32 stream;
......@@ -53,7 +53,7 @@ struct sndrv_rawmidi_status32 {
u32 avail;
u32 xruns;
unsigned char reserved[16];
};
} __attribute__((packed));
#define CVT_sndrv_rawmidi_status()\
{\
......@@ -67,6 +67,8 @@ struct sndrv_rawmidi_status32 {
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
......
......@@ -27,16 +27,67 @@
#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 */
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[] = {
{ SNDRV_SEQ_IOCTL_PVERSION, NULL },
{ SNDRV_SEQ_IOCTL_CLIENT_ID, NULL },
{ SNDRV_SEQ_IOCTL_SYSTEM_INFO, NULL },
{ SNDRV_SEQ_IOCTL_GET_CLIENT_INFO, NULL },
{ SNDRV_SEQ_IOCTL_SET_CLIENT_INFO, NULL },
{ SNDRV_SEQ_IOCTL_CREATE_PORT, NULL },
{ SNDRV_SEQ_IOCTL_DELETE_PORT, NULL },
{ SNDRV_SEQ_IOCTL_GET_PORT_INFO, NULL },
{ SNDRV_SEQ_IOCTL_SET_PORT_INFO, NULL },
{ 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) },
{ SNDRV_SEQ_IOCTL_SUBSCRIBE_PORT, NULL },
{ SNDRV_SEQ_IOCTL_UNSUBSCRIBE_PORT, NULL },
{ SNDRV_SEQ_IOCTL_CREATE_QUEUE, NULL },
......@@ -47,8 +98,6 @@ struct ioctl32_mapper seq_mappers[] = {
{ SNDRV_SEQ_IOCTL_GET_QUEUE_STATUS, NULL },
{ SNDRV_SEQ_IOCTL_GET_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_SET_QUEUE_TIMER, NULL },
{ SNDRV_SEQ_IOCTL_GET_QUEUE_CLIENT, NULL },
......@@ -59,6 +108,7 @@ struct ioctl32_mapper seq_mappers[] = {
{ SNDRV_SEQ_IOCTL_QUERY_SUBS, NULL },
{ SNDRV_SEQ_IOCTL_GET_SUBSCRIPTION, 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 },
};
......@@ -73,6 +73,8 @@ struct sndrv_timer_status32 {
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);
/*
*/
......
......@@ -439,7 +439,7 @@ int copy_to_user_fromio(void *dst, unsigned long src, size_t count)
size_t c = count;
if (c > sizeof(buf))
c = sizeof(buf);
memcpy_fromio(buf, src, c);
memcpy_fromio(buf, (void*)src, c);
if (copy_to_user(dst, buf, c))
return -EFAULT;
count -= c;
......@@ -462,7 +462,7 @@ int copy_from_user_toio(unsigned long dst, const void *src, size_t count)
c = sizeof(buf);
if (copy_from_user(buf, src, c))
return -EFAULT;
memcpy_toio(dst, buf, c);
memcpy_toio((void*)dst, buf, c);
count -= c;
dst += c;
src += c;
......@@ -484,7 +484,7 @@ int copy_from_user_toio(unsigned long dst, const void *src, size_t count)
*/
#ifdef __i386__
#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)
#endif
void *snd_pci_hack_alloc_consistent(struct pci_dev *hwdev, size_t size,
......
......@@ -37,6 +37,9 @@
#include "seq_info.h"
#include "seq_system.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
......@@ -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.ptr = (char*)buf + sizeof(snd_seq_event_t);
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 */
......@@ -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() */
static void get_client_info(client_t *cptr, snd_seq_client_info_t *info)
{
......@@ -2042,6 +2089,7 @@ static struct seq_ioctl_table {
int (*func)(client_t *client, unsigned long arg);
} ioctl_tables[] = {
{ 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_SET_CLIENT_INFO, snd_seq_ioctl_set_client_info },
{ SNDRV_SEQ_IOCTL_CREATE_PORT, snd_seq_ioctl_create_port },
......
......@@ -61,6 +61,7 @@ struct _snd_seq_client {
struct list_head ports_list_head;
rwlock_t ports_lock;
struct semaphore ports_mutex;
int convert32; /* convert 32->64bit */
/* output pool */
pool_t *pool; /* memory pool for this client */
......
......@@ -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 */
{ 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 */
{ 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 */
{ 0, }
};
......@@ -1233,7 +1233,10 @@ static void __devinit intel8x0_measure_ac97_clock(intel8x0_t *chip)
chip->playback.substream = NULL; /* don't process interrupts */
/* 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);
port = chip->bmport + chip->playback.reg_offset;
spin_lock_irqsave(&chip->reg_lock, flags);
......@@ -1412,7 +1415,7 @@ static struct shortname_table {
{ PCI_DEVICE_ID_INTEL_ICH4, "Intel 82801DB-ICH4" },
{ PCI_DEVICE_ID_SI_7012, "SiS SI7012" },
{ PCI_DEVICE_ID_NVIDIA_MCP_AUDIO, "NVidia NForce" },
{ 0x764d, "AMD AMD8111" },
{ 0x746d, "AMD AMD8111" },
{ 0x7445, "AMD AMD768" },
{ 0, 0 },
};
......
......@@ -25,6 +25,7 @@
#include <linux/delay.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/pci.h>
#include <sound/core.h>
#include <sound/control.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