]>
Commit | Line | Data |
---|---|---|
2cb7cef9 BS |
1 | From: Takashi Iwai <tiwai@suse.de> |
2 | Subject: ALSA: hda - Always sync writes in single_cmd mode | |
3 | Patch-mainline: | |
4 | References: bnc#502903 | |
5 | ||
6 | In the single_cmd mode, the hardware cannot store the multiple replies | |
7 | like on RIRB, thus each verb has to sync and wait for the response no | |
8 | matter whether the return value is needed or not. Otherwise it may | |
9 | result in a wrong return value from the previous verb. | |
10 | ||
11 | Signed-off-by: Takashi Iwai <tiwai@suse.de> | |
12 | ||
13 | --- | |
14 | sound/pci/hda/hda_intel.c | 36 +++++++++++++++++++++++------------- | |
15 | 1 file changed, 23 insertions(+), 13 deletions(-) | |
16 | ||
17 | --- a/sound/pci/hda/hda_intel.c | |
18 | +++ b/sound/pci/hda/hda_intel.c | |
19 | @@ -661,6 +661,27 @@ | |
20 | * I left the codes, however, for debugging/testing purposes. | |
21 | */ | |
22 | ||
23 | +/* receive a response */ | |
24 | +static int azx_single_wait_for_response(struct azx *chip) | |
25 | +{ | |
26 | + int timeout = 50; | |
27 | + | |
28 | + while (timeout--) { | |
29 | + /* check IRV busy bit */ | |
30 | + if (azx_readw(chip, IRS) & ICH6_IRS_VALID) { | |
31 | + /* reuse rirb.res as the response return value */ | |
32 | + chip->rirb.res = azx_readl(chip, IR); | |
33 | + return 0; | |
34 | + } | |
35 | + udelay(1); | |
36 | + } | |
37 | + if (printk_ratelimit()) | |
38 | + snd_printd(SFX "get_response timeout: IRS=0x%x\n", | |
39 | + azx_readw(chip, IRS)); | |
40 | + chip->rirb.res = -1; | |
41 | + return -EIO; | |
42 | +} | |
43 | + | |
44 | /* send a command */ | |
45 | static int azx_single_send_cmd(struct hda_bus *bus, u32 val) | |
46 | { | |
47 | @@ -676,7 +697,7 @@ | |
48 | azx_writel(chip, IC, val); | |
49 | azx_writew(chip, IRS, azx_readw(chip, IRS) | | |
50 | ICH6_IRS_BUSY); | |
51 | - return 0; | |
52 | + return azx_single_wait_for_response(chip); | |
53 | } | |
54 | udelay(1); | |
55 | } | |
56 | @@ -690,18 +711,7 @@ | |
57 | static unsigned int azx_single_get_response(struct hda_bus *bus) | |
58 | { | |
59 | struct azx *chip = bus->private_data; | |
60 | - int timeout = 50; | |
61 | - | |
62 | - while (timeout--) { | |
63 | - /* check IRV busy bit */ | |
64 | - if (azx_readw(chip, IRS) & ICH6_IRS_VALID) | |
65 | - return azx_readl(chip, IR); | |
66 | - udelay(1); | |
67 | - } | |
68 | - if (printk_ratelimit()) | |
69 | - snd_printd(SFX "get_response timeout: IRS=0x%x\n", | |
70 | - azx_readw(chip, IRS)); | |
71 | - return (unsigned int)-1; | |
72 | + return chip->rirb.res; | |
73 | } | |
74 | ||
75 | /* |