Commit 68089abc authored by Jaroslav Kysela's avatar Jaroslav Kysela

ALSA update

  - reduced stack usage for functions using >1024+ bytes
  - fixed behaviour when OSS emulation is selected
  - fix in kmod support for sequencer
parent 8086afae
...@@ -426,25 +426,28 @@ static int snd_ctl_elem_info(snd_ctl_file_t *ctl, snd_ctl_elem_info_t *_info) ...@@ -426,25 +426,28 @@ static int snd_ctl_elem_info(snd_ctl_file_t *ctl, snd_ctl_elem_info_t *_info)
static int snd_ctl_elem_read(snd_card_t *card, snd_ctl_elem_value_t *_control) static int snd_ctl_elem_read(snd_card_t *card, snd_ctl_elem_value_t *_control)
{ {
snd_ctl_elem_value_t control; snd_ctl_elem_value_t *control;
snd_kcontrol_t *kctl; snd_kcontrol_t *kctl;
int result, indirect; int result, indirect;
if (copy_from_user(&control, _control, sizeof(control))) control = kmalloc(sizeof(*control), GFP_KERNEL);
if (control == NULL)
return -ENOMEM;
if (copy_from_user(control, _control, sizeof(*control)))
return -EFAULT; return -EFAULT;
read_lock(&card->control_rwlock); read_lock(&card->control_rwlock);
kctl = snd_ctl_find_id(card, &control.id); kctl = snd_ctl_find_id(card, &control->id);
if (kctl == NULL) { if (kctl == NULL) {
result = -ENOENT; result = -ENOENT;
} else { } else {
indirect = kctl->access & SNDRV_CTL_ELEM_ACCESS_INDIRECT ? 1 : 0; indirect = kctl->access & SNDRV_CTL_ELEM_ACCESS_INDIRECT ? 1 : 0;
if (control.indirect != indirect) { if (control->indirect != indirect) {
result = -EACCES; result = -EACCES;
} else { } else {
if ((kctl->access & SNDRV_CTL_ELEM_ACCESS_READ) && kctl->get != NULL) { if ((kctl->access & SNDRV_CTL_ELEM_ACCESS_READ) && kctl->get != NULL) {
result = kctl->get(kctl, &control); result = kctl->get(kctl, control);
if (result >= 0) if (result >= 0)
control.id = kctl->id; control->id = kctl->id;
} else } else
result = -EPERM; result = -EPERM;
} }
...@@ -453,25 +456,29 @@ static int snd_ctl_elem_read(snd_card_t *card, snd_ctl_elem_value_t *_control) ...@@ -453,25 +456,29 @@ static int snd_ctl_elem_read(snd_card_t *card, snd_ctl_elem_value_t *_control)
if (result >= 0) if (result >= 0)
if (copy_to_user(_control, &control, sizeof(control))) if (copy_to_user(_control, &control, sizeof(control)))
return -EFAULT; return -EFAULT;
kfree(control);
return result; return result;
} }
static int snd_ctl_elem_write(snd_ctl_file_t *file, snd_ctl_elem_value_t *_control) static int snd_ctl_elem_write(snd_ctl_file_t *file, snd_ctl_elem_value_t *_control)
{ {
snd_card_t *card = file->card; snd_card_t *card = file->card;
snd_ctl_elem_value_t control; snd_ctl_elem_value_t *control;
snd_kcontrol_t *kctl; snd_kcontrol_t *kctl;
int result, indirect; int result, indirect;
if (copy_from_user(&control, _control, sizeof(control))) control = kmalloc(sizeof(*control), GFP_KERNEL);
if (control == NULL)
return -ENOMEM;
if (copy_from_user(control, _control, sizeof(*control)))
return -EFAULT; return -EFAULT;
read_lock(&card->control_rwlock); read_lock(&card->control_rwlock);
kctl = snd_ctl_find_id(card, &control.id); kctl = snd_ctl_find_id(card, &control->id);
if (kctl == NULL) { if (kctl == NULL) {
result = -ENOENT; result = -ENOENT;
} else { } else {
indirect = kctl->access & SNDRV_CTL_ELEM_ACCESS_INDIRECT ? 1 : 0; indirect = kctl->access & SNDRV_CTL_ELEM_ACCESS_INDIRECT ? 1 : 0;
if (control.indirect != indirect) { if (control->indirect != indirect) {
result = -EACCES; result = -EACCES;
} else { } else {
read_lock(&card->control_owner_lock); read_lock(&card->control_owner_lock);
...@@ -480,9 +487,9 @@ static int snd_ctl_elem_write(snd_ctl_file_t *file, snd_ctl_elem_value_t *_contr ...@@ -480,9 +487,9 @@ static int snd_ctl_elem_write(snd_ctl_file_t *file, snd_ctl_elem_value_t *_contr
(kctl->owner != NULL && kctl->owner != file)) { (kctl->owner != NULL && kctl->owner != file)) {
result = -EPERM; result = -EPERM;
} else { } else {
result = kctl->put(kctl, &control); result = kctl->put(kctl, control);
if (result >= 0) if (result >= 0)
control.id = kctl->id; control->id = kctl->id;
} }
read_unlock(&card->control_owner_lock); read_unlock(&card->control_owner_lock);
if (result > 0) { if (result > 0) {
...@@ -498,6 +505,7 @@ static int snd_ctl_elem_write(snd_ctl_file_t *file, snd_ctl_elem_value_t *_contr ...@@ -498,6 +505,7 @@ static int snd_ctl_elem_write(snd_ctl_file_t *file, snd_ctl_elem_value_t *_contr
if (result >= 0) if (result >= 0)
if (copy_to_user(_control, &control, sizeof(control))) if (copy_to_user(_control, &control, sizeof(control)))
return -EFAULT; return -EFAULT;
kfree(control);
return result; return result;
} }
......
...@@ -327,7 +327,7 @@ static int snd_hwdep_dev_register(snd_device_t *device) ...@@ -327,7 +327,7 @@ static int snd_hwdep_dev_register(snd_device_t *device)
up(&register_mutex); up(&register_mutex);
return err; return err;
} }
#ifdef SNDRV_OSS_INFO_DEV_AUDIO #ifdef CONFIG_SND_OSSEMUL
hwdep->ossreg = 0; hwdep->ossreg = 0;
if (hwdep->oss_type >= 0) { if (hwdep->oss_type >= 0) {
if ((hwdep->oss_type == SNDRV_OSS_DEVICE_TYPE_DMFM) && (hwdep->device != 0)) { if ((hwdep->oss_type == SNDRV_OSS_DEVICE_TYPE_DMFM) && (hwdep->device != 0)) {
...@@ -359,7 +359,7 @@ static int snd_hwdep_dev_unregister(snd_device_t *device) ...@@ -359,7 +359,7 @@ static int snd_hwdep_dev_unregister(snd_device_t *device)
up(&register_mutex); up(&register_mutex);
return -EINVAL; return -EINVAL;
} }
#ifdef SNDRV_OSS_INFO_DEV_AUDIO #ifdef CONFIG_SND_OSSEMUL
if (hwdep->ossreg) if (hwdep->ossreg)
snd_unregister_oss_device(hwdep->oss_type, hwdep->card, hwdep->device); snd_unregister_oss_device(hwdep->oss_type, hwdep->card, hwdep->device);
#endif #endif
......
...@@ -499,10 +499,10 @@ char *snd_kmalloc_strdup(const char *string, int flags) ...@@ -499,10 +499,10 @@ char *snd_kmalloc_strdup(const char *string, int flags)
int copy_to_user_fromio(void *dst, unsigned long src, size_t count) int copy_to_user_fromio(void *dst, unsigned long src, size_t count)
{ {
#if defined(__i386_) || defined(CONFIG_SPARC32) #if defined(__i386__) || defined(CONFIG_SPARC32)
return copy_to_user(dst, (const void*)src, count) ? -EFAULT : 0; return copy_to_user(dst, (const void*)src, count) ? -EFAULT : 0;
#else #else
char buf[1024]; char buf[256];
while (count) { while (count) {
size_t c = count; size_t c = count;
if (c > sizeof(buf)) if (c > sizeof(buf))
...@@ -520,10 +520,10 @@ int copy_to_user_fromio(void *dst, unsigned long src, size_t count) ...@@ -520,10 +520,10 @@ int copy_to_user_fromio(void *dst, unsigned long src, size_t count)
int copy_from_user_toio(unsigned long dst, const void *src, size_t count) int copy_from_user_toio(unsigned long dst, const void *src, size_t count)
{ {
#if defined(__i386_) || defined(CONFIG_SPARC32) #if defined(__i386__) || defined(CONFIG_SPARC32)
return copy_from_user((void*)dst, src, count) ? -EFAULT : 0; return copy_from_user((void*)dst, src, count) ? -EFAULT : 0;
#else #else
char buf[1024]; char buf[256];
while (count) { while (count) {
size_t c = count; size_t c = count;
if (c > sizeof(buf)) if (c > sizeof(buf))
......
...@@ -495,18 +495,25 @@ static void snd_mixer_oss_get_volume1_vol(snd_mixer_oss_file_t *fmixer, ...@@ -495,18 +495,25 @@ static void snd_mixer_oss_get_volume1_vol(snd_mixer_oss_file_t *fmixer,
snd_kcontrol_t *kctl, snd_kcontrol_t *kctl,
int *left, int *right) int *left, int *right)
{ {
snd_ctl_elem_info_t uinfo; snd_ctl_elem_info_t *uinfo;
snd_ctl_elem_value_t uctl; snd_ctl_elem_value_t *uctl;
snd_runtime_check(kctl != NULL, return); snd_runtime_check(kctl != NULL, return);
memset(&uinfo, 0, sizeof(uinfo)); uinfo = snd_kcalloc(sizeof(*uinfo), GFP_ATOMIC);
memset(&uctl, 0, sizeof(uctl)); uctl = snd_kcalloc(sizeof(*uctl), GFP_ATOMIC);
snd_runtime_check(!kctl->info(kctl, &uinfo), return); if (uinfo == NULL || uctl == NULL)
snd_runtime_check(!kctl->get(kctl, &uctl), return); goto __unalloc;
snd_runtime_check(uinfo.type != SNDRV_CTL_ELEM_TYPE_BOOLEAN || uinfo.value.integer.min != 0 || uinfo.value.integer.max != 1, return); snd_runtime_check(!kctl->info(kctl, uinfo), goto __unalloc);
*left = snd_mixer_oss_conv1(uctl.value.integer.value[0], uinfo.value.integer.min, uinfo.value.integer.max, &pslot->volume[0]); snd_runtime_check(!kctl->get(kctl, uctl), goto __unalloc);
if (uinfo.count > 1) snd_runtime_check(uinfo->type != SNDRV_CTL_ELEM_TYPE_BOOLEAN || uinfo->value.integer.min != 0 || uinfo->value.integer.max != 1, return);
*right = snd_mixer_oss_conv1(uctl.value.integer.value[1], uinfo.value.integer.min, uinfo.value.integer.max, &pslot->volume[1]); *left = snd_mixer_oss_conv1(uctl->value.integer.value[0], uinfo->value.integer.min, uinfo->value.integer.max, &pslot->volume[0]);
if (uinfo->count > 1)
*right = snd_mixer_oss_conv1(uctl->value.integer.value[1], uinfo->value.integer.min, uinfo->value.integer.max, &pslot->volume[1]);
__unalloc:
if (uctl)
kfree(uctl);
if (uinfo)
kfree(uinfo);
} }
static void snd_mixer_oss_get_volume1_sw(snd_mixer_oss_file_t *fmixer, static void snd_mixer_oss_get_volume1_sw(snd_mixer_oss_file_t *fmixer,
...@@ -515,21 +522,28 @@ static void snd_mixer_oss_get_volume1_sw(snd_mixer_oss_file_t *fmixer, ...@@ -515,21 +522,28 @@ static void snd_mixer_oss_get_volume1_sw(snd_mixer_oss_file_t *fmixer,
int *left, int *right, int *left, int *right,
int route) int route)
{ {
snd_ctl_elem_info_t uinfo; snd_ctl_elem_info_t *uinfo;
snd_ctl_elem_value_t uctl; snd_ctl_elem_value_t *uctl;
snd_runtime_check(kctl != NULL, return); snd_runtime_check(kctl != NULL, return);
memset(&uinfo, 0, sizeof(uinfo)); uinfo = snd_kcalloc(sizeof(*uinfo), GFP_ATOMIC);
memset(&uctl, 0, sizeof(uctl)); uctl = snd_kcalloc(sizeof(*uctl), GFP_ATOMIC);
snd_runtime_check(!kctl->info(kctl, &uinfo), return); if (uinfo == NULL || uctl == NULL)
snd_runtime_check(!kctl->get(kctl, &uctl), return); goto __unalloc;
if (!uctl.value.integer.value[0]) { snd_runtime_check(!kctl->info(kctl, uinfo), goto __unalloc);
snd_runtime_check(!kctl->get(kctl, uctl), goto __unalloc);
if (!uctl->value.integer.value[0]) {
*left = 0; *left = 0;
if (uinfo.count == 1) if (uinfo->count == 1)
*right = 0; *right = 0;
} }
if (uinfo.count > 1 && !uctl.value.integer.value[route ? 3 : 1]) if (uinfo->count > 1 && !uctl->value.integer.value[route ? 3 : 1])
*right = 0; *right = 0;
__unalloc:
if (uctl)
kfree(uctl);
if (uinfo)
kfree(uinfo);
} }
static int snd_mixer_oss_get_volume1(snd_mixer_oss_file_t *fmixer, static int snd_mixer_oss_get_volume1(snd_mixer_oss_file_t *fmixer,
...@@ -566,21 +580,28 @@ static void snd_mixer_oss_put_volume1_vol(snd_mixer_oss_file_t *fmixer, ...@@ -566,21 +580,28 @@ static void snd_mixer_oss_put_volume1_vol(snd_mixer_oss_file_t *fmixer,
snd_kcontrol_t *kctl, snd_kcontrol_t *kctl,
int left, int right) int left, int right)
{ {
snd_ctl_elem_info_t uinfo; snd_ctl_elem_info_t *uinfo;
snd_ctl_elem_value_t uctl; snd_ctl_elem_value_t *uctl;
int res; int res;
snd_runtime_check(kctl != NULL, return); snd_runtime_check(kctl != NULL, return);
memset(&uinfo, 0, sizeof(uinfo)); uinfo = snd_kcalloc(sizeof(*uinfo), GFP_ATOMIC);
memset(&uctl, 0, sizeof(uctl)); uctl = snd_kcalloc(sizeof(*uctl), GFP_ATOMIC);
snd_runtime_check(!kctl->info(kctl, &uinfo), return); if (uinfo == NULL || uctl == NULL)
snd_runtime_check(uinfo.type != SNDRV_CTL_ELEM_TYPE_BOOLEAN || uinfo.value.integer.min != 0 || uinfo.value.integer.max != 1, return); goto __unalloc;
uctl.value.integer.value[0] = snd_mixer_oss_conv2(left, uinfo.value.integer.min, uinfo.value.integer.max); snd_runtime_check(!kctl->info(kctl, uinfo), goto __unalloc);
if (uinfo.count > 1) snd_runtime_check(uinfo->type != SNDRV_CTL_ELEM_TYPE_BOOLEAN || uinfo->value.integer.min != 0 || uinfo->value.integer.max != 1, return);
uctl.value.integer.value[1] = snd_mixer_oss_conv2(right, uinfo.value.integer.min, uinfo.value.integer.max); uctl->value.integer.value[0] = snd_mixer_oss_conv2(left, uinfo->value.integer.min, uinfo->value.integer.max);
snd_runtime_check((res = kctl->put(kctl, &uctl)) >= 0, return); if (uinfo->count > 1)
uctl->value.integer.value[1] = snd_mixer_oss_conv2(right, uinfo->value.integer.min, uinfo->value.integer.max);
snd_runtime_check((res = kctl->put(kctl, uctl)) >= 0, goto __unalloc);
if (res > 0) if (res > 0)
snd_ctl_notify(fmixer->card, SNDRV_CTL_EVENT_MASK_VALUE, &kctl->id); snd_ctl_notify(fmixer->card, SNDRV_CTL_EVENT_MASK_VALUE, &kctl->id);
__unalloc:
if (uctl)
kfree(uctl);
if (uinfo)
kfree(uinfo);
} }
static void snd_mixer_oss_put_volume1_sw(snd_mixer_oss_file_t *fmixer, static void snd_mixer_oss_put_volume1_sw(snd_mixer_oss_file_t *fmixer,
...@@ -589,27 +610,34 @@ static void snd_mixer_oss_put_volume1_sw(snd_mixer_oss_file_t *fmixer, ...@@ -589,27 +610,34 @@ static void snd_mixer_oss_put_volume1_sw(snd_mixer_oss_file_t *fmixer,
int left, int right, int left, int right,
int route) int route)
{ {
snd_ctl_elem_info_t uinfo; snd_ctl_elem_info_t *uinfo;
snd_ctl_elem_value_t uctl; snd_ctl_elem_value_t *uctl;
int res; int res;
snd_runtime_check(kctl != NULL, return); snd_runtime_check(kctl != NULL, return);
memset(&uinfo, 0, sizeof(uinfo)); uinfo = snd_kcalloc(sizeof(*uinfo), GFP_ATOMIC);
memset(&uctl, 0, sizeof(uctl)); uctl = snd_kcalloc(sizeof(*uctl), GFP_ATOMIC);
snd_runtime_check(!kctl->info(kctl, &uinfo), return); if (uinfo == NULL || uctl == NULL)
if (uinfo.count > 1) { goto __unalloc;
uctl.value.integer.value[0] = left > 0 ? 1 : 0; snd_runtime_check(!kctl->info(kctl, uinfo), goto __unalloc);
uctl.value.integer.value[route ? 3 : 1] = right > 0 ? 1 : 0; if (uinfo->count > 1) {
uctl->value.integer.value[0] = left > 0 ? 1 : 0;
uctl->value.integer.value[route ? 3 : 1] = right > 0 ? 1 : 0;
if (route) { if (route) {
uctl.value.integer.value[1] = uctl->value.integer.value[1] =
uctl.value.integer.value[2] = 0; uctl->value.integer.value[2] = 0;
} }
} else { } else {
uctl.value.integer.value[0] = (left > 0 || right > 0) ? 1 : 0; uctl->value.integer.value[0] = (left > 0 || right > 0) ? 1 : 0;
} }
snd_runtime_check((res = kctl->put(kctl, &uctl)) >= 0, return); snd_runtime_check((res = kctl->put(kctl, uctl)) >= 0, goto __unalloc);
if (res > 0) if (res > 0)
snd_ctl_notify(fmixer->card, SNDRV_CTL_EVENT_MASK_VALUE, &kctl->id); snd_ctl_notify(fmixer->card, SNDRV_CTL_EVENT_MASK_VALUE, &kctl->id);
__unalloc:
if (uctl)
kfree(uctl);
if (uinfo)
kfree(uinfo);
} }
static int snd_mixer_oss_put_volume1(snd_mixer_oss_file_t *fmixer, static int snd_mixer_oss_put_volume1(snd_mixer_oss_file_t *fmixer,
...@@ -718,17 +746,21 @@ static int snd_mixer_oss_get_recsrc2(snd_mixer_oss_file_t *fmixer, int *active_i ...@@ -718,17 +746,21 @@ static int snd_mixer_oss_get_recsrc2(snd_mixer_oss_file_t *fmixer, int *active_i
snd_kcontrol_t *kctl; snd_kcontrol_t *kctl;
snd_mixer_oss_slot_t *pslot; snd_mixer_oss_slot_t *pslot;
struct slot *slot; struct slot *slot;
snd_ctl_elem_info_t uinfo; snd_ctl_elem_info_t *uinfo;
snd_ctl_elem_value_t uctl; snd_ctl_elem_value_t *uctl;
int err, idx; int err, idx;
uinfo = snd_kcalloc(sizeof(*uinfo), GFP_KERNEL);
uctl = snd_kcalloc(sizeof(*uctl), GFP_KERNEL);
if (uinfo == NULL || uctl == NULL) {
err = -ENOMEM;
goto __unlock;
}
read_lock(&card->control_rwlock); read_lock(&card->control_rwlock);
kctl = snd_mixer_oss_test_id(mixer, "Capture Source", 0); kctl = snd_mixer_oss_test_id(mixer, "Capture Source", 0);
snd_runtime_check(kctl != NULL, return -ENOENT); snd_runtime_check(kctl != NULL, err = -ENOENT; goto __unlock);
memset(&uinfo, 0, sizeof(uinfo)); snd_runtime_check(!(err = kctl->info(kctl, uinfo)), goto __unlock);
memset(&uctl, 0, sizeof(uctl)); snd_runtime_check(!(err = kctl->get(kctl, uctl)), goto __unlock);
snd_runtime_check(!(err = kctl->info(kctl, &uinfo)), read_unlock(&card->control_rwlock); return err);
snd_runtime_check(!(err = kctl->get(kctl, &uctl)), read_unlock(&card->control_rwlock); return err);
read_unlock(&card->control_rwlock); read_unlock(&card->control_rwlock);
for (idx = 0; idx < 32; idx++) { for (idx = 0; idx < 32; idx++) {
if (!(mixer->mask_recsrc & (1 << idx))) if (!(mixer->mask_recsrc & (1 << idx)))
...@@ -739,12 +771,21 @@ static int snd_mixer_oss_get_recsrc2(snd_mixer_oss_file_t *fmixer, int *active_i ...@@ -739,12 +771,21 @@ static int snd_mixer_oss_get_recsrc2(snd_mixer_oss_file_t *fmixer, int *active_i
continue; continue;
if (!(slot->present & SNDRV_MIXER_OSS_PRESENT_CAPTURE)) if (!(slot->present & SNDRV_MIXER_OSS_PRESENT_CAPTURE))
continue; continue;
if (slot->capture_item == uctl.value.enumerated.item[0]) { if (slot->capture_item == uctl->value.enumerated.item[0]) {
*active_index = idx; *active_index = idx;
break; break;
} }
} }
return 0; err = 0;
goto __unalloc;
__unlock:
read_unlock(&card->control_rwlock);
__unalloc:
if (uctl)
kfree(uctl);
if (uinfo)
kfree(uinfo);
return err;
} }
static int snd_mixer_oss_put_recsrc2(snd_mixer_oss_file_t *fmixer, int active_index) static int snd_mixer_oss_put_recsrc2(snd_mixer_oss_file_t *fmixer, int active_index)
...@@ -754,16 +795,20 @@ static int snd_mixer_oss_put_recsrc2(snd_mixer_oss_file_t *fmixer, int active_in ...@@ -754,16 +795,20 @@ static int snd_mixer_oss_put_recsrc2(snd_mixer_oss_file_t *fmixer, int active_in
snd_kcontrol_t *kctl; snd_kcontrol_t *kctl;
snd_mixer_oss_slot_t *pslot; snd_mixer_oss_slot_t *pslot;
struct slot *slot = NULL; struct slot *slot = NULL;
snd_ctl_elem_info_t uinfo; snd_ctl_elem_info_t *uinfo;
snd_ctl_elem_value_t uctl; snd_ctl_elem_value_t *uctl;
int err, idx; int err, idx;
uinfo = snd_kcalloc(sizeof(*uinfo), GFP_KERNEL);
uctl = snd_kcalloc(sizeof(*uctl), GFP_KERNEL);
if (uinfo == NULL || uctl == NULL) {
err = -ENOMEM;
goto __unlock;
}
read_lock(&card->control_rwlock); read_lock(&card->control_rwlock);
kctl = snd_mixer_oss_test_id(mixer, "Capture Source", 0); kctl = snd_mixer_oss_test_id(mixer, "Capture Source", 0);
snd_runtime_check(kctl != NULL, read_unlock(&card->control_rwlock); return -ENOENT); snd_runtime_check(kctl != NULL, err = -ENOENT; goto __unlock);
memset(&uinfo, 0, sizeof(uinfo)); snd_runtime_check(!(err = kctl->info(kctl, uinfo)), goto __unlock);
memset(&uctl, 0, sizeof(uctl));
snd_runtime_check(!(err = kctl->info(kctl, &uinfo)), read_unlock(&card->control_rwlock); return err);
for (idx = 0; idx < 32; idx++) { for (idx = 0; idx < 32; idx++) {
if (!(mixer->mask_recsrc & (1 << idx))) if (!(mixer->mask_recsrc & (1 << idx)))
continue; continue;
...@@ -778,14 +823,19 @@ static int snd_mixer_oss_put_recsrc2(snd_mixer_oss_file_t *fmixer, int active_in ...@@ -778,14 +823,19 @@ static int snd_mixer_oss_put_recsrc2(snd_mixer_oss_file_t *fmixer, int active_in
slot = NULL; slot = NULL;
} }
snd_runtime_check(slot != NULL, goto __unlock); snd_runtime_check(slot != NULL, goto __unlock);
for (idx = 0; idx < uinfo.count; idx++) for (idx = 0; idx < uinfo->count; idx++)
uctl.value.enumerated.item[idx] = slot->capture_item; uctl->value.enumerated.item[idx] = slot->capture_item;
snd_runtime_check((err = kctl->put(kctl, &uctl)) >= 0, ); snd_runtime_check((err = kctl->put(kctl, uctl)) >= 0, );
if (err > 0) if (err > 0)
snd_ctl_notify(fmixer->card, SNDRV_CTL_EVENT_MASK_VALUE, &kctl->id); snd_ctl_notify(fmixer->card, SNDRV_CTL_EVENT_MASK_VALUE, &kctl->id);
err = 0;
__unlock: __unlock:
read_unlock(&card->control_rwlock); read_unlock(&card->control_rwlock);
return 0; if (uctl)
kfree(uctl);
if (uinfo)
kfree(uinfo);
return err;
} }
struct snd_mixer_oss_assign_table { struct snd_mixer_oss_assign_table {
......
...@@ -1417,7 +1417,7 @@ static int snd_rawmidi_dev_register(snd_device_t *device) ...@@ -1417,7 +1417,7 @@ static int snd_rawmidi_dev_register(snd_device_t *device)
up(&register_mutex); up(&register_mutex);
return err; return err;
} }
#ifdef SNDRV_OSS_INFO_DEV_AUDIO #ifdef CONFIG_SND_OSSEMUL
rmidi->ossreg = 0; rmidi->ossreg = 0;
if (rmidi->device == snd_midi_map[rmidi->card->number]) { if (rmidi->device == snd_midi_map[rmidi->card->number]) {
if (snd_register_oss_device(SNDRV_OSS_DEVICE_TYPE_MIDI, if (snd_register_oss_device(SNDRV_OSS_DEVICE_TYPE_MIDI,
...@@ -1425,7 +1425,9 @@ static int snd_rawmidi_dev_register(snd_device_t *device) ...@@ -1425,7 +1425,9 @@ static int snd_rawmidi_dev_register(snd_device_t *device)
snd_printk(KERN_ERR "unable to register OSS rawmidi device %i:%i\n", rmidi->card->number, 0); snd_printk(KERN_ERR "unable to register OSS rawmidi device %i:%i\n", rmidi->card->number, 0);
} else { } else {
rmidi->ossreg++; rmidi->ossreg++;
#ifdef SNDRV_OSS_INFO_DEV_MIDI
snd_oss_info_register(SNDRV_OSS_INFO_DEV_MIDI, rmidi->card->number, rmidi->name); snd_oss_info_register(SNDRV_OSS_INFO_DEV_MIDI, rmidi->card->number, rmidi->name);
#endif
} }
} }
if (rmidi->device == snd_amidi_map[rmidi->card->number]) { if (rmidi->device == snd_amidi_map[rmidi->card->number]) {
...@@ -1436,7 +1438,7 @@ static int snd_rawmidi_dev_register(snd_device_t *device) ...@@ -1436,7 +1438,7 @@ static int snd_rawmidi_dev_register(snd_device_t *device)
rmidi->ossreg++; rmidi->ossreg++;
} }
} }
#endif #endif /* CONFIG_SND_OSSEMUL */
up(&register_mutex); up(&register_mutex);
sprintf(name, "midi%d", rmidi->device); sprintf(name, "midi%d", rmidi->device);
entry = snd_info_create_card_entry(rmidi->card, name, rmidi->card->proc_root); entry = snd_info_create_card_entry(rmidi->card, name, rmidi->card->proc_root);
...@@ -1480,17 +1482,19 @@ static int snd_rawmidi_dev_unregister(snd_device_t *device) ...@@ -1480,17 +1482,19 @@ static int snd_rawmidi_dev_unregister(snd_device_t *device)
snd_info_unregister(rmidi->proc_entry); snd_info_unregister(rmidi->proc_entry);
rmidi->proc_entry = NULL; rmidi->proc_entry = NULL;
} }
#ifdef SNDRV_OSS_INFO_DEV_AUDIO #ifdef CONFIG_SND_OSSEMUL
if (rmidi->ossreg) { if (rmidi->ossreg) {
if (rmidi->device == snd_midi_map[rmidi->card->number]) { if (rmidi->device == snd_midi_map[rmidi->card->number]) {
snd_unregister_oss_device(SNDRV_OSS_DEVICE_TYPE_MIDI, rmidi->card, 0); snd_unregister_oss_device(SNDRV_OSS_DEVICE_TYPE_MIDI, rmidi->card, 0);
#ifdef SNDRV_OSS_INFO_DEV_MIDI
snd_oss_info_unregister(SNDRV_OSS_INFO_DEV_MIDI, rmidi->card->number); snd_oss_info_unregister(SNDRV_OSS_INFO_DEV_MIDI, rmidi->card->number);
#endif
} }
if (rmidi->device == snd_amidi_map[rmidi->card->number]) if (rmidi->device == snd_amidi_map[rmidi->card->number])
snd_unregister_oss_device(SNDRV_OSS_DEVICE_TYPE_MIDI, rmidi->card, 1); snd_unregister_oss_device(SNDRV_OSS_DEVICE_TYPE_MIDI, rmidi->card, 1);
rmidi->ossreg = 0; rmidi->ossreg = 0;
} }
#endif #endif /* CONFIG_SND_OSSEMUL */
if (rmidi->ops && rmidi->ops->dev_unregister) if (rmidi->ops && rmidi->ops->dev_unregister)
rmidi->ops->dev_unregister(rmidi); rmidi->ops->dev_unregister(rmidi);
snd_unregister_device(SNDRV_DEVICE_TYPE_RAWMIDI, rmidi->card, rmidi->device); snd_unregister_device(SNDRV_DEVICE_TYPE_RAWMIDI, rmidi->card, rmidi->device);
......
...@@ -152,9 +152,11 @@ client_t *snd_seq_client_use_ptr(int clientid) ...@@ -152,9 +152,11 @@ client_t *snd_seq_client_use_ptr(int clientid)
} }
} else if (clientid >= 64 && clientid < 128) { } else if (clientid >= 64 && clientid < 128) {
int card = (clientid - 64) / 8; int card = (clientid - 64) / 8;
if (card < snd_ecards_limit && ! card_requested[card]) { if (card < snd_ecards_limit) {
if (! card_requested[card]) {
card_requested[card] = 1; card_requested[card] = 1;
snd_request_card(card); snd_request_card(card);
}
snd_seq_device_load_drivers(); snd_seq_device_load_drivers();
} }
} }
......
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