Fix for kern/17446. Restore the audio settings if an error occured.

This commit is contained in:
cbiere 2006-11-01 06:39:19 +00:00
parent 3429d8a242
commit 87261698f4
1 changed files with 26 additions and 22 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: audio.c,v 1.211 2006/10/12 01:30:50 christos Exp $ */
/* $NetBSD: audio.c,v 1.212 2006/11/01 06:39:19 cbiere Exp $ */
/*
* Copyright (c) 1991-1993 Regents of the University of California.
@ -61,7 +61,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: audio.c,v 1.211 2006/10/12 01:30:50 christos Exp $");
__KERNEL_RCSID(0, "$NetBSD: audio.c,v 1.212 2006/11/01 06:39:19 cbiere Exp $");
#include "audio.h"
#if NAUDIO > 0
@ -3269,7 +3269,7 @@ audiosetinfo(struct audio_softc *sc, struct audio_info *ai)
if (error) {
DPRINTF(("%s: hw->set_params() failed with %d\n",
__func__, error));
return error;
goto cleanup;
}
audio_check_params(&pp);
@ -3287,19 +3287,20 @@ audiosetinfo(struct audio_softc *sc, struct audio_info *ai)
if (sc->sc_pr.mmapped && pfilters.req_size > 0) {
DPRINTF(("%s: mmapped, and filters are requested.\n",
__func__));
return EINVAL;
error = EINVAL;
goto cleanup;
}
/* construct new filter chain */
if (setmode & AUMODE_PLAY) {
error = audio_setup_pfilters(sc, &pp, &pfilters);
if (error)
return error;
goto cleanup;
}
if (setmode & AUMODE_RECORD) {
error = audio_setup_rfilters(sc, &rp, &rfilters);
if (error)
return error;
goto cleanup;
}
DPRINTF(("%s: filter setup is completed.\n", __func__));
@ -3329,7 +3330,7 @@ audiosetinfo(struct audio_softc *sc, struct audio_info *ai)
}
error = au_set_port(sc, &sc->sc_outports, p->port);
if (error)
return error;
goto cleanup;
}
if (SPECIFIED(r->port)) {
if (!cleared) {
@ -3338,32 +3339,32 @@ audiosetinfo(struct audio_softc *sc, struct audio_info *ai)
}
error = au_set_port(sc, &sc->sc_inports, r->port);
if (error)
return error;
goto cleanup;
}
if (SPECIFIED(p->gain)) {
au_get_gain(sc, &sc->sc_outports, &gain, &balance);
error = au_set_gain(sc, &sc->sc_outports, p->gain, balance);
if (error)
return error;
goto cleanup;
}
if (SPECIFIED(r->gain)) {
au_get_gain(sc, &sc->sc_inports, &gain, &balance);
error = au_set_gain(sc, &sc->sc_inports, r->gain, balance);
if (error)
return error;
goto cleanup;
}
if (SPECIFIED_CH(p->balance)) {
au_get_gain(sc, &sc->sc_outports, &gain, &balance);
error = au_set_gain(sc, &sc->sc_outports, gain, p->balance);
if (error)
return error;
goto cleanup;
}
if (SPECIFIED_CH(r->balance)) {
au_get_gain(sc, &sc->sc_inports, &gain, &balance);
error = au_set_gain(sc, &sc->sc_inports, gain, r->balance);
if (error)
return error;
goto cleanup;
}
if (SPECIFIED(ai->monitor_gain) && sc->sc_monitor_port != -1) {
@ -3375,7 +3376,7 @@ audiosetinfo(struct audio_softc *sc, struct audio_info *ai)
ct.un.value.level[AUDIO_MIXER_LEVEL_MONO] = ai->monitor_gain;
error = sc->hw_if->set_port(sc->hw_hdl, &ct);
if (error)
return error;
goto cleanup;
}
if (SPECIFIED_CH(p->pause)) {
@ -3439,13 +3440,16 @@ audiosetinfo(struct audio_softc *sc, struct audio_info *ai)
if (hw->commit_settings) {
error = hw->commit_settings(sc->hw_hdl);
if (error)
return error;
goto cleanup;
}
cleanup:
if (cleared || pausechange) {
int init_error;
s = splaudio();
error = audio_initbufs(sc);
if (error) goto err;
init_error = audio_initbufs(sc);
if (init_error) goto err;
if (sc->sc_pr.blksize != oldpblksize ||
sc->sc_rr.blksize != oldrblksize ||
sc->sc_pustream != oldpus ||
@ -3453,15 +3457,15 @@ audiosetinfo(struct audio_softc *sc, struct audio_info *ai)
audio_calcwater(sc);
if ((sc->sc_mode & AUMODE_PLAY) &&
pbus && !sc->sc_pbus)
error = audiostartp(sc);
if (!error &&
init_error = audiostartp(sc);
if (!init_error &&
(sc->sc_mode & AUMODE_RECORD) &&
rbus && !sc->sc_rbus)
error = audiostartr(sc);
init_error = audiostartr(sc);
err:
splx(s);
if (error)
return error;
if (init_error)
return init_error;
}
/* Change water marks after initializing the buffers. */
@ -3485,7 +3489,7 @@ audiosetinfo(struct audio_softc *sc, struct audio_info *ai)
sc->sc_pr.usedhigh - sc->sc_pr.blksize;
}
return 0;
return error;
}
int