[ALSA] hda-intel - Switch to polling mode for CORB/RIRB communication
authorTakashi Iwai <tiwai@suse.de>
Mon, 21 Aug 2006 15:57:44 +0000 (17:57 +0200)
committerJaroslav Kysela <perex@suse.cz>
Sat, 23 Sep 2006 08:42:10 +0000 (10:42 +0200)
Automatically switch to polling mode for CORB/RIRB communication
if the irq-driven mode seems not working well.  If the polling
mode still doesn't work, switch to single_cmd mode as fallback.

Signed-off-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Jaroslav Kysela <perex@suse.cz>
sound/pci/hda/hda_intel.c

index 79d63c99f09245d58a5f339d262cb24d68718e73..ce75e07aaa2a7238244938871b6169367fd74d56 100644 (file)
@@ -332,6 +332,7 @@ struct azx {
        int position_fix;
        unsigned int initialized: 1;
        unsigned int single_cmd: 1;
+       unsigned int polling_mode: 1;
 };
 
 /* driver types */
@@ -518,8 +519,23 @@ static unsigned int azx_rirb_get_response(struct hda_codec *codec)
        struct azx *chip = codec->bus->private_data;
        int timeout = 50;
 
-       while (chip->rirb.cmds) {
+       for (;;) {
+               if (chip->polling_mode) {
+                       spin_lock_irq(&chip->reg_lock);
+                       azx_update_rirb(chip);
+                       spin_unlock_irq(&chip->reg_lock);
+               }
+               if (! chip->rirb.cmds)
+                       break;
                if (! --timeout) {
+                       if (! chip->polling_mode) {
+                               snd_printk(KERN_WARNING "hda_intel: "
+                                          "azx_get_response timeout, "
+                                          "switching to polling mode...\n");
+                               chip->polling_mode = 1;
+                               timeout = 50;
+                               continue;
+                       }
                        snd_printk(KERN_ERR
                                   "hda_intel: azx_get_response timeout, "
                                   "switching to single_cmd mode...\n");