vserver 1.9.5.x5
[linux-2.6.git] / sound / pci / es1938.c
index 3d7f98c..6057e54 100644 (file)
@@ -82,13 +82,12 @@ MODULE_SUPPORTED_DEVICE("{{ESS,ES1938},"
 static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;     /* Index 0-MAX */
 static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;      /* ID for this card */
 static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;     /* Enable this card */
-static int boot_devs;
 
-module_param_array(index, int, boot_devs, 0444);
+module_param_array(index, int, NULL, 0444);
 MODULE_PARM_DESC(index, "Index value for ESS Solo-1 soundcard.");
-module_param_array(id, charp, boot_devs, 0444);
+module_param_array(id, charp, NULL, 0444);
 MODULE_PARM_DESC(id, "ID string for ESS Solo-1 soundcard.");
-module_param_array(enable, bool, boot_devs, 0444);
+module_param_array(enable, bool, NULL, 0444);
 MODULE_PARM_DESC(enable, "Enable ESS Solo-1 soundcard.");
 
 #define SLIO_REG(chip, x) ((chip)->io_port + ESSIO_REG_##x)
@@ -1395,7 +1394,7 @@ static int es1938_suspend(snd_card_t *card, unsigned int state)
 
        outb(0x00, SLIO_REG(chip, IRQCONTROL)); /* disable irqs */
 
-       snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
+       pci_disable_device(chip->pci);
        return 0;
 }
 
@@ -1415,7 +1414,6 @@ static int es1938_resume(snd_card_t *card, unsigned int state)
                        snd_es1938_write(chip, *s, *d);
        }
 
-       snd_power_change_state(card, SNDRV_CTL_POWER_D0);
        return 0;
 }
 #endif /* CONFIG_PM */
@@ -1424,8 +1422,9 @@ static int snd_es1938_free(es1938_t *chip)
 {
        /* disable irqs */
        outb(0x00, SLIO_REG(chip, IRQCONTROL));
-       /*if (chip->rmidi)
-         snd_es1938_mixer_bits(chip, ESSSB_IREG_MPU401CONTROL, 0x40, 0);*/
+       if (chip->rmidi)
+               snd_es1938_mixer_bits(chip, ESSSB_IREG_MPU401CONTROL, 0x40, 0);
+
 #if defined(CONFIG_GAMEPORT) || (defined(MODULE) && defined(CONFIG_GAMEPORT_MODULE))
        if (chip->gameport.io)
                gameport_unregister_port(&chip->gameport);
@@ -1433,6 +1432,7 @@ static int snd_es1938_free(es1938_t *chip)
        if (chip->irq >= 0)
                free_irq(chip->irq, (void *)chip);
        pci_release_regions(chip->pci);
+       pci_disable_device(chip->pci);
        kfree(chip);
        return 0;
 }
@@ -1462,18 +1462,22 @@ static int __devinit snd_es1938_create(snd_card_t * card,
        if (pci_set_dma_mask(pci, 0x00ffffff) < 0 ||
            pci_set_consistent_dma_mask(pci, 0x00ffffff) < 0) {
                 snd_printk("architecture does not support 24bit PCI busmaster DMA\n");
+               pci_disable_device(pci);
                 return -ENXIO;
         }
 
        chip = kcalloc(1, sizeof(*chip), GFP_KERNEL);
-       if (chip == NULL)
+       if (chip == NULL) {
+               pci_disable_device(pci);
                return -ENOMEM;
+       }
        spin_lock_init(&chip->reg_lock);
        spin_lock_init(&chip->mixer_lock);
        chip->card = card;
        chip->pci = pci;
        if ((err = pci_request_regions(pci, "ESS Solo-1")) < 0) {
                kfree(chip);
+               pci_disable_device(pci);
                return err;
        }
        chip->io_port = pci_resource_start(pci, 0);
@@ -1571,6 +1575,9 @@ static irqreturn_t snd_es1938_interrupt(int irq, void *dev_id, struct pt_regs *r
 
        /* MPU401 */
        if (status & 0x80) {
+               // the following line is evil! It switches off MIDI interrupt handling after the first interrupt received.
+               // replacing the last 0 by 0x40 works for ESS-Solo1, but just doing nothing works as well!
+               // andreas@flying-snail.de
                // snd_es1938_mixer_bits(chip, ESSSB_IREG_MPU401CONTROL, 0x40, 0); /* ack? */
                if (chip->rmidi) {
                        handled = 1;
@@ -1685,8 +1692,11 @@ static int __devinit snd_es1938_probe(struct pci_dev *pci,
        if (snd_mpu401_uart_new(card, 0, MPU401_HW_MPU401,
                                chip->mpu_port, 1, chip->irq, 0, &chip->rmidi) < 0) {
                printk(KERN_ERR "es1938: unable to initialize MPU-401\n");
-       } /*else
-           snd_es1938_mixer_bits(chip, ESSSB_IREG_MPU401CONTROL, 0x40, 0x40);*/
+       } else {
+               // this line is vital for MIDI interrupt handling on ess-solo1
+               // andreas@flying-snail.de
+               snd_es1938_mixer_bits(chip, ESSSB_IREG_MPU401CONTROL, 0x40, 0x40);
+       }
 
 #if defined(CONFIG_GAMEPORT) || (defined(MODULE) && defined(CONFIG_GAMEPORT_MODULE))
        chip->gameport.io = chip->game_port;