diff -u linux-2.4.22/drivers/sound/btaudio.c linux/drivers/sound/btaudio.c --- linux-2.4.22/drivers/sound/btaudio.c 2003-09-08 17:26:58.000000000 +0200 +++ linux/drivers/sound/btaudio.c 2003-09-08 17:30:22.000000000 +0200 @@ -1,7 +1,7 @@ /* - btaudio - bt878 audio dma driver for linux 2.4.x + btaudio - bt878 audio dma driver for linux 2.4 / 2.5 - (c) 2000-2002 Gerd Knorr + (c) 2000-2003 Gerd Knorr This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -19,14 +19,12 @@ */ -#include #include #include #include #include #include #include -#include #include #include #include @@ -37,6 +35,9 @@ #include #include +# define irqreturn_t void +# define IRQ_RETVAL(foobar) +# define strlcpy(dest,src,len) strncpy(dest,src,(len)-1) /* mmio access */ #define btwrite(dat,adr) writel((dat), (bta->mmio+(adr))) @@ -152,15 +153,30 @@ int rate; }; -static struct btaudio *btaudios = NULL; -static unsigned int debug = 0; -static unsigned int irq_debug = 0; +static struct btaudio *btaudios = NULL; +static unsigned int btcount = 0; +static unsigned int debug = 0; +static unsigned int irq_debug = 0; /* -------------------------------------------------------------- */ #define BUF_DEFAULT 128*1024 #define BUF_MIN 8192 +static void free_buffer(struct btaudio *bta) +{ + if (NULL != bta->buf_cpu) { + pci_free_consistent(bta->pci, bta->buf_size, + bta->buf_cpu, bta->buf_dma); + bta->buf_cpu = NULL; + } + if (NULL != bta->risc_cpu) { + pci_free_consistent(bta->pci, bta->risc_size, + bta->risc_cpu, bta->risc_dma); + bta->risc_cpu = NULL; + } +} + static int alloc_buffer(struct btaudio *bta) { if (NULL == bta->buf_cpu) { @@ -172,7 +188,7 @@ break; } if (NULL == bta->buf_cpu) - return -ENOMEM; + goto err; memset(bta->buf_cpu,0,bta->buf_size); } if (NULL == bta->risc_cpu) { @@ -180,23 +196,13 @@ bta->risc_cpu = pci_alloc_consistent (bta->pci, bta->risc_size, &bta->risc_dma); if (NULL == bta->risc_cpu) - return -ENOMEM; + goto err; } return 0; -} -static void free_buffer(struct btaudio *bta) -{ - if (NULL != bta->buf_cpu) { - pci_free_consistent(bta->pci, bta->buf_size, - bta->buf_cpu, bta->buf_dma); - bta->buf_cpu = NULL; - } - if (NULL != bta->risc_cpu) { - pci_free_consistent(bta->pci, bta->risc_size, - bta->risc_cpu, bta->risc_dma); - bta->risc_cpu = NULL; - } + err: + free_buffer(bta); + return -ENOMEM; } static int make_risc(struct btaudio *bta) @@ -330,8 +336,8 @@ if (cmd == SOUND_MIXER_INFO) { mixer_info info; memset(&info,0,sizeof(info)); - strncpy(info.id,"bt878",sizeof(info.id)-1); - strncpy(info.name,"Brooktree Bt878 audio",sizeof(info.name)-1); + strlcpy(info.id,"bt878",sizeof(info.id)); + strlcpy(info.name,"Brooktree Bt878 audio",sizeof(info.name)); info.modify_counter = bta->mixcount; if (copy_to_user((void *)arg, &info, sizeof(info))) return -EFAULT; @@ -340,8 +346,8 @@ if (cmd == SOUND_OLD_MIXER_INFO) { _old_mixer_info info; memset(&info,0,sizeof(info)); - strncpy(info.id,"bt878",sizeof(info.id)-1); - strncpy(info.name,"Brooktree Bt878 audio",sizeof(info.name)-1); + strlcpy(info.id,"bt878",sizeof(info.id)); + strlcpy(info.name,"Brooktree Bt878 audio",sizeof(info.name)); if (copy_to_user((void *)arg, &info, sizeof(info))) return -EFAULT; return 0; @@ -426,11 +432,11 @@ } static struct file_operations btaudio_mixer_fops = { - owner: THIS_MODULE, - llseek: no_llseek, - open: btaudio_mixer_open, - release: btaudio_mixer_release, - ioctl: btaudio_mixer_ioctl, + .owner = THIS_MODULE, + .llseek = no_llseek, + .open = btaudio_mixer_open, + .release = btaudio_mixer_release, + .ioctl = btaudio_mixer_ioctl, }; /* -------------------------------------------------------------- */ @@ -791,25 +797,25 @@ } static struct file_operations btaudio_digital_dsp_fops = { - owner: THIS_MODULE, - llseek: no_llseek, - open: btaudio_dsp_open_digital, - release: btaudio_dsp_release, - read: btaudio_dsp_read, - write: btaudio_dsp_write, - ioctl: btaudio_dsp_ioctl, - poll: btaudio_dsp_poll, + .owner = THIS_MODULE, + .llseek = no_llseek, + .open = btaudio_dsp_open_digital, + .release = btaudio_dsp_release, + .read = btaudio_dsp_read, + .write = btaudio_dsp_write, + .ioctl = btaudio_dsp_ioctl, + .poll = btaudio_dsp_poll, }; static struct file_operations btaudio_analog_dsp_fops = { - owner: THIS_MODULE, - llseek: no_llseek, - open: btaudio_dsp_open_analog, - release: btaudio_dsp_release, - read: btaudio_dsp_read, - write: btaudio_dsp_write, - ioctl: btaudio_dsp_ioctl, - poll: btaudio_dsp_poll, + .owner = THIS_MODULE, + .llseek = no_llseek, + .open = btaudio_dsp_open_analog, + .release = btaudio_dsp_release, + .read = btaudio_dsp_read, + .write = btaudio_dsp_write, + .ioctl = btaudio_dsp_ioctl, + .poll = btaudio_dsp_poll, }; /* -------------------------------------------------------------- */ @@ -818,18 +824,20 @@ "RISCI", "FBUS", "FTRGT", "FDSR", "PPERR", "RIPERR", "PABORT", "OCERR", "SCERR" }; -static void btaudio_irq(int irq, void *dev_id, struct pt_regs * regs) +static irqreturn_t btaudio_irq(int irq, void *dev_id, struct pt_regs * regs) { int count = 0; u32 stat,astat; struct btaudio *bta = dev_id; + int handled = 0; for (;;) { count++; stat = btread(REG_INT_STAT); astat = stat & btread(REG_INT_MASK); if (!astat) - return; + break; + handled = 1; btwrite(astat,REG_INT_STAT); if (irq_debug) { @@ -865,29 +873,31 @@ btwrite(0, REG_INT_MASK); } } - return; + return IRQ_RETVAL(handled); } /* -------------------------------------------------------------- */ -static unsigned int dsp1 = -1; -static unsigned int dsp2 = -1; -static unsigned int mixer = -1; +#define BTAUDIO_MAX 16 + +static unsigned int dsp1[BTAUDIO_MAX] = { [ 0 ... BTAUDIO_MAX-1 ] = -1 }; +static unsigned int dsp2[BTAUDIO_MAX] = { [ 0 ... BTAUDIO_MAX-1 ] = -1 }; +static unsigned int mixer[BTAUDIO_MAX] = { [ 0 ... BTAUDIO_MAX-1 ] = -1 }; +static int digital[BTAUDIO_MAX] = { [ 0 ... BTAUDIO_MAX-1 ] = 1 }; +static int analog[BTAUDIO_MAX] = { [ 0 ... BTAUDIO_MAX-1 ] = 1 }; +static int rate[BTAUDIO_MAX] = { [ 0 ... BTAUDIO_MAX-1 ] = 0 }; static int latency = -1; -static int digital = 1; -static int analog = 1; -static int rate = 0; #define BTA_OSPREY200 1 static struct cardinfo cards[] = { [0] = { - name: "default", - rate: 32000, + .name = "default", + .rate = 32000, }, [BTA_OSPREY200] = { - name: "Osprey 200", - rate: 44100, + .name = "Osprey 200", + .rate = 44100, }, }; @@ -899,6 +909,9 @@ unsigned char revision,lat; int rc = -EBUSY; + if (BTAUDIO_MAX == btcount) + return -EBUSY; + if (pci_enable_device(pci_dev)) return -EIO; if (!request_mem_region(pci_resource_start(pci_dev,0), @@ -932,8 +945,8 @@ /* sample rate */ bta->rate = card->rate; - if (rate) - bta->rate = rate; + if (rate[btcount]) + bta->rate = rate[btcount]; init_MUTEX(&bta->lock); init_waitqueue_head(&bta->readq); @@ -955,7 +968,7 @@ /* init hw */ btwrite(0, REG_GPIO_DMA_CTL); btwrite(0, REG_INT_MASK); - btwrite(~0x0UL, REG_INT_STAT); + btwrite(~(u32)0, REG_INT_STAT); pci_set_master(pci_dev); if ((rc = request_irq(bta->irq, btaudio_irq, SA_SHIRQ|SA_INTERRUPT, @@ -966,9 +979,9 @@ } /* register devices */ - if (digital) { + if (digital[btcount]) { rc = bta->dsp_digital = - register_sound_dsp(&btaudio_digital_dsp_fops,dsp1); + register_sound_dsp(&btaudio_digital_dsp_fops,dsp1[btcount]); if (rc < 0) { printk(KERN_WARNING "btaudio: can't register digital dsp (rc=%d)\n",rc); @@ -977,9 +990,9 @@ printk(KERN_INFO "btaudio: registered device dsp%d [digital]\n", bta->dsp_digital >> 4); } - if (analog) { + if (analog[btcount]) { rc = bta->dsp_analog = - register_sound_dsp(&btaudio_analog_dsp_fops,dsp2); + register_sound_dsp(&btaudio_analog_dsp_fops,dsp2[btcount]); if (rc < 0) { printk(KERN_WARNING "btaudio: can't register analog dsp (rc=%d)\n",rc); @@ -987,7 +1000,8 @@ } printk(KERN_INFO "btaudio: registered device dsp%d [analog]\n", bta->dsp_analog >> 4); - rc = bta->mixer_dev = register_sound_mixer(&btaudio_mixer_fops,mixer); + rc = bta->mixer_dev = register_sound_mixer(&btaudio_mixer_fops, + mixer[btcount]); if (rc < 0) { printk(KERN_WARNING "btaudio: can't register mixer (rc=%d)\n",rc); @@ -1000,6 +1014,7 @@ /* hook into linked list */ bta->next = btaudios; btaudios = bta; + btcount++; pci_set_drvdata(pci_dev,bta); return 0; @@ -1027,7 +1042,7 @@ /* turn off all DMA / IRQs */ btand(~15, REG_GPIO_DMA_CTL); btwrite(0, REG_INT_MASK); - btwrite(~0x0UL, REG_INT_STAT); + btwrite(~(u32)0, REG_INT_STAT); /* unregister devices */ if (digital) { @@ -1052,6 +1067,7 @@ ; /* if (NULL == walk->next) BUG(); */ walk->next = bta->next; } + btcount--; pci_set_drvdata(pci_dev, NULL); kfree(bta); @@ -1060,33 +1076,33 @@ /* -------------------------------------------------------------- */ -static struct pci_device_id btaudio_pci_tbl[] __devinitdata = { +static struct pci_device_id btaudio_pci_tbl[] = { { - vendor: PCI_VENDOR_ID_BROOKTREE, - device: 0x0878, - subvendor: 0x0070, - subdevice: 0xff01, - driver_data: BTA_OSPREY200, + .vendor = PCI_VENDOR_ID_BROOKTREE, + .device = 0x0878, + .subvendor = 0x0070, + .subdevice = 0xff01, + .driver_data = BTA_OSPREY200, },{ - vendor: PCI_VENDOR_ID_BROOKTREE, - device: 0x0878, - subvendor: PCI_ANY_ID, - subdevice: PCI_ANY_ID, + .vendor = PCI_VENDOR_ID_BROOKTREE, + .device = 0x0878, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, },{ - vendor: PCI_VENDOR_ID_BROOKTREE, - device: 0x0878, - subvendor: PCI_ANY_ID, - subdevice: PCI_ANY_ID, + .vendor = PCI_VENDOR_ID_BROOKTREE, + .device = 0x0879, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, },{ /* --- end of list --- */ } }; static struct pci_driver btaudio_pci_driver = { - name: "btaudio", - id_table: btaudio_pci_tbl, - probe: btaudio_probe, - remove: __devexit_p(btaudio_remove), + .name = "btaudio", + .id_table = btaudio_pci_tbl, + .probe = btaudio_probe, + .remove = __devexit_p(btaudio_remove), }; static int btaudio_init_module(void) @@ -1107,15 +1123,21 @@ module_init(btaudio_init_module); module_exit(btaudio_cleanup_module); -MODULE_PARM(dsp1,"i"); -MODULE_PARM(dsp2,"i"); -MODULE_PARM(mixer,"i"); -MODULE_PARM(debug,"i"); -MODULE_PARM(irq_debug,"i"); -MODULE_PARM(digital,"i"); -MODULE_PARM(analog,"i"); -MODULE_PARM(rate,"i"); -MODULE_PARM(latency,"i"); +MODULE_PARM(dsp1, "1-" __stringify(BTAUDIO_MAX) "i"); +MODULE_PARM_DESC(dsp1,"digital dsp nr"); +MODULE_PARM(dsp2, "1-" __stringify(BTAUDIO_MAX) "i"); +MODULE_PARM_DESC(dsp2,"analog dsp nr"); +MODULE_PARM(mixer, "1-" __stringify(BTAUDIO_MAX) "i"); +MODULE_PARM_DESC(mixer,"mixer nr"); +MODULE_PARM(debug, "i"); +MODULE_PARM(irq_debug, "i"); +MODULE_PARM(digital, "1-" __stringify(BTAUDIO_MAX) "i"); +MODULE_PARM_DESC(digital,"register digital dsp device"); +MODULE_PARM(analog, "1-" __stringify(BTAUDIO_MAX) "i"); +MODULE_PARM_DESC(analog,"register analog dsp device (and mixer)"); +MODULE_PARM(rate, "1-" __stringify(BTAUDIO_MAX) "i"); +MODULE_PARM_DESC(rate,"sample rate supported by the hardware"); +MODULE_PARM(latency, "i"); MODULE_PARM_DESC(latency,"pci latency timer"); MODULE_DEVICE_TABLE(pci, btaudio_pci_tbl);