fedora core 6 1.2949 + vserver 2.2.0
[linux-2.6.git] / drivers / atm / eni.c
index 8b13703..5aab7bd 100644 (file)
@@ -4,7 +4,6 @@
  
 
 #include <linux/module.h>
-#include <linux/config.h>
 #include <linux/kernel.h>
 #include <linux/mm.h>
 #include <linux/pci.h>
@@ -59,7 +58,6 @@
  * - doesn't support OAM cells
  * - eni_put_free may hang if not putting memory fragments that _complete_
  *   2^n block (never happens in real life, though)
- * - keeps IRQ even if initialization fails
  */
 
 
@@ -173,7 +171,7 @@ static void dump_mem(struct eni_dev *eni_dev)
        int i;
 
        for (i = 0; i < eni_dev->free_len; i++)
-               printk(KERN_DEBUG "  %d: 0x%lx %d\n",i,
+               printk(KERN_DEBUG "  %d: %p %d\n",i,
                    eni_dev->free_list[i].start,
                    1 << eni_dev->free_list[i].order);
 }
@@ -191,19 +189,19 @@ static void dump(struct atm_dev *dev)
        printk(KERN_NOTICE "TX buffers\n");
        for (i = 0; i < NR_CHAN; i++)
                if (eni_dev->tx[i].send)
-                       printk(KERN_NOTICE "  TX %d @ 0x%lx: %ld\n",i,
+                       printk(KERN_NOTICE "  TX %d @ %p: %ld\n",i,
                            eni_dev->tx[i].send,eni_dev->tx[i].words*4);
        printk(KERN_NOTICE "RX buffers\n");
        for (i = 0; i < 1024; i++)
                if (eni_dev->rx_map[i] && ENI_VCC(eni_dev->rx_map[i])->rx)
-                       printk(KERN_NOTICE "  RX %d @ 0x%lx: %ld\n",i,
+                       printk(KERN_NOTICE "  RX %d @ %p: %ld\n",i,
                            ENI_VCC(eni_dev->rx_map[i])->recv,
                            ENI_VCC(eni_dev->rx_map[i])->words*4);
        printk(KERN_NOTICE "----\n");
 }
 
 
-static void eni_put_free(struct eni_dev *eni_dev,unsigned long start,
+static void eni_put_free(struct eni_dev *eni_dev, void __iomem *start,
     unsigned long size)
 {
        struct eni_free *list;
@@ -215,17 +213,17 @@ static void eni_put_free(struct eni_dev *eni_dev,unsigned long start,
        len = eni_dev->free_len;
        while (size) {
                if (len >= eni_dev->free_list_size) {
-                       printk(KERN_CRIT "eni_put_free overflow (0x%lx,%ld)\n",
+                       printk(KERN_CRIT "eni_put_free overflow (%p,%ld)\n",
                            start,size);
                        break;
                }
-               for (order = 0; !((start | size) & (1 << order)); order++);
+               for (order = 0; !(((unsigned long)start | size) & (1 << order)); order++);
                if (MID_MIN_BUF_SIZE > (1 << order)) {
                        printk(KERN_CRIT "eni_put_free: order %d too small\n",
                            order);
                        break;
                }
-               list[len].start = start;
+               list[len].start = (void __iomem *) start;
                list[len].order = order;
                len++;
                start += 1 << order;
@@ -236,16 +234,16 @@ static void eni_put_free(struct eni_dev *eni_dev,unsigned long start,
 }
 
 
-static unsigned long eni_alloc_mem(struct eni_dev *eni_dev,unsigned long *size)
+static void __iomem *eni_alloc_mem(struct eni_dev *eni_dev, unsigned long *size)
 {
        struct eni_free *list;
-       unsigned long start;
+       void __iomem *start;
        int len,i,order,best_order,index;
 
        list = eni_dev->free_list;
        len = eni_dev->free_len;
        if (*size < MID_MIN_BUF_SIZE) *size = MID_MIN_BUF_SIZE;
-       if (*size > MID_MAX_BUF_SIZE) return 0;
+       if (*size > MID_MAX_BUF_SIZE) return NULL;
        for (order = 0; (1 << order) < *size; order++);
        DPRINTK("trying: %ld->%d\n",*size,order);
        best_order = 65; /* we don't have more than 2^64 of anything ... */
@@ -260,7 +258,7 @@ static unsigned long eni_alloc_mem(struct eni_dev *eni_dev,unsigned long *size)
                                best_order = list[i].order;
                                index = i;
                        }
-       if (best_order == 65) return 0;
+       if (best_order == 65) return NULL;
        start = list[index].start-eni_dev->base_diff;
        list[index] = list[--len];
        eni_dev->free_len = len;
@@ -273,7 +271,7 @@ static unsigned long eni_alloc_mem(struct eni_dev *eni_dev,unsigned long *size)
 }
 
 
-static void eni_free_mem(struct eni_dev *eni_dev,unsigned long start,
+static void eni_free_mem(struct eni_dev *eni_dev, void __iomem *start,
     unsigned long size)
 {
        struct eni_free *list;
@@ -283,20 +281,20 @@ static void eni_free_mem(struct eni_dev *eni_dev,unsigned long start,
        list = eni_dev->free_list;
        len = eni_dev->free_len;
        for (order = -1; size; order++) size >>= 1;
-       DPRINTK("eni_free_mem: 0x%lx+0x%lx (order %d)\n",start,size,order);
+       DPRINTK("eni_free_mem: %p+0x%lx (order %d)\n",start,size,order);
        for (i = 0; i < len; i++)
-               if (list[i].start == (start^(1 << order)) &&
+               if (((unsigned long) list[i].start) == ((unsigned long)start^(1 << order)) &&
                    list[i].order == order) {
                        DPRINTK("match[%d]: 0x%lx/0x%lx(0x%x), %d/%d\n",i,
                            list[i].start,start,1 << order,list[i].order,order);
                        list[i] = list[--len];
-                       start &= ~(unsigned long) (1 << order);
+                       start = (void __iomem *) ((unsigned long) start & ~(unsigned long) (1 << order));
                        order++;
                        i = -1;
                        continue;
                }
        if (len >= eni_dev->free_list_size) {
-               printk(KERN_ALERT "eni_free_mem overflow (0x%lx,%d)\n",start,
+               printk(KERN_ALERT "eni_free_mem overflow (%p,%d)\n",start,
                    order);
                return;
        }
@@ -333,7 +331,7 @@ static void rx_ident_err(struct atm_vcc *vcc)
        printk(KERN_ALERT "  host descr 0x%lx, rx pos 0x%lx, descr value "
            "0x%x\n",eni_vcc->descr,eni_vcc->rx_pos,
            (unsigned) readl(eni_vcc->recv+eni_vcc->descr*4));
-       printk(KERN_ALERT "  last 0x%p, servicing %d\n",eni_vcc->last,
+       printk(KERN_ALERT "  last %p, servicing %d\n",eni_vcc->last,
            eni_vcc->servicing);
        EVENT("---dump ends here---\n",0,0);
        printk(KERN_NOTICE "---recent events---\n");
@@ -538,7 +536,7 @@ static int rx_aal0(struct atm_vcc *vcc)
                return 0;
        }
        skb_put(skb,length);
-       skb->stamp = eni_vcc->timestamp;
+       skb_set_timestamp(skb, &eni_vcc->timestamp);
        DPRINTK("got len %ld\n",length);
        if (do_rx_dma(vcc,skb,1,length >> 2,length >> 2)) return 1;
        eni_vcc->rxing++;
@@ -617,7 +615,8 @@ static int rx_aal5(struct atm_vcc *vcc)
 
 static inline int rx_vcc(struct atm_vcc *vcc)
 {
-       unsigned long vci_dsc,tmp;
+       void __iomem *vci_dsc;
+       unsigned long tmp;
        struct eni_vcc *eni_vcc;
 
        eni_vcc = ENI_VCC(vcc);
@@ -728,7 +727,7 @@ static void dequeue_rx(struct atm_dev *dev)
        struct eni_vcc *eni_vcc;
        struct atm_vcc *vcc;
        struct sk_buff *skb;
-       unsigned long vci_dsc;
+       void __iomem *vci_dsc;
        int first;
 
        eni_dev = ENI_DEV(dev);
@@ -808,7 +807,7 @@ static int open_rx_first(struct atm_vcc *vcc)
 
 static int open_rx_second(struct atm_vcc *vcc)
 {
-       unsigned long here;
+       void __iomem *here;
        struct eni_dev *eni_dev;
        struct eni_vcc *eni_vcc;
        unsigned long size;
@@ -840,7 +839,7 @@ static int open_rx_second(struct atm_vcc *vcc)
 static void close_rx(struct atm_vcc *vcc)
 {
        DECLARE_WAITQUEUE(wait,current);
-       unsigned long here;
+       void __iomem *here;
        struct eni_dev *eni_dev;
        struct eni_vcc *eni_vcc;
 
@@ -1289,7 +1288,8 @@ static int reserve_or_set_tx(struct atm_vcc *vcc,struct atm_trafprm *txtp,
        struct eni_dev *eni_dev = ENI_DEV(vcc->dev);
        struct eni_vcc *eni_vcc = ENI_VCC(vcc);
        struct eni_tx *tx;
-       unsigned long size,mem;
+       unsigned long size;
+       void __iomem *mem;
        int rate,ubr,unlimited,new_tx;
        int pre,res,order;
        int error;
@@ -1313,7 +1313,7 @@ static int reserve_or_set_tx(struct atm_vcc *vcc,struct atm_trafprm *txtp,
                size = UBR_BUFFER;
        }
        new_tx = !eni_vcc->tx;
-       mem = 0; /* for gcc */
+       mem = NULL; /* for gcc */
        if (!new_tx) tx = eni_vcc->tx;
        else {
                mem = eni_alloc_mem(eni_dev,&size);
@@ -1347,7 +1347,7 @@ static int reserve_or_set_tx(struct atm_vcc *vcc,struct atm_trafprm *txtp,
                error = -EINVAL;
        if (error) {
                if (new_tx) {
-                       tx->send = 0;
+                       tx->send = NULL;
                        eni_free_mem(eni_dev,mem,size);
                }
                return error;
@@ -1421,7 +1421,7 @@ static void close_tx(struct atm_vcc *vcc)
                    eni_in(MID_TX_DESCRSTART(eni_vcc->tx->index)))
                        schedule();
                eni_free_mem(eni_dev,eni_vcc->tx->send,eni_vcc->tx->words << 2);
-               eni_vcc->tx->send = 0;
+               eni_vcc->tx->send = NULL;
                eni_dev->tx_bw += eni_vcc->tx->reserved;
        }
        eni_vcc->tx = NULL;
@@ -1442,7 +1442,7 @@ static int start_tx(struct atm_dev *dev)
        skb_queue_head_init(&eni_dev->tx_queue);
        eni_out(0,MID_DMA_WR_TX);
        for (i = 0; i < NR_CHAN; i++) {
-               eni_dev->tx[i].send = 0;
+               eni_dev->tx[i].send = NULL;
                eni_dev->tx[i].index = i;
        }
        return 0;
@@ -1488,7 +1488,7 @@ static void bug_int(struct atm_dev *dev,unsigned long reason)
 }
 
 
-static irqreturn_t eni_int(int irq,void *dev_id,struct pt_regs *regs)
+static irqreturn_t eni_int(int irq,void *dev_id)
 {
        struct atm_dev *dev;
        struct eni_dev *eni_dev;
@@ -1687,9 +1687,9 @@ static int __devinit get_esi_asic(struct atm_dev *dev)
 #undef GET_SEPROM
 
 
-static int __devinit get_esi_fpga(struct atm_dev *dev,unsigned long base)
+static int __devinit get_esi_fpga(struct atm_dev *dev, void __iomem *base)
 {
-       unsigned long mac_base;
+       void __iomem *mac_base;
        int i;
 
        mac_base = base+EPROM_SIZE-sizeof(struct midway_eprom);
@@ -1700,10 +1700,11 @@ static int __devinit get_esi_fpga(struct atm_dev *dev,unsigned long base)
 
 static int __devinit eni_do_init(struct atm_dev *dev)
 {
-       struct midway_eprom *eprom;
+       struct midway_eprom __iomem *eprom;
        struct eni_dev *eni_dev;
        struct pci_dev *pci_dev;
-       unsigned long real_base,base;
+       unsigned long real_base;
+       void __iomem *base;
        unsigned char revision;
        int error,i,last;
 
@@ -1730,17 +1731,16 @@ static int __devinit eni_do_init(struct atm_dev *dev)
        }
        printk(KERN_NOTICE DEV_LABEL "(itf %d): rev.%d,base=0x%lx,irq=%d,",
            dev->number,revision,real_base,eni_dev->irq);
-       if (!(base = (unsigned long) ioremap_nocache(real_base,MAP_MAX_SIZE))) {
+       if (!(base = ioremap_nocache(real_base,MAP_MAX_SIZE))) {
                printk("\n");
                printk(KERN_ERR DEV_LABEL "(itf %d): can't set up page "
                    "mapping\n",dev->number);
                return error;
        }
-       eni_dev->base_diff = real_base-base;
+       eni_dev->base_diff = real_base - (unsigned long) base;
        /* id may not be present in ASIC Tonga boards - check this @@@ */
        if (!eni_dev->asic) {
-               eprom = (struct midway_eprom *) (base+EPROM_SIZE-sizeof(struct
-                   midway_eprom));
+               eprom = (base+EPROM_SIZE-sizeof(struct midway_eprom));
                if (readl(&eprom->magic) != ENI155_MAGIC) {
                        printk("\n");
                        printk(KERN_ERR KERN_ERR DEV_LABEL "(itf %d): bad "
@@ -1790,30 +1790,32 @@ static int __devinit eni_do_init(struct atm_dev *dev)
 static int __devinit eni_start(struct atm_dev *dev)
 {
        struct eni_dev *eni_dev;
-       unsigned long buf,buffer_mem;
+       
+       void __iomem *buf;
+       unsigned long buffer_mem;
        int error;
 
        DPRINTK(">eni_start\n");
        eni_dev = ENI_DEV(dev);
-       if (request_irq(eni_dev->irq,&eni_int,SA_SHIRQ,DEV_LABEL,dev)) {
+       if (request_irq(eni_dev->irq,&eni_int,IRQF_SHARED,DEV_LABEL,dev)) {
                printk(KERN_ERR DEV_LABEL "(itf %d): IRQ%d is already in use\n",
                    dev->number,eni_dev->irq);
-               return -EAGAIN;
+               error = -EAGAIN;
+               goto out;
        }
-       /* @@@ should release IRQ on error */
        pci_set_master(eni_dev->pci_dev);
        if ((error = pci_write_config_word(eni_dev->pci_dev,PCI_COMMAND,
            PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER |
            (eni_dev->asic ? PCI_COMMAND_PARITY | PCI_COMMAND_SERR : 0)))) {
                printk(KERN_ERR DEV_LABEL "(itf %d): can't enable memory+"
                    "master (0x%02x)\n",dev->number,error);
-               return error;
+               goto free_irq;
        }
        if ((error = pci_write_config_byte(eni_dev->pci_dev,PCI_TONGA_CTRL,
            END_SWAP_DMA))) {
                printk(KERN_ERR DEV_LABEL "(itf %d): can't set endian swap "
                    "(0x%02x)\n",dev->number,error);
-               return error;
+               goto free_irq;
        }
        /* determine addresses of internal tables */
        eni_dev->vci = eni_dev->ram;
@@ -1828,14 +1830,15 @@ static int __devinit eni_start(struct atm_dev *dev)
        tasklet_init(&eni_dev->task,eni_tasklet,(unsigned long) dev);
        eni_dev->events = 0;
        /* initialize memory management */
-       buffer_mem = eni_dev->mem-(buf-eni_dev->ram);
+       buffer_mem = eni_dev->mem - (buf - eni_dev->ram);
        eni_dev->free_list_size = buffer_mem/MID_MIN_BUF_SIZE/2;
-       eni_dev->free_list = (struct eni_free *) kmalloc(
+       eni_dev->free_list = kmalloc(
            sizeof(struct eni_free)*(eni_dev->free_list_size+1),GFP_KERNEL);
        if (!eni_dev->free_list) {
                printk(KERN_ERR DEV_LABEL "(itf %d): couldn't get free page\n",
                    dev->number);
-               return -ENOMEM;
+               error = -ENOMEM;
+               goto free_irq;
        }
        eni_dev->free_len = 0;
        eni_put_free(eni_dev,buf,buffer_mem);
@@ -1851,17 +1854,26 @@ static int __devinit eni_start(struct atm_dev *dev)
         */
        eni_out(0xffffffff,MID_IE);
        error = start_tx(dev);
-       if (error) return error;
+       if (error) goto free_list;
        error = start_rx(dev);
-       if (error) return error;
+       if (error) goto free_list;
        error = dev->phy->start(dev);
-       if (error) return error;
+       if (error) goto free_list;
        eni_out(eni_in(MID_MC_S) | (1 << MID_INT_SEL_SHIFT) |
            MID_TX_LOCK_MODE | MID_DMA_ENABLE | MID_TX_ENABLE | MID_RX_ENABLE,
            MID_MC_S);
            /* Tonga uses SBus INTReq1 */
        (void) eni_in(MID_ISA); /* clear Midway interrupts */
        return 0;
+
+free_list:
+       kfree(eni_dev->free_list);
+
+free_irq:
+       free_irq(eni_dev->irq, eni_dev);
+
+out:
+       return error;
 }
 
 
@@ -1955,7 +1967,7 @@ static int eni_change_qos(struct atm_vcc *vcc,struct atm_qos *qos,int flgs)
         */
        tasklet_disable(&eni_dev->task);
        skb_queue_walk(&eni_dev->tx_queue, skb) {
-               unsigned long dsc;
+               void __iomem *dsc;
 
                if (ATM_SKB(skb)->vcc != vcc) continue;
                dsc = tx->send+ENI_PRV_POS(skb)*4;
@@ -2136,9 +2148,9 @@ static int eni_proc_read(struct atm_dev *dev,loff_t *pos,char *page)
 
                if (!tx->send) continue;
                if (!--left) {
-                       return sprintf(page,"tx[%d]:    0x%06lx-0x%06lx "
+                       return sprintf(page,"tx[%d]:    0x%ld-0x%ld "
                            "(%6ld bytes), rsv %d cps, shp %d cps%s\n",i,
-                           tx->send-eni_dev->ram,
+                           (unsigned long) (tx->send - eni_dev->ram),
                            tx->send-eni_dev->ram+tx->words*4-1,tx->words*4,
                            tx->reserved,tx->shaping,
                            tx == eni_dev->ubr ? " (UBR)" : "");
@@ -2162,9 +2174,9 @@ static int eni_proc_read(struct atm_dev *dev,loff_t *pos,char *page)
                        if (--left) continue;
                        length = sprintf(page,"vcc %4d: ",vcc->vci);
                        if (eni_vcc->rx) {
-                               length += sprintf(page+length,"0x%06lx-0x%06lx "
+                               length += sprintf(page+length,"0x%ld-0x%ld "
                                    "(%6ld bytes)",
-                                   eni_vcc->recv-eni_dev->ram,
+                                   (unsigned long) (eni_vcc->recv - eni_dev->ram),
                                    eni_vcc->recv-eni_dev->ram+eni_vcc->words*4-1,
                                    eni_vcc->words*4);
                                if (eni_vcc->tx) length += sprintf(page+length,", ");
@@ -2183,8 +2195,8 @@ static int eni_proc_read(struct atm_dev *dev,loff_t *pos,char *page)
                unsigned long offset;
 
                if (--left) continue;
-               offset = eni_dev->ram+eni_dev->base_diff;
-               return sprintf(page,"free      0x%06lx-0x%06lx (%6d bytes)\n",
+               offset = (unsigned long) eni_dev->ram+eni_dev->base_diff;
+               return sprintf(page,"free      %p-%p (%6d bytes)\n",
                    fe->start-offset,fe->start-offset+(1 << fe->order)-1,
                    1 << fe->order);
        }
@@ -2220,7 +2232,7 @@ static int __devinit eni_init_one(struct pci_dev *pci_dev,
                goto out0;
        }
 
-       eni_dev = (struct eni_dev *) kmalloc(sizeof(struct eni_dev),GFP_KERNEL);
+       eni_dev = kmalloc(sizeof(struct eni_dev),GFP_KERNEL);
        if (!eni_dev) goto out0;
        if (!cpu_zeroes) {
                cpu_zeroes = pci_alloc_consistent(pci_dev,ENI_ZEROES_SIZE,
@@ -2285,9 +2297,7 @@ static int __init eni_init(void)
                    sizeof(skb->cb),sizeof(struct eni_skb_prv));
                return -EIO;
        }
-       if (pci_register_driver(&eni_driver) > 0) return 0;
-       pci_unregister_driver (&eni_driver);
-       return -ENODEV;
+       return pci_register_driver(&eni_driver);
 }