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) ...@@ -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) 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_value data; struct sndrv_ctl_elem_value32 *data32;
struct sndrv_ctl_elem_value32 data32;
int err, i; int err, i;
int type; int type;
mm_segment_t oldseg; mm_segment_t oldseg;
/* FIXME: check the sane ioctl.. */ /* FIXME: check the sane ioctl.. */
if (copy_from_user(&data32, (void*)arg, sizeof(data32))) data = kmalloc(sizeof(*data), GFP_KERNEL);
return -EFAULT; data32 = kmalloc(sizeof(*data32), GFP_KERNEL);
memset(&data, 0, sizeof(data)); if (data == NULL || data32 == NULL) {
data.id = data32.id; err = -ENOMEM;
data.indirect = data32.indirect; goto __end;
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 (copy_from_user(data32, (void*)arg, sizeof(*data32))) {
if (type < 0) err = -EFAULT;
return type; 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) { if (! data.indirect) {
switch (type) { switch (type) {
case SNDRV_CTL_ELEM_TYPE_BOOLEAN: case SNDRV_CTL_ELEM_TYPE_BOOLEAN:
case SNDRV_CTL_ELEM_TYPE_INTEGER: case SNDRV_CTL_ELEM_TYPE_INTEGER:
for (i = 0; i < 128; i++) for (i = 0; i < 128; i++)
data.value.integer.value[i] = data32.value.integer.value[i]; data->value.integer.value[i] = data32->value.integer.value[i];
break; break;
case SNDRV_CTL_ELEM_TYPE_INTEGER64: case SNDRV_CTL_ELEM_TYPE_INTEGER64:
for (i = 0; i < 64; i++) for (i = 0; i < 64; i++)
data.value.integer64.value[i] = data32.value.integer64.value[i]; data->value.integer64.value[i] = data32->value.integer64.value[i];
break; break;
case SNDRV_CTL_ELEM_TYPE_ENUMERATED: case SNDRV_CTL_ELEM_TYPE_ENUMERATED:
for (i = 0; i < 128; i++) for (i = 0; i < 128; i++)
data.value.enumerated.item[i] = data32.value.enumerated.item[i]; data->value.enumerated.item[i] = data32->value.enumerated.item[i];
break; break;
case SNDRV_CTL_ELEM_TYPE_BYTES: case SNDRV_CTL_ELEM_TYPE_BYTES:
memcpy(data.value.bytes.data, data32.value.bytes.data, memcpy(data->value.bytes.data, data32->value.bytes.data,
sizeof(data.value.bytes.data)); sizeof(data->value.bytes.data));
break; break;
case SNDRV_CTL_ELEM_TYPE_IEC958: case SNDRV_CTL_ELEM_TYPE_IEC958:
data.value.iec958 = data32.value.iec958; data->value.iec958 = data32->value.iec958;
break; break;
default: default:
printk("unknown type %d\n", type); printk("unknown type %d\n", type);
...@@ -313,40 +323,46 @@ static int _snd_ioctl32_ctl_elem_value(unsigned int fd, unsigned int cmd, unsign ...@@ -313,40 +323,46 @@ static int _snd_ioctl32_ctl_elem_value(unsigned int fd, unsigned int cmd, unsign
oldseg = get_fs(); oldseg = get_fs();
set_fs(KERNEL_DS); 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); set_fs(oldseg);
if (err < 0) if (err < 0)
return err; goto __end;
/* restore info to 32bit */ /* restore info to 32bit */
if (! data.indirect) { if (! data.indirect) {
switch (type) { switch (type) {
case SNDRV_CTL_ELEM_TYPE_BOOLEAN: case SNDRV_CTL_ELEM_TYPE_BOOLEAN:
case SNDRV_CTL_ELEM_TYPE_INTEGER: case SNDRV_CTL_ELEM_TYPE_INTEGER:
for (i = 0; i < 128; i++) for (i = 0; i < 128; i++)
data32.value.integer.value[i] = data.value.integer.value[i]; data32->value.integer.value[i] = data->value.integer.value[i];
break; break;
case SNDRV_CTL_ELEM_TYPE_INTEGER64: case SNDRV_CTL_ELEM_TYPE_INTEGER64:
for (i = 0; i < 64; i++) for (i = 0; i < 64; i++)
data32.value.integer64.value[i] = data.value.integer64.value[i]; data32->value.integer64.value[i] = data->value.integer64.value[i];
break; break;
case SNDRV_CTL_ELEM_TYPE_ENUMERATED: case SNDRV_CTL_ELEM_TYPE_ENUMERATED:
for (i = 0; i < 128; i++) for (i = 0; i < 128; i++)
data32.value.enumerated.item[i] = data.value.enumerated.item[i]; data32->value.enumerated.item[i] = data->value.enumerated.item[i];
break; break;
case SNDRV_CTL_ELEM_TYPE_BYTES: case SNDRV_CTL_ELEM_TYPE_BYTES:
memcpy(data32.value.bytes.data, data.value.bytes.data, memcpy(data32->value.bytes.data, data->value.bytes.data,
sizeof(data.value.bytes.data)); sizeof(data->value.bytes.data));
break; break;
case SNDRV_CTL_ELEM_TYPE_IEC958: case SNDRV_CTL_ELEM_TYPE_IEC958:
data32.value.iec958 = data.value.iec958; data32->value.iec958 = data->value.iec958;
break; break;
default: default:
break; break;
} }
} }
if (copy_to_user((void*)arg, &data32, sizeof(data32))) err = 0;
return -EFAULT; if (copy_to_user((void*)arg, data32, sizeof(*data32)))
return 0; 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); 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 ...@@ -79,6 +79,44 @@ static int _snd_ioctl32_##type(unsigned int fd, unsigned int cmd, unsigned long
return 0;\ 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) \ #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) {\ 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);\ return _snd_ioctl32_##type(fd, cmd, arg, file, native_ctl);\
......
...@@ -172,7 +172,7 @@ struct sndrv_pcm_status32 { ...@@ -172,7 +172,7 @@ struct sndrv_pcm_status32 {
DEFINE_ALSA_IOCTL(pcm_uframes_str); DEFINE_ALSA_IOCTL(pcm_uframes_str);
DEFINE_ALSA_IOCTL(pcm_sframes_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_sw_params);
DEFINE_ALSA_IOCTL(pcm_channel_info); DEFINE_ALSA_IOCTL(pcm_channel_info);
DEFINE_ALSA_IOCTL(pcm_status); DEFINE_ALSA_IOCTL(pcm_status);
...@@ -230,7 +230,7 @@ static int _snd_ioctl32_xfern(unsigned int fd, unsigned int cmd, unsigned long a ...@@ -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_file_t *pcm_file;
snd_pcm_substream_t *substream; snd_pcm_substream_t *substream;
struct sndrv_xfern32 data32, *srcptr = (struct sndrv_xfern32*)arg; struct sndrv_xfern32 data32, *srcptr = (struct sndrv_xfern32*)arg;
void *bufs[128]; void *bufs = NULL;
int err = 0, ch, i; int err = 0, ch, i;
u32 *bufptr; u32 *bufptr;
mm_segment_t oldseg; mm_segment_t oldseg;
...@@ -260,6 +260,9 @@ static int _snd_ioctl32_xfern(unsigned int fd, unsigned int cmd, unsigned long a ...@@ -260,6 +260,9 @@ static int _snd_ioctl32_xfern(unsigned int fd, unsigned int cmd, unsigned long a
return -EFAULT; return -EFAULT;
__get_user(data32.bufs, &srcptr->bufs); __get_user(data32.bufs, &srcptr->bufs);
bufptr = (u32*)TO_PTR(data32.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++) { for (i = 0; i < ch; i++) {
u32 ptr; u32 ptr;
if (get_user(ptr, bufptr)) if (get_user(ptr, bufptr))
...@@ -278,10 +281,11 @@ static int _snd_ioctl32_xfern(unsigned int fd, unsigned int cmd, unsigned long a ...@@ -278,10 +281,11 @@ static int _snd_ioctl32_xfern(unsigned int fd, unsigned int cmd, unsigned long a
break; break;
} }
set_fs(oldseg); set_fs(oldseg);
if (err < 0) if (err >= 0) {
return err; if (put_user(err, &srcptr->result))
if (put_user(err, &srcptr->result)) err = -EFAULT;
return -EFAULT; }
kfree(bufs);
return 0; return 0;
} }
...@@ -343,24 +347,38 @@ static void snd_pcm_hw_convert_to_old_params(struct sndrv_pcm_hw_params_old32 *o ...@@ -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) 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_old32 *data32;
struct sndrv_pcm_hw_params data; struct sndrv_pcm_hw_params *data;
mm_segment_t oldseg; mm_segment_t oldseg;
int err; int err;
if (copy_from_user(&data32, (void*)arg, sizeof(data32))) data32 = kcalloc(sizeof(*data32), GFP_KERNEL);
return -EFAULT; data = kcalloc(sizeof(*data), GFP_KERNEL);
snd_pcm_hw_convert_from_old_params(&data, &data32); 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(); oldseg = get_fs();
set_fs(KERNEL_DS); 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); set_fs(oldseg);
if (err < 0) if (err < 0)
return err; goto __end;
snd_pcm_hw_convert_to_old_params(&data32, &data); snd_pcm_hw_convert_to_old_params(data32, data);
if (copy_to_user((void*)arg, &data32, sizeof(data32))) err = 0;
return -EFAULT; if (copy_to_user((void*)arg, data32, sizeof(*data32)))
return 0; 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, ...@@ -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, 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_param_t var, unsigned int best, int *dir)
{ {
snd_pcm_hw_params_t save; snd_pcm_hw_params_t *save = NULL;
int v; int v;
unsigned int saved_min; unsigned int saved_min;
int last = 0; int last = 0;
...@@ -1493,30 +1493,42 @@ int snd_pcm_hw_param_near(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, ...@@ -1493,30 +1493,42 @@ int snd_pcm_hw_param_near(snd_pcm_t *pcm, snd_pcm_hw_params_t *params,
maxdir = 1; maxdir = 1;
max--; max--;
} }
save = *params; save = kmalloc(sizeof(*save), GFP_KERNEL);
if (save == NULL)
return -ENOMEM;
*save = *params;
saved_min = min; saved_min = min;
min = snd_pcm_hw_param_min(pcm, params, var, min, &mindir); min = snd_pcm_hw_param_min(pcm, params, var, min, &mindir);
if (min >= 0) { if (min >= 0) {
snd_pcm_hw_params_t params1; snd_pcm_hw_params_t *params1;
if (max < 0) if (max < 0)
goto _end; goto _end;
if ((unsigned int)min == saved_min && mindir == valdir) if ((unsigned int)min == saved_min && mindir == valdir)
goto _end; goto _end;
params1 = save; params1 = kmalloc(sizeof(*params1), GFP_KERNEL);
max = snd_pcm_hw_param_max(pcm, &params1, var, max, &maxdir); if (params1 == NULL) {
if (max < 0) kfree(save);
return -ENOMEM;
}
*params1 = *save;
max = snd_pcm_hw_param_max(pcm, params1, var, max, &maxdir);
if (max < 0) {
kfree(params1);
goto _end; goto _end;
}
if (boundary_nearer(max, maxdir, best, valdir, min, mindir)) { if (boundary_nearer(max, maxdir, best, valdir, min, mindir)) {
*params = params1; *params = *params1;
last = 1; last = 1;
} }
kfree(params1);
} else { } else {
*params = save; *params = *save;
max = snd_pcm_hw_param_max(pcm, params, var, max, &maxdir); max = snd_pcm_hw_param_max(pcm, params, var, max, &maxdir);
assert(max >= 0); assert(max >= 0);
last = 1; last = 1;
} }
_end: _end:
kfree(save);
if (last) if (last)
v = snd_pcm_hw_param_last(pcm, params, var, dir); v = snd_pcm_hw_param_last(pcm, params, var, dir);
else else
......
...@@ -1848,7 +1848,10 @@ int snd_pcm_release(struct inode *inode, struct file *file) ...@@ -1848,7 +1848,10 @@ int snd_pcm_release(struct inode *inode, struct file *file)
snd_assert(substream != NULL, return -ENXIO); snd_assert(substream != NULL, return -ENXIO);
snd_assert(!atomic_read(&substream->runtime->mmap_count), ); snd_assert(!atomic_read(&substream->runtime->mmap_count), );
pcm = substream->pcm; 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); fasync_helper(-1, file, 0, &substream->runtime->fasync);
down(&pcm->open_mutex); down(&pcm->open_mutex);
snd_pcm_release_file(pcm_file); snd_pcm_release_file(pcm_file);
...@@ -2110,7 +2113,7 @@ static int snd_pcm_playback_ioctl1(snd_pcm_substream_t *substream, ...@@ -2110,7 +2113,7 @@ static int snd_pcm_playback_ioctl1(snd_pcm_substream_t *substream,
{ {
snd_xfern_t xfern, *_xfern = arg; snd_xfern_t xfern, *_xfern = arg;
snd_pcm_runtime_t *runtime = substream->runtime; snd_pcm_runtime_t *runtime = substream->runtime;
void *bufs[128]; void *bufs;
snd_pcm_sframes_t result; snd_pcm_sframes_t result;
if (runtime->status->state == SNDRV_PCM_STATE_OPEN) if (runtime->status->state == SNDRV_PCM_STATE_OPEN)
return -EBADFD; return -EBADFD;
...@@ -2120,9 +2123,15 @@ static int snd_pcm_playback_ioctl1(snd_pcm_substream_t *substream, ...@@ -2120,9 +2123,15 @@ static int snd_pcm_playback_ioctl1(snd_pcm_substream_t *substream,
return -EFAULT; return -EFAULT;
if (copy_from_user(&xfern, _xfern, sizeof(xfern))) if (copy_from_user(&xfern, _xfern, sizeof(xfern)))
return -EFAULT; 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; return -EFAULT;
}
result = snd_pcm_lib_writev(substream, bufs, xfern.frames); result = snd_pcm_lib_writev(substream, bufs, xfern.frames);
kfree(bufs);
__put_user(result, &_xfern->result); __put_user(result, &_xfern->result);
return result < 0 ? result : 0; return result < 0 ? result : 0;
} }
...@@ -2181,7 +2190,7 @@ static int snd_pcm_capture_ioctl1(snd_pcm_substream_t *substream, ...@@ -2181,7 +2190,7 @@ static int snd_pcm_capture_ioctl1(snd_pcm_substream_t *substream,
{ {
snd_xfern_t xfern, *_xfern = arg; snd_xfern_t xfern, *_xfern = arg;
snd_pcm_runtime_t *runtime = substream->runtime; snd_pcm_runtime_t *runtime = substream->runtime;
void *bufs[128]; void *bufs;
snd_pcm_sframes_t result; snd_pcm_sframes_t result;
if (runtime->status->state == SNDRV_PCM_STATE_OPEN) if (runtime->status->state == SNDRV_PCM_STATE_OPEN)
return -EBADFD; return -EBADFD;
...@@ -2191,9 +2200,15 @@ static int snd_pcm_capture_ioctl1(snd_pcm_substream_t *substream, ...@@ -2191,9 +2200,15 @@ static int snd_pcm_capture_ioctl1(snd_pcm_substream_t *substream,
return -EFAULT; return -EFAULT;
if (copy_from_user(&xfern, _xfern, sizeof(xfern))) if (copy_from_user(&xfern, _xfern, sizeof(xfern)))
return -EFAULT; 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; return -EFAULT;
}
result = snd_pcm_lib_readv(substream, bufs, xfern.frames); result = snd_pcm_lib_readv(substream, bufs, xfern.frames);
kfree(bufs);
__put_user(result, &_xfern->result); __put_user(result, &_xfern->result);
return result < 0 ? result : 0; return result < 0 ? result : 0;
} }
...@@ -2343,7 +2358,7 @@ static ssize_t snd_pcm_readv(struct file *file, const struct iovec *_vector, ...@@ -2343,7 +2358,7 @@ static ssize_t snd_pcm_readv(struct file *file, const struct iovec *_vector,
snd_pcm_runtime_t *runtime; snd_pcm_runtime_t *runtime;
snd_pcm_sframes_t result; snd_pcm_sframes_t result;
unsigned long i; unsigned long i;
void *bufs[128]; void *bufs;
snd_pcm_uframes_t frames; snd_pcm_uframes_t frames;
pcm_file = snd_magic_cast(snd_pcm_file_t, file->private_data, return -ENXIO); 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, ...@@ -2352,16 +2367,20 @@ static ssize_t snd_pcm_readv(struct file *file, const struct iovec *_vector,
runtime = substream->runtime; runtime = substream->runtime;
if (runtime->status->state == SNDRV_PCM_STATE_OPEN) if (runtime->status->state == SNDRV_PCM_STATE_OPEN)
return -EBADFD; return -EBADFD;
if (count > 128 || count != runtime->channels) if (count > 1024 || count != runtime->channels)
return -EINVAL; return -EINVAL;
if (!frame_aligned(runtime, _vector->iov_len)) if (!frame_aligned(runtime, _vector->iov_len))
return -EINVAL; return -EINVAL;
frames = bytes_to_samples(runtime, _vector->iov_len); 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) for (i = 0; i < count; ++i)
bufs[i] = _vector[i].iov_base; bufs[i] = _vector[i].iov_base;
result = snd_pcm_lib_readv(substream, bufs, frames); result = snd_pcm_lib_readv(substream, bufs, frames);
if (result > 0) if (result > 0)
result = frames_to_bytes(runtime, result); result = frames_to_bytes(runtime, result);
kfree(bufs);
return result; return result;
} }
...@@ -2373,10 +2392,12 @@ static ssize_t snd_pcm_writev(struct file *file, const struct iovec *_vector, ...@@ -2373,10 +2392,12 @@ static ssize_t snd_pcm_writev(struct file *file, const struct iovec *_vector,
snd_pcm_runtime_t *runtime; snd_pcm_runtime_t *runtime;
snd_pcm_sframes_t result; snd_pcm_sframes_t result;
unsigned long i; unsigned long i;
void *bufs[128]; void *bufs;
snd_pcm_uframes_t frames; snd_pcm_uframes_t frames;
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 3, 0)
up(&file->f_dentry->d_inode->i_sem); 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); pcm_file = snd_magic_cast(snd_pcm_file_t, file->private_data, result = -ENXIO; goto end);
substream = pcm_file->substream; substream = pcm_file->substream;
snd_assert(substream != NULL, result = -ENXIO; goto end); 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, ...@@ -2391,13 +2412,19 @@ static ssize_t snd_pcm_writev(struct file *file, const struct iovec *_vector,
goto end; goto end;
} }
frames = bytes_to_samples(runtime, _vector->iov_len); 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) for (i = 0; i < count; ++i)
bufs[i] = _vector[i].iov_base; bufs[i] = _vector[i].iov_base;
result = snd_pcm_lib_writev(substream, bufs, frames); result = snd_pcm_lib_writev(substream, bufs, frames);
if (result > 0) if (result > 0)
result = frames_to_bytes(runtime, result); result = frames_to_bytes(runtime, result);
kfree(bufs);
end: end:
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 3, 0)
down(&file->f_dentry->d_inode->i_sem); down(&file->f_dentry->d_inode->i_sem);
#endif
return result; return result;
} }
#endif #endif
......
...@@ -22,7 +22,6 @@ ...@@ -22,7 +22,6 @@
#include <sound/driver.h> #include <sound/driver.h>
#include <asm/io.h> #include <asm/io.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/isapnp.h>
#include <linux/pm.h> #include <linux/pm.h>
#include <linux/slab.h> #include <linux/slab.h>
#ifndef LINUX_ISAPNP_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 ...@@ -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); snd_emu8000_free(hw);
return err; return err;
} }
#if defined(CONFIG_SND_SEQUENCER) || defined(CONFIG_SND_SEQUENCER_MODULE)
if (snd_seq_device_new(card, index, SNDRV_SEQ_DEV_ID_EMU8000, if (snd_seq_device_new(card, index, SNDRV_SEQ_DEV_ID_EMU8000,
sizeof(emu8000_t*), &awe) >= 0) { sizeof(emu8000_t*), &awe) >= 0) {
strcpy(awe->name, "EMU-8000"); strcpy(awe->name, "EMU-8000");
*(emu8000_t**)SNDRV_SEQ_DEVICE_ARGPTR(awe) = hw; *(emu8000_t**)SNDRV_SEQ_DEVICE_ARGPTR(awe) = hw;
} }
#endif
if (awe_ret) if (awe_ret)
*awe_ret = awe; *awe_ret = awe;
......
...@@ -114,7 +114,7 @@ MODULE_PARM_DESC(osrun_time, "how many seconds to wait for the ICS2115 OS"); ...@@ -114,7 +114,7 @@ MODULE_PARM_DESC(osrun_time, "how many seconds to wait for the ICS2115 OS");
#ifdef WF_DEBUG #ifdef WF_DEBUG
#ifdef NEW_MACRO_VARARGS #if defined(NEW_MACRO_VARARGS) || __GNUC__ >= 3
#define DPRINT(cond, ...) \ #define DPRINT(cond, ...) \
if ((dev->debug & (cond)) == (cond)) { \ if ((dev->debug & (cond)) == (cond)) { \
snd_printk (__VA_ARGS__); \ snd_printk (__VA_ARGS__); \
......
...@@ -77,7 +77,7 @@ CONFIG_SND_ICE1712 ...@@ -77,7 +77,7 @@ CONFIG_SND_ICE1712
CONFIG_SND_INTEL8X0 CONFIG_SND_INTEL8X0
Say 'Y' or 'M' to include support for Intel8x0 based soundcards, 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 CONFIG_SND_SONICVIBES
Say 'Y' or 'M' to include support for S3 SonicVibes based soundcards. Say 'Y' or 'M' to include support for S3 SonicVibes based soundcards.
......
...@@ -4,9 +4,9 @@ mainmenu_option next_comment ...@@ -4,9 +4,9 @@ mainmenu_option next_comment
comment 'PCI devices' comment 'PCI devices'
dep_tristate 'ALi PCI Audio M5451' CONFIG_SND_ALI5451 $CONFIG_SND 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_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 'EMU10K1 (SB Live! & Audigy, E-mu APS)' CONFIG_SND_EMU10K1 $CONFIG_SND
dep_tristate 'Korg 1212 IO' CONFIG_SND_KORG1212 $CONFIG_SND dep_tristate 'Korg 1212 IO' CONFIG_SND_KORG1212 $CONFIG_SND
dep_tristate 'NeoMagic NM256AV/ZX' CONFIG_SND_NM256 $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 ...@@ -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 Digi96, 96/8, 96/8 PRO' CONFIG_SND_RME96 $CONFIG_SND
dep_tristate 'RME Digi9652 (Hammerfall)' CONFIG_SND_RME9652 $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 '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 'Yamaha YMF724/740/744/754' CONFIG_SND_YMFPCI $CONFIG_SND
dep_tristate 'Avance Logic ALS4000' CONFIG_SND_ALS4000 $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 '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 1370' CONFIG_SND_ENS1370 $CONFIG_SND
dep_tristate '(Creative) Ensoniq AudioPCI 1371/1373' CONFIG_SND_ENS1371 $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 ES1968/1978 (Maestro-1/2/2E)' CONFIG_SND_ES1968 $CONFIG_SND
dep_tristate 'ESS Allegro/Maestro3' CONFIG_SND_MAESTRO3 $CONFIG_SND dep_tristate 'ESS Allegro/Maestro3' CONFIG_SND_MAESTRO3 $CONFIG_SND
dep_tristate 'ForteMedia FM801' CONFIG_SND_FM801 $CONFIG_SND dep_tristate 'ForteMedia FM801' CONFIG_SND_FM801 $CONFIG_SND
dep_tristate 'ICEnsemble ICE1712 (Envy24)' CONFIG_SND_ICE1712 $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 '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 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 endmenu
...@@ -862,6 +862,7 @@ static void snd_emu10k1_tram_peek(emu10k1_t *emu, emu10k1_fx8010_code_t *icode) ...@@ -862,6 +862,7 @@ static void snd_emu10k1_tram_peek(emu10k1_t *emu, emu10k1_fx8010_code_t *icode)
{ {
int tram; int tram;
memset(icode->tram_valid, 0, sizeof(icode->tram_valid));
for (tram = 0; tram < 0xa0; tram++) { for (tram = 0; tram < 0xa0; tram++) {
set_bit(tram, icode->tram_valid); set_bit(tram, icode->tram_valid);
icode->tram_data_map[tram] = snd_emu10k1_ptr_read(emu, TANKMEMDATAREGBASE + tram, 0); 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) ...@@ -885,6 +886,7 @@ static void snd_emu10k1_code_peek(emu10k1_t *emu, emu10k1_fx8010_code_t *icode)
{ {
u32 pc; u32 pc;
memset(icode->code_valid, 0, sizeof(icode->code_valid));
for (pc = 0; pc < 512; pc++) { for (pc = 0; pc < 512; pc++) {
set_bit(pc, icode->code_valid); set_bit(pc, icode->code_valid);
icode->code[pc][0] = snd_emu10k1_efx_read(emu, pc * 2); 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 ...@@ -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; int i = 0, j;
unsigned int total = 0; unsigned int total = 0;
...@@ -1044,7 +1046,7 @@ static void snd_emu10k1_list_controls(emu10k1_t *emu, emu10k1_fx8010_code_t *ico ...@@ -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) { list_for_each(list, &emu->fx8010.gpr_ctl) {
ctl = emu10k1_gpr_ctl(list); ctl = emu10k1_gpr_ctl(list);
total++; total++;
if (i < icode->gpr_list_control_count) { if (_gctl && i < icode->gpr_list_control_count) {
memset(&gctl, 0, sizeof(gctl)); memset(&gctl, 0, sizeof(gctl));
id = &ctl->kcontrol->id; id = &ctl->kcontrol->id;
gctl.id.iface = id->iface; gctl.id.iface = id->iface;
...@@ -1061,13 +1063,14 @@ static void snd_emu10k1_list_controls(emu10k1_t *emu, emu10k1_fx8010_code_t *ico ...@@ -1061,13 +1063,14 @@ static void snd_emu10k1_list_controls(emu10k1_t *emu, emu10k1_fx8010_code_t *ico
gctl.min = ctl->min; gctl.min = ctl->min;
gctl.max = ctl->max; gctl.max = ctl->max;
gctl.translation = ctl->translation; 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; icode->gpr_list_control_total = total;
return 0;
} }
static int snd_emu10k1_icode_poke(emu10k1_t *emu, emu10k1_fx8010_code_t *icode) 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) ...@@ -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) static int snd_emu10k1_icode_peek(emu10k1_t *emu, emu10k1_fx8010_code_t *icode)
{ {
int err;
down(&emu->fx8010.lock); down(&emu->fx8010.lock);
strncpy(icode->name, emu->fx8010.name, sizeof(icode->name)-1); strncpy(icode->name, emu->fx8010.name, sizeof(icode->name)-1);
emu->fx8010.name[sizeof(emu->fx8010.name)-1] = '\0'; 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) ...@@ -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_gpr_peek(emu, icode);
snd_emu10k1_tram_peek(emu, icode); snd_emu10k1_tram_peek(emu, icode);
snd_emu10k1_code_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); up(&emu->fx8010.lock);
return 0; return err;
} }
static int snd_emu10k1_ipcm_poke(emu10k1_t *emu, emu10k1_fx8010_pcm_t *ipcm) 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 ...@@ -2171,9 +2176,13 @@ static int snd_emu10k1_fx8010_ioctl(snd_hwdep_t * hw, struct file *file, unsigne
kfree(icode); kfree(icode);
return res; return res;
case SNDRV_EMU10K1_IOCTL_CODE_PEEK: 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) if (icode == NULL)
return -ENOMEM; return -ENOMEM;
if (copy_from_user(icode, (void *)arg, sizeof(*icode))) {
kfree(icode);
return -EFAULT;
}
res = snd_emu10k1_icode_peek(emu, icode); res = snd_emu10k1_icode_peek(emu, icode);
if (res == 0 && copy_to_user((void *)arg, icode, sizeof(*icode))) { if (res == 0 && copy_to_user((void *)arg, icode, sizeof(*icode))) {
kfree(icode); kfree(icode);
......
...@@ -1538,6 +1538,7 @@ YMFPCI_DOUBLE("ADC Playback Volume", 0, YDSXGR_PRIADCOUTVOL), ...@@ -1538,6 +1538,7 @@ YMFPCI_DOUBLE("ADC Playback Volume", 0, YDSXGR_PRIADCOUTVOL),
YMFPCI_DOUBLE("ADC Capture Volume", 0, YDSXGR_PRIADCLOOPVOL), YMFPCI_DOUBLE("ADC Capture Volume", 0, YDSXGR_PRIADCLOOPVOL),
YMFPCI_DOUBLE("ADC Playback Volume", 1, YDSXGR_SECADCOUTVOL), YMFPCI_DOUBLE("ADC Playback Volume", 1, YDSXGR_SECADCOUTVOL),
YMFPCI_DOUBLE("ADC Capture Volume", 1, YDSXGR_SECADCLOOPVOL), 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("AC97 ", PLAYBACK,VOLUME), 0, YDSXGR_ZVOUTVOL),
YMFPCI_DOUBLE(SNDRV_CTL_NAME_IEC958("", CAPTURE,VOLUME), 0, YDSXGR_ZVLOOPVOL), YMFPCI_DOUBLE(SNDRV_CTL_NAME_IEC958("", CAPTURE,VOLUME), 0, YDSXGR_ZVLOOPVOL),
YMFPCI_DOUBLE(SNDRV_CTL_NAME_IEC958("AC97 ",PLAYBACK,VOLUME), 1, YDSXGR_SPDIFOUTVOL), 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) ...@@ -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_NATIVEADCINVOL, 0x3fff3fff);
snd_ymfpci_writel(chip, YDSXGR_NATIVEDACINVOL, 0x3fff3fff); snd_ymfpci_writel(chip, YDSXGR_NATIVEDACINVOL, 0x3fff3fff);
snd_ymfpci_writel(chip, YDSXGR_PRIADCLOOPVOL, 0x3fff3fff); snd_ymfpci_writel(chip, YDSXGR_PRIADCLOOPVOL, 0x3fff3fff);
snd_ymfpci_writel(chip, YDSXGR_LEGACYOUTVOL, 0x3fff3fff);
return 0; return 0;
} }
...@@ -2036,6 +2038,7 @@ static int snd_ymfpci_free(ymfpci_t *chip) ...@@ -2036,6 +2038,7 @@ static int snd_ymfpci_free(ymfpci_t *chip)
if (chip->res_reg_area) { /* don't touch busy hardware */ if (chip->res_reg_area) { /* don't touch busy hardware */
snd_ymfpci_writel(chip, YDSXGR_NATIVEDACOUTVOL, 0); snd_ymfpci_writel(chip, YDSXGR_NATIVEDACOUTVOL, 0);
snd_ymfpci_writel(chip, YDSXGR_BUF441OUTVOL, 0); snd_ymfpci_writel(chip, YDSXGR_BUF441OUTVOL, 0);
snd_ymfpci_writel(chip, YDSXGR_LEGACYOUTVOL, 0);
snd_ymfpci_writel(chip, YDSXGR_STATUS, ~0); snd_ymfpci_writel(chip, YDSXGR_STATUS, ~0);
snd_ymfpci_disable_dsp(chip); snd_ymfpci_disable_dsp(chip);
snd_ymfpci_writel(chip, YDSXGR_PLAYCTRLBASE, 0); snd_ymfpci_writel(chip, YDSXGR_PLAYCTRLBASE, 0);
...@@ -2100,6 +2103,7 @@ static int saved_regs_index[] = { ...@@ -2100,6 +2103,7 @@ static int saved_regs_index[] = {
YDSXGR_SPDIFLOOPVOL, YDSXGR_SPDIFLOOPVOL,
YDSXGR_SPDIFOUTVOL, YDSXGR_SPDIFOUTVOL,
YDSXGR_ZVOUTVOL, YDSXGR_ZVOUTVOL,
YDSXGR_LEGACYOUTVOL,
/* address bases */ /* address bases */
YDSXGR_PLAYCTRLBASE, YDSXGR_PLAYCTRLBASE,
YDSXGR_RECCTRLBASE, YDSXGR_RECCTRLBASE,
...@@ -2112,7 +2116,7 @@ static int saved_regs_index[] = { ...@@ -2112,7 +2116,7 @@ static int saved_regs_index[] = {
YDSXGR_ADCFORMAT, YDSXGR_ADCFORMAT,
YDSXGR_ADCSLOTSR, 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) 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