From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([208.118.235.92]:40008) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1SCsMz-0005RW-Cx for qemu-devel@nongnu.org; Wed, 28 Mar 2012 08:53:07 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1SCsMr-0007qb-0n for qemu-devel@nongnu.org; Wed, 28 Mar 2012 08:52:56 -0400 From: =?UTF-8?q?Andreas=20F=C3=A4rber?= Date: Wed, 28 Mar 2012 14:52:23 +0200 Message-Id: <1332939159-16434-21-git-send-email-afaerber@suse.de> In-Reply-To: <1332939159-16434-1-git-send-email-afaerber@suse.de> References: <1332939159-16434-1-git-send-email-afaerber@suse.de> MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable Subject: [Qemu-devel] [PATCH stable-0.15 20/36] hda: do not mix output and input stream states, RHBZ #740493 List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Cc: kvm@suse.de, qemu-stable@nongnu.org, Bruce Rogers , Marc-Andr? Lureau , =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= , =?UTF-8?q?Andreas=20F=C3=A4rber?= From: Marc-Andr=C3=A9 Lureau Windows 7 may use the same stream number for input and output. Current code will confuse streams. Changes since v1: - keep running_compat[] for migration version 1 - add running_real[] for migration version 2 Signed-off-by: Marc-Andr? Lureau Signed-off-by: malc (cherry picked from commit ba43d28916c4f51c19bd7366089155ce81bee058) Signed-off-by: Bruce Rogers Signed-off-by: Andreas F=C3=A4rber --- hw/hda-audio.c | 26 +++++++++++++++++++------- hw/intel-hda.c | 9 +++++---- hw/intel-hda.h | 2 +- 3 files changed, 25 insertions(+), 12 deletions(-) diff --git a/hw/hda-audio.c b/hw/hda-audio.c index c699d6f..9b089e6 100644 --- a/hw/hda-audio.c +++ b/hw/hda-audio.c @@ -466,7 +466,8 @@ struct HDAAudioState { QEMUSoundCard card; const desc_codec *desc; HDAAudioStream st[4]; - bool running[16]; + bool running_compat[16]; + bool running_real[2 * 16]; =20 /* properties */ uint32_t debug; @@ -663,7 +664,7 @@ static void hda_audio_command(HDACodecDevice *hda, ui= nt32_t nid, uint32_t data) st->channel =3D payload & 0x0f; dprint(a, 2, "%s: stream %d, channel %d\n", st->node->name, st->stream, st->channel); - hda_audio_set_running(st, a->running[st->stream]); + hda_audio_set_running(st, a->running_real[st->output * 16 + st->= stream]); hda_codec_response(hda, true, 0); break; case AC_VERB_GET_CONV: @@ -746,16 +747,20 @@ fail: hda_codec_response(hda, true, 0); } =20 -static void hda_audio_stream(HDACodecDevice *hda, uint32_t stnr, bool ru= nning) +static void hda_audio_stream(HDACodecDevice *hda, uint32_t stnr, bool ru= nning, bool output) { HDAAudioState *a =3D DO_UPCAST(HDAAudioState, hda, hda); int s; =20 - a->running[stnr] =3D running; + a->running_compat[stnr] =3D running; + a->running_real[output * 16 + stnr] =3D running; for (s =3D 0; s < ARRAY_SIZE(a->st); s++) { if (a->st[s].node =3D=3D NULL) { continue; } + if (a->st[s].output !=3D output) { + continue; + } if (a->st[s].stream !=3D stnr) { continue; } @@ -837,6 +842,12 @@ static int hda_audio_post_load(void *opaque, int ver= sion) int i; =20 dprint(a, 1, "%s\n", __FUNCTION__); + if (version =3D=3D 1) { + /* assume running_compat[] is for output streams */ + for (i =3D 0; i < ARRAY_SIZE(a->running_compat); i++) + a->running_real[16 + i] =3D a->running_compat[i]; + } + for (i =3D 0; i < ARRAY_SIZE(a->st); i++) { st =3D a->st + i; if (st->node =3D=3D NULL) @@ -844,7 +855,7 @@ static int hda_audio_post_load(void *opaque, int vers= ion) hda_codec_parse_fmt(st->format, &st->as); hda_audio_setup(st); hda_audio_set_amp(st); - hda_audio_set_running(st, a->running[st->stream]); + hda_audio_set_running(st, a->running_real[st->output * 16 + st->= stream]); } return 0; } @@ -868,13 +879,14 @@ static const VMStateDescription vmstate_hda_audio_s= tream =3D { =20 static const VMStateDescription vmstate_hda_audio =3D { .name =3D "hda-audio", - .version_id =3D 1, + .version_id =3D 2, .post_load =3D hda_audio_post_load, .fields =3D (VMStateField []) { VMSTATE_STRUCT_ARRAY(st, HDAAudioState, 4, 0, vmstate_hda_audio_stream, HDAAudioStream), - VMSTATE_BOOL_ARRAY(running, HDAAudioState, 16), + VMSTATE_BOOL_ARRAY(running_compat, HDAAudioState, 16), + VMSTATE_BOOL_ARRAY_V(running_real, HDAAudioState, 2 * 16, 2), VMSTATE_END_OF_LIST() } }; diff --git a/hw/intel-hda.c b/hw/intel-hda.c index 7d02558..904e4fc 100644 --- a/hw/intel-hda.c +++ b/hw/intel-hda.c @@ -485,7 +485,7 @@ static void intel_hda_parse_bdl(IntelHDAState *d, Int= elHDAStream *st) st->bp =3D 0; } =20 -static void intel_hda_notify_codecs(IntelHDAState *d, uint32_t stream, b= ool running) +static void intel_hda_notify_codecs(IntelHDAState *d, uint32_t stream, b= ool running, bool output) { DeviceState *qdev; HDACodecDevice *cdev; @@ -493,7 +493,7 @@ static void intel_hda_notify_codecs(IntelHDAState *d,= uint32_t stream, bool runn QLIST_FOREACH(qdev, &d->codecs.qbus.children, sibling) { cdev =3D DO_UPCAST(HDACodecDevice, qdev, qdev); if (cdev->info->stream) { - cdev->info->stream(cdev, stream, running); + cdev->info->stream(cdev, stream, running, output); } } } @@ -567,6 +567,7 @@ static void intel_hda_set_ics(IntelHDAState *d, const= IntelHDAReg *reg, uint32_t =20 static void intel_hda_set_st_ctl(IntelHDAState *d, const IntelHDAReg *re= g, uint32_t old) { + bool output =3D reg->stream >=3D 4; IntelHDAStream *st =3D d->st + reg->stream; =20 if (st->ctl & 0x01) { @@ -582,11 +583,11 @@ static void intel_hda_set_st_ctl(IntelHDAState *d, = const IntelHDAReg *reg, uint3 dprint(d, 1, "st #%d: start %d (ring buf %d bytes)\n", reg->stream, stnr, st->cbl); intel_hda_parse_bdl(d, st); - intel_hda_notify_codecs(d, stnr, true); + intel_hda_notify_codecs(d, stnr, true, output); } else { /* stop */ dprint(d, 1, "st #%d: stop %d\n", reg->stream, stnr); - intel_hda_notify_codecs(d, stnr, false); + intel_hda_notify_codecs(d, stnr, false, output); } } intel_hda_update_irq(d); diff --git a/hw/intel-hda.h b/hw/intel-hda.h index 4e44e38..65fd2a8 100644 --- a/hw/intel-hda.h +++ b/hw/intel-hda.h @@ -34,7 +34,7 @@ struct HDACodecDeviceInfo { int (*init)(HDACodecDevice *dev); int (*exit)(HDACodecDevice *dev); void (*command)(HDACodecDevice *dev, uint32_t nid, uint32_t data); - void (*stream)(HDACodecDevice *dev, uint32_t stnr, bool running); + void (*stream)(HDACodecDevice *dev, uint32_t stnr, bool running, boo= l output); }; =20 void hda_codec_bus_init(DeviceState *dev, HDACodecBus *bus, --=20 1.7.7