netdev
[Top] [All Lists]

[PATCH] (9/42) seeq8005

To: jgarzik@xxxxxxxxx
Subject: [PATCH] (9/42) seeq8005
From: Stephen Hemminger <shemminger@xxxxxxxx>
Date: Wed, 12 Nov 2003 16:41:48 -0800
Cc: netdev@xxxxxxxxxxx
Sender: netdev-bounce@xxxxxxxxxxx
Based on viro NE33-seeq8005
        * switched seeq8005 to dynamic allocation
        * seeq8005: embedded ->priv
        * seeq8005: fixed resource leaks on failure exits
        * seeq8005: fixed clobbering on autoprobe
        * seeq8005: fixed jiffies truncation
        * seeq8005: fixed a typo in Kconfig - module is _not_ called ewrk3

diff -Nru a/drivers/net/Space.c b/drivers/net/Space.c
--- a/drivers/net/Space.c       Tue Nov 11 09:35:45 2003
+++ b/drivers/net/Space.c       Tue Nov 11 09:35:45 2003
@@ -72,7 +72,7 @@
 extern struct net_device *ni65_probe(int unit);
 extern int sonic_probe(struct net_device *);
 extern struct net_device *SK_init(int unit);
-extern int seeq8005_probe(struct net_device *);
+extern struct net_device *seeq8005_probe(int unit);
 extern int smc_init( struct net_device * );
 extern int atarilance_probe(struct net_device *);
 extern int sun3lance_probe(struct net_device *);
@@ -231,13 +231,13 @@
 #ifdef CONFIG_SMC9194
        {smc_init, 0},
 #endif
-#ifdef CONFIG_SEEQ8005 
-       {seeq8005_probe, 0},
-#endif
        {NULL, 0},
 };
 
 static struct devprobe2 isa_probes2[] __initdata = {
+#ifdef CONFIG_SEEQ8005 
+       {seeq8005_probe, 0},
+#endif
 #ifdef CONFIG_CS89x0
        {cs89x0_probe, 0},
 #endif
diff -Nru a/drivers/net/seeq8005.c b/drivers/net/seeq8005.c
--- a/drivers/net/seeq8005.c    Tue Nov 11 09:35:45 2003
+++ b/drivers/net/seeq8005.c    Tue Nov 11 09:35:45 2003
@@ -78,8 +78,6 @@
 
 /* Index to functions, as function prototypes. */
 
-extern int seeq8005_probe(struct net_device *dev);
-
 static int seeq8005_probe1(struct net_device *dev, int ioaddr);
 static int seeq8005_open(struct net_device *dev);
 static void seeq8005_timeout(struct net_device *dev);
@@ -102,22 +100,48 @@
    If dev->base_addr == 1, always return failure.
    */
 
-int __init 
-seeq8005_probe(struct net_device *dev)
-{
-       int i;
-       int base_addr = dev ? dev->base_addr : 0;
-
-       if (base_addr > 0x1ff)          /* Check a single specified location. */
-               return seeq8005_probe1(dev, base_addr);
-       else if (base_addr != 0)        /* Don't probe at all. */
-               return -ENXIO;
-
-       for (i = 0; seeq8005_portlist[i]; i++)
-               if (seeq8005_probe1(dev, seeq8005_portlist[i]) == 0)
-                       return 0;
+static int io = 0x320;
+static int irq = 10;
 
-       return -ENODEV;
+struct net_device * __init seeq8005_probe(int unit)
+{
+       struct net_device *dev = alloc_etherdev(sizeof(struct net_local));
+       unsigned *port;
+       int err = 0;
+
+       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;
+       }
+
+       if (io > 0x1ff) {       /* Check a single specified location. */
+               err = seeq8005_probe1(dev, io);
+       } else if (io != 0) {   /* Don't probe at all. */
+               err = -ENXIO;
+       } else {
+               for (port = seeq8005_portlist; *port; port++) {
+                       if (seeq8005_probe1(dev, *port) == 0)
+                               break;
+               }
+               if (!*port)
+                       err = -ENODEV;
+       }
+       if (err)
+               goto out;
+       err = register_netdev(dev);
+       if (err)
+               goto out1;
+       return dev;
+out1:
+       release_region(dev->base_addr, SEEQ8005_IO_EXTENT);
+out:
+       free_netdev(dev);
+       return ERR_PTR(err);
 }
 
 /* This is the real probe routine.  Linux has a history of friendly device
@@ -274,6 +298,7 @@
 
        /* Fill in the 'dev' fields. */
        dev->base_addr = ioaddr;
+       dev->irq = irq;
 
        /* Retrieve and print the ethernet address. */
        for (i = 0; i < 6; i++)
@@ -307,13 +332,6 @@
                 }
        }
 #endif
-
-       /* Initialize the device structure. */
-       dev->priv = kmalloc(sizeof(struct net_local), GFP_KERNEL);
-       if (dev->priv == NULL)
-               return -ENOMEM;
-       memset(dev->priv, 0, sizeof(struct net_local));
-
        dev->open               = seeq8005_open;
        dev->stop               = seeq8005_close;
        dev->hard_start_xmit    = seeq8005_send_packet;
@@ -321,10 +339,6 @@
        dev->watchdog_timeo     = HZ/20;
        dev->get_stats          = seeq8005_get_stats;
        dev->set_multicast_list = set_multicast_list;
-
-       /* Fill in the fields of the device structure with ethernet values. */
-       ether_setup(dev);
-       
        dev->flags &= ~IFF_MULTICAST;
 
        return 0;
@@ -721,9 +735,7 @@
        
 #ifdef MODULE
 
-static struct net_device dev_seeq = { .init = seeq8005_probe };
-static int io = 0x320;
-static int irq = 10;
+static struct net_device *dev_seeq;
 MODULE_LICENSE("GPL");
 MODULE_PARM(io, "i");
 MODULE_PARM(irq, "i");
@@ -732,28 +744,17 @@
 
 int init_module(void)
 {
-       dev_seeq.irq=irq;
-       dev_seeq.base_addr=io;
-       if (register_netdev(&dev_seeq) != 0)
-               return -EIO;
+       dev_seeq = seeq8005_probe(-1);
+       if (IS_ERR(dev_seeq))
+               return PTR_ERR(dev_seeq);
        return 0;
 }
 
 void cleanup_module(void)
 {
-       unregister_netdev(&dev_seeq);
-
-       /*
-        *      Free up the private structure, or leak memory :-)
-        */
-
-       kfree(dev_seeq.priv);
-       dev_seeq.priv = NULL;   /* gets re-allocated by el1_probe1 */
-
-       /*
-        *      If we don't do this, we can't re-insmod it later.
-        */
-       release_region(dev_seeq.base_addr, SEEQ8005_IO_EXTENT);
+       unregister_netdev(dev_seeq);
+       release_region(dev_seeq->base_addr, SEEQ8005_IO_EXTENT);
+       free_netdev(dev_seeq);
 }
 
 #endif /* MODULE */

<Prev in Thread] Current Thread [Next in Thread>
  • [PATCH] (9/42) seeq8005, Stephen Hemminger <=