netdev
[Top] [All Lists]

[PATCH] (08/12) Probe2 -- 3c507

To: jgarzik@xxxxxxxxx
Subject: [PATCH] (08/12) Probe2 -- 3c507
From: Stephen Hemminger <shemminger@xxxxxxxx>
Date: Tue, 14 Oct 2003 15:34:10 -0700
Cc: netdev@xxxxxxxxxxx
Sender: netdev-bounce@xxxxxxxxxxx
Originally by Al Viro (NE19-3c507)
        * switched 3c507 to dynamic allocation
        * 3c507: embedded ->priv
        * 3c507: fixed clobbering on autoprobe
        * NB: 3c507.c buggers port 0x100 without claiming it.  Most likely it
          should be doing request_region() there.
Updated to apply agains jgarzik/net-drivers-2.5-exp

diff -Nru a/drivers/net/3c507.c b/drivers/net/3c507.c
--- a/drivers/net/3c507.c       Tue Oct 14 14:27:21 2003
+++ b/drivers/net/3c507.c       Tue Oct 14 14:27:21 2003
@@ -74,10 +74,6 @@
 #define debug net_debug
 
 
-/* A zero-terminated list of common I/O addresses to be probed. */
-static unsigned int netcard_portlist[] __initdata =
-       { 0x300, 0x320, 0x340, 0x280, 0};
-
 /*
                        Details of the i82586.
 
@@ -286,8 +282,6 @@
 
 /* Index to functions, as function prototypes. */
 
-extern int el16_probe(struct net_device *dev); /* Called from Space.c */
-
 static int     el16_probe1(struct net_device *dev, int ioaddr);
 static int     el16_open(struct net_device *dev);
 static int     el16_send_packet(struct sk_buff *skb, struct net_device *dev);
@@ -301,6 +295,10 @@
 static void init_82586_mem(struct net_device *dev);
 static struct ethtool_ops netdev_ethtool_ops;
 
+static int io = 0x300;
+static int irq;
+static int mem_start;
+
 
 /* Check for a network adaptor of this type, and return '0' iff one exists.
        If dev->base_addr == 0, probe all likely locations.
@@ -309,23 +307,50 @@
        device and return success.
        */
 
-int __init el16_probe(struct net_device *dev)
+struct net_device * __init el16_probe(int unit)
 {
-       int base_addr = dev->base_addr;
-       int i;
+       struct net_device *dev = alloc_etherdev(sizeof(struct net_local));
+       static unsigned ports[] = { 0x300, 0x320, 0x340, 0x280, 0};
+       unsigned *port;
+       int err = -ENODEV;
+
+       if (!dev)
+               return ERR_PTR(-ENODEV);
+
+       if (unit >= 0) {
+               sprintf(dev->name, "eth%d", unit);
+               netdev_boot_setup_check(dev);
+               io = dev->base_addr;
+               irq = dev->irq;
+               mem_start = dev->mem_start & 15;
+       }
 
        SET_MODULE_OWNER(dev);
 
-       if (base_addr > 0x1ff)  /* Check a single specified location. */
-               return el16_probe1(dev, base_addr);
-       else if (base_addr != 0)
-               return -ENXIO;          /* Don't probe at all. */
-
-       for (i = 0; netcard_portlist[i]; i++)
-               if (el16_probe1(dev, netcard_portlist[i]) == 0)
-                       return 0;
+       if (io > 0x1ff)         /* Check a single specified location. */
+               err = el16_probe1(dev, io);
+       else if (io != 0)
+               err = -ENXIO;           /* Don't probe at all. */
+       else {
+                       for (port = ports; *port; port++) {
+                                       err = el16_probe1(dev, io);
+                                       if (!err)
+                                               break;
+                       }
+       }
 
-       return -ENODEV;
+       if (err)
+               goto out;
+       err = register_netdev(dev);
+       if (err)
+               goto out1;
+       return dev;
+out1:
+       free_irq(dev->irq, dev);
+       release_region(dev->base_addr, EL16_IO_EXTENT);
+out:
+       free_netdev(dev);
+       return ERR_PTR(err);
 }
 
 static int __init el16_probe1(struct net_device *dev, int ioaddr)
@@ -383,8 +408,8 @@
                printk(" %02x", dev->dev_addr[i]);
        }
 
-       if ((dev->mem_start & 0xf) > 0)
-               net_debug = dev->mem_start & 7;
+       if (mem_start)
+               net_debug = mem_start & 7;
 
 #ifdef MEM_BASE
        dev->mem_start = MEM_BASE;
@@ -416,27 +441,18 @@
        if (net_debug)
                printk(version);
 
-       /* Initialize the device structure. */
-       lp = dev->priv = kmalloc(sizeof(struct net_local), GFP_KERNEL);
-       if (dev->priv == NULL) {
-               retval = -ENOMEM;
-               goto out;
-       }
-       memset(dev->priv, 0, sizeof(struct net_local));
+       lp = dev->priv;
+       memset(lp, 0, sizeof(*lp));
        spin_lock_init(&lp->lock);
 
-       dev->open               = el16_open;
-       dev->stop               = el16_close;
+       dev->open = el16_open;
+       dev->stop = el16_close;
        dev->hard_start_xmit = el16_send_packet;
        dev->get_stats  = el16_get_stats;
        dev->tx_timeout = el16_tx_timeout;
        dev->watchdog_timeo = TX_TIMEOUT;
        dev->ethtool_ops = &netdev_ethtool_ops;
-
-       ether_setup(dev);       /* Generic ethernet behaviour */
-
-       dev->flags&=~IFF_MULTICAST;     /* Multicast doesn't work */
-
+       dev->flags &= ~IFF_MULTICAST;   /* Multicast doesn't work */
        return 0;
 out:
        release_region(ioaddr, EL16_IO_EXTENT);
@@ -899,9 +915,7 @@
 };
 
 #ifdef MODULE
-static struct net_device dev_3c507;
-static int io = 0x300;
-static int irq;
+static struct net_device *dev_3c507;
 MODULE_PARM(io, "i");
 MODULE_PARM(irq, "i");
 MODULE_PARM_DESC(io, "EtherLink16 I/O base address");
@@ -911,26 +925,18 @@
 {
        if (io == 0)
                printk("3c507: You should not use auto-probing with insmod!\n");
-       dev_3c507.base_addr = io;
-       dev_3c507.irq       = irq;
-       dev_3c507.init      = el16_probe;
-       if (register_netdev(&dev_3c507) != 0) {
-               printk("3c507: register_netdev() returned non-zero.\n");
-               return -EIO;
-       }
-       return 0;
+       dev_3c507 = el16_probe(-1);
+       return IS_ERR(dev_3c507) ? PTR_ERR(dev_3c507) : 0;
 }
 
 void
 cleanup_module(void)
 {
-       unregister_netdev(&dev_3c507);
-       kfree(dev_3c507.priv);
-       dev_3c507.priv = NULL;
-
-       /* If we don't do this, we can't re-insmod it later. */
-       free_irq(dev_3c507.irq, &dev_3c507);
-       release_region(dev_3c507.base_addr, EL16_IO_EXTENT);
+       struct net_device *dev = dev_3c507;
+       unregister_netdev(dev);
+       free_irq(dev->irq, dev);
+       release_region(dev->base_addr, EL16_IO_EXTENT);
+       free_netdev(dev);
 }
 #endif /* MODULE */
 MODULE_LICENSE("GPL");
diff -Nru a/drivers/net/Space.c b/drivers/net/Space.c
--- a/drivers/net/Space.c       Tue Oct 14 14:27:21 2003
+++ b/drivers/net/Space.c       Tue Oct 14 14:27:21 2003
@@ -60,7 +60,7 @@
 extern int el1_probe(struct net_device *);
 extern int wavelan_probe(struct net_device *);
 extern int arlan_probe(struct net_device *);
-extern int el16_probe(struct net_device *);
+extern struct net_device *el16_probe(int unit);
 extern int elmc_probe(struct net_device *);
 extern int skmca_probe(struct net_device *);
 extern struct net_device *elplus_probe(int unit);
@@ -271,13 +271,13 @@
 #ifdef CONFIG_ARLAN            /* Aironet */
        {arlan_probe, 0},
 #endif
-#ifdef CONFIG_EL16             /* 3c507 */
-       {el16_probe, 0},
-#endif
        {NULL, 0},
 };
 
 static struct devprobe2 isa_probes2[] __initdata = {
+#ifdef CONFIG_EL16             /* 3c507 */
+       {el16_probe, 0},
+#endif
 #ifdef CONFIG_ELPLUS           /* 3c505 */
        {elplus_probe, 0},
 #endif

<Prev in Thread] Current Thread [Next in Thread>
  • [PATCH] (08/12) Probe2 -- 3c507, Stephen Hemminger <=