]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - drivers/net/ibmlana.c
[netdrvr] ibmtr: PCMCIA IBMTR is ok on 64bit
[linux-2.6-omap-h63xx.git] / drivers / net / ibmlana.c
index fe85d6fcba33aa022dd0f67c21ac346f2e5d2ce1..f02764725a221fdde54b43ea9be1e7d65c8e8b75 100644 (file)
@@ -71,7 +71,7 @@ History:
   June 1st, 2000
        corrected version codes, added support for the latest 2.3 changes
   Oct 28th, 2002
   June 1st, 2000
        corrected version codes, added support for the latest 2.3 changes
   Oct 28th, 2002
-       cleaned up for the 2.5 tree <alan@redhat.com>
+       cleaned up for the 2.5 tree <alan@lxorguk.ukuu.org.uk>
 
  *************************************************************************/
 
 
  *************************************************************************/
 
@@ -83,7 +83,7 @@ History:
 #include <linux/interrupt.h>
 #include <linux/delay.h>
 #include <linux/time.h>
 #include <linux/interrupt.h>
 #include <linux/delay.h>
 #include <linux/time.h>
-#include <linux/mca-legacy.h>
+#include <linux/mca.h>
 #include <linux/module.h>
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
 #include <linux/module.h>
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
@@ -161,13 +161,13 @@ static void PrTime(void)
 
 /* deduce resources out of POS registers */
 
 
 /* deduce resources out of POS registers */
 
-static void getaddrs(int slot, int *base, int *memlen, int *iobase,
-                    int *irq, ibmlana_medium * medium)
+static void getaddrs(struct mca_device *mdev, int *base, int *memlen,
+                    int *iobase, int *irq, ibmlana_medium *medium)
 {
        u_char pos0, pos1;
 
 {
        u_char pos0, pos1;
 
-       pos0 = mca_read_stored_pos(slot, 2);
-       pos1 = mca_read_stored_pos(slot, 3);
+       pos0 = mca_device_read_stored_pos(mdev, 2);
+       pos1 = mca_device_read_stored_pos(mdev, 3);
 
        *base = 0xc0000 + ((pos1 & 0xf0) << 9);
        *memlen = (pos1 & 0x01) ? 0x8000 : 0x4000;
 
        *base = 0xc0000 + ((pos1 & 0xf0) << 9);
        *memlen = (pos1 & 0x01) ? 0x8000 : 0x4000;
@@ -591,7 +591,7 @@ static void irqrx_handler(struct net_device *dev)
 
                        skb = dev_alloc_skb(rda.length + 2);
                        if (skb == NULL)
 
                        skb = dev_alloc_skb(rda.length + 2);
                        if (skb == NULL)
-                               priv->stat.rx_dropped++;
+                               dev->stats.rx_dropped++;
                        else {
                                /* copy out data */
 
                        else {
                                /* copy out data */
 
@@ -606,8 +606,8 @@ static void irqrx_handler(struct net_device *dev)
 
                                /* bookkeeping */
                                dev->last_rx = jiffies;
 
                                /* bookkeeping */
                                dev->last_rx = jiffies;
-                               priv->stat.rx_packets++;
-                               priv->stat.rx_bytes += rda.length;
+                               dev->stats.rx_packets++;
+                               dev->stats.rx_bytes += rda.length;
 
                                /* pass to the upper layers */
                                netif_rx(skb);
 
                                /* pass to the upper layers */
                                netif_rx(skb);
@@ -617,11 +617,11 @@ static void irqrx_handler(struct net_device *dev)
                /* otherwise check error status bits and increase statistics */
 
                else {
                /* otherwise check error status bits and increase statistics */
 
                else {
-                       priv->stat.rx_errors++;
+                       dev->stats.rx_errors++;
                        if (rda.status & RCREG_FAER)
                        if (rda.status & RCREG_FAER)
-                               priv->stat.rx_frame_errors++;
+                               dev->stats.rx_frame_errors++;
                        if (rda.status & RCREG_CRCR)
                        if (rda.status & RCREG_CRCR)
-                               priv->stat.rx_crc_errors++;
+                               dev->stats.rx_crc_errors++;
                }
 
                /* descriptor processed, will become new last descriptor in queue */
                }
 
                /* descriptor processed, will become new last descriptor in queue */
@@ -656,8 +656,8 @@ static void irqtx_handler(struct net_device *dev)
        memcpy_fromio(&tda, priv->base + priv->tdastart + (priv->currtxdescr * sizeof(tda_t)), sizeof(tda_t));
 
        /* update statistics */
        memcpy_fromio(&tda, priv->base + priv->tdastart + (priv->currtxdescr * sizeof(tda_t)), sizeof(tda_t));
 
        /* update statistics */
-       priv->stat.tx_packets++;
-       priv->stat.tx_bytes += tda.length;
+       dev->stats.tx_packets++;
+       dev->stats.tx_bytes += tda.length;
 
        /* update our pointers */
        priv->txused[priv->currtxdescr] = 0;
 
        /* update our pointers */
        priv->txused[priv->currtxdescr] = 0;
@@ -680,15 +680,15 @@ static void irqtxerr_handler(struct net_device *dev)
        memcpy_fromio(&tda, priv->base + priv->tdastart + (priv->currtxdescr * sizeof(tda_t)), sizeof(tda_t));
 
        /* update statistics */
        memcpy_fromio(&tda, priv->base + priv->tdastart + (priv->currtxdescr * sizeof(tda_t)), sizeof(tda_t));
 
        /* update statistics */
-       priv->stat.tx_errors++;
+       dev->stats.tx_errors++;
        if (tda.status & (TCREG_NCRS | TCREG_CRSL))
        if (tda.status & (TCREG_NCRS | TCREG_CRSL))
-               priv->stat.tx_carrier_errors++;
+               dev->stats.tx_carrier_errors++;
        if (tda.status & TCREG_EXC)
        if (tda.status & TCREG_EXC)
-               priv->stat.tx_aborted_errors++;
+               dev->stats.tx_aborted_errors++;
        if (tda.status & TCREG_OWC)
        if (tda.status & TCREG_OWC)
-               priv->stat.tx_window_errors++;
+               dev->stats.tx_window_errors++;
        if (tda.status & TCREG_FU)
        if (tda.status & TCREG_FU)
-               priv->stat.tx_fifo_errors++;
+               dev->stats.tx_fifo_errors++;
 
        /* update our pointers */
        priv->txused[priv->currtxdescr] = 0;
 
        /* update our pointers */
        priv->txused[priv->currtxdescr] = 0;
@@ -704,9 +704,9 @@ static void irqtxerr_handler(struct net_device *dev)
 
 /* general interrupt entry */
 
 
 /* general interrupt entry */
 
-static irqreturn_t irq_handler(int irq, void *device)
+static irqreturn_t irq_handler(int dummy, void *device)
 {
 {
-       struct net_device *dev = (struct net_device *) device;
+       struct net_device *dev = device;
        u16 ival;
 
        /* in case we're not meant... */
        u16 ival;
 
        /* in case we're not meant... */
@@ -744,6 +744,7 @@ static irqreturn_t irq_handler(int irq, void *device)
 
 /* MCA info */
 
 
 /* MCA info */
 
+#if 0 /* info available elsewhere, but this is kept for reference */
 static int ibmlana_getinfo(char *buf, int slot, void *d)
 {
        int len = 0, i;
 static int ibmlana_getinfo(char *buf, int slot, void *d)
 {
        int len = 0, i;
@@ -771,6 +772,7 @@ static int ibmlana_getinfo(char *buf, int slot, void *d)
 
        return len;
 }
 
        return len;
 }
+#endif
 
 /* open driver.  Means also initialization and start of LANCE */
 
 
 /* open driver.  Means also initialization and start of LANCE */
 
@@ -824,7 +826,7 @@ static int ibmlana_tx(struct sk_buff *skb, struct net_device *dev)
 
        if (priv->txusedcnt >= TXBUFCNT) {
                retval = -EIO;
 
        if (priv->txusedcnt >= TXBUFCNT) {
                retval = -EIO;
-               priv->stat.tx_dropped++;
+               dev->stats.tx_dropped++;
                goto tx_done;
        }
 
                goto tx_done;
        }
 
@@ -876,14 +878,6 @@ tx_done:
        return retval;
 }
 
        return retval;
 }
 
-/* return pointer to Ethernet statistics */
-
-static struct net_device_stats *ibmlana_stats(struct net_device *dev)
-{
-       ibmlana_priv *priv = netdev_priv(dev);
-       return &priv->stat;
-}
-
 /* switch receiver mode. */
 
 static void ibmlana_set_multicast_list(struct net_device *dev)
 /* switch receiver mode. */
 
 static void ibmlana_set_multicast_list(struct net_device *dev)
@@ -898,43 +892,52 @@ static void ibmlana_set_multicast_list(struct net_device *dev)
  * hardware check
  * ------------------------------------------------------------------------ */
 
  * hardware check
  * ------------------------------------------------------------------------ */
 
+static int ibmlana_irq;
+static int ibmlana_io;
 static int startslot;          /* counts through slots when probing multiple devices */
 
 static int startslot;          /* counts through slots when probing multiple devices */
 
-static int ibmlana_probe(struct net_device *dev)
+static short ibmlana_adapter_ids[] __initdata = {
+       IBM_LANA_ID,
+       0x0000
+};
+
+static char *ibmlana_adapter_names[] __devinitdata = {
+       "IBM LAN Adapter/A",
+       NULL
+};
+
+static int __devinit ibmlana_init_one(struct device *kdev)
 {
 {
-       int slot, z;
+       struct mca_device *mdev = to_mca_device(kdev);
+       struct net_device *dev;
+       int slot = mdev->slot, z, rc;
        int base = 0, irq = 0, iobase = 0, memlen = 0;
        ibmlana_priv *priv;
        ibmlana_medium medium;
        int base = 0, irq = 0, iobase = 0, memlen = 0;
        ibmlana_priv *priv;
        ibmlana_medium medium;
+       DECLARE_MAC_BUF(mac);
 
 
-       SET_MODULE_OWNER(dev);
+       dev = alloc_etherdev(sizeof(ibmlana_priv));
+       if (!dev)
+               return -ENOMEM;
 
 
-       /* can't work without an MCA bus ;-) */
-       if (MCA_bus == 0)
-               return -ENODEV;
+       dev->irq = ibmlana_irq;
+       dev->base_addr = ibmlana_io;
 
        base = dev->mem_start;
        irq = dev->irq;
 
 
        base = dev->mem_start;
        irq = dev->irq;
 
-       for (slot = startslot; (slot = mca_find_adapter(IBM_LANA_ID, slot)) != -1; slot++) {
-               /* deduce card addresses */
-               getaddrs(slot, &base, &memlen, &iobase, &irq, &medium);
-
-               /* slot already in use ? */
-               if (mca_is_adapter_used(slot))
-                       continue;
-               /* were we looking for something different ? */
-               if (dev->irq && dev->irq != irq)
-                       continue;
-               if (dev->mem_start && dev->mem_start != base)
-                       continue;
-               /* found something that matches */
-               break;
-       }
+       /* deduce card addresses */
+       getaddrs(mdev, &base, &memlen, &iobase, &irq, &medium);
 
 
-       /* nothing found ? */
-       if (slot == -1)
-               return (base != 0 || irq != 0) ? -ENXIO : -ENODEV;
+       /* were we looking for something different ? */
+       if (dev->irq && dev->irq != irq) {
+               rc = -ENODEV;
+               goto err_out;
+       }
+       if (dev->mem_start && dev->mem_start != base) {
+               rc = -ENODEV;
+               goto err_out;
+       }
 
        /* announce success */
        printk(KERN_INFO "%s: IBM LAN Adapter/A found in slot %d\n", dev->name, slot + 1);
 
        /* announce success */
        printk(KERN_INFO "%s: IBM LAN Adapter/A found in slot %d\n", dev->name, slot + 1);
@@ -943,16 +946,16 @@ static int ibmlana_probe(struct net_device *dev)
        if (!request_region(iobase, IBM_LANA_IORANGE, DRV_NAME)) {
                printk(KERN_ERR "%s: cannot allocate I/O range at %#x!\n", DRV_NAME, iobase);
                startslot = slot + 1;
        if (!request_region(iobase, IBM_LANA_IORANGE, DRV_NAME)) {
                printk(KERN_ERR "%s: cannot allocate I/O range at %#x!\n", DRV_NAME, iobase);
                startslot = slot + 1;
-               return -EBUSY;
+               rc = -EBUSY;
+               goto err_out;
        }
 
        priv = netdev_priv(dev);
        priv->slot = slot;
        }
 
        priv = netdev_priv(dev);
        priv->slot = slot;
-       priv->realirq = irq;
+       priv->realirq = mca_device_transform_irq(mdev, irq);
        priv->medium = medium;
        spin_lock_init(&priv->lock);
 
        priv->medium = medium;
        spin_lock_init(&priv->lock);
 
-
        /* set base + irq for this device (irq not allocated so far) */
 
        dev->irq = 0;
        /* set base + irq for this device (irq not allocated so far) */
 
        dev->irq = 0;
@@ -964,23 +967,18 @@ static int ibmlana_probe(struct net_device *dev)
        if (!priv->base) {
                printk(KERN_ERR "%s: cannot remap memory!\n", DRV_NAME);
                startslot = slot + 1;
        if (!priv->base) {
                printk(KERN_ERR "%s: cannot remap memory!\n", DRV_NAME);
                startslot = slot + 1;
-               release_region(iobase, IBM_LANA_IORANGE);
-               return -EBUSY;
+               rc = -EBUSY;
+               goto err_out_reg;
        }
 
        }
 
-       /* make procfs entries */
-       mca_set_adapter_name(slot, "IBM LAN Adapter/A");
-       mca_set_adapter_procfn(slot, (MCA_ProcFn) ibmlana_getinfo, dev);
-
-       mca_mark_as_used(slot);
+       mca_device_set_name(mdev, ibmlana_adapter_names[mdev->index]);
+       mca_device_set_claim(mdev, 1);
 
        /* set methods */
 
        dev->open = ibmlana_open;
        dev->stop = ibmlana_close;
        dev->hard_start_xmit = ibmlana_tx;
 
        /* set methods */
 
        dev->open = ibmlana_open;
        dev->stop = ibmlana_close;
        dev->hard_start_xmit = ibmlana_tx;
-       dev->do_ioctl = NULL;
-       dev->get_stats = ibmlana_stats;
        dev->set_multicast_list = ibmlana_set_multicast_list;
        dev->flags |= IFF_MULTICAST;
 
        dev->set_multicast_list = ibmlana_set_multicast_list;
        dev->flags |= IFF_MULTICAST;
 
@@ -992,11 +990,10 @@ static int ibmlana_probe(struct net_device *dev)
        /* print config */
 
        printk(KERN_INFO "%s: IRQ %d, I/O %#lx, memory %#lx-%#lx, "
        /* print config */
 
        printk(KERN_INFO "%s: IRQ %d, I/O %#lx, memory %#lx-%#lx, "
-              "MAC address %02x:%02x:%02x:%02x:%02x:%02x.\n",
+              "MAC address %s.\n",
               dev->name, priv->realirq, dev->base_addr,
               dev->mem_start, dev->mem_end - 1,
               dev->name, priv->realirq, dev->base_addr,
               dev->mem_start, dev->mem_end - 1,
-              dev->dev_addr[0], dev->dev_addr[1], dev->dev_addr[2],
-              dev->dev_addr[3], dev->dev_addr[4], dev->dev_addr[5]);
+              print_mac(mac, dev->dev_addr));
        printk(KERN_INFO "%s: %s medium\n", dev->name, MediaNames[priv->medium]);
 
        /* reset board */
        printk(KERN_INFO "%s: %s medium\n", dev->name, MediaNames[priv->medium]);
 
        /* reset board */
@@ -1007,6 +1004,35 @@ static int ibmlana_probe(struct net_device *dev)
 
        startslot = slot + 1;
 
 
        startslot = slot + 1;
 
+       rc = register_netdev(dev);
+       if (rc)
+               goto err_out_claimed;
+
+       dev_set_drvdata(kdev, dev);
+       return 0;
+
+err_out_claimed:
+       mca_device_set_claim(mdev, 0);
+       iounmap(priv->base);
+err_out_reg:
+       release_region(iobase, IBM_LANA_IORANGE);
+err_out:
+       free_netdev(dev);
+       return rc;
+}
+
+static int ibmlana_remove_one(struct device *kdev)
+{
+       struct mca_device *mdev = to_mca_device(kdev);
+       struct net_device *dev = dev_get_drvdata(kdev);
+       ibmlana_priv *priv = netdev_priv(dev);
+
+       unregister_netdev(dev);
+       /*DeinitBoard(dev); */
+       release_region(dev->base_addr, IBM_LANA_IORANGE);
+       mca_device_set_claim(mdev, 0);
+       iounmap(priv->base);
+       free_netdev(dev);
        return 0;
 }
 
        return 0;
 }
 
@@ -1014,66 +1040,31 @@ static int ibmlana_probe(struct net_device *dev)
  * modularization support
  * ------------------------------------------------------------------------ */
 
  * modularization support
  * ------------------------------------------------------------------------ */
 
-#ifdef MODULE
-
-#define DEVMAX 5
-
-static struct net_device *moddevs[DEVMAX];
-static int irq;
-static int io;
-
-module_param(irq, int, 0);
-module_param(io, int, 0);
+module_param_named(irq, ibmlana_irq, int, 0);
+module_param_named(io, ibmlana_io, int, 0);
 MODULE_PARM_DESC(irq, "IBM LAN/A IRQ number");
 MODULE_PARM_DESC(io, "IBM LAN/A I/O base address");
 MODULE_LICENSE("GPL");
 
 MODULE_PARM_DESC(irq, "IBM LAN/A IRQ number");
 MODULE_PARM_DESC(io, "IBM LAN/A I/O base address");
 MODULE_LICENSE("GPL");
 
-int init_module(void)
-{
-       int z;
+static struct mca_driver ibmlana_driver = {
+       .id_table = ibmlana_adapter_ids,
+       .driver = {
+               .name   = "ibmlana",
+               .bus    = &mca_bus_type,
+               .probe  = ibmlana_init_one,
+               .remove = ibmlana_remove_one,
+       },
+};
 
 
-       startslot = 0;
-       for (z = 0; z < DEVMAX; z++) {
-               struct net_device *dev = alloc_etherdev(sizeof(ibmlana_priv));
-               if (!dev)
-                       break;
-               dev->irq = irq;
-               dev->base_addr = io;
-               if (ibmlana_probe(dev)) {
-                       free_netdev(dev);
-                       break;
-               }
-               if (register_netdev(dev)) {
-                       ibmlana_priv *priv = netdev_priv(dev);
-                       release_region(dev->base_addr, IBM_LANA_IORANGE);
-                       mca_mark_as_unused(priv->slot);
-                       mca_set_adapter_name(priv->slot, "");
-                       mca_set_adapter_procfn(priv->slot, NULL, NULL);
-                       iounmap(priv->base);
-                       free_netdev(dev);
-                       break;
-               }
-               moddevs[z] = dev;
-       }
-       return (z > 0) ? 0 : -EIO;
+static int __init ibmlana_init_module(void)
+{
+       return mca_register_driver(&ibmlana_driver);
 }
 
 }
 
-void cleanup_module(void)
+static void __exit ibmlana_cleanup_module(void)
 {
 {
-       int z;
-       for (z = 0; z < DEVMAX; z++) {
-               struct net_device *dev = moddevs[z];
-               if (dev) {
-                       ibmlana_priv *priv = netdev_priv(dev);
-                       unregister_netdev(dev);
-                       /*DeinitBoard(dev); */
-                       release_region(dev->base_addr, IBM_LANA_IORANGE);
-                       mca_mark_as_unused(priv->slot);
-                       mca_set_adapter_name(priv->slot, "");
-                       mca_set_adapter_procfn(priv->slot, NULL, NULL);
-                       iounmap(priv->base);
-                       free_netdev(dev);
-               }
-       }
+       mca_unregister_driver(&ibmlana_driver);
 }
 }
-#endif                         /* MODULE */
+
+module_init(ibmlana_init_module);
+module_exit(ibmlana_cleanup_module);