diff options
author | Jacob Meuser <jakemsr@cvs.openbsd.org> | 2010-04-20 02:17:25 +0000 |
---|---|---|
committer | Jacob Meuser <jakemsr@cvs.openbsd.org> | 2010-04-20 02:17:25 +0000 |
commit | 9ac611b2a61e730cf8af9f79266895224f02ad8c (patch) | |
tree | 7b659fd1b61c60f57889de957d1dc1b37c407f93 /sys/dev/pci/azalia.c | |
parent | 4254baf5281dcf7815c3c107f6c2847fce4b7772 (diff) |
- an unsolicited response contains the codec address, not the codec
index
- we only care about unsolicited responses from the codec we're using
- no need to enable unsolicited responses until we know which codec
we're using
fixes crash reported by jacekm@
Diffstat (limited to 'sys/dev/pci/azalia.c')
-rw-r--r-- | sys/dev/pci/azalia.c | 25 |
1 files changed, 12 insertions, 13 deletions
diff --git a/sys/dev/pci/azalia.c b/sys/dev/pci/azalia.c index 29e4e8a17e0..78ead0e85f8 100644 --- a/sys/dev/pci/azalia.c +++ b/sys/dev/pci/azalia.c @@ -1,4 +1,4 @@ -/* $OpenBSD: azalia.c,v 1.171 2010/04/04 20:07:45 kettenis Exp $ */ +/* $OpenBSD: azalia.c,v 1.172 2010/04/20 02:17:24 jakemsr Exp $ */ /* $NetBSD: azalia.c,v 1.20 2006/05/07 08:31:44 kent Exp $ */ /*- @@ -801,7 +801,6 @@ int azalia_init(azalia_t *az, int resuming) { int err; - uint32_t gctl; err = azalia_reset(az); if (err) @@ -833,10 +832,6 @@ azalia_init(azalia_t *az, int resuming) AZ_WRITE_4(az, INTCTL, AZ_READ_4(az, INTCTL) | HDA_INTCTL_CIE | HDA_INTCTL_GIE); - /* enable unsolicited response */ - gctl = AZ_READ_4(az, GCTL); - AZ_WRITE_4(az, GCTL, gctl | HDA_GCTL_UNSOL); - return(0); } @@ -904,6 +899,9 @@ azalia_init_codecs(azalia_t *az) } } + /* Enable unsolicited responses now that az->codecno is set. */ + AZ_WRITE_4(az, GCTL, AZ_READ_4(az, GCTL) | HDA_GCTL_UNSOL); + return(0); } @@ -1221,21 +1219,22 @@ void azalia_rirb_kick_unsol_events(void *v) { azalia_t *az = v; + int addr, tag; if (az->unsolq_kick) return; az->unsolq_kick = TRUE; while (az->unsolq_rp != az->unsolq_wp) { - int i; - int tag; - codec_t *codec; - i = RIRB_RESP_CODEC(az->unsolq[az->unsolq_rp].resp_ex); + addr = RIRB_RESP_CODEC(az->unsolq[az->unsolq_rp].resp_ex); tag = RIRB_UNSOL_TAG(az->unsolq[az->unsolq_rp].resp); - codec = &az->codecs[i]; - DPRINTF(("%s: codec#=%d tag=%d\n", __func__, i, tag)); + DPRINTF(("%s: codec address=%d tag=%d\n", __func__, addr, tag)); + az->unsolq_rp++; az->unsolq_rp %= UNSOLQ_SIZE; - azalia_unsol_event(codec, tag); + + /* We only care about events on the using codec. */ + if (az->codecs[az->codecno].address == addr) + azalia_unsol_event(&az->codecs[az->codecno], tag); } az->unsolq_kick = FALSE; } |