static int snd_sbdsp_dev_free(struct snd_device *device) { struct snd_sb *chip = device->device_data; return snd_sbdsp_free(chip); }
int snd_sbdsp_create(struct snd_card *card, unsigned long port, int irq, irqreturn_t (*irq_handler)(int, void *, struct pt_regs *), int dma8, int dma16, unsigned short hardware, struct snd_sb **r_chip) { struct snd_sb *chip; int err; static struct snd_device_ops ops = { .dev_free = snd_sbdsp_dev_free, }; snd_assert(r_chip != NULL, return -EINVAL); *r_chip = NULL; chip = kzalloc(sizeof(*chip), GFP_KERNEL); if (chip == NULL) return -ENOMEM; spin_lock_init(&chip->reg_lock); spin_lock_init(&chip->open_lock); spin_lock_init(&chip->midi_input_lock); spin_lock_init(&chip->mixer_lock); chip->irq = -1; chip->dma8 = -1; chip->dma16 = -1; chip->port = port; if (request_irq(irq, irq_handler, hardware == SB_HW_ALS4000 ? SA_INTERRUPT | SA_SHIRQ : SA_INTERRUPT, "SoundBlaster", (void *) chip)) { snd_printk(KERN_ERR "sb: can't grab irq %d\n", irq); snd_sbdsp_free(chip); return -EBUSY; } chip->irq = irq; if (hardware == SB_HW_ALS4000) goto __skip_allocation; if ((chip->res_port = request_region(port, 16, "SoundBlaster")) == NULL) { snd_printk(KERN_ERR "sb: can't grab port 0x%lx\n", port); snd_sbdsp_free(chip); return -EBUSY; } #ifdef CONFIG_ISA if (dma8 >= 0 && request_dma(dma8, "SoundBlaster - 8bit")) { snd_printk(KERN_ERR "sb: can't grab DMA8 %d\n", dma8); snd_sbdsp_free(chip); return -EBUSY; } chip->dma8 = dma8; if (dma16 >= 0) { if (hardware != SB_HW_ALS100 && (dma16 < 5 || dma16 > 7)) { /* no duplex */ dma16 = -1; } else if (request_dma(dma16, "SoundBlaster - 16bit")) { snd_printk(KERN_ERR "sb: can't grab DMA16 %d\n", dma16); snd_sbdsp_free(chip); return -EBUSY; } } chip->dma16 = dma16; #endif __skip_allocation: chip->card = card; chip->hardware = hardware; if ((err = snd_sbdsp_probe(chip)) < 0) { snd_sbdsp_free(chip); return err; } if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) { snd_sbdsp_free(chip); return err; } *r_chip = chip; return 0; }
int snd_sbdsp_create(struct snd_card *card, unsigned long port, int irq, irq_handler_t irq_handler, int dma8, int dma16, unsigned short hardware, struct snd_sb **r_chip) { struct snd_sb *chip; int err; static struct snd_device_ops ops = { .dev_free = snd_sbdsp_dev_free, }; if (snd_BUG_ON(!r_chip)) return -EINVAL; *r_chip = NULL; chip = kzalloc(sizeof(*chip), GFP_KERNEL); if (chip == NULL) return -ENOMEM; spin_lock_init(&chip->reg_lock); spin_lock_init(&chip->open_lock); spin_lock_init(&chip->midi_input_lock); spin_lock_init(&chip->mixer_lock); chip->irq = -1; chip->dma8 = -1; chip->dma16 = -1; chip->port = port; if (request_irq(irq, irq_handler, (hardware == SB_HW_ALS4000 || hardware == SB_HW_CS5530) ? IRQF_SHARED : IRQF_DISABLED, "SoundBlaster", (void *) chip)) { ; snd_sbdsp_free(chip); return -EBUSY; } chip->irq = irq; if (hardware == SB_HW_ALS4000) goto __skip_allocation; if ((chip->res_port = request_region(port, 16, "SoundBlaster")) == NULL) { ; snd_sbdsp_free(chip); return -EBUSY; } #ifdef CONFIG_ISA if (dma8 >= 0 && request_dma(dma8, "SoundBlaster - 8bit")) { ; snd_sbdsp_free(chip); return -EBUSY; } chip->dma8 = dma8; if (dma16 >= 0) { if (hardware != SB_HW_ALS100 && (dma16 < 5 || dma16 > 7)) { /* no duplex */ dma16 = -1; } else if (request_dma(dma16, "SoundBlaster - 16bit")) { ; snd_sbdsp_free(chip); return -EBUSY; } } chip->dma16 = dma16; #endif __skip_allocation: chip->card = card; chip->hardware = hardware; if ((err = snd_sbdsp_probe(chip)) < 0) { snd_sbdsp_free(chip); return err; } if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) { snd_sbdsp_free(chip); return err; } *r_chip = chip; return 0; }