aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2009-05-28 05:59:12 -0400
committerTakashi Iwai <tiwai@suse.de>2009-05-28 06:01:24 -0400
commitb05a7d4fed7e51dca37d0a31baf1466de30b1f01 (patch)
tree35a9a23a6289f5c4c966d1068771ab805f123e9c /sound/pci
parentaa2936f5fe060e95ae06685149645b234085a468 (diff)
ALSA: hda - Always sync writes in single_cmd mode
In the single_cmd mode, the hardware cannot store the multiple replies like on RIRB, thus each verb has to sync and wait for the response no matter whether the return value is needed or not. Otherwise it may result in a wrong return value from the previous verb. Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/pci')
-rw-r--r--sound/pci/hda/hda_intel.c36
1 files changed, 23 insertions, 13 deletions
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
index 01d8d97dca4f..31a695e6e37d 100644
--- a/sound/pci/hda/hda_intel.c
+++ b/sound/pci/hda/hda_intel.c
@@ -673,6 +673,27 @@ static unsigned int azx_rirb_get_response(struct hda_bus *bus)
673 * I left the codes, however, for debugging/testing purposes. 673 * I left the codes, however, for debugging/testing purposes.
674 */ 674 */
675 675
676/* receive a response */
677static int azx_single_wait_for_response(struct azx *chip)
678{
679 int timeout = 50;
680
681 while (timeout--) {
682 /* check IRV busy bit */
683 if (azx_readw(chip, IRS) & ICH6_IRS_VALID) {
684 /* reuse rirb.res as the response return value */
685 chip->rirb.res = azx_readl(chip, IR);
686 return 0;
687 }
688 udelay(1);
689 }
690 if (printk_ratelimit())
691 snd_printd(SFX "get_response timeout: IRS=0x%x\n",
692 azx_readw(chip, IRS));
693 chip->rirb.res = -1;
694 return -EIO;
695}
696
676/* send a command */ 697/* send a command */
677static int azx_single_send_cmd(struct hda_bus *bus, u32 val) 698static int azx_single_send_cmd(struct hda_bus *bus, u32 val)
678{ 699{
@@ -688,7 +709,7 @@ static int azx_single_send_cmd(struct hda_bus *bus, u32 val)
688 azx_writel(chip, IC, val); 709 azx_writel(chip, IC, val);
689 azx_writew(chip, IRS, azx_readw(chip, IRS) | 710 azx_writew(chip, IRS, azx_readw(chip, IRS) |
690 ICH6_IRS_BUSY); 711 ICH6_IRS_BUSY);
691 return 0; 712 return azx_single_wait_for_response(chip);
692 } 713 }
693 udelay(1); 714 udelay(1);
694 } 715 }
@@ -702,18 +723,7 @@ static int azx_single_send_cmd(struct hda_bus *bus, u32 val)
702static unsigned int azx_single_get_response(struct hda_bus *bus) 723static unsigned int azx_single_get_response(struct hda_bus *bus)
703{ 724{
704 struct azx *chip = bus->private_data; 725 struct azx *chip = bus->private_data;
705 int timeout = 50; 726 return chip->rirb.res;
706
707 while (timeout--) {
708 /* check IRV busy bit */
709 if (azx_readw(chip, IRS) & ICH6_IRS_VALID)
710 return azx_readl(chip, IR);
711 udelay(1);
712 }
713 if (printk_ratelimit())
714 snd_printd(SFX "get_response timeout: IRS=0x%x\n",
715 azx_readw(chip, IRS));
716 return (unsigned int)-1;
717} 727}
718 728
719/* 729/*