X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=sound%2Fcore%2Foss%2Fmixer_oss.c;h=98ed9a9f0da65f503c9e5a08602d51c764500929;hb=65da6b7c3bf0bd6a149128079565e5f4efec28ac;hp=b9901566a1d667f115918495814d68a976c669b7;hpb=6a77f38946aaee1cd85eeec6cf4229b204c15071;p=linux-2.6.git diff --git a/sound/core/oss/mixer_oss.c b/sound/core/oss/mixer_oss.c index b9901566a..98ed9a9f0 100644 --- a/sound/core/oss/mixer_oss.c +++ b/sound/core/oss/mixer_oss.c @@ -359,16 +359,9 @@ static int snd_mixer_oss_ioctl1(snd_mixer_oss_file_t *fmixer, unsigned int cmd, return -ENXIO; } -/* FIXME: need to unlock BKL to allow preemption */ -static int snd_mixer_oss_ioctl(struct inode *inode, struct file *file, - unsigned int cmd, unsigned long arg) +static long snd_mixer_oss_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { - int err; - /* FIXME: need to unlock BKL to allow preemption */ - unlock_kernel(); - err = snd_mixer_oss_ioctl1((snd_mixer_oss_file_t *) file->private_data, cmd, arg); - lock_kernel(); - return err; + return snd_mixer_oss_ioctl1((snd_mixer_oss_file_t *) file->private_data, cmd, arg); } int snd_mixer_oss_ioctl_card(snd_card_t *card, unsigned int cmd, unsigned long arg) @@ -384,6 +377,13 @@ int snd_mixer_oss_ioctl_card(snd_card_t *card, unsigned int cmd, unsigned long a return snd_mixer_oss_ioctl1(&fmixer, cmd, arg); } +#ifdef CONFIG_COMPAT +/* all compatible */ +#define snd_mixer_oss_ioctl_compat snd_mixer_oss_ioctl +#else +#define snd_mixer_oss_ioctl_compat NULL +#endif + /* * REGISTRATION PART */ @@ -393,7 +393,8 @@ static struct file_operations snd_mixer_oss_f_ops = .owner = THIS_MODULE, .open = snd_mixer_oss_open, .release = snd_mixer_oss_release, - .ioctl = snd_mixer_oss_ioctl, + .unlocked_ioctl = snd_mixer_oss_ioctl, + .compat_ioctl = snd_mixer_oss_ioctl_compat, }; static snd_minor_t snd_mixer_oss_reg = @@ -521,7 +522,7 @@ static void snd_mixer_oss_get_volume1_vol(snd_mixer_oss_file_t *fmixer, goto __unalloc; snd_runtime_check(!kctl->info(kctl, uinfo), goto __unalloc); snd_runtime_check(!kctl->get(kctl, uctl), 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(uinfo->type != SNDRV_CTL_ELEM_TYPE_BOOLEAN || uinfo->value.integer.min != 0 || uinfo->value.integer.max != 1, goto __unalloc); *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]); @@ -615,7 +616,7 @@ static void snd_mixer_oss_put_volume1_vol(snd_mixer_oss_file_t *fmixer, if (uinfo == NULL || uctl == NULL) goto __unalloc; snd_runtime_check(!kctl->info(kctl, uinfo), 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(uinfo->type != SNDRV_CTL_ELEM_TYPE_BOOLEAN || uinfo->value.integer.min != 0 || uinfo->value.integer.max != 1, goto __unalloc); uctl->value.integer.value[0] = snd_mixer_oss_conv2(left, uinfo->value.integer.min, uinfo->value.integer.max); if (uinfo->count > 1) uctl->value.integer.value[1] = snd_mixer_oss_conv2(right, uinfo->value.integer.min, uinfo->value.integer.max); @@ -856,7 +857,7 @@ struct snd_mixer_oss_assign_table { static int snd_mixer_oss_build_test(snd_mixer_oss_t *mixer, struct slot *slot, const char *name, int index, int item) { - snd_ctl_elem_info_t info; + snd_ctl_elem_info_t *info; snd_kcontrol_t *kcontrol; snd_card_t *card = mixer->card; int err; @@ -867,15 +868,22 @@ static int snd_mixer_oss_build_test(snd_mixer_oss_t *mixer, struct slot *slot, c up_read(&card->controls_rwsem); return 0; } - if ((err = kcontrol->info(kcontrol, &info)) < 0) { + info = kmalloc(sizeof(*info), GFP_KERNEL); + if (! info) { + up_read(&card->controls_rwsem); + return -ENOMEM; + } + if ((err = kcontrol->info(kcontrol, info)) < 0) { up_read(&card->controls_rwsem); + kfree(info); return err; } slot->numid[item] = kcontrol->id.numid; up_read(&card->controls_rwsem); - if (info.count > slot->channels) - slot->channels = info.count; + if (info->count > slot->channels) + slot->channels = info->count; slot->present |= 1 << item; + kfree(info); return 0; } @@ -960,10 +968,16 @@ static int snd_mixer_oss_build_input(snd_mixer_oss_t *mixer, struct snd_mixer_os return 0; down_read(&mixer->card->controls_rwsem); if (ptr->index == 0 && (kctl = snd_mixer_oss_test_id(mixer, "Capture Source", 0)) != NULL) { - snd_ctl_elem_info_t uinfo; + snd_ctl_elem_info_t *uinfo; - memset(&uinfo, 0, sizeof(uinfo)); - if (kctl->info(kctl, &uinfo)) { + uinfo = kmalloc(sizeof(*uinfo), GFP_KERNEL); + if (! uinfo) { + up_read(&mixer->card->controls_rwsem); + return -ENOMEM; + } + + memset(uinfo, 0, sizeof(*uinfo)); + if (kctl->info(kctl, uinfo)) { up_read(&mixer->card->controls_rwsem); return 0; } @@ -973,21 +987,22 @@ static int snd_mixer_oss_build_input(snd_mixer_oss_t *mixer, struct snd_mixer_os if (!strcmp(str, "Master Mono")) strcpy(str, "Mix Mono"); slot.capture_item = 0; - if (!strcmp(uinfo.value.enumerated.name, str)) { + if (!strcmp(uinfo->value.enumerated.name, str)) { slot.present |= SNDRV_MIXER_OSS_PRESENT_CAPTURE; } else { - for (slot.capture_item = 1; slot.capture_item < uinfo.value.enumerated.items; slot.capture_item++) { - uinfo.value.enumerated.item = slot.capture_item; - if (kctl->info(kctl, &uinfo)) { + for (slot.capture_item = 1; slot.capture_item < uinfo->value.enumerated.items; slot.capture_item++) { + uinfo->value.enumerated.item = slot.capture_item; + if (kctl->info(kctl, uinfo)) { up_read(&mixer->card->controls_rwsem); return 0; } - if (!strcmp(uinfo.value.enumerated.name, str)) { + if (!strcmp(uinfo->value.enumerated.name, str)) { slot.present |= SNDRV_MIXER_OSS_PRESENT_CAPTURE; break; } } } + kfree(uinfo); } up_read(&mixer->card->controls_rwsem); if (slot.present != 0) {