diff options
Diffstat (limited to 'sound')
45 files changed, 1353 insertions, 119 deletions
diff --git a/sound/Config.help b/sound/Config.help new file mode 100644 index 000000000000..3d003545abaf --- /dev/null +++ b/sound/Config.help @@ -0,0 +1,7 @@ +CONFIG_SOUND_PRIME + Say 'Y' or 'M' to enable Open Sound System drivers. + +CONFIG_SOUND_SND + Say 'Y' or 'M' to enable Advanced Linux Sound Architecture (ALSA) drivers. + You need to install also alsa-lib and alsa-utils packages available on + the ALSA website at <http://www.alsa-project.org>. diff --git a/sound/core/Config.help b/sound/core/Config.help new file mode 100644 index 000000000000..85541f1f97b1 --- /dev/null +++ b/sound/core/Config.help @@ -0,0 +1,40 @@ +CONFIG_SND_SEQUENCER + Say 'Y' or 'M' to enable MIDI sequencer and router support. This feature + allows routing and enqueing MIDI events. Events can be processed at given + time. + +CONFIG_SND_SEQ_DUMMY + Say 'Y' or 'M' to enable dummy sequencer client. This client is a simple + midi-through client. All normal input events are redirected to output port + immediately. + +CONFIG_SND_OSSEMUL + Say 'Y' to enable OSS (Open Sound System) API emulation code. + +CONFIG_SND_MIXER_OSS + Say 'Y' or 'M' to enable mixer OSS API emulation (/dev/mixer*). + +CONFIG_SND_PCM_OSS + Say 'Y' or 'M' to enable digital audio (PCM) OSS API emulation (/dev/dsp*). + +CONFIG_SND_SEQUENCER_OSS + Say 'Y' or 'M' to enable OSS sequencer emulation (both /dev/sequencer and + /dev/music interfaces). + +CONFIG_SND_RTCTIMER + Say 'Y' or 'M' to enable RTC timer support for ALSA. ALSA code uses RTC + timer as precise timing source and maps the RTC timer to the ALSA's timer + interface. ALSA sequencer code can also use this timing source. + +CONFIG_SND_VERBOSE_PRINTK + Say 'Y' to enable verbose log messages. These messages will help to + identify source file and position containing printed messages. + +CONFIG_SND_DEBUG + Say 'Y' to enable ALSA debug code. + +CONFIG_SND_DEBUG_MEMORY + Say 'Y' to enable debugging of memory allocation. + +CONFIG_SND_DEBUG_DETECTION + Say 'Y' to enable debugging of hardware detection. diff --git a/sound/core/Config.in b/sound/core/Config.in index 5e9b5a1c176a..38c93ed8bb1c 100644 --- a/sound/core/Config.in +++ b/sound/core/Config.in @@ -1,5 +1,14 @@ # ALSA soundcard-configuration +if [ "$CONFIG_X86_64" = "y" -a "$CONFIG_IA32_EMULATION" = "y" ]; then + dep_tristate ' Emulation for 32-bit applications' CONFIG_SND_BIT32_EMUL +fi +if [ "$CONFIG_PPC64" = "y" ]; then + dep_tristate ' Emulation for 32-bit applications' CONFIG_SND_BIT32_EMUL +fi +if [ "$CONFIG_SPARC64" = "y" ]; then + dep_tristate ' Emulation for 32-bit applications' CONFIG_SND_BIT32_EMUL +fi dep_tristate ' Sequencer support' CONFIG_SND_SEQUENCER $CONFIG_SND if [ "$CONFIG_SND_SEQUENCER" != "n" ]; then dep_tristate ' Sequencer dummy client' CONFIG_SND_SEQ_DUMMY $CONFIG_SND_SEQUENCER diff --git a/sound/core/Makefile b/sound/core/Makefile index 50dd397f4843..83f5d792b5e7 100644 --- a/sound/core/Makefile +++ b/sound/core/Makefile @@ -45,6 +45,11 @@ endif obj-$(CONFIG_SND_SEQUENCER) += snd-timer.o +subdir-$(CONFIG_SND_BIT32_EMUL) += ioctl32 +ifeq ($(CONFIG_SND_BIT32_EMUL),y) + obj-y += ioctl32/_ioctl32.o +endif + # Toplevel Module Dependency obj-$(CONFIG_SND_DUMMY) += snd-pcm.o snd-timer.o snd.o obj-$(CONFIG_SND_VIRMIDI) += snd-rawmidi.o snd.o snd-timer.o @@ -72,8 +77,8 @@ obj-$(CONFIG_SND_OPTI92X_AD1848) += snd-pcm.o snd-timer.o snd.o snd-rawmidi.o sn obj-$(CONFIG_SND_OPTI92X_CS4231) += snd-pcm.o snd-timer.o snd.o snd-rawmidi.o snd-hwdep.o obj-$(CONFIG_SND_OPTI93X) += snd-pcm.o snd-timer.o snd.o snd-rawmidi.o snd-hwdep.o obj-$(CONFIG_SND_SB8) += snd-pcm.o snd-timer.o snd.o snd-rawmidi.o snd-hwdep.o -obj-$(CONFIG_SND_SB16) += snd-pcm.o snd-timer.o snd.o snd-hwdep.o snd-rawmidi.o -obj-$(CONFIG_SND_SBAWE) += snd-pcm.o snd-timer.o snd.o snd-hwdep.o snd-rawmidi.o +obj-$(CONFIG_SND_SB16) += snd-pcm.o snd-timer.o snd.o snd-rawmidi.o +obj-$(CONFIG_SND_SBAWE) += snd-pcm.o snd-timer.o snd.o snd-rawmidi.o obj-$(CONFIG_SND_ES968) += snd-pcm.o snd-timer.o snd.o snd-rawmidi.o obj-$(CONFIG_SND_WAVEFRONT) += snd-pcm.o snd-timer.o snd.o snd-rawmidi.o snd-hwdep.o obj-$(CONFIG_SND_ALS4000) += snd-pcm.o snd-timer.o snd.o snd-rawmidi.o snd-hwdep.o @@ -85,7 +90,7 @@ obj-$(CONFIG_SND_ES1938) += snd-pcm.o snd-timer.o snd.o snd-hwdep.o snd-rawmidi. obj-$(CONFIG_SND_ES1968) += snd-pcm.o snd-timer.o snd.o snd-rawmidi.o obj-$(CONFIG_SND_FM801) += snd-pcm.o snd-timer.o snd.o snd-rawmidi.o snd-hwdep.o obj-$(CONFIG_SND_ICE1712) += snd-pcm.o snd-timer.o snd.o snd-rawmidi.o -obj-$(CONFIG_SND_INTEL8X0) += snd-pcm.o snd-timer.o snd.o +obj-$(CONFIG_SND_INTEL8X0) += snd-pcm.o snd-timer.o snd.o snd-rawmidi.o obj-$(CONFIG_SND_MAESTRO3) += snd-pcm.o snd-timer.o snd.o obj-$(CONFIG_SND_RME96) += snd-pcm.o snd-timer.o snd.o obj-$(CONFIG_SND_SONICVIBES) += snd-pcm.o snd-timer.o snd.o snd-rawmidi.o snd-hwdep.o @@ -100,6 +105,10 @@ obj-$(CONFIG_SND_RME9652) += snd-pcm.o snd-timer.o snd.o obj-$(CONFIG_SND_TRIDENT) += snd-pcm.o snd-timer.o snd.o snd-rawmidi.o obj-$(CONFIG_SND_YMFPCI) += snd-pcm.o snd-timer.o snd.o snd-rawmidi.o snd-hwdep.o obj-$(CONFIG_SND_POWERMAC) += snd-pcm.o snd-timer.o snd.o +ifeq ($(CONFIG_SND_SB16_CSP),y) + obj-$(CONFIG_SND_SB16) += snd-hwdep.o + obj-$(CONFIG_SND_SBAWE) += snd-hwdep.o +endif include $(TOPDIR)/Rules.make diff --git a/sound/core/info.c b/sound/core/info.c index 5e6eb497eac4..da8e938bb6cd 100644 --- a/sound/core/info.c +++ b/sound/core/info.c @@ -24,12 +24,12 @@ #include <linux/init.h> #include <linux/vmalloc.h> #include <linux/time.h> +#include <linux/smp_lock.h> #include <sound/core.h> #include <sound/minors.h> #include <sound/info.h> #include <sound/version.h> #include <linux/proc_fs.h> -#include <linux/smp_lock.h> #ifdef CONFIG_DEVFS_FS #include <linux/devfs_fs_kernel.h> #endif @@ -55,7 +55,7 @@ int snd_info_check_reserved_words(const char *str) "memdebug", "detect", "devices", - "oss-devices", + "oss", "cards", "timers", "synth", @@ -124,6 +124,9 @@ int snd_iprintf(snd_info_buffer_t * buffer, char *fmt,...) struct proc_dir_entry *snd_proc_root = NULL; struct proc_dir_entry *snd_proc_dev = NULL; snd_info_entry_t *snd_seq_root = NULL; +#ifdef CONFIG_SND_OSSEMUL +snd_info_entry_t *snd_oss_root = NULL; +#endif #ifdef LINUX_2_2 static void snd_info_fill_inode(struct inode *inode, int fill) @@ -163,11 +166,13 @@ static loff_t snd_info_entry_llseek(struct file *file, loff_t offset, int orig) { snd_info_private_data_t *data; struct snd_info_entry *entry; - int ret = -EINVAL; + loff_t ret; data = snd_magic_cast(snd_info_private_data_t, file->private_data, return -ENXIO); entry = data->entry; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 3) lock_kernel(); +#endif switch (entry->content) { case SNDRV_INFO_CONTENT_TEXT: switch (orig) { @@ -181,6 +186,7 @@ static loff_t snd_info_entry_llseek(struct file *file, loff_t offset, int orig) goto out; case 2: /* SEEK_END */ default: + ret = -EINVAL; goto out; } break; @@ -195,7 +201,9 @@ static loff_t snd_info_entry_llseek(struct file *file, loff_t offset, int orig) } ret = -ENXIO; out: +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 3) unlock_kernel(); +#endif return ret; } @@ -623,6 +631,19 @@ int __init snd_info_init(void) if (p == NULL) return -ENOMEM; snd_proc_dev = p; +#ifdef CONFIG_SND_OSSEMUL + { + snd_info_entry_t *entry; + if ((entry = snd_info_create_module_entry(THIS_MODULE, "oss", NULL)) == NULL) + return -ENOMEM; + entry->mode = S_IFDIR | S_IRUGO | S_IXUGO; + if (snd_info_register(entry) < 0) { + snd_info_free_entry(entry); + return -ENOMEM; + } + snd_oss_root = entry; + } +#endif #if defined(CONFIG_SND_SEQUENCER) || defined(CONFIG_SND_SEQUENCER_MODULE) { snd_info_entry_t *entry; @@ -664,6 +685,10 @@ int __exit snd_info_done(void) if (snd_seq_root) snd_info_unregister(snd_seq_root); #endif +#ifdef CONFIG_SND_OSSEMUL + if (snd_oss_root) + snd_info_unregister(snd_oss_root); +#endif snd_remove_proc_entry(snd_proc_root, snd_proc_dev); snd_remove_proc_entry(&proc_root, snd_proc_root); } diff --git a/sound/core/info_oss.c b/sound/core/info_oss.c index 940882ff8531..85e7bcbb72eb 100644 --- a/sound/core/info_oss.c +++ b/sound/core/info_oss.c @@ -114,7 +114,7 @@ int snd_info_minor_register(void) snd_info_entry_t *entry; memset(snd_sndstat_strings, 0, sizeof(snd_sndstat_strings)); - if ((entry = snd_info_create_module_entry(THIS_MODULE, "sndstat", NULL)) != NULL) { + if ((entry = snd_info_create_module_entry(THIS_MODULE, "sndstat", snd_oss_root)) != NULL) { entry->content = SNDRV_INFO_CONTENT_TEXT; entry->c.text.read_size = 2048; entry->c.text.read = snd_sndstat_proc_read; diff --git a/sound/core/ioctl32/Makefile b/sound/core/ioctl32/Makefile new file mode 100644 index 000000000000..ddd94bfd3dfd --- /dev/null +++ b/sound/core/ioctl32/Makefile @@ -0,0 +1,17 @@ +# +# Makefile for ALSA +# Copyright (c) 1999 by Jaroslav Kysela <perex@suse.cz> +# + +O_TARGET := _ioctl32.o + +list-multi := snd-ioctl32.o + +snd-ioctl32-objs := ioctl32.o pcm32.o rawmidi32.o timer32.o hwdep32.o + +obj-$(CONFIG_SND_BIT32_EMUL) += snd-ioctl32.o + +include $(TOPDIR)/Rules.make + +snd-ioctl32.o: $(snd-ioctl32-objs) + $(LD) $(LD_RFLAG) -r -o $@ $(snd-ioctl32-objs) diff --git a/sound/core/ioctl32/hwdep32.c b/sound/core/ioctl32/hwdep32.c new file mode 100644 index 000000000000..5d0eb0cc3ee0 --- /dev/null +++ b/sound/core/ioctl32/hwdep32.c @@ -0,0 +1,37 @@ +/* + * 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 + * + */ + +#define __NO_VERSION__ +#include <sound/driver.h> +#include <linux/time.h> +#include <sound/core.h> +#include <sound/timer.h> +#include <asm/uaccess.h> +#include "ioctl32.h" + +#define AP(x) snd_ioctl32_##x + +struct ioctl32_mapper hwdep_mappers[] = { + { SNDRV_HWDEP_IOCTL_PVERSION, NULL }, + { SNDRV_HWDEP_IOCTL_INFO, NULL }, + { SNDRV_CTL_IOCTL_HWDEP_NEXT_DEVICE, NULL }, + { SNDRV_CTL_IOCTL_HWDEP_INFO, NULL }, + { 0 }, +}; diff --git a/sound/core/ioctl32/ioctl32.c b/sound/core/ioctl32/ioctl32.c new file mode 100644 index 000000000000..cb22362f40b9 --- /dev/null +++ b/sound/core/ioctl32/ioctl32.c @@ -0,0 +1,357 @@ +/* + * 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 + * + */ + +#define __NO_VERSION__ +#include <sound/driver.h> +#include <linux/smp_lock.h> +#include <linux/time.h> +#include <sound/core.h> +#include <sound/control.h> +#include <asm/uaccess.h> +#include "ioctl32.h" + +/* + * register/unregister mappers + * exported for other modules + */ + +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; + + lock_kernel(); + for (m = mappers; m->cmd; m++) { + err = register_ioctl32_conversion(m->cmd, m->handler); + if (err < 0) { + unlock_kernel(); + return err; + } + m->registered++; + } + return 0; +} + +void snd_ioctl32_unregister(struct ioctl32_mapper *mappers) +{ + struct ioctl32_mapper *m; + + lock_kernel(); + for (m = mappers; m->cmd; m++) { + if (m->registered) { + unregister_ioctl32_conversion(m->cmd); + m->registered = 0; + } + } + unlock_kernel(); +} + + +/* + * Controls + */ + +struct sndrv_ctl_elem_list32 { + u32 offset; + u32 space; + u32 used; + u32 count; + u32 pids; + unsigned char reserved[50]; +}; + +#define CVT_sndrv_ctl_elem_list()\ +{\ + COPY(offset);\ + COPY(space);\ + COPY(used);\ + COPY(count);\ + CPTR(pids);\ +} + +DEFINE_ALSA_IOCTL(ctl_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 { + u32 items; + u32 item; + char name[64]; + } enumerated; + unsigned char reserved[128]; + } value; + unsigned char reserved[64]; +}; + +static int snd_ioctl32_ctl_elem_info(unsigned int fd, unsigned int cmd, unsigned long arg, struct file *file) +{ + struct sndrv_ctl_elem_info data; + struct sndrv_ctl_elem_info32 data32; + int err; + + if (copy_from_user(&data32, (void*)arg, sizeof(data32))) + return -EFAULT; + memset(&data, 0, sizeof(data)); + data.id = data32.id; + err = file->f_op->ioctl(file->f_dentry->d_inode, file, cmd, (unsigned long)&data); + if (err < 0) + return err; + /* restore info to 32bit */ + data32.type = data.type; + data32.access = data.access; + data32.count = data.count; + data32.owner = data.owner; + switch (data.type) { + 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.step = data.value.integer.step; + break; + case SNDRV_CTL_ELEM_TYPE_ENUMERATED: + data32.value.enumerated.items = data.value.enumerated.items; + data32.value.enumerated.item = data.value.enumerated.item; + memcpy(data32.value.enumerated.name, data.value.enumerated.name, + sizeof(data.value.enumerated.name)); + break; + default: + break; + } + if (copy_to_user((void*)arg, &data32, sizeof(data32))) + return -EFAULT; + return err; +} + + +struct sndrv_ctl_elem_value32 { + struct sndrv_ctl_elem_id id; + unsigned int indirect: 1; + union { + union { + s32 value[128]; + u32 value_ptr; + } integer; + union { + u32 item[128]; + u32 item_ptr; + } enumerated; + union { + unsigned char data[512]; + u32 data_ptr; + } bytes; + struct sndrv_aes_iec958 iec958; + } value; + unsigned char reserved[128]; +}; + + +/* hmm, it's so hard to retrieve the value type from the control id.. */ +static int get_ctl_type(struct file *file, snd_ctl_elem_id_t *id) +{ + snd_ctl_file_t *ctl; + snd_kcontrol_t *kctl; + snd_ctl_elem_info_t info; + int err; + + ctl = snd_magic_cast(snd_ctl_file_t, file->private_data, return -ENXIO); + + read_lock(&ctl->card->control_rwlock); + kctl = snd_ctl_find_id(ctl->card, id); + if (! kctl) { + read_unlock(&ctl->card->control_rwlock); + return -ENXIO; + } + info.id = *id; + err = kctl->info(kctl, &info); + if (err >= 0) + err = info.type; + read_unlock(&ctl->card->control_rwlock); + return err; +} + + +static int snd_ioctl32_ctl_elem_value(unsigned int fd, unsigned int cmd, unsigned long arg, struct file *file) +{ + // too big? + struct sndrv_ctl_elem_value data; + struct sndrv_ctl_elem_value32 data32; + int err, i; + int type; + /* FIXME: check the sane ioctl.. */ + + if (copy_from_user(&data32, (void*)arg, sizeof(data32))) + return -EFAULT; + 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 (! 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]; + break; + case SNDRV_CTL_ELEM_TYPE_ENUMERATED: + for (i = 0; i < 128; i++) + data.value.enumerated.item[i] = data32.value.enumerated.item[i]; + break; + case SNDRV_CTL_ELEM_TYPE_BYTES: + memcpy(data.value.bytes.data, data32.value.bytes.data, + sizeof(data.value.bytes.data)); + break; + case SNDRV_CTL_ELEM_TYPE_IEC958: + data.value.iec958 = data32.value.iec958; + break; + default: + break; + } + } + + err = file->f_op->ioctl(file->f_dentry->d_inode, file, cmd, (unsigned long)&data); + if (err < 0) + return 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]; + break; + case SNDRV_CTL_ELEM_TYPE_ENUMERATED: + for (i = 0; i < 128; i++) + data.value.enumerated.item[i] = data32.value.enumerated.item[i]; + break; + case SNDRV_CTL_ELEM_TYPE_BYTES: + memcpy(data.value.bytes.data, data32.value.bytes.data, + sizeof(data.value.bytes.data)); + break; + case SNDRV_CTL_ELEM_TYPE_IEC958: + data.value.iec958 = data32.value.iec958; + break; + default: + break; + } + } + if (copy_to_user((void*)arg, &data32, sizeof(data32))) + return -EFAULT; + return err; +} + + +/* + */ + +#define AP(x) snd_ioctl32_##x + +static struct ioctl32_mapper control_mappers[] = { + /* controls (without rawmidi, hwdep, timer releated ones) */ + { SNDRV_CTL_IOCTL_PVERSION, NULL }, + { SNDRV_CTL_IOCTL_CARD_INFO , NULL }, + { SNDRV_CTL_IOCTL_ELEM_LIST, AP(ctl_elem_list) }, + { SNDRV_CTL_IOCTL_ELEM_INFO, AP(ctl_elem_info) }, + { SNDRV_CTL_IOCTL_ELEM_READ, AP(ctl_elem_value) }, + { SNDRV_CTL_IOCTL_ELEM_WRITE, AP(ctl_elem_value) }, + { SNDRV_CTL_IOCTL_ELEM_LOCK, NULL }, + { SNDRV_CTL_IOCTL_ELEM_UNLOCK, NULL }, + { SNDRV_CTL_IOCTL_SUBSCRIBE_EVENTS, NULL }, + { SNDRV_CTL_IOCTL_HWDEP_NEXT_DEVICE, NULL }, + { SNDRV_CTL_IOCTL_PCM_NEXT_DEVICE, NULL }, + { SNDRV_CTL_IOCTL_PCM_INFO, NULL }, + { SNDRV_CTL_IOCTL_PCM_PREFER_SUBDEVICE, NULL }, + { SNDRV_CTL_IOCTL_POWER, NULL }, + { SNDRV_CTL_IOCTL_POWER_STATE, NULL }, + { 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[]; + +static void snd_ioctl32_done(void) +{ + 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) +{ + int err; + + err = snd_ioctl32_register(control_mappers); + if (err < 0) + return err; + err = snd_ioctl32_register(pcm_mappers); + if (err < 0) { + snd_ioctl32_done(); + return err; + } + err = snd_ioctl32_register(rawmidi_mappers); + if (err < 0) { + snd_ioctl32_done(); + return err; + } + err = snd_ioctl32_register(timer_mappers); + if (err < 0) { + snd_ioctl32_done(); + return err; + } + err = snd_ioctl32_register(hwdep_mappers); + if (err < 0) { + snd_ioctl32_done(); + return err; + } +} + +module_init(snd_ioctl32_init) +module_exit(snd_ioctl32_done) diff --git a/sound/core/ioctl32/ioctl32.h b/sound/core/ioctl32/ioctl32.h new file mode 100644 index 000000000000..08c20d58dd55 --- /dev/null +++ b/sound/core/ioctl32/ioctl32.h @@ -0,0 +1,79 @@ +/* + * 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 A(x) + * macro to a valid 64-bit pointer which is accessible via copy_from/to_user. + * + */ + +#ifndef __ALSA_IOCTL32_H +#define __ALSA_IOCTL32_H + +#define TO_PTR(x) A(x) + +#define COPY(x) (dst->x = src->x) +#define CPTR(x) (dst->x = (typeof(dst->x))A(src->x)) + +#define convert_from_32(type, dstp, srcp)\ +{\ + struct sndrv_##type *dst = dstp;\ + struct sndrv_##type##32 *src = srcp;\ + CVT_##sndrv_##type();\ +} + +#define convert_to_32(type, dstp, srcp)\ +{\ + struct sndrv_##type *src = srcp;\ + struct sndrv_##type##32 *dst = dstp;\ + CVT_##sndrv_##type();\ +} + + +#define DEFINE_ALSA_IOCTL(type) \ +static int snd_ioctl32_##type(unsigned int fd, unsigned int cmd, unsigned long arg, struct file *file)\ +{\ + struct sndrv_##type##32 data32;\ + struct sndrv_##type data;\ + int err;\ + if (copy_from_user(&data32, (void*)arg, sizeof(data32)))\ + return -EFAULT;\ + 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)) {\ + convert_to_32(type, &data32, &data);\ + if (copy_to_user((void*)arg, &data32, sizeof(data32)))\ + return -EFAULT;\ + }\ + return err;\ +} + +struct ioctl32_mapper { + unsigned int cmd; + int (*handler)(unsigned int, unsigned int, unsigned long, struct file * filp); + int registered; +}; + +int snd_ioctl32_register(struct ioctl32_mapper *mappers); +void snd_ioctl32_unregister(struct ioctl32_mapper *mappers); + +#endif /* __ALSA_IOCTL32_H */ diff --git a/sound/core/ioctl32/pcm32.c b/sound/core/ioctl32/pcm32.c new file mode 100644 index 000000000000..3aa994c7bc74 --- /dev/null +++ b/sound/core/ioctl32/pcm32.c @@ -0,0 +1,296 @@ +/* + * 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 + * + */ + +#define __NO_VERSION__ +#include <sound/driver.h> +#include <linux/time.h> +#include <sound/core.h> +#include <sound/pcm.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(val); } +#define CVT_sndrv_pcm_uframes_str() { COPY(val); } + + +struct sndrv_interval32 { + u32 min, max; + unsigned int openmin:1, + openmax:1, + integer:1, + empty:1; +}; + +struct sndrv_pcm_hw_params32 { + u32 flags; + u32 masks[SNDRV_PCM_HW_PARAM_LAST_MASK - SNDRV_PCM_HW_PARAM_FIRST_MASK + 1]; + struct sndrv_interval32 intervals[SNDRV_PCM_HW_PARAM_LAST_INTERVAL - SNDRV_PCM_HW_PARAM_FIRST_INTERVAL + 1]; + u32 rmask; + u32 cmask; + u32 info; + u32 msbits; + u32 rate_num; + u32 rate_den; + u32 fifo_size; + unsigned char reserved[64]; +}; + +#define numberof(array) (sizeof(array)/sizeof(array[0])) + +#define CVT_sndrv_pcm_hw_params()\ +{\ + int i;\ + COPY(flags);\ + for (i = 0; i < numberof(dst->masks); i++)\ + COPY(masks[i]);\ + for (i = 0; i < numberof(dst->intervals); i++) {\ + COPY(intervals[i].min);\ + COPY(intervals[i].max);\ + COPY(intervals[i].openmin);\ + COPY(intervals[i].openmax);\ + COPY(intervals[i].integer);\ + COPY(intervals[i].empty);\ + }\ + COPY(rmask);\ + COPY(cmask);\ + COPY(info);\ + COPY(msbits);\ + COPY(rate_num);\ + COPY(rate_den);\ + COPY(fifo_size);\ +} + +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]; +}; + +#define CVT_sndrv_pcm_sw_params()\ +{\ + COPY(tstamp_mode);\ + COPY(period_step);\ + COPY(sleep_min);\ + COPY(avail_min);\ + COPY(xfer_align);\ + COPY(start_threshold);\ + COPY(stop_threshold);\ + COPY(silence_threshold);\ + COPY(silence_size);\ + COPY(boundary);\ +} + +struct sndrv_pcm_channel_info32 { + u32 channel; + u32 offset; + u32 first; + u32 step; +}; + +#define CVT_sndrv_pcm_channel_info()\ +{\ + COPY(channel);\ + COPY(offset);\ + COPY(first);\ + COPY(step);\ +} + +struct timeval32 { + s32 tv_sec; + s32 tv_usec; +}; + +struct sndrv_pcm_status32 { + s32 state; + struct timeval32 trigger_tstamp; + struct timeval32 tstamp; + u32 appl_ptr; + u32 hw_ptr; + s32 delay; + u32 avail; + u32 avail_max; + u32 overrange; + s32 suspended_state; + unsigned char reserved[60]; +}; + +#define CVT_sndrv_pcm_status()\ +{\ + COPY(state);\ + COPY(trigger_tstamp.tv_sec);\ + COPY(trigger_tstamp.tv_usec);\ + COPY(tstamp.tv_sec);\ + COPY(tstamp.tv_usec);\ + COPY(appl_ptr);\ + COPY(hw_ptr);\ + COPY(delay);\ + COPY(avail);\ + COPY(avail_max);\ + COPY(overrange);\ + COPY(suspended_state);\ +} + +struct sndrv_xferi32 { + s32 result; + u32 buf; + u32 frames; +}; + +#define CVT_sndrv_xferi()\ +{\ + COPY(result);\ + CPTR(buf);\ + COPY(frames);\ +} + +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; +}; + +/* + * 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) +{ + snd_pcm_file_t *pcm_file; + snd_pcm_substream_t *substream; + struct sndrv_xfern32 data32, *srcptr = (struct sndrv_xfern32*)arg; + void *bufs[128]; + int err = 0, ch, i; + u32 *bufptr; + + /* FIXME: need to check whether fop->ioctl is sane */ + + pcm_file = snd_magic_cast(snd_pcm_file_t, file->private_data, return -ENXIO); + substream = pcm_file->substream; + snd_assert(substream != NULL && substream->runtime, return -ENXIO); + + /* check validty of the command */ + switch (cmd) { + 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; + 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 (get_user(data32.frames, &srcptr->frames)) + return -EFAULT; + __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; + bufs[ch] = (void*)TO_PTR(ptr); + bufptr++; + } + switch (cmd) { + 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) + return err; + if (put_user(err, &srcptr->result)) + return -EFAULT; + return err < 0 ? err : 0; +} + + +#define AP(x) snd_ioctl32_##x + +struct ioctl32_mapper pcm_mappers[] = { + { SNDRV_PCM_IOCTL_PVERSION, NULL }, + { SNDRV_PCM_IOCTL_INFO, NULL }, + { SNDRV_PCM_IOCTL_HW_REFINE, AP(pcm_hw_params) }, + { SNDRV_PCM_IOCTL_HW_PARAMS, AP(pcm_hw_params) }, + { SNDRV_PCM_IOCTL_HW_FREE, NULL }, + { SNDRV_PCM_IOCTL_SW_PARAMS, AP(pcm_sw_params) }, + { SNDRV_PCM_IOCTL_STATUS, AP(pcm_status) }, + { SNDRV_PCM_IOCTL_DELAY, AP(pcm_sframes_str) }, + { SNDRV_PCM_IOCTL_CHANNEL_INFO, AP(pcm_channel_info) }, + { SNDRV_PCM_IOCTL_PREPARE, NULL }, + { SNDRV_PCM_IOCTL_RESET, NULL }, + { SNDRV_PCM_IOCTL_START, NULL }, + { SNDRV_PCM_IOCTL_DROP, NULL }, + { SNDRV_PCM_IOCTL_DRAIN, NULL }, + { SNDRV_PCM_IOCTL_PAUSE, NULL }, + { SNDRV_PCM_IOCTL_REWIND, AP(pcm_uframes_str) }, + { SNDRV_PCM_IOCTL_RESUME, NULL }, + { SNDRV_PCM_IOCTL_XRUN, NULL }, + { SNDRV_PCM_IOCTL_WRITEI_FRAMES, AP(xferi) }, + { SNDRV_PCM_IOCTL_READI_FRAMES, AP(xferi) }, + { SNDRV_PCM_IOCTL_WRITEN_FRAMES, AP(xfern) }, + { SNDRV_PCM_IOCTL_READN_FRAMES, AP(xfern) }, + { SNDRV_PCM_IOCTL_LINK, NULL }, + { SNDRV_PCM_IOCTL_UNLINK, NULL }, + + { SNDRV_CTL_IOCTL_PCM_NEXT_DEVICE, NULL }, + { SNDRV_CTL_IOCTL_PCM_INFO, NULL }, + { SNDRV_CTL_IOCTL_PCM_PREFER_SUBDEVICE, NULL }, + + { 0 }, +}; diff --git a/sound/core/ioctl32/rawmidi32.c b/sound/core/ioctl32/rawmidi32.c new file mode 100644 index 000000000000..d5e89ffd9f98 --- /dev/null +++ b/sound/core/ioctl32/rawmidi32.c @@ -0,0 +1,86 @@ +/* + * 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 + * + */ + +#define __NO_VERSION__ +#include <sound/driver.h> +#include <linux/time.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: 1; + unsigned char reserved[16]; +}; + +#define CVT_sndrv_rawmidi_params()\ +{\ + COPY(stream);\ + COPY(buffer_size);\ + COPY(avail_min);\ + COPY(no_active_sensing);\ +} + +struct timeval32 { + s32 tv_sec; + s32 tv_usec; +}; + +struct sndrv_rawmidi_status32 { + s32 stream; + struct timeval32 tstamp; + u32 avail; + u32 xruns; + unsigned char reserved[16]; +}; + +#define CVT_sndrv_rawmidi_status()\ +{\ + COPY(stream);\ + COPY(tstamp.tv_sec);\ + COPY(tstamp.tv_usec);\ + COPY(avail);\ + COPY(xruns);\ +} + +DEFINE_ALSA_IOCTL(rawmidi_params); +DEFINE_ALSA_IOCTL(rawmidi_status); + + +#define AP(x) snd_ioctl32_##x + +struct ioctl32_mapper rawmidi_mappers[] = { + { SNDRV_RAWMIDI_IOCTL_PVERSION, NULL }, + { SNDRV_RAWMIDI_IOCTL_INFO, NULL }, + { SNDRV_RAWMIDI_IOCTL_PARAMS, AP(rawmidi_params) }, + { SNDRV_RAWMIDI_IOCTL_STATUS, AP(rawmidi_status) }, + { SNDRV_RAWMIDI_IOCTL_DROP, NULL }, + { SNDRV_RAWMIDI_IOCTL_DRAIN, NULL }, + + { SNDRV_CTL_IOCTL_RAWMIDI_NEXT_DEVICE, NULL }, + { SNDRV_CTL_IOCTL_RAWMIDI_INFO, NULL }, + { SNDRV_CTL_IOCTL_RAWMIDI_PREFER_SUBDEVICE, NULL }, + + { 0 }, +}; diff --git a/sound/core/ioctl32/timer32.c b/sound/core/ioctl32/timer32.c new file mode 100644 index 000000000000..4e657f7a309f --- /dev/null +++ b/sound/core/ioctl32/timer32.c @@ -0,0 +1,93 @@ +/* + * 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 + * + */ + +#define __NO_VERSION__ +#include <sound/driver.h> +#include <linux/time.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 ticks; + u32 resolution; + unsigned char reserved[64]; +}; + +#define CVT_sndrv_timer_info()\ +{\ + COPY(flags);\ + COPY(card);\ + memcpy(dst->id, src->id, sizeof(src->id));\ + memcpy(dst->name, src->name, sizeof(src->name));\ + COPY(ticks);\ + COPY(resolution);\ +} + +struct timeval32 { + s32 tv_sec; + s32 tv_usec; +}; + +struct sndrv_timer_status32 { + struct timeval32 tstamp; + u32 resolution; + u32 lost; + u32 overrun; + u32 queue; + unsigned char reserved[64]; +}; + +#define CVT_sndrv_timer_status()\ +{\ + COPY(tstamp.tv_sec);\ + COPY(tstamp.tv_usec);\ + COPY(resolution);\ + COPY(lost);\ + COPY(overrun);\ + COPY(queue);\ +} + +DEFINE_ALSA_IOCTL(timer_info); +DEFINE_ALSA_IOCTL(timer_status); + + +/* + */ + +#define AP(x) snd_ioctl32_##x + +struct ioctl32_mapper timer_mappers[] = { + { SNDRV_TIMER_IOCTL_PVERSION, NULL }, + { SNDRV_TIMER_IOCTL_NEXT_DEVICE, NULL }, + { SNDRV_TIMER_IOCTL_SELECT, NULL }, + { SNDRV_TIMER_IOCTL_INFO, AP(timer_info) }, + { SNDRV_TIMER_IOCTL_PARAMS, NULL }, + { SNDRV_TIMER_IOCTL_STATUS, AP(timer_status) }, + { SNDRV_TIMER_IOCTL_START, NULL }, + { SNDRV_TIMER_IOCTL_STOP, NULL }, + { SNDRV_TIMER_IOCTL_CONTINUE, NULL }, + { 0 }, +}; diff --git a/sound/core/oss/pcm_oss.c b/sound/core/oss/pcm_oss.c index 57bcaa94802c..03cc8bce04b2 100644 --- a/sound/core/oss/pcm_oss.c +++ b/sound/core/oss/pcm_oss.c @@ -516,7 +516,6 @@ static int snd_pcm_oss_make_ready(snd_pcm_substream_t *substream) snd_pcm_sframes_t snd_pcm_oss_write3(snd_pcm_substream_t *substream, const char *ptr, snd_pcm_uframes_t frames, int in_kernel) { snd_pcm_runtime_t *runtime = substream->runtime; - mm_segment_t fs; int ret; while (1) { if (runtime->status->state == SNDRV_PCM_STATE_XRUN || @@ -525,11 +524,14 @@ snd_pcm_sframes_t snd_pcm_oss_write3(snd_pcm_substream_t *substream, const char if (ret < 0) break; } - if (in_kernel) + if (in_kernel) { + mm_segment_t fs; fs = snd_enter_user(); - ret = snd_pcm_lib_write(substream, ptr, frames); - if (in_kernel) + ret = snd_pcm_lib_write(substream, ptr, frames); snd_leave_user(fs); + } else { + ret = snd_pcm_lib_write(substream, ptr, frames); + } if (ret != -EPIPE && ret != -ESTRPIPE) break; /* test, if we can't store new data, because the stream */ @@ -543,7 +545,6 @@ snd_pcm_sframes_t snd_pcm_oss_write3(snd_pcm_substream_t *substream, const char snd_pcm_sframes_t snd_pcm_oss_read3(snd_pcm_substream_t *substream, char *ptr, snd_pcm_uframes_t frames, int in_kernel) { snd_pcm_runtime_t *runtime = substream->runtime; - mm_segment_t fs; int ret; while (1) { if (runtime->status->state == SNDRV_PCM_STATE_XRUN || @@ -556,11 +557,15 @@ snd_pcm_sframes_t snd_pcm_oss_read3(snd_pcm_substream_t *substream, char *ptr, s if (ret < 0) break; } - if (in_kernel) - fs = snd_enter_user(); ret = snd_pcm_lib_read(substream, ptr, frames); - if (in_kernel) + if (in_kernel) { + mm_segment_t fs; + fs = snd_enter_user(); + ret = snd_pcm_lib_read(substream, ptr, frames); snd_leave_user(fs); + } else { + ret = snd_pcm_lib_read(substream, ptr, frames); + } if (ret != -EPIPE && ret != -ESTRPIPE) break; } @@ -570,7 +575,6 @@ snd_pcm_sframes_t snd_pcm_oss_read3(snd_pcm_substream_t *substream, char *ptr, s snd_pcm_sframes_t snd_pcm_oss_writev3(snd_pcm_substream_t *substream, void **bufs, snd_pcm_uframes_t frames, int in_kernel) { snd_pcm_runtime_t *runtime = substream->runtime; - mm_segment_t fs; int ret; while (1) { if (runtime->status->state == SNDRV_PCM_STATE_XRUN || @@ -579,13 +583,17 @@ snd_pcm_sframes_t snd_pcm_oss_writev3(snd_pcm_substream_t *substream, void **buf if (ret < 0) break; } - if (in_kernel) + if (in_kernel) { + mm_segment_t fs; fs = snd_enter_user(); - ret = snd_pcm_lib_writev(substream, bufs, frames); - if (in_kernel) + ret = snd_pcm_lib_writev(substream, bufs, frames); snd_leave_user(fs); + } else { + ret = snd_pcm_lib_writev(substream, bufs, frames); + } if (ret != -EPIPE && ret != -ESTRPIPE) break; + /* test, if we can't store new data, because the stream */ /* has not been started */ if (runtime->status->state == SNDRV_PCM_STATE_PREPARED) @@ -597,7 +605,6 @@ snd_pcm_sframes_t snd_pcm_oss_writev3(snd_pcm_substream_t *substream, void **buf snd_pcm_sframes_t snd_pcm_oss_readv3(snd_pcm_substream_t *substream, void **bufs, snd_pcm_uframes_t frames, int in_kernel) { snd_pcm_runtime_t *runtime = substream->runtime; - mm_segment_t fs; int ret; while (1) { if (runtime->status->state == SNDRV_PCM_STATE_XRUN || @@ -610,11 +617,14 @@ snd_pcm_sframes_t snd_pcm_oss_readv3(snd_pcm_substream_t *substream, void **bufs if (ret < 0) break; } - if (in_kernel) + if (in_kernel) { + mm_segment_t fs; fs = snd_enter_user(); - ret = snd_pcm_lib_readv(substream, bufs, frames); - if (in_kernel) + ret = snd_pcm_lib_readv(substream, bufs, frames); snd_leave_user(fs); + } else { + ret = snd_pcm_lib_readv(substream, bufs, frames); + } if (ret != -EPIPE && ret != -ESTRPIPE) break; } diff --git a/sound/core/rtctimer.c b/sound/core/rtctimer.c index 51005b69d76b..c7085ae4aef5 100644 --- a/sound/core/rtctimer.c +++ b/sound/core/rtctimer.c @@ -18,19 +18,12 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * - * - *================================================================ - * For enabling this timer, apply the patch file to your kernel. - * The configure script checks the patch automatically. - * The patches, rtc-xxx.dif, are found under utils/patches, where - * xxx is the kernel version. - *================================================================ - * */ #include <sound/driver.h> #include <linux/init.h> #include <linux/time.h> +#include <linux/interrupt.h> #include <sound/core.h> #include <sound/timer.h> #include <sound/info.h> @@ -59,7 +52,7 @@ static int rtctimer_stop(snd_timer_t *t); /* - * The harware depenant description for this timer. + * The hardware dependent description for this timer. */ static struct _snd_timer_hardware rtc_hw = { flags: SNDRV_TIMER_HW_FIRST|SNDRV_TIMER_HW_AUTO, @@ -72,7 +65,7 @@ static struct _snd_timer_hardware rtc_hw = { int rtctimer_freq = RTC_FREQ; /* frequency */ static snd_timer_t *rtctimer; -static volatile int rtc_inc = 0; +static atomic_t rtc_inc = ATOMIC_INIT(0); static rtc_task_t rtc_task; /* tasklet */ @@ -83,6 +76,10 @@ static struct tasklet_struct rtc_tq; static int rtctimer_open(snd_timer_t *t) { + err = rtc_register(&rtc_task); + if (err < 0) + return err; + t->private_data = &rtc_task; MOD_INC_USE_COUNT; return 0; } @@ -90,6 +87,11 @@ rtctimer_open(snd_timer_t *t) static int rtctimer_close(snd_timer_t *t) { + rtc_task_t *rtc = t->private_data; + if (rtc) { + rtc_unregister(rtc); + t->private_data = NULL; + } MOD_DEC_USE_COUNT; return 0; } @@ -101,7 +103,7 @@ rtctimer_start(snd_timer_t *timer) snd_assert(rtc != NULL, return -EINVAL); rtc_control(rtc, RTC_IRQP_SET, rtctimer_freq); rtc_control(rtc, RTC_PIE_ON, 0); - rtc_inc = 0; + atomic_set(&rtc_inc, 0); return 0; } @@ -119,12 +121,15 @@ rtctimer_stop(snd_timer_t *timer) */ static void rtctimer_interrupt(void *private_data) { - rtc_inc++; + atomic_inc(&rtc_inc); #ifdef USE_TASKLET tasklet_hi_schedule(&rtc_tq); #else - snd_timer_interrupt((snd_timer_t*)private_data, rtc_inc); - rtc_inc = 0; + { + int ticks = atomic_read(&rtc_inc); + snd_timer_interrupt((snd_timer_t*)private_data, ticks); + atomic_sub(ticks, &rtc_inc); + } #endif /* USE_TASKLET */ } @@ -132,20 +137,16 @@ static void rtctimer_interrupt(void *private_data) static void rtctimer_interrupt2(unsigned long private_data) { snd_timer_t *timer = (snd_timer_t *)private_data; + int ticks; + snd_assert(timer != NULL, return); do { - snd_timer_interrupt(timer, 1); - } while (--rtc_inc > 0); + ticks = atomic_read(&rtc_inc); + snd_timer_interrupt(timer, ticks); + } while (!atomic_sub_and_test(ticks, &rtc_inc)); } #endif /* USE_TASKLET */ -static void rtctimer_private_free(snd_timer_t *timer) -{ - rtc_task_t *rtc = timer->private_data; - if (rtc) - rtc_unregister(rtc); -} - /* * ENTRY functions @@ -179,23 +180,16 @@ static int __init rtctimer_init(void) timer->hw = rtc_hw; timer->hw.resolution = NANO_SEC / rtctimer_freq; - /* register RTC callback */ + /* set up RTC callback */ rtc_task.func = rtctimer_interrupt; rtc_task.private_data = timer; - err = rtc_register(&rtc_task); - if (err < 0) { - snd_timer_global_free(timer); - return err; - } - timer->private_data = &rtc_task; - timer->private_free = rtctimer_private_free; err = snd_timer_global_register(timer); if (err < 0) { snd_timer_global_free(timer); return err; } - rtctimer = timer; + rtctimer = timer; /* remember this */ return 0; } @@ -210,7 +204,7 @@ static void __exit rtctimer_exit(void) /* - * exported stuffs + * exported stuff */ module_init(rtctimer_init) module_exit(rtctimer_exit) diff --git a/sound/core/seq/Makefile b/sound/core/seq/Makefile index ef7fc7a9e5a5..569cd0ae110f 100644 --- a/sound/core/seq/Makefile +++ b/sound/core/seq/Makefile @@ -72,6 +72,7 @@ obj-$(CONFIG_SND_ES1938) += snd-seq-device.o snd-seq-midi-emul.o snd-seq.o snd-s obj-$(CONFIG_SND_ES1968) += snd-seq-midi.o snd-seq.o snd-seq-device.o snd-seq-midi-event.o obj-$(CONFIG_SND_FM801) += snd-seq-midi.o snd-seq.o snd-seq-device.o snd-seq-midi-event.o snd-seq-midi-emul.o snd-seq-instr.o obj-$(CONFIG_SND_ICE1712) += snd-seq-midi.o snd-seq.o snd-seq-device.o snd-seq-midi-event.o +obj-$(CONFIG_SND_INTEL8X0) += snd-seq-midi.o snd-seq.o snd-seq-device.o snd-seq-midi-event.o obj-$(CONFIG_SND_SONICVIBES) += snd-seq-midi.o snd-seq.o snd-seq-device.o snd-seq-midi-event.o snd-seq-midi-emul.o snd-seq-instr.o obj-$(CONFIG_SND_VIA686) += snd-seq-midi.o snd-seq.o snd-seq-device.o snd-seq-midi-event.o obj-$(CONFIG_SND_ALI5451) += snd-seq-midi.o snd-seq.o snd-seq-device.o snd-seq-midi-event.o diff --git a/sound/core/seq/seq_midi_event.c b/sound/core/seq/seq_midi_event.c index b3ced9438d91..7ebf0514b16b 100644 --- a/sound/core/seq/seq_midi_event.c +++ b/sound/core/seq/seq_midi_event.c @@ -68,8 +68,8 @@ static struct status_event_list_t { event_decode_t decode; } status_event[] = { /* 0x80 - 0xf0 */ - {SNDRV_SEQ_EVENT_NOTEOFF, 2, note_event, note_decode}, - {SNDRV_SEQ_EVENT_NOTEON, 2, note_event, note_decode}, + {SNDRV_SEQ_EVENT_NOTEOFF, 2, note_event, note_decode}, + {SNDRV_SEQ_EVENT_NOTEON, 2, note_event, note_decode}, {SNDRV_SEQ_EVENT_KEYPRESS, 2, note_event, note_decode}, {SNDRV_SEQ_EVENT_CONTROLLER, 2, two_param_ctrl_event, two_param_decode}, {SNDRV_SEQ_EVENT_PGMCHANGE, 1, one_param_ctrl_event, one_param_decode}, @@ -78,9 +78,9 @@ static struct status_event_list_t { {SNDRV_SEQ_EVENT_NONE, 0, NULL, NULL}, /* 0xf0 */ /* 0xf0 - 0xff */ {SNDRV_SEQ_EVENT_SYSEX, 1, NULL, NULL}, /* sysex: 0xf0 */ - {SNDRV_SEQ_EVENT_QFRAME, 1, one_param_event, one_param_decode}, /* 0xf1 */ - {SNDRV_SEQ_EVENT_SONGPOS, 2, songpos_event, songpos_decode}, /* 0xf2 */ - {SNDRV_SEQ_EVENT_SONGSEL, 1, one_param_event, one_param_decode}, /* 0xf3 */ + {SNDRV_SEQ_EVENT_QFRAME, 1, one_param_event, one_param_decode}, /* 0xf1 */ + {SNDRV_SEQ_EVENT_SONGPOS, 2, songpos_event, songpos_decode}, /* 0xf2 */ + {SNDRV_SEQ_EVENT_SONGSEL, 1, one_param_event, one_param_decode}, /* 0xf3 */ {SNDRV_SEQ_EVENT_NONE, 0, NULL, NULL}, /* 0xf4 */ {SNDRV_SEQ_EVENT_NONE, 0, NULL, NULL}, /* 0xf5 */ {SNDRV_SEQ_EVENT_TUNE_REQUEST, 0, NULL, NULL}, /* 0xf6 */ @@ -92,7 +92,7 @@ static struct status_event_list_t { {SNDRV_SEQ_EVENT_STOP, 0, NULL, NULL}, /* 0xfc */ {SNDRV_SEQ_EVENT_NONE, 0, NULL, NULL}, /* 0xfd */ {SNDRV_SEQ_EVENT_SENSING, 0, NULL, NULL}, /* 0xfe */ - {SNDRV_SEQ_EVENT_RESET, 0, NULL, NULL}, /* 0xff */ + {SNDRV_SEQ_EVENT_RESET, 0, NULL, NULL}, /* 0xff */ }; static int extra_decode_ctrl14(snd_midi_event_t *dev, unsigned char *buf, int len, snd_seq_event_t *ev); @@ -128,6 +128,7 @@ int snd_midi_event_new(int bufsize, snd_midi_event_t **rdev) } } dev->bufsize = bufsize; + dev->lastcmd = 0xff; spin_lock_init(&dev->lock); *rdev = dev; return 0; diff --git a/sound/core/seq/seq_virmidi.c b/sound/core/seq/seq_virmidi.c index df7d693256ab..62271b8b21c8 100644 --- a/sound/core/seq/seq_virmidi.c +++ b/sound/core/seq/seq_virmidi.c @@ -233,8 +233,7 @@ static int snd_virmidi_output_open(snd_rawmidi_substream_t * substream) } vmidi->seq_mode = rdev->seq_mode; vmidi->client = rdev->client; - vmidi->port = rdev->port; - snd_midi_event_init(vmidi->parser); + vmidi->port = rdev->port; snd_virmidi_init_event(vmidi, &vmidi->event); vmidi->rdev = rdev; runtime->private_data = vmidi; diff --git a/sound/core/sound_oss.c b/sound/core/sound_oss.c index c3c363091fad..21ce042c818d 100644 --- a/sound/core/sound_oss.c +++ b/sound/core/sound_oss.c @@ -212,7 +212,7 @@ int __init snd_minor_info_oss_init(void) { snd_info_entry_t *entry; - entry = snd_info_create_module_entry(THIS_MODULE, "oss-devices", NULL); + entry = snd_info_create_module_entry(THIS_MODULE, "devices", snd_oss_root); if (entry) { entry->content = SNDRV_INFO_CONTENT_TEXT; entry->c.text.read_size = PAGE_SIZE; diff --git a/sound/drivers/Config.help b/sound/drivers/Config.help new file mode 100644 index 000000000000..7fea38481809 --- /dev/null +++ b/sound/drivers/Config.help @@ -0,0 +1,18 @@ +CONFIG_SND_DUMMY + Say 'Y' or 'M' to include dummy driver. This driver does nothing, but + emulates various mixer controls and PCM devices. + +CONFIG_SND_VIRMIDI + Say 'Y' or 'M' to include virtual MIDI driver. This driver allows to + connect applications using raw MIDI devices to sequencer. + +CONFIG_SND_MTPAV + Say 'Y' or 'M' to include support for MOTU MidiTimePiece AV multiport + MIDI adapter. + +CONFIG_SND_SERIAL_U16550 + Say 'Y' or 'M' to include support for MIDI serial port driver. It works + with serial UARTs 16550 and better. + +CONFIG_SND_MPU401 + Say 'Y' or 'M' to include support for MPU401 hardware using UART access. diff --git a/sound/drivers/mpu401/Makefile b/sound/drivers/mpu401/Makefile index 731ac31ac7f2..d21747f1cd30 100644 --- a/sound/drivers/mpu401/Makefile +++ b/sound/drivers/mpu401/Makefile @@ -37,6 +37,7 @@ obj-$(CONFIG_SND_ES1938) += snd-mpu401-uart.o obj-$(CONFIG_SND_ES1968) += snd-mpu401-uart.o obj-$(CONFIG_SND_FM801) += snd-mpu401-uart.o obj-$(CONFIG_SND_ICE1712) += snd-mpu401-uart.o +obj-$(CONFIG_SND_INTEL8X0) += snd-mpu401-uart.o obj-$(CONFIG_SND_SONICVIBES) += snd-mpu401-uart.o obj-$(CONFIG_SND_VIA686) += snd-mpu401-uart.o obj-$(CONFIG_SND_ALI5451) += snd-mpu401-uart.o diff --git a/sound/drivers/mpu401/mpu401_uart.c b/sound/drivers/mpu401/mpu401_uart.c index 8993ade328cf..b399150e2a6f 100644 --- a/sound/drivers/mpu401/mpu401_uart.c +++ b/sound/drivers/mpu401/mpu401_uart.c @@ -28,6 +28,7 @@ #include <linux/delay.h> #include <linux/init.h> #include <linux/slab.h> +#include <linux/ioport.h> #include <sound/core.h> #include <sound/mpu401.h> diff --git a/sound/drivers/mtpav.c b/sound/drivers/mtpav.c index 64913d5104ba..450032e8a34a 100644 --- a/sound/drivers/mtpav.c +++ b/sound/drivers/mtpav.c @@ -54,6 +54,7 @@ #include <asm/io.h> #include <linux/init.h> #include <linux/slab.h> +#include <linux/ioport.h> #include <sound/core.h> #define SNDRV_GET_ID #include <sound/initval.h> diff --git a/sound/drivers/opl3/Makefile b/sound/drivers/opl3/Makefile index 77ce497b9877..371dfb9b1bfe 100644 --- a/sound/drivers/opl3/Makefile +++ b/sound/drivers/opl3/Makefile @@ -29,7 +29,7 @@ obj-$(CONFIG_SND_GUSEXTREME) += snd-opl3-lib.o obj-$(CONFIG_SND_OPTI92X_AD1848) += snd-opl3-lib.o obj-$(CONFIG_SND_OPTI92X_CS4231) += snd-opl3-lib.o obj-$(CONFIG_SND_OPTI93X) += snd-opl3-lib.o -obj-$(CONFIG_SND_SB) += snd-opl3-lib.o +obj-$(CONFIG_SND_SB8) += snd-opl3-lib.o obj-$(CONFIG_SND_SB16) += snd-opl3-lib.o obj-$(CONFIG_SND_SBAWE) += snd-opl3-lib.o obj-$(CONFIG_SND_WAVEFRONT) += snd-opl3-lib.o @@ -54,7 +54,7 @@ ifeq ($(subst m,y,$(CONFIG_SND_SEQUENCER)),y) obj-$(CONFIG_SND_OPTI92X_AD1848) += snd-opl3-synth.o obj-$(CONFIG_SND_OPTI92X_CS4231) += snd-opl3-synth.o obj-$(CONFIG_SND_OPTI93X) += snd-opl3-synth.o - obj-$(CONFIG_SND_SB) += snd-opl3-synth.o + obj-$(CONFIG_SND_SB8) += snd-opl3-synth.o obj-$(CONFIG_SND_SB16) += snd-opl3-synth.o obj-$(CONFIG_SND_SBAWE) += snd-opl3-synth.o obj-$(CONFIG_SND_WAVEFRONT) += snd-opl3-synth.o diff --git a/sound/drivers/opl3/opl3_lib.c b/sound/drivers/opl3/opl3_lib.c index 8f8400bee5f3..91faf5941b4b 100644 --- a/sound/drivers/opl3/opl3_lib.c +++ b/sound/drivers/opl3/opl3_lib.c @@ -28,6 +28,7 @@ #include <linux/delay.h> #include <linux/init.h> #include <linux/slab.h> +#include <linux/ioport.h> #include <sound/minors.h> MODULE_AUTHOR("Jaroslav Kysela <perex@suse.cz>, Hannu Savolainen 1993-1996, Rob Hooft"); diff --git a/sound/drivers/serial-u16550.c b/sound/drivers/serial-u16550.c index 51668110b772..b2ff32b30623 100644 --- a/sound/drivers/serial-u16550.c +++ b/sound/drivers/serial-u16550.c @@ -39,7 +39,7 @@ * * Usage example for MS-124T, with A-B switch in A position: * setserial /dev/ttyS0 uart none - * /sbin/modprobe snd-card-serial snd_port=0x3f8 snd_irq=4 \ + * /sbin/modprobe snd-serial-u16550 snd_port=0x3f8 snd_irq=4 \ * snd_adaptor=1 snd_speed=19200 * * - In MS-124W S/A mode, one raw MIDI substream is supported @@ -49,7 +49,7 @@ * * Usage example for S/A mode: * setserial /dev/ttyS0 uart none - * /sbin/modprobe snd-card-serial snd_port=0x3f8 snd_irq=4 \ + * /sbin/modprobe snd-serial-u16550 snd_port=0x3f8 snd_irq=4 \ * snd_adaptor=2 * * - In MS-124W M/B mode, the driver supports 16 ALSA raw MIDI @@ -67,7 +67,7 @@ * * Usage example for M/B mode: * setserial /dev/ttyS0 uart none - * /sbin/insmod snd-card-serial snd_port=0x3f8 snd_irq=4 \ + * /sbin/insmod snd-serial-u16550 snd_port=0x3f8 snd_irq=4 \ * snd_adaptor=3 * * - The MS-124W hardware's M/A mode is currently not supported. @@ -106,6 +106,7 @@ #include <asm/io.h> #include <linux/init.h> #include <linux/slab.h> +#include <linux/ioport.h> #include <sound/core.h> #include <sound/rawmidi.h> #define SNDRV_GET_ID diff --git a/sound/i2c/Makefile b/sound/i2c/Makefile index eff64d7553a5..b9c505fb552d 100644 --- a/sound/i2c/Makefile +++ b/sound/i2c/Makefile @@ -13,7 +13,7 @@ snd-i2c-objs := i2c.o snd-cs8427-objs := cs8427.o snd-tea6330t-objs := tea6330t.o -# Module Dependency +# Toplevel Module Dependency obj-$(CONFIG_SND_INTERWAVE_STB) += snd-tea6330t.o snd-i2c.o obj-$(CONFIG_SND_ICE1712) += snd-cs8427.o snd-i2c.o diff --git a/sound/isa/Config.help b/sound/isa/Config.help new file mode 100644 index 000000000000..eac9a93c8c19 --- /dev/null +++ b/sound/isa/Config.help @@ -0,0 +1,99 @@ +CONFIG_SND_AD1816A + Say 'Y' or 'M' to include support for Analog Devices SoundPort AD1816A or + compatible sound chips. + +CONFIG_SND_AD1848 + Say 'Y' or 'M' to include support for AD1848 (Analog Devices) or CS4248 + (Cirrus Logic - Crystal Semiconductors) chips. Please, for newer chips + from Cirrus Logic, use CS4231, CS4232 or CS4236+ driver. + +CONFIG_SND_CS4231 + Say 'Y' or 'M' to include support for CS4231 chips from Cirrus Logic - + Crystal Semiconductors. + +CONFIG_SND_CS4232 + Say 'Y' or 'M' to include support for CS4232 chips from Cirrus Logic - + Crystal Semiconductors. + +CONFIG_SND_CS4236 + Say 'Y' or 'M' to include support for CS4235,CS4236,CS4237B,CS4238B,CS4239 + chips from Cirrus Logic - Crystal Semiconductors. + +CONFIG_SND_ES968 + Say 'Y' or 'M' to include support for ESS AudioDrive ES968 chip. + +CONFIG_SND_ES1688 + Say 'Y' or 'M' to include support for ESS AudioDrive ES688 or ES1688 chips. + +CONFIG_SND_ES18XX + Say 'Y' or 'M' to include support for ESS AudioDrive ES18xx chips. + +CONFIG_SND_GUSCLASSIC + Say 'Y' or 'M' to include support for Gravis UltraSound Classic soundcard. + +CONFIG_SND_GUSEXTREME + Say 'Y' or 'M' to include support for Gravis UltraSound Extreme soundcard. + +CONFIG_SND_GUSMAX + Say 'Y' or 'M' to include support for Gravis UltraSound MAX soundcard. + +CONFIG_SND_INTERWAVE + Say 'Y' or 'M' to include support for AMD InterWave based soundcards + (Gravis UltraSound Plug & Play, STB SoundRage32, MED3210, Dynasonic Pro, + Panasonic PCA761AW). + +CONFIG_SND_INTERWAVE_STB + Say 'Y' or 'M' to include support for AMD InterWave based soundcards + with TEA6330T bass and treble regulator (UltraSound 32-Pro). + +CONFIG_SND_OPTI92X_AD1848 + Say 'Y' or 'M' to include support for Opti92x soundcards equiped with + AD1848 codec. + +CONFIG_SND_OPTI92X_CS4231 + Say 'Y' or 'M' to include support for Opti92x soundcards equiped with + CS4231 codec. + +CONFIG_SND_OPTI93X + Say 'Y' or 'M' to include support for Opti93x soundcards. + +CONFIG_SND_SB8 + Say 'Y' or 'M' to include support for Sound Blaster 1.0/2.0/Pro (8-bit) + soundcards or 100% compatible from Creative. + +CONFIG_SND_SB16 + Say 'Y' or 'M' to include support for Sound Blaster 16 (including + Plug and Play version). + +CONFIG_SND_SBAWE + Say 'Y' or 'M' to include support for Sound Blaster AWE (including + Plug and Play version). + +CONFIG_SND_SB16_CSP + Say 'Y' to include support for CSP core. This special coprocessor + can do variable tasks like various compression and decompression + algorithms. + +CONFIG_SND_WAVEFRONT + Say 'Y' or 'M' to include support for Turtle Beach Maui, Tropez + and Tropez+ soundcards based on Wavefront chip. + +CONFIG_SND_ALS100 + Say 'Y' or 'M' to include support for Avance Logic ALS100, ALS110, + ALS120 and ALS200 soundcards. + +CONFIG_SND_AZT2320 + Say 'Y' or 'M' to include support for Aztech Systems AZT2320 soundcard. + +CONFIG_SND_CMI8330 + Say 'Y' or 'M' to include support for C-Media CMI8330 based soundcards. + +CONFIG_SND_DT0197H + Say 'Y' or 'M' to include support for Diamond Technologies DT-0197H + soundcards. + +CONFIG_SND_OPL3SA2 + Say 'Y' or 'M' to include support for Yamaha OPL3SA2 or OPL3SA3 chips. + +CONFIG_SND_SGALAXY + Say 'Y' or 'M' to include support for Aztech Sound Galaxy. diff --git a/sound/isa/ad1816a/ad1816a_lib.c b/sound/isa/ad1816a/ad1816a_lib.c index 2688d1bba07a..4461706461c7 100644 --- a/sound/isa/ad1816a/ad1816a_lib.c +++ b/sound/isa/ad1816a/ad1816a_lib.c @@ -24,6 +24,7 @@ #include <linux/delay.h> #include <linux/init.h> #include <linux/slab.h> +#include <linux/ioport.h> #include <sound/core.h> #include <sound/ad1816a.h> diff --git a/sound/isa/ad1848/ad1848_lib.c b/sound/isa/ad1848/ad1848_lib.c index 9e69d06cd835..7680dbf77491 100644 --- a/sound/isa/ad1848/ad1848_lib.c +++ b/sound/isa/ad1848/ad1848_lib.c @@ -25,6 +25,7 @@ #include <asm/dma.h> #include <linux/delay.h> #include <linux/slab.h> +#include <linux/ioport.h> #include <sound/core.h> #include <sound/ad1848.h> diff --git a/sound/isa/azt2320.c b/sound/isa/azt2320.c index fa55a9fdf120..8e84e21628be 100644 --- a/sound/isa/azt2320.c +++ b/sound/isa/azt2320.c @@ -134,7 +134,7 @@ static const struct isapnp_card_id *snd_azt2320_isapnp_id[SNDRV_CARDS] __devinit static struct isapnp_card_id snd_azt2320_pnpids[] __devinitdata = { /* PRO16V */ ISAPNP_AZT2320('A','Z','T',0x1008,0x1008,0x2001), - /* --- */ + /* Aztech Sound Galaxy 16 */ ISAPNP_AZT2320('A','Z','T',0x2320,0x0001,0x0002), /* Packard Bell Sound III 336 AM/SP */ ISAPNP_AZT2320('A','Z','T',0x3000,0x1003,0x2001), diff --git a/sound/isa/cs423x/cs4231_lib.c b/sound/isa/cs423x/cs4231_lib.c index 23236e5c1111..f3c629c124ab 100644 --- a/sound/isa/cs423x/cs4231_lib.c +++ b/sound/isa/cs423x/cs4231_lib.c @@ -32,6 +32,7 @@ #include <linux/pm.h> #include <linux/init.h> #include <linux/slab.h> +#include <linux/ioport.h> #include <sound/core.h> #include <sound/cs4231.h> diff --git a/sound/isa/es1688/es1688_lib.c b/sound/isa/es1688/es1688_lib.c index 3102bf15d916..b9f05ba2455d 100644 --- a/sound/isa/es1688/es1688_lib.c +++ b/sound/isa/es1688/es1688_lib.c @@ -25,6 +25,7 @@ #include <linux/init.h> #include <linux/delay.h> #include <linux/slab.h> +#include <linux/ioport.h> #include <sound/core.h> #include <sound/es1688.h> #include <sound/initval.h> diff --git a/sound/isa/gus/gus_main.c b/sound/isa/gus/gus_main.c index 262f2c163946..9d3a947bf3e9 100644 --- a/sound/isa/gus/gus_main.c +++ b/sound/isa/gus/gus_main.c @@ -24,6 +24,7 @@ #include <linux/init.h> #include <linux/delay.h> #include <linux/slab.h> +#include <linux/ioport.h> #include <sound/core.h> #include <sound/gus.h> #include <sound/control.h> diff --git a/sound/isa/opl3sa2.c b/sound/isa/opl3sa2.c index a389a6548c99..1c8ca4ac6857 100644 --- a/sound/isa/opl3sa2.c +++ b/sound/isa/opl3sa2.c @@ -177,7 +177,7 @@ static struct isapnp_card_id snd_opl3sa2_pnpids[] __devinitdata = { ISAPNP_OPL3SA2('Y','M','H',0x0020,0x0021), /* Yamaha OPL3-SA3 (integrated on Intel's Pentium II AL440LX motherboard) */ ISAPNP_OPL3SA2('Y','M','H',0x0030,0x0021), - /* ??? */ + /* Yamaha OPL3-SA2 */ ISAPNP_OPL3SA2('Y','M','H',0x0800,0x0021), /* NeoMagic MagicWave 3DX */ ISAPNP_OPL3SA2('N','M','X',0x2200,0x2210), diff --git a/sound/isa/sb/Makefile b/sound/isa/sb/Makefile index abf402366675..37b6d10fe07d 100644 --- a/sound/isa/sb/Makefile +++ b/sound/isa/sb/Makefile @@ -27,12 +27,12 @@ obj-$(CONFIG_SND_DT0197H) += snd-sb16-dsp.o snd-sb-common.o obj-$(CONFIG_SND_SB8) += snd-sb8.o snd-sb8-dsp.o snd-sb-common.o obj-$(CONFIG_SND_SB16) += snd-sb16.o snd-sb16-dsp.o snd-sb-common.o obj-$(CONFIG_SND_SBAWE) += snd-sbawe.o snd-sb16-dsp.o snd-sb-common.o +obj-$(CONFIG_SND_ES968) += snd-es968.o snd-sb8-dsp.o snd-sb-common.o +obj-$(CONFIG_SND_ALS4000) += snd-sb-common.o ifeq ($(CONFIG_SND_SB16_CSP),y) obj-$(CONFIG_SND_SB16) += snd-sb16-csp.o obj-$(CONFIG_SND_SBAWE) += snd-sb16-csp.o endif -obj-$(CONFIG_SND_ES968) += snd-es968.o snd-sb8-dsp.o snd-sb-common.o -obj-$(CONFIG_SND_ALS4000) += snd-sb-common.o ifeq ($(subst m,y,$(CONFIG_SND_SEQUENCER)),y) obj-$(CONFIG_SND_SBAWE) += snd-emu8000-synth.o endif diff --git a/sound/isa/sb/emu8000.c b/sound/isa/sb/emu8000.c index 61f4a0130161..01f06bf66086 100644 --- a/sound/isa/sb/emu8000.c +++ b/sound/isa/sb/emu8000.c @@ -25,6 +25,7 @@ #include <linux/wait.h> #include <linux/sched.h> #include <linux/slab.h> +#include <linux/ioport.h> #include <sound/core.h> #include <sound/emu8000.h> #include <sound/emu8000_reg.h> diff --git a/sound/isa/sb/sb16_main.c b/sound/isa/sb/sb16_main.c index 0d59af55cd1b..bd3ddcf38e68 100644 --- a/sound/isa/sb/sb16_main.c +++ b/sound/isa/sb/sb16_main.c @@ -209,11 +209,11 @@ static void snd_sb16_csp_capture_close(sb_t *chip) #else #define snd_sb16_csp_playback_prepare(chip, runtime) /*nop*/ #define snd_sb16_csp_capture_prepare(chip, runtime) /*nop*/ -#define snd_sb16_csp_update(chip) /*nop*/ +#define snd_sb16_csp_update(chip) /*nop*/ #define snd_sb16_csp_playback_open(chip, runtime) /*nop*/ -#define snd_sb16_csp_playback_close(chip) /*nop*/ +#define snd_sb16_csp_playback_close(chip) /*nop*/ #define snd_sb16_csp_capture_open(chip, runtime) /*nop*/ -#define snd_sb16_csp_capture_close(chip) /*nop*/ +#define snd_sb16_csp_capture_close(chip) /*nop*/ #endif diff --git a/sound/isa/sb/sb8.c b/sound/isa/sb/sb8.c index d668a174621a..1cbf406d389f 100644 --- a/sound/isa/sb/sb8.c +++ b/sound/isa/sb/sb8.c @@ -22,6 +22,7 @@ #include <sound/driver.h> #include <linux/init.h> #include <linux/slab.h> +#include <linux/ioport.h> #include <sound/core.h> #include <sound/sb.h> #include <sound/opl3.h> diff --git a/sound/isa/sb/sb_common.c b/sound/isa/sb/sb_common.c index 22da20bf6f21..3f7a796773a0 100644 --- a/sound/isa/sb/sb_common.c +++ b/sound/isa/sb/sb_common.c @@ -26,6 +26,7 @@ #include <linux/delay.h> #include <linux/init.h> #include <linux/slab.h> +#include <linux/ioport.h> #include <sound/core.h> #include <sound/sb.h> #include <sound/initval.h> diff --git a/sound/isa/sgalaxy.c b/sound/isa/sgalaxy.c index 10f4fdf0edb5..869c351d9fe8 100644 --- a/sound/isa/sgalaxy.c +++ b/sound/isa/sgalaxy.c @@ -119,7 +119,7 @@ static int __init snd_sgalaxy_setup_wss(unsigned long port, int irq, int dma) static int dma_bits[] = {1, 2, 0, 3}; int tmp, tmp1; - unsigned int flags; + unsigned long flags; if ((tmp = inb(port + 3)) == 0xff) { diff --git a/sound/isa/wavefront/wavefront_synth.c b/sound/isa/wavefront/wavefront_synth.c index b356878ebb87..777bb390fc0d 100644 --- a/sound/isa/wavefront/wavefront_synth.c +++ b/sound/isa/wavefront/wavefront_synth.c @@ -111,30 +111,6 @@ MODULE_PARM_DESC(ramcheck_time, "how many seconds to wait for the RAM test"); MODULE_PARM(osrun_time,"i"); MODULE_PARM_DESC(osrun_time, "how many seconds to wait for the ICS2115 OS"); -/* - * This sucks, hopefully it'll get standardised - */ - -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,18) && LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0) -#define loops_per_sec loops_per_jiffy*HZ -#elif LINUX_VERSION_CODE == KERNEL_VERSION(2,4,0) && defined(I_DIRTY_PAGES) /* linux/fs.h */ -#define loops_per_sec loops_per_jiffy*HZ -#elif LINUX_VERSION_CODE > KERNEL_VERSION(2,4,0) -#define loops_per_sec loops_per_jiffy*HZ -#endif - -#if defined(__alpha__) || defined(__powerpc__) -#ifdef __SMP__ -#define LOOPS_PER_SEC (cpu_data[smp_processor_id()].loops_per_sec) -#else -#define LOOPS_PER_SEC (loops_per_sec) -#endif -#endif - -#if defined(__i386__) -#define LOOPS_PER_SEC (current_cpu_data.loops_per_sec) -#endif - /* if WF_DEBUG not defined, no run-time debugging messages will be available via the debug flag setting. Given the current beta state of the driver, this will remain set until a future @@ -323,26 +299,16 @@ wavefront_wait (snd_wavefront_t *dev, int mask) { int i; - static int short_loop_cnt = 0; - - /* Compute the loop count that lets us sleep for about the - right amount of time, cache issues, bus speeds and all - other issues being unequal but largely irrelevant. - */ - - if (short_loop_cnt == 0) { - short_loop_cnt = wait_usecs * - (LOOPS_PER_SEC / 1000000); - } /* Spin for a short period of time, because >99% of all requests to the WaveFront can be serviced inline like this. */ - for (i = 0; i < short_loop_cnt; i++) { + for (i = 0; i < wait_usecs; i += 5) { if (wavefront_status (dev) & mask) { return 1; } + udelay(5); } for (i = 0; i < sleep_tries; i++) { @@ -1316,18 +1282,21 @@ wavefront_fetch_multisample (snd_wavefront_t *dev, for (i = 0; i < num_samples; i++) { char d[2]; + int val; - if ((d[0] = wavefront_read (dev)) == -1) { + if ((val = wavefront_read (dev)) == -1) { snd_printk ("upload multisample failed " "during sample loop.\n"); return -(EIO); } + d[0] = val; - if ((d[1] = wavefront_read (dev)) == -1) { + if ((val = wavefront_read (dev)) == -1) { snd_printk ("upload multisample failed " "during sample loop.\n"); return -(EIO); } + d[1] = val; header->hdr.ms.SampleNumber[i] = demunge_int32 ((unsigned char *) d, 2); diff --git a/sound/pci/Config.help b/sound/pci/Config.help new file mode 100644 index 000000000000..98a97d30de3b --- /dev/null +++ b/sound/pci/Config.help @@ -0,0 +1,75 @@ +CONFIG_SND_ALI5451 + Say 'Y' or 'M' to include support for ALI PCI Audio M5451 sound core. + +CONFIG_SND_CS46XX + Say 'Y' or 'M' to include support for Cirrus Logic CS4610 / CS4612 / + CS4614 / CS4615 / CS4622 / CS4624 / CS4630 / CS4280 chips. + +CONFIG_SND_CS46XX_ACCEPT_VALID + Say 'Y' to allow sample resolution for mmap() transfers. + +CONFIG_SND_EMU10K1 + Say 'Y' or 'M' to include support for Sound Blaster PCI 512, Live!, + Audigy and E-mu APS (partially supported). + +CONFIG_SND_KORG1212 + Say 'Y' or 'M' to include support for Korg 1212IO. + +CONFIG_SND_NM256 + Say 'Y' or 'M' to include support for NeoMagic NM256AV/ZX chips. + +CONFIG_SND_RME96 + Say 'Y' or 'M' to include support for RME Digi96, Digi96/8 and + Digi96/8 PRO/PAD/PST. + +CONFIG_SND_RME9652 + Say 'Y' or 'M' to include support for RME Hammerfall (RME Digi9652 / + Digi9636) soundcards. + +CONFIG_SND_TRIDENT + +CONFIG_SND_YMFPCI + Say 'Y' or 'M' to include support for Yamaha PCI audio chips - + YMF724, YMF724F, YMF740, YMF740C, YMF744, YMF754. + +CONFIG_SND_ALS4000 + Say 'Y' or 'M' to include support for Avance Logic ALS4000. + +CONFIG_SND_CMIPCI + Say 'Y' or 'M' to include support for C-Media CMI8338 and 8738 PCI + soundcards. + +CONFIG_SND_ENS1370 + Say 'Y' or 'M' to include support for Ensoniq AudioPCI ES1370. + +CONFIG_SND_ENS1371 + Say 'Y' or 'M' to include support for Ensoniq AudioPCI ES1371 and + Sound Blaster PCI 64 or 128 soundcards. + +CONFIG_SND_ES1938 + Say 'Y' or 'M' to include support for ESS Solo-1 (ES1938, ES1946) + soundcard. + +CONFIG_SND_ES1968 + Say 'Y' or 'M' to include support for ESS Maestro 1/2/2E. + +CONFIG_SND_MAESTRO3 + Say 'Y' or 'M' to include support for ESS Maestro 3 (Allegro) soundcard. + +CONFIG_SND_FM801 + Say 'Y' or 'M' to include support for ForteMedia FM801 based soundcards. + +CONFIG_SND_ICE1712 + Say 'Y' or 'M' to include support for ICE1712 (Envy24) based soundcards. + +CONFIG_SND_INTEL8X0 + Say 'Y' or 'M' to include support for Intel8x0 based soundcards. + +CONFIG_SND_SONICVIBES + Say 'Y' or 'M' to include support for S3 SonicVibes based soundcards. + +CONFIG_SND_VIA686 + Say 'Y' or 'M' to include support for VIA VT82C686A/B South Bridge. + +CONFIG_SND_VIA8233 + Say 'Y' or 'M' to include support for VIA VT8233 South Bridge. diff --git a/sound/pci/ymfpci/ymfpci.c b/sound/pci/ymfpci/ymfpci.c index 1bfa2b6e4a65..9d9df8f76c5a 100644 --- a/sound/pci/ymfpci/ymfpci.c +++ b/sound/pci/ymfpci/ymfpci.c @@ -109,7 +109,7 @@ static int __devinit snd_card_ymfpci_probe(struct pci_dev *pci, } legacy_ctrl = 0; - legacy_ctrl2 = 0; + legacy_ctrl2 = 0x0800; /* SMOD = 01 */ if (id->device >= 0x0010) { /* YMF 744/754 */ if (snd_fm_port[dev] < 0) diff --git a/sound/synth/Makefile b/sound/synth/Makefile index 6fc37031ca26..7bcf311f089d 100644 --- a/sound/synth/Makefile +++ b/sound/synth/Makefile @@ -15,8 +15,8 @@ export-objs := util_mem.o snd-util-mem-objs := util_mem.o # Toplevel Module Dependency -obj-$(CONFIG_SND_TRIDENT) += snd-util-mem.o obj-$(CONFIG_SND_EMU10K1) += snd-util-mem.o +obj-$(CONFIG_SND_TRIDENT) += snd-util-mem.o ifeq ($(subst m,y,$(CONFIG_SND_SEQUENCER)),y) obj-$(CONFIG_SND_SBAWE) += snd-util-mem.o endif |
