ALSA: usb-audio: add support for Akai MPD16
[safe/jmp/linux-2.6] / drivers / atm / zatm.c
index afcf1ad..702acce 100644 (file)
@@ -3,9 +3,7 @@
 /* Written 1995-2000 by Werner Almesberger, EPFL LRC/ICA */
 
 
-#include <linux/config.h>
 #include <linux/module.h>
-#include <linux/sched.h>
 #include <linux/kernel.h>
 #include <linux/mm.h>
 #include <linux/pci.h>
 #include <linux/skbuff.h>
 #include <linux/netdevice.h>
 #include <linux/delay.h>
-#include <linux/ioport.h> /* for request_region */
 #include <linux/uio.h>
 #include <linux/init.h>
+#include <linux/dma-mapping.h>
 #include <linux/atm_zatm.h>
 #include <linux/capability.h>
 #include <linux/bitops.h>
 #include <linux/wait.h>
+#include <linux/slab.h>
 #include <asm/byteorder.h>
 #include <asm/system.h>
 #include <asm/string.h>
@@ -400,7 +399,7 @@ unsigned long *x;
 EVENT("error code 0x%x/0x%x\n",(here[3] & uPD98401_AAL5_ES) >>
   uPD98401_AAL5_ES_SHIFT,error);
                skb = ((struct rx_buffer_head *) bus_to_virt(here[2]))->skb;
-               do_gettimeofday(&skb->stamp);
+               __net_timestamp(skb);
 #if 0
 printk("[-3..0] 0x%08lx 0x%08lx 0x%08lx 0x%08lx\n",((unsigned *) skb->data)[-3],
   ((unsigned *) skb->data)[-2],((unsigned *) skb->data)[-1],
@@ -417,10 +416,12 @@ printk("dummy: 0x%08lx, 0x%08lx\n",dummy[0],dummy[1]);
                chan = (here[3] & uPD98401_AAL5_CHAN) >>
                    uPD98401_AAL5_CHAN_SHIFT;
                if (chan < zatm_dev->chans && zatm_dev->rx_map[chan]) {
+                       int pos;
                        vcc = zatm_dev->rx_map[chan];
-                       if (skb == zatm_dev->last_free[ZATM_VCC(vcc)->pool])
-                               zatm_dev->last_free[ZATM_VCC(vcc)->pool] = NULL;
-                       skb_unlink(skb);
+                       pos = ZATM_VCC(vcc)->pool;
+                       if (skb == zatm_dev->last_free[pos])
+                               zatm_dev->last_free[pos] = NULL;
+                       skb_unlink(skb, zatm_dev->pool + pos);
                }
                else {
                        printk(KERN_ERR DEV_LABEL "(itf %d): RX indication "
@@ -496,8 +497,8 @@ static int open_rx_first(struct atm_vcc *vcc)
                        vcc->qos.rxtp.max_sdu = 65464;
                        /* fix this - we may want to receive 64kB SDUs
                           later */
-               cells = (vcc->qos.rxtp.max_sdu+ATM_AAL5_TRAILER+
-                   ATM_CELL_PAYLOAD-1)/ATM_CELL_PAYLOAD;
+               cells = DIV_ROUND_UP(vcc->qos.rxtp.max_sdu + ATM_AAL5_TRAILER,
+                               ATM_CELL_PAYLOAD);
                zatm_vcc->pool = pool_index(cells*ATM_CELL_PAYLOAD);
        }
        else {
@@ -602,9 +603,8 @@ static int start_rx(struct atm_dev *dev)
 DPRINTK("start_rx\n");
        zatm_dev = ZATM_DEV(dev);
        size = sizeof(struct atm_vcc *)*zatm_dev->chans;
-       zatm_dev->rx_map = (struct atm_vcc **) kmalloc(size,GFP_KERNEL);
+       zatm_dev->rx_map =  kzalloc(size,GFP_KERNEL);
        if (!zatm_dev->rx_map) return -ENOMEM;
-       memset(zatm_dev->rx_map,0,size);
        /* set VPI/VCI split (use all VCIs and give what's left to VPIs) */
        zpokel(zatm_dev,(1 << dev->ci_range.vci_bits)-1,uPD98401_VRR);
        /* prepare free buffer pools */
@@ -667,11 +667,13 @@ printk("NONONONOO!!!!\n");
                u32 *put;
                int i;
 
-               dsc = (u32 *) kmalloc(uPD98401_TXPD_SIZE*2+
-                   uPD98401_TXBD_SIZE*ATM_SKB(skb)->iovcnt,GFP_ATOMIC);
+               dsc = kmalloc(uPD98401_TXPD_SIZE * 2 +
+                       uPD98401_TXBD_SIZE * ATM_SKB(skb)->iovcnt, GFP_ATOMIC);
                if (!dsc) {
-                       if (vcc->pop) vcc->pop(vcc,skb);
-                       else dev_kfree_skb_irq(skb);
+                       if (vcc->pop)
+                               vcc->pop(vcc, skb);
+                       else
+                               dev_kfree_skb_irq(skb);
                        return -EAGAIN;
                }
                /* @@@ should check alignment */
@@ -681,7 +683,7 @@ printk("NONONONOO!!!!\n");
                    (ATM_SKB(skb)->atm_options & ATM_ATMOPT_CLP ?
                    uPD98401_CLPM_1 : uPD98401_CLPM_0));
                dsc[1] = 0;
-               dsc[2] = ATM_SKB(skb)->iovcnt*uPD98401_TXBD_SIZE;
+               dsc[2] = ATM_SKB(skb)->iovcnt * uPD98401_TXBD_SIZE;
                dsc[3] = virt_to_bus(put);
                for (i = 0; i < ATM_SKB(skb)->iovcnt; i++) {
                        *put++ = ((struct iovec *) skb->data)[i].iov_len;
@@ -798,6 +800,7 @@ static int alloc_shaper(struct atm_dev *dev,int *pcr,int min,int max,int ubr)
                i = m = 1;
                zatm_dev->ubr_ref_cnt++;
                zatm_dev->ubr = shaper;
+               *pcr = 0;
        }
        else {
                if (min) {
@@ -818,7 +821,7 @@ static int alloc_shaper(struct atm_dev *dev,int *pcr,int min,int max,int ubr)
                        }
                        else {
                                i = 255;
-                               m = (ATM_OC3_PCR*255+max-1)/max;
+                               m = DIV_ROUND_UP(ATM_OC3_PCR*255, max);
                        }
                }
                if (i > m) {
@@ -913,7 +916,7 @@ static int open_tx_first(struct atm_vcc *vcc)
        unsigned long flags;
        u32 *loop;
        unsigned short chan;
-       int pcr,unlimited;
+       int unlimited;
 
        DPRINTK("open_tx_first\n");
        zatm_dev = ZATM_DEV(vcc->dev);
@@ -934,6 +937,8 @@ static int open_tx_first(struct atm_vcc *vcc)
            vcc->qos.txtp.max_pcr >= ATM_OC3_PCR);
        if (unlimited && zatm_dev->ubr != -1) zatm_vcc->shaper = zatm_dev->ubr;
        else {
+               int uninitialized_var(pcr);
+
                if (unlimited) vcc->qos.txtp.max_sdu = ATM_MAX_AAL5_PDU;
                if ((zatm_vcc->shaper = alloc_shaper(vcc->dev,&pcr,
                    vcc->qos.txtp.min_pcr,vcc->qos.txtp.max_pcr,unlimited))
@@ -948,9 +953,8 @@ static int open_tx_first(struct atm_vcc *vcc)
        skb_queue_head_init(&zatm_vcc->tx_queue);
        init_waitqueue_head(&zatm_vcc->tx_wait);
        /* initialize ring */
-       zatm_vcc->ring = kmalloc(RING_SIZE,GFP_KERNEL);
+       zatm_vcc->ring = kzalloc(RING_SIZE,GFP_KERNEL);
        if (!zatm_vcc->ring) return -ENOMEM;
-       memset(zatm_vcc->ring,0,RING_SIZE);
        loop = zatm_vcc->ring+RING_ENTRIES*RING_WORDS;
        loop[0] = uPD98401_TXPD_V;
        loop[1] = loop[2] = 0;
@@ -994,7 +998,7 @@ static int start_tx(struct atm_dev *dev)
 
        DPRINTK("start_tx\n");
        zatm_dev = ZATM_DEV(dev);
-       zatm_dev->tx_map = (struct atm_vcc **) kmalloc(sizeof(struct atm_vcc *)*
+       zatm_dev->tx_map = kmalloc(sizeof(struct atm_vcc *)*
            zatm_dev->chans,GFP_KERNEL);
        if (!zatm_dev->tx_map) return -ENOMEM;
        zatm_dev->tx_bw = ATM_OC3_PCR;
@@ -1010,7 +1014,7 @@ static int start_tx(struct atm_dev *dev)
 /*------------------------------- interrupts --------------------------------*/
 
 
-static irqreturn_t zatm_int(int irq,void *dev_id,struct pt_regs *regs)
+static irqreturn_t zatm_int(int irq,void *dev_id)
 {
        struct atm_dev *dev;
        struct zatm_dev *zatm_dev;
@@ -1176,12 +1180,11 @@ static void __devinit eprom_get_esi(struct atm_dev *dev)
 /*--------------------------------- entries ---------------------------------*/
 
 
-static int __init zatm_init(struct atm_dev *dev)
+static int __devinit zatm_init(struct atm_dev *dev)
 {
        struct zatm_dev *zatm_dev;
        struct pci_dev *pci_dev;
        unsigned short command;
-       unsigned char revision;
        int error,i,last;
        unsigned long t0,t1,t2;
 
@@ -1191,8 +1194,7 @@ static int __init zatm_init(struct atm_dev *dev)
        pci_dev = zatm_dev->pci_dev;
        zatm_dev->base = pci_resource_start(pci_dev, 0);
        zatm_dev->irq = pci_dev->irq;
-       if ((error = pci_read_config_word(pci_dev,PCI_COMMAND,&command)) ||
-           (error = pci_read_config_byte(pci_dev,PCI_REVISION_ID,&revision))) {
+       if ((error = pci_read_config_word(pci_dev,PCI_COMMAND,&command))) {
                printk(KERN_ERR DEV_LABEL "(itf %d): init error 0x%02x\n",
                    dev->number,error);
                return -EINVAL;
@@ -1205,7 +1207,7 @@ static int __init zatm_init(struct atm_dev *dev)
        }
        eprom_get_esi(dev);
        printk(KERN_NOTICE DEV_LABEL "(itf %d): rev.%d,base=0x%x,irq=%d,",
-           dev->number,revision,zatm_dev->base,zatm_dev->irq);
+           dev->number,pci_dev->revision,zatm_dev->base,zatm_dev->irq);
        /* reset uPD98401 */
        zout(0,SWR);
        while (!(zin(GSR) & uPD98401_INT_IND));
@@ -1255,24 +1257,24 @@ static int __init zatm_init(struct atm_dev *dev)
 }
 
 
-static int __init zatm_start(struct atm_dev *dev)
+static int __devinit zatm_start(struct atm_dev *dev)
 {
-       struct zatm_dev *zatm_dev;
+       struct zatm_dev *zatm_dev = ZATM_DEV(dev);
+       struct pci_dev *pdev = zatm_dev->pci_dev;
        unsigned long curr;
        int pools,vccs,rx;
-       int error,i,ld;
+       int error, i, ld;
 
        DPRINTK("zatm_start\n");
-       zatm_dev = ZATM_DEV(dev);
        zatm_dev->rx_map = zatm_dev->tx_map = NULL;
-       for (i = 0; i < NR_MBX; i++)
-               zatm_dev->mbx_start[i] = 0;
-       if (request_irq(zatm_dev->irq,&zatm_int,SA_SHIRQ,DEV_LABEL,dev)) {
-               printk(KERN_ERR DEV_LABEL "(itf %d): IRQ%d is already in use\n",
-                   dev->number,zatm_dev->irq);
-               return -EAGAIN;
+       for (i = 0; i < NR_MBX; i++)
+               zatm_dev->mbx_start[i] = 0;
+       error = request_irq(zatm_dev->irq, zatm_int, IRQF_SHARED, DEV_LABEL, dev);
+       if (error < 0) {
+               printk(KERN_ERR DEV_LABEL "(itf %d): IRQ%d is already in use\n",
+                   dev->number,zatm_dev->irq);
+               goto done;
        }
-       request_region(zatm_dev->base,uPD98401_PORTS,DEV_LABEL);
        /* define memory regions */
        pools = NR_POOLS;
        if (NR_SHAPERS*SHAPER_SIZE > pools*POOL_SIZE)
@@ -1299,51 +1301,66 @@ static int __init zatm_start(struct atm_dev *dev)
            "%ld VCs\n",dev->number,NR_SHAPERS,pools,rx,
            (zatm_dev->mem-curr*4)/VC_SIZE);
        /* create mailboxes */
-       for (i = 0; i < NR_MBX; i++)
-               if (mbx_entries[i]) {
-                       unsigned long here;
-
-                       here = (unsigned long) kmalloc(2*MBX_SIZE(i),
-                           GFP_KERNEL);
-                       if (!here) {
-                               error = -ENOMEM;
-                               goto out;
-                       }
-                       if ((here^(here+MBX_SIZE(i))) & ~0xffffUL)/* paranoia */
-                               here = (here & ~0xffffUL)+0x10000;
-                       zatm_dev->mbx_start[i] = here;
-                       if ((here^virt_to_bus((void *) here)) & 0xffff) {
-                               printk(KERN_ERR DEV_LABEL "(itf %d): system "
-                                   "bus incompatible with driver\n",
-                                   dev->number);
-                               error = -ENODEV;
-                               goto out;
-                       }
-                       DPRINTK("mbx@0x%08lx-0x%08lx\n",here,here+MBX_SIZE(i));
-                       zatm_dev->mbx_end[i] = (here+MBX_SIZE(i)) & 0xffff;
-                       zout(virt_to_bus((void *) here) >> 16,MSH(i));
-                       zout(virt_to_bus((void *) here),MSL(i));
-                       zout((here+MBX_SIZE(i)) & 0xffff,MBA(i));
-                       zout(here & 0xffff,MTA(i));
-                       zout(here & 0xffff,MWA(i));
+       for (i = 0; i < NR_MBX; i++) {
+               void *mbx;
+               dma_addr_t mbx_dma;
+
+               if (!mbx_entries[i])
+                       continue;
+               mbx = pci_alloc_consistent(pdev, 2*MBX_SIZE(i), &mbx_dma);
+               if (!mbx) {
+                       error = -ENOMEM;
+                       goto out;
                }
+               /*
+                * Alignment provided by pci_alloc_consistent() isn't enough
+                * for this device.
+                */
+               if (((unsigned long)mbx ^ mbx_dma) & 0xffff) {
+                       printk(KERN_ERR DEV_LABEL "(itf %d): system "
+                              "bus incompatible with driver\n", dev->number);
+                       pci_free_consistent(pdev, 2*MBX_SIZE(i), mbx, mbx_dma);
+                       error = -ENODEV;
+                       goto out;
+               }
+               DPRINTK("mbx@0x%08lx-0x%08lx\n", mbx, mbx + MBX_SIZE(i));
+               zatm_dev->mbx_start[i] = (unsigned long)mbx;
+               zatm_dev->mbx_dma[i] = mbx_dma;
+               zatm_dev->mbx_end[i] = (zatm_dev->mbx_start[i] + MBX_SIZE(i)) &
+                                       0xffff;
+               zout(mbx_dma >> 16, MSH(i));
+               zout(mbx_dma, MSL(i));
+               zout(zatm_dev->mbx_end[i], MBA(i));
+               zout((unsigned long)mbx & 0xffff, MTA(i));
+               zout((unsigned long)mbx & 0xffff, MWA(i));
+       }
        error = start_tx(dev);
-       if (error) goto out;
+       if (error)
+               goto out;
        error = start_rx(dev);
-       if (error) goto out;
+       if (error)
+               goto out_tx;
        error = dev->phy->start(dev);
-       if (error) goto out;
+       if (error)
+               goto out_rx;
        zout(0xffffffff,IMR); /* enable interrupts */
        /* enable TX & RX */
        zout(zin(GMR) | uPD98401_GMR_SE | uPD98401_GMR_RE,GMR);
-       return 0;
-    out:
-       for (i = 0; i < NR_MBX; i++)
-               kfree(&zatm_dev->mbx_start[i]);
+done:
+       return error;
+
+out_rx:
        kfree(zatm_dev->rx_map);
+out_tx:
        kfree(zatm_dev->tx_map);
+out:
+       while (i-- > 0) {
+               pci_free_consistent(pdev, 2*MBX_SIZE(i), 
+                                   (void *)zatm_dev->mbx_start[i],
+                                   zatm_dev->mbx_dma[i]);
+       }
        free_irq(zatm_dev->irq, dev);
-       return error;
+       goto done;
 }
 
 
@@ -1501,7 +1518,7 @@ static int zatm_getsockopt(struct atm_vcc *vcc,int level,int optname,
 
 
 static int zatm_setsockopt(struct atm_vcc *vcc,int level,int optname,
-    void __user *optval,int optlen)
+    void __user *optval,unsigned int optlen)
 {
        return -EINVAL;
 }
@@ -1574,7 +1591,7 @@ static int __devinit zatm_init_one(struct pci_dev *pci_dev,
        struct zatm_dev *zatm_dev;
        int ret = -ENOMEM;
 
-       zatm_dev = (struct zatm_dev *) kmalloc(sizeof(*zatm_dev), GFP_KERNEL);
+       zatm_dev = kmalloc(sizeof(*zatm_dev), GFP_KERNEL);
        if (!zatm_dev) {
                printk(KERN_EMERG "%s: memory shortage\n", DEV_LABEL);
                goto out;