summaryrefslogtreecommitdiffstats
path: root/sound
diff options
context:
space:
mode:
authorDavid Henningsson <david.henningsson@canonical.com>2014-01-29 13:12:31 +0100
committerTakashi Iwai <tiwai@suse.de>2014-01-30 12:39:15 +0100
commit3d692451eaf213e44f343aa2be06501b56ab2077 (patch)
treeec74f762d2c7b693821de2fa55dfc475f3d40c17 /sound
parent3760bc74832cf97606964321c8078819f4f5eb13 (diff)
downloadlinux-3d692451eaf213e44f343aa2be06501b56ab2077.tar.bz2
ALSA: hda - Do not accept responses from non-existing codecs
While looking into some spurious responses, I found that the addr value was treated a bit inconsistent: values 8..0xf will be treated as codec 0 and values 0..7 will be treated as no error regardless of whether there is a codec there, or not. With this patch, all non-existing codecs will be treated equally. In addition, printing rp and wp could help figuring out if the wp value is reported wrongly from the controller or if something else is wrong. Signed-off-by: David Henningsson <david.henningsson@canonical.com> Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound')
-rw-r--r--sound/pci/hda/hda_intel.c23
1 files changed, 9 insertions, 14 deletions
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
index fa2879a21a50..e87eac552ec5 100644
--- a/sound/pci/hda/hda_intel.c
+++ b/sound/pci/hda/hda_intel.c
@@ -834,18 +834,6 @@ static unsigned int azx_command_addr(u32 cmd)
return addr;
}
-static unsigned int azx_response_addr(u32 res)
-{
- unsigned int addr = res & 0xf;
-
- if (addr >= AZX_MAX_CODECS) {
- snd_BUG();
- addr = 0;
- }
-
- return addr;
-}
-
/* send a command */
static int azx_corb_send_cmd(struct hda_bus *bus, u32 val)
{
@@ -907,8 +895,15 @@ static void azx_update_rirb(struct azx *chip)
rp = chip->rirb.rp << 1; /* an RIRB entry is 8-bytes */
res_ex = le32_to_cpu(chip->rirb.buf[rp + 1]);
res = le32_to_cpu(chip->rirb.buf[rp]);
- addr = azx_response_addr(res_ex);
- if (res_ex & ICH6_RIRB_EX_UNSOL_EV)
+ addr = res_ex & 0xf;
+ if ((addr >= AZX_MAX_CODECS) || !(chip->codec_mask & (1 << addr))) {
+ snd_printk(KERN_ERR SFX "%s: spurious response %#x:%#x, rp = %d, wp = %d",
+ pci_name(chip->pci),
+ res, res_ex,
+ chip->rirb.rp, wp);
+ snd_BUG();
+ }
+ else if (res_ex & ICH6_RIRB_EX_UNSOL_EV)
snd_hda_queue_unsol_event(chip->bus, res, res_ex);
else if (chip->rirb.cmds[addr]) {
chip->rirb.res[addr] = res;