Commit 7d350417 authored by Jaroslav Kysela's avatar Jaroslav Kysela

ALSA update

  - reduced stack usage (>1024 bytes) in ioctl32 routines and PCM routines
  - PCM midlevel - fixed drop in release()
  - OPL3SA2 - removed wrong inclusion of <linux/isapnp.h>
  - EMU8000 - fixed compilation when sequencer is not selected
  - Wavefront - fixed compilation for GCC3
  - fixed gameport dependency in pci/Config.in
  - EMU10K1 - fixed icode peek ioctl in emufx()
  - YMFPCI - added FM legacy volume control
parent 56338b9f
......@@ -264,46 +264,56 @@ 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, unsigned int native_ctl)
{
// too big?
struct sndrv_ctl_elem_value data;
struct sndrv_ctl_elem_value32 data32;
struct sndrv_ctl_elem_value *data;
struct sndrv_ctl_elem_value32 *data32;
int err, i;
int type;
mm_segment_t oldseg;
/* 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;
data = kmalloc(sizeof(*data), GFP_KERNEL);
data32 = kmalloc(sizeof(*data32), GFP_KERNEL);
if (data == NULL || data32 == NULL) {
err = -ENOMEM;
goto __end;
}
if (copy_from_user(data32, (void*)arg, sizeof(*data32))) {
err = -EFAULT;
goto __end;
}
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) {
err = type;
goto __end;
}
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];
data->value.integer.value[i] = data32->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];
data->value.integer64.value[i] = data32->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];
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));
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;
data->value.iec958 = data32->value.iec958;
break;
default:
printk("unknown type %d\n", type);
......@@ -313,40 +323,46 @@ static int _snd_ioctl32_ctl_elem_value(unsigned int fd, unsigned int cmd, unsign
oldseg = get_fs();
set_fs(KERNEL_DS);
err = file->f_op->ioctl(file->f_dentry->d_inode, file, native_ctl, (unsigned long)&data);
err = file->f_op->ioctl(file->f_dentry->d_inode, file, native_ctl, (unsigned long)data);
set_fs(oldseg);
if (err < 0)
return err;
goto __end;
/* 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++)
data32.value.integer.value[i] = data.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++)
data32.value.integer64.value[i] = data.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++)
data32.value.enumerated.item[i] = data.value.enumerated.item[i];
data32->value.enumerated.item[i] = data->value.enumerated.item[i];
break;
case SNDRV_CTL_ELEM_TYPE_BYTES:
memcpy(data32.value.bytes.data, data.value.bytes.data,
sizeof(data.value.bytes.data));
memcpy(data32->value.bytes.data, data->value.bytes.data,
sizeof(data->value.bytes.data));
break;
case SNDRV_CTL_ELEM_TYPE_IEC958:
data32.value.iec958 = data.value.iec958;
data32->value.iec958 = data->value.iec958;
break;
default:
break;
}
}
if (copy_to_user((void*)arg, &data32, sizeof(data32)))
return -EFAULT;
return 0;
err = 0;
if (copy_to_user((void*)arg, data32, sizeof(*data32)))
err = -EFAULT;
__end:
if (data32)
kfree(data32);
if (data)
kfree(data);
return err;
}
DEFINE_ALSA_IOCTL_ENTRY(ctl_elem_read, ctl_elem_value, SNDRV_CTL_IOCTL_ELEM_READ);
......
......@@ -79,6 +79,44 @@ static int _snd_ioctl32_##type(unsigned int fd, unsigned int cmd, unsigned long
return 0;\
}
#define DEFINE_ALSA_IOCTL_BIG(type) \
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;\
int err;\
data32 = kcalloc(sizeof(*data32), GFP_KERNEL); \
data = kcalloc(sizeof(*data), GFP_KERNEL); \
if (data32 == NULL || data == NULL) { \
err = -ENOMEM; \
goto __end; \
}
if (copy_from_user(data32, (void*)arg, sizeof(*data32))) { \
err = -EFAULT; \
goto __end; \
}
memset(data, 0, sizeof(*data));\
convert_from_32(type, data, data32);\
oldseg = get_fs();\
set_fs(KERNEL_DS);\
err = file->f_op->ioctl(file->f_dentry->d_inode, file, native_ctl, (unsigned long)data);\
if (err < 0) \
goto __end;\
err = 0;\
if (native_ctl & (_IOC_READ << _IOC_DIRSHIFT)) {\
convert_to_32(type, data32, data);\
if (copy_to_user((void*)arg, data32, sizeof(*data32)))\
err = -EFAULT;\
}\
__end:\
if (data)\
kfree(data);\
if (data32)\
kfree(data32);\
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);\
......
......@@ -172,7 +172,7 @@ struct sndrv_pcm_status32 {
DEFINE_ALSA_IOCTL(pcm_uframes_str);
DEFINE_ALSA_IOCTL(pcm_sframes_str);
DEFINE_ALSA_IOCTL(pcm_hw_params);
DEFINE_ALSA_IOCTL_BIG(pcm_hw_params);
DEFINE_ALSA_IOCTL(pcm_sw_params);
DEFINE_ALSA_IOCTL(pcm_channel_info);
DEFINE_ALSA_IOCTL(pcm_status);
......@@ -230,7 +230,7 @@ static int _snd_ioctl32_xfern(unsigned int fd, unsigned int cmd, unsigned long a
snd_pcm_file_t *pcm_file;
snd_pcm_substream_t *substream;
struct sndrv_xfern32 data32, *srcptr = (struct sndrv_xfern32*)arg;
void *bufs[128];
void *bufs = NULL;
int err = 0, ch, i;
u32 *bufptr;
mm_segment_t oldseg;
......@@ -260,6 +260,9 @@ static int _snd_ioctl32_xfern(unsigned int fd, unsigned int cmd, unsigned long a
return -EFAULT;
__get_user(data32.bufs, &srcptr->bufs);
bufptr = (u32*)TO_PTR(data32.bufs);
bufs = kmalloc(sizeof(void *) * 128, GFP_KERNEL)
if (bufs == NULL)
return -ENOMEM;
for (i = 0; i < ch; i++) {
u32 ptr;
if (get_user(ptr, bufptr))
......@@ -278,10 +281,11 @@ static int _snd_ioctl32_xfern(unsigned int fd, unsigned int cmd, unsigned long a
break;
}
set_fs(oldseg);
if (err < 0)
return err;
if (put_user(err, &srcptr->result))
return -EFAULT;
if (err >= 0) {
if (put_user(err, &srcptr->result))
err = -EFAULT;
}
kfree(bufs);
return 0;
}
......@@ -343,24 +347,38 @@ static void snd_pcm_hw_convert_to_old_params(struct sndrv_pcm_hw_params_old32 *o
static int _snd_ioctl32_pcm_hw_params_old(unsigned int fd, unsigned int cmd, unsigned long arg, struct file *file, unsigned int native_ctl)
{
struct sndrv_pcm_hw_params_old32 data32;
struct sndrv_pcm_hw_params data;
struct sndrv_pcm_hw_params_old32 *data32;
struct sndrv_pcm_hw_params *data;
mm_segment_t oldseg;
int err;
if (copy_from_user(&data32, (void*)arg, sizeof(data32)))
return -EFAULT;
snd_pcm_hw_convert_from_old_params(&data, &data32);
data32 = kcalloc(sizeof(*data32), GFP_KERNEL);
data = kcalloc(sizeof(*data), GFP_KERNEL);
if (data32 == NULL || data == NULL) {
err = -ENOMEM;
goto __end;
}
if (copy_from_user(data32, (void*)arg, sizeof(*data32))) {
err = -EFAULT;
goto __end;
}
snd_pcm_hw_convert_from_old_params(data, data32);
oldseg = get_fs();
set_fs(KERNEL_DS);
err = file->f_op->ioctl(file->f_dentry->d_inode, file, native_ctl, (unsigned long)&data);
err = file->f_op->ioctl(file->f_dentry->d_inode, file, native_ctl, (unsigned long)data);
set_fs(oldseg);
if (err < 0)
return err;
snd_pcm_hw_convert_to_old_params(&data32, &data);
if (copy_to_user((void*)arg, &data32, sizeof(data32)))
return -EFAULT;
return 0;
goto __end;
snd_pcm_hw_convert_to_old_params(data32, data);
err = 0;
if (copy_to_user((void*)arg, data32, sizeof(*data32)))
err = -EFAULT;
__end:
if (data)
kfree(data);
if (data32)
kfree(data32);
return err;
}
......
......@@ -1473,7 +1473,7 @@ static int boundary_nearer(int min, int mindir,
int snd_pcm_hw_param_near(snd_pcm_t *pcm, snd_pcm_hw_params_t *params,
snd_pcm_hw_param_t var, unsigned int best, int *dir)
{
snd_pcm_hw_params_t save;
snd_pcm_hw_params_t *save = NULL;
int v;
unsigned int saved_min;
int last = 0;
......@@ -1493,30 +1493,42 @@ int snd_pcm_hw_param_near(snd_pcm_t *pcm, snd_pcm_hw_params_t *params,
maxdir = 1;
max--;
}
save = *params;
save = kmalloc(sizeof(*save), GFP_KERNEL);
if (save == NULL)
return -ENOMEM;
*save = *params;
saved_min = min;
min = snd_pcm_hw_param_min(pcm, params, var, min, &mindir);
if (min >= 0) {
snd_pcm_hw_params_t params1;
snd_pcm_hw_params_t *params1;
if (max < 0)
goto _end;
if ((unsigned int)min == saved_min && mindir == valdir)
goto _end;
params1 = save;
max = snd_pcm_hw_param_max(pcm, &params1, var, max, &maxdir);
if (max < 0)
params1 = kmalloc(sizeof(*params1), GFP_KERNEL);
if (params1 == NULL) {
kfree(save);
return -ENOMEM;
}
*params1 = *save;
max = snd_pcm_hw_param_max(pcm, params1, var, max, &maxdir);
if (max < 0) {
kfree(params1);
goto _end;
}
if (boundary_nearer(max, maxdir, best, valdir, min, mindir)) {
*params = params1;
*params = *params1;
last = 1;
}
kfree(params1);
} else {
*params = save;
*params = *save;
max = snd_pcm_hw_param_max(pcm, params, var, max, &maxdir);
assert(max >= 0);
last = 1;
}
_end:
kfree(save);
if (last)
v = snd_pcm_hw_param_last(pcm, params, var, dir);
else
......
......@@ -1848,7 +1848,10 @@ int snd_pcm_release(struct inode *inode, struct file *file)
snd_assert(substream != NULL, return -ENXIO);
snd_assert(!atomic_read(&substream->runtime->mmap_count), );
pcm = substream->pcm;
snd_pcm_capture_drop(substream);
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
snd_pcm_playback_drop(substream);
else
snd_pcm_capture_drop(substream);
fasync_helper(-1, file, 0, &substream->runtime->fasync);
down(&pcm->open_mutex);
snd_pcm_release_file(pcm_file);
......@@ -2110,7 +2113,7 @@ static int snd_pcm_playback_ioctl1(snd_pcm_substream_t *substream,
{
snd_xfern_t xfern, *_xfern = arg;
snd_pcm_runtime_t *runtime = substream->runtime;
void *bufs[128];
void *bufs;
snd_pcm_sframes_t result;
if (runtime->status->state == SNDRV_PCM_STATE_OPEN)
return -EBADFD;
......@@ -2120,9 +2123,15 @@ static int snd_pcm_playback_ioctl1(snd_pcm_substream_t *substream,
return -EFAULT;
if (copy_from_user(&xfern, _xfern, sizeof(xfern)))
return -EFAULT;
if (copy_from_user(bufs, xfern.bufs, sizeof(*bufs) * runtime->channels))
bufs = kmalloc(sizeof(void *) * runtime->channels, GFP_KERNEL);
if (bufs == NULL)
return -ENOMEM;
if (copy_from_user(bufs, xfern.bufs, sizeof(void *) * runtime->channels)) {
kfree(bufs);
return -EFAULT;
}
result = snd_pcm_lib_writev(substream, bufs, xfern.frames);
kfree(bufs);
__put_user(result, &_xfern->result);
return result < 0 ? result : 0;
}
......@@ -2181,7 +2190,7 @@ static int snd_pcm_capture_ioctl1(snd_pcm_substream_t *substream,
{
snd_xfern_t xfern, *_xfern = arg;
snd_pcm_runtime_t *runtime = substream->runtime;
void *bufs[128];
void *bufs;
snd_pcm_sframes_t result;
if (runtime->status->state == SNDRV_PCM_STATE_OPEN)
return -EBADFD;
......@@ -2191,9 +2200,15 @@ static int snd_pcm_capture_ioctl1(snd_pcm_substream_t *substream,
return -EFAULT;
if (copy_from_user(&xfern, _xfern, sizeof(xfern)))
return -EFAULT;
if (copy_from_user(bufs, xfern.bufs, sizeof(*bufs) * runtime->channels))
bufs = kmalloc(sizeof(void *) * runtime->channels, GFP_KERNEL);
if (bufs == NULL)
return -ENOMEM;
if (copy_from_user(bufs, xfern.bufs, sizeof(void *) * runtime->channels)) {
kfree(bufs);
return -EFAULT;
}
result = snd_pcm_lib_readv(substream, bufs, xfern.frames);
kfree(bufs);
__put_user(result, &_xfern->result);
return result < 0 ? result : 0;
}
......@@ -2343,7 +2358,7 @@ static ssize_t snd_pcm_readv(struct file *file, const struct iovec *_vector,
snd_pcm_runtime_t *runtime;
snd_pcm_sframes_t result;
unsigned long i;
void *bufs[128];
void *bufs;
snd_pcm_uframes_t frames;
pcm_file = snd_magic_cast(snd_pcm_file_t, file->private_data, return -ENXIO);
......@@ -2352,16 +2367,20 @@ static ssize_t snd_pcm_readv(struct file *file, const struct iovec *_vector,
runtime = substream->runtime;
if (runtime->status->state == SNDRV_PCM_STATE_OPEN)
return -EBADFD;
if (count > 128 || count != runtime->channels)
if (count > 1024 || count != runtime->channels)
return -EINVAL;
if (!frame_aligned(runtime, _vector->iov_len))
return -EINVAL;
frames = bytes_to_samples(runtime, _vector->iov_len);
bufs = kmalloc(sizeof(void *) * count, GFP_KERNEL);
if (bufs == NULL)
return -ENOMEM;
for (i = 0; i < count; ++i)
bufs[i] = _vector[i].iov_base;
result = snd_pcm_lib_readv(substream, bufs, frames);
if (result > 0)
result = frames_to_bytes(runtime, result);
kfree(bufs);
return result;
}
......@@ -2373,10 +2392,12 @@ static ssize_t snd_pcm_writev(struct file *file, const struct iovec *_vector,
snd_pcm_runtime_t *runtime;
snd_pcm_sframes_t result;
unsigned long i;
void *bufs[128];
void *bufs;
snd_pcm_uframes_t frames;
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 3, 0)
up(&file->f_dentry->d_inode->i_sem);
#endif
pcm_file = snd_magic_cast(snd_pcm_file_t, file->private_data, result = -ENXIO; goto end);
substream = pcm_file->substream;
snd_assert(substream != NULL, result = -ENXIO; goto end);
......@@ -2391,13 +2412,19 @@ static ssize_t snd_pcm_writev(struct file *file, const struct iovec *_vector,
goto end;
}
frames = bytes_to_samples(runtime, _vector->iov_len);
bufs = kcalloc(sizeof(void *) * count, GFP_KERNEL);
if (bufs == NULL)
return -ENOMEM;
for (i = 0; i < count; ++i)
bufs[i] = _vector[i].iov_base;
result = snd_pcm_lib_writev(substream, bufs, frames);
if (result > 0)
result = frames_to_bytes(runtime, result);
kfree(bufs);
end:
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 3, 0)
down(&file->f_dentry->d_inode->i_sem);
#endif
return result;
}
#endif
......
......@@ -22,7 +22,6 @@
#include <sound/driver.h>
#include <asm/io.h>
#include <linux/init.h>
#include <linux/isapnp.h>
#include <linux/pm.h>
#include <linux/slab.h>
#ifndef LINUX_ISAPNP_H
......
......@@ -1138,11 +1138,13 @@ snd_emu8000_new(snd_card_t *card, int index, long port, int seq_ports, snd_seq_d
snd_emu8000_free(hw);
return err;
}
#if defined(CONFIG_SND_SEQUENCER) || defined(CONFIG_SND_SEQUENCER_MODULE)
if (snd_seq_device_new(card, index, SNDRV_SEQ_DEV_ID_EMU8000,
sizeof(emu8000_t*), &awe) >= 0) {
strcpy(awe->name, "EMU-8000");
*(emu8000_t**)SNDRV_SEQ_DEVICE_ARGPTR(awe) = hw;
}
#endif
if (awe_ret)
*awe_ret = awe;
......
......@@ -114,7 +114,7 @@ MODULE_PARM_DESC(osrun_time, "how many seconds to wait for the ICS2115 OS");
#ifdef WF_DEBUG
#ifdef NEW_MACRO_VARARGS
#if defined(NEW_MACRO_VARARGS) || __GNUC__ >= 3
#define DPRINT(cond, ...) \
if ((dev->debug & (cond)) == (cond)) { \
snd_printk (__VA_ARGS__); \
......
......@@ -77,7 +77,7 @@ CONFIG_SND_ICE1712
CONFIG_SND_INTEL8X0
Say 'Y' or 'M' to include support for Intel8x0 based soundcards,
SiS 7012, AMD768/8111 and NVidia NForce chips.
SiS 7012, AMD768/8111, NVidia NForce and ALi 5455 chips.
CONFIG_SND_SONICVIBES
Say 'Y' or 'M' to include support for S3 SonicVibes based soundcards.
......
......@@ -4,9 +4,9 @@ mainmenu_option next_comment
comment 'PCI devices'
dep_tristate 'ALi PCI Audio M5451' CONFIG_SND_ALI5451 $CONFIG_SND
dep_tristate 'Cirrus Logic (Sound Fusion) CS4280/CS461x/CS462x/CS463x' CONFIG_SND_CS46XX $CONFIG_SND
dep_tristate 'Cirrus Logic (Sound Fusion) CS4280/CS461x/CS462x/CS463x' CONFIG_SND_CS46XX $CONFIG_SND $CONFIG_SOUND_GAMEPORT
dep_mbool ' Cirrus Logic (Sound Fusion) New DSP support (EXPERIMENTAL)' CONFIG_SND_CS46XX_NEW_DSP $CONFIG_SND_CS46XX $CONFIG_EXPERIMENTAL
dep_tristate 'Cirrus Logic (Sound Fusion) CS4281' CONFIG_SND_CS4281 $CONFIG_SND
dep_tristate 'Cirrus Logic (Sound Fusion) CS4281' CONFIG_SND_CS4281 $CONFIG_SND $CONFIG_SOUND_GAMEPORT
dep_tristate 'EMU10K1 (SB Live! & Audigy, E-mu APS)' CONFIG_SND_EMU10K1 $CONFIG_SND
dep_tristate 'Korg 1212 IO' CONFIG_SND_KORG1212 $CONFIG_SND
dep_tristate 'NeoMagic NM256AV/ZX' CONFIG_SND_NM256 $CONFIG_SND
......@@ -14,30 +14,19 @@ dep_tristate 'RME Digi32, 32/8, 32 PRO' CONFIG_SND_RME32 $CONFIG_SND
dep_tristate 'RME Digi96, 96/8, 96/8 PRO' CONFIG_SND_RME96 $CONFIG_SND
dep_tristate 'RME Digi9652 (Hammerfall)' CONFIG_SND_RME9652 $CONFIG_SND
dep_tristate 'RME Hammerfall DSP Audio' CONFIG_SND_HDSP $CONFIG_SND
dep_tristate 'Trident 4D-Wave DX/NX; SiS 7018' CONFIG_SND_TRIDENT $CONFIG_SND
dep_tristate 'Trident 4D-Wave DX/NX; SiS 7018' CONFIG_SND_TRIDENT $CONFIG_SND $CONFIG_SOUND_GAMEPORT
dep_tristate 'Yamaha YMF724/740/744/754' CONFIG_SND_YMFPCI $CONFIG_SND
dep_tristate 'Avance Logic ALS4000' CONFIG_SND_ALS4000 $CONFIG_SND
dep_tristate 'C-Media 8738, 8338' CONFIG_SND_CMIPCI $CONFIG_SND
dep_tristate '(Creative) Ensoniq AudioPCI 1370' CONFIG_SND_ENS1370 $CONFIG_SND
dep_tristate '(Creative) Ensoniq AudioPCI 1371/1373' CONFIG_SND_ENS1371 $CONFIG_SND
dep_tristate 'ESS ES1938/1946 (Solo-1)' CONFIG_SND_ES1938 $CONFIG_SND
dep_tristate 'ESS ES1938/1946 (Solo-1)' CONFIG_SND_ES1938 $CONFIG_SND $CONFIG_SOUND_GAMEPORT
dep_tristate 'ESS ES1968/1978 (Maestro-1/2/2E)' CONFIG_SND_ES1968 $CONFIG_SND
dep_tristate 'ESS Allegro/Maestro3' CONFIG_SND_MAESTRO3 $CONFIG_SND
dep_tristate 'ForteMedia FM801' CONFIG_SND_FM801 $CONFIG_SND
dep_tristate 'ICEnsemble ICE1712 (Envy24)' CONFIG_SND_ICE1712 $CONFIG_SND
dep_tristate 'Intel i8x0/MX440, SiS 7012; Ali 5455; NForce Audio; AMD768/8111' CONFIG_SND_INTEL8X0 $CONFIG_SND
dep_tristate 'S3 SonicVibes' CONFIG_SND_SONICVIBES $CONFIG_SND
dep_tristate 'S3 SonicVibes' CONFIG_SND_SONICVIBES $CONFIG_SND $CONFIG_SOUND_GAMEPORT
dep_tristate 'VIA 82C686A/B, 8233 South Bridge' CONFIG_SND_VIA82XX $CONFIG_SND
# define gameport if necessary
if [ "$CONFIG_INPUT_GAMEPORT" != "n" ]; then
if [ "$CONFIG_SND_CS4281" = "y" \
-o "$CONFIG_SND_ES1938" = "y" \
-o "$CONFIG_SND_CS46XX" = "y" \
-o "$CONFIG_SND_SONICVIBES" = "y" \
-o "$CONFIG_SND_TRIDENT" = "y" ]; then
define_tristate CONFIG_INPUT_GAMEPORT y
fi
fi
endmenu
......@@ -862,6 +862,7 @@ static void snd_emu10k1_tram_peek(emu10k1_t *emu, emu10k1_fx8010_code_t *icode)
{
int tram;
memset(icode->tram_valid, 0, sizeof(icode->tram_valid));
for (tram = 0; tram < 0xa0; tram++) {
set_bit(tram, icode->tram_valid);
icode->tram_data_map[tram] = snd_emu10k1_ptr_read(emu, TANKMEMDATAREGBASE + tram, 0);
......@@ -885,6 +886,7 @@ static void snd_emu10k1_code_peek(emu10k1_t *emu, emu10k1_fx8010_code_t *icode)
{
u32 pc;
memset(icode->code_valid, 0, sizeof(icode->code_valid));
for (pc = 0; pc < 512; pc++) {
set_bit(pc, icode->code_valid);
icode->code[pc][0] = snd_emu10k1_efx_read(emu, pc * 2);
......@@ -1031,7 +1033,7 @@ static void snd_emu10k1_del_controls(emu10k1_t *emu, emu10k1_fx8010_code_t *icod
}
}
static void snd_emu10k1_list_controls(emu10k1_t *emu, emu10k1_fx8010_code_t *icode)
static int snd_emu10k1_list_controls(emu10k1_t *emu, emu10k1_fx8010_code_t *icode)
{
int i = 0, j;
unsigned int total = 0;
......@@ -1044,7 +1046,7 @@ static void snd_emu10k1_list_controls(emu10k1_t *emu, emu10k1_fx8010_code_t *ico
list_for_each(list, &emu->fx8010.gpr_ctl) {
ctl = emu10k1_gpr_ctl(list);
total++;
if (i < icode->gpr_list_control_count) {
if (_gctl && i < icode->gpr_list_control_count) {
memset(&gctl, 0, sizeof(gctl));
id = &ctl->kcontrol->id;
gctl.id.iface = id->iface;
......@@ -1061,13 +1063,14 @@ static void snd_emu10k1_list_controls(emu10k1_t *emu, emu10k1_fx8010_code_t *ico
gctl.min = ctl->min;
gctl.max = ctl->max;
gctl.translation = ctl->translation;
snd_runtime_check(copy_to_user(_gctl, &gctl, sizeof(gctl)) == 0, goto __next);
if (copy_to_user(_gctl, &gctl, sizeof(gctl)))
return -EFAULT;
_gctl++;
i++;
}
__next:
_gctl++;
i++;
}
icode->gpr_list_control_total = total;
return 0;
}
static int snd_emu10k1_icode_poke(emu10k1_t *emu, emu10k1_fx8010_code_t *icode)
......@@ -1103,6 +1106,8 @@ static int snd_emu10k1_icode_poke(emu10k1_t *emu, emu10k1_fx8010_code_t *icode)
static int snd_emu10k1_icode_peek(emu10k1_t *emu, emu10k1_fx8010_code_t *icode)
{
int err;
down(&emu->fx8010.lock);
strncpy(icode->name, emu->fx8010.name, sizeof(icode->name)-1);
emu->fx8010.name[sizeof(emu->fx8010.name)-1] = '\0';
......@@ -1110,9 +1115,9 @@ static int snd_emu10k1_icode_peek(emu10k1_t *emu, emu10k1_fx8010_code_t *icode)
snd_emu10k1_gpr_peek(emu, icode);
snd_emu10k1_tram_peek(emu, icode);
snd_emu10k1_code_peek(emu, icode);
snd_emu10k1_list_controls(emu, icode);
err = snd_emu10k1_list_controls(emu, icode);
up(&emu->fx8010.lock);
return 0;
return err;
}
static int snd_emu10k1_ipcm_poke(emu10k1_t *emu, emu10k1_fx8010_pcm_t *ipcm)
......@@ -2171,9 +2176,13 @@ static int snd_emu10k1_fx8010_ioctl(snd_hwdep_t * hw, struct file *file, unsigne
kfree(icode);
return res;
case SNDRV_EMU10K1_IOCTL_CODE_PEEK:
icode = (emu10k1_fx8010_code_t *)snd_kcalloc(sizeof(*icode), GFP_KERNEL);
icode = (emu10k1_fx8010_code_t *)kmalloc(sizeof(*icode), GFP_KERNEL);
if (icode == NULL)
return -ENOMEM;
if (copy_from_user(icode, (void *)arg, sizeof(*icode))) {
kfree(icode);
return -EFAULT;
}
res = snd_emu10k1_icode_peek(emu, icode);
if (res == 0 && copy_to_user((void *)arg, icode, sizeof(*icode))) {
kfree(icode);
......
......@@ -1538,6 +1538,7 @@ YMFPCI_DOUBLE("ADC Playback Volume", 0, YDSXGR_PRIADCOUTVOL),
YMFPCI_DOUBLE("ADC Capture Volume", 0, YDSXGR_PRIADCLOOPVOL),
YMFPCI_DOUBLE("ADC Playback Volume", 1, YDSXGR_SECADCOUTVOL),
YMFPCI_DOUBLE("ADC Capture Volume", 1, YDSXGR_SECADCLOOPVOL),
YMFPCI_DOUBLE("FM Legacy Volume", 0, YDSXGR_LEGACYOUTVOL),
YMFPCI_DOUBLE(SNDRV_CTL_NAME_IEC958("AC97 ", PLAYBACK,VOLUME), 0, YDSXGR_ZVOUTVOL),
YMFPCI_DOUBLE(SNDRV_CTL_NAME_IEC958("", CAPTURE,VOLUME), 0, YDSXGR_ZVLOOPVOL),
YMFPCI_DOUBLE(SNDRV_CTL_NAME_IEC958("AC97 ",PLAYBACK,VOLUME), 1, YDSXGR_SPDIFOUTVOL),
......@@ -2022,6 +2023,7 @@ static int __devinit snd_ymfpci_memalloc(ymfpci_t *chip)
snd_ymfpci_writel(chip, YDSXGR_NATIVEADCINVOL, 0x3fff3fff);
snd_ymfpci_writel(chip, YDSXGR_NATIVEDACINVOL, 0x3fff3fff);
snd_ymfpci_writel(chip, YDSXGR_PRIADCLOOPVOL, 0x3fff3fff);
snd_ymfpci_writel(chip, YDSXGR_LEGACYOUTVOL, 0x3fff3fff);
return 0;
}
......@@ -2036,6 +2038,7 @@ static int snd_ymfpci_free(ymfpci_t *chip)
if (chip->res_reg_area) { /* don't touch busy hardware */
snd_ymfpci_writel(chip, YDSXGR_NATIVEDACOUTVOL, 0);
snd_ymfpci_writel(chip, YDSXGR_BUF441OUTVOL, 0);
snd_ymfpci_writel(chip, YDSXGR_LEGACYOUTVOL, 0);
snd_ymfpci_writel(chip, YDSXGR_STATUS, ~0);
snd_ymfpci_disable_dsp(chip);
snd_ymfpci_writel(chip, YDSXGR_PLAYCTRLBASE, 0);
......@@ -2100,6 +2103,7 @@ static int saved_regs_index[] = {
YDSXGR_SPDIFLOOPVOL,
YDSXGR_SPDIFOUTVOL,
YDSXGR_ZVOUTVOL,
YDSXGR_LEGACYOUTVOL,
/* address bases */
YDSXGR_PLAYCTRLBASE,
YDSXGR_RECCTRLBASE,
......@@ -2112,7 +2116,7 @@ static int saved_regs_index[] = {
YDSXGR_ADCFORMAT,
YDSXGR_ADCSLOTSR,
};
#define YDSXGR_NUM_SAVED_REGS (sizeof(saved_regs_index)/sizeof(saved_regs_index[0]))
#define YDSXGR_NUM_SAVED_REGS ARRAY_SIZE(saved_regs_index)
void snd_ymfpci_suspend(ymfpci_t *chip)
{
......
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