From 5828f47dd2fd18341f4253e9294bf47b13a663d1 Mon Sep 17 00:00:00 2001 From: Stephen Hemminger <shemminger@osdl.org> Date: Sat, 10 Jan 2004 05:08:56 -0500 Subject: [PATCH] [PATCH] (32/42) mac8390 NE57-mac8390 * switched mac8390 to dynamic allocation * mac8390: fixed resource leaks on failure exits * get rid of MOD_INC/DEC --- drivers/net/Space.c | 8 ++-- drivers/net/mac8390.c | 97 ++++++++++++++++++++++++++----------------- 2 files changed, 63 insertions(+), 42 deletions(-) diff --git a/drivers/net/Space.c b/drivers/net/Space.c index 987030dbf80b..8fac5ce63135 100644 --- a/drivers/net/Space.c +++ b/drivers/net/Space.c @@ -88,7 +88,7 @@ extern struct net_device *tc515_probe(int unit); extern struct net_device *lance_probe(int unit); extern int mace_probe(struct net_device *dev); extern int macsonic_probe(struct net_device *dev); -extern int mac8390_probe(struct net_device *dev); +extern struct net_device *mac8390_probe(int unit); extern struct net_device *mac89x0_probe(int unit); extern struct net_device *mc32_probe(int unit); extern struct net_device *cops_probe(int unit); @@ -325,14 +325,14 @@ static struct devprobe m68k_probes[] __initdata = { #endif #ifdef CONFIG_MACSONIC /* Mac SONIC-based Ethernet of all sorts */ {macsonic_probe, 0}, -#endif -#ifdef CONFIG_MAC8390 /* NuBus NS8390-based cards */ - {mac8390_probe, 0}, #endif {NULL, 0}, }; static struct devprobe2 m68k_probes2[] __initdata = { +#ifdef CONFIG_MAC8390 /* NuBus NS8390-based cards */ + {mac8390_probe, 0}, +#endif #ifdef CONFIG_MAC89x0 {mac89x0_probe, 0}, #endif diff --git a/drivers/net/mac8390.c b/drivers/net/mac8390.c index 4b2b653246b6..930b54471d91 100644 --- a/drivers/net/mac8390.c +++ b/drivers/net/mac8390.c @@ -124,11 +124,10 @@ static int useresources[] = { static char version[] __initdata = "mac8390.c: v0.4 2001-05-15 David Huggins-Daines <dhd@debian.org> and others\n"; -extern int mac8390_probe(struct net_device * dev); extern enum mac8390_type mac8390_ident(struct nubus_dev * dev); extern int mac8390_memsize(unsigned long membase); extern int mac8390_memtest(struct net_device * dev); -extern int mac8390_initdev(struct net_device * dev, struct nubus_dev * ndev, +static int mac8390_initdev(struct net_device * dev, struct nubus_dev * ndev, enum mac8390_type type); static int mac8390_open(struct net_device * dev); @@ -223,14 +222,14 @@ int __init mac8390_memsize(unsigned long membase) return i * 0x1000; } -static int probed __initdata = 0; - -int __init mac8390_probe(struct net_device * dev) +struct net_device * __init mac8390_probe(int unit) { + struct net_device *dev; volatile unsigned short *i; - int boards_found = 0; int version_disp = 0; struct nubus_dev * ndev = NULL; + static int probed; + int err = -ENDOEV; struct nubus_dir dir; struct nubus_dirent ent; @@ -238,28 +237,29 @@ int __init mac8390_probe(struct net_device * dev) enum mac8390_type cardtype; - if (probed) - return -ENODEV; - probed++; - /* probably should check for Nubus instead */ if (!MACH_IS_MAC) - return -ENODEV; + return ERR_PTR(-ENODEV); + + dev = alloc_etherdev(0); + if (!dev) + return ERR_PTR(-ENOMEM); + dev->priv = NULL; + + if (unit >= 0) + sprintf(dev->name, "eth%d", unit); + + SET_MODULE_OWNER(dev); while ((ndev = nubus_find_type(NUBUS_CAT_NETWORK, NUBUS_TYPE_ETHERNET, ndev))) { - - dev = NULL; - - if ((cardtype = mac8390_ident(ndev)) == MAC8390_NONE) + /* Have we seen it already? */ + if (slots & (1<<ndev->board->slot)) continue; + slots |= 1<<ndev->board->slot; - dev = init_etherdev(dev, 0); - if (dev == NULL) { - printk(KERN_ERR "Unable to allocate etherdev" - "structure!\n"); - return -ENOMEM; - } + if ((cardtype = mac8390_ident(ndev)) == MAC8390_NONE) + continue; if (version_disp == 0) { version_disp = 1; @@ -358,21 +358,28 @@ int __init mac8390_probe(struct net_device * dev) printk(KERN_ERR "Card type %s is" " unsupported, sorry\n", cardname[cardtype]); - return -ENODEV; + continue; } } /* Do the nasty 8390 stuff */ - if (mac8390_initdev(dev, ndev, cardtype)) - continue; - boards_found++; + if (!mac8390_initdev(dev, ndev, cardtype)) + break; } - /* We're outta here */ - if (boards_found > 0) - return 0; - else - return -ENODEV; + if (!ndev) + goto out; + err = register_netdev(dev); + if (err) + goto out1; + return dev; + +out1: + kfree(dev->priv); + dev->priv = NULL; +out: + free_netdev(dev); + return ERR_PTE(err); } #ifdef MODULE @@ -380,26 +387,40 @@ MODULE_AUTHOR("David Huggins-Daines <dhd@debian.org> and others"); MODULE_DESCRIPTION("Macintosh NS8390-based Nubus Ethernet driver"); MODULE_LICENSE("GPL"); +/* overkill, of course */ +static struct net_device *dev_mac8390[15]; int init_module(void) { - if (mac8390_probe(NULL)) { + int i; + for (i = 0; i < 15; i++) { + struct net_device *dev = mac8390_probe(-1); + if (IS_ERR(dev)) + break; + dev_mac890[i] = dev; + } + if (!i) { printk(KERN_NOTICE "mac8390.c: No useable cards found, driver NOT installed.\n"); return -ENODEV; } - lock_8390_module(); return 0; } void cleanup_module(void) { - /* FIXME: should probably keep track of net_device structs - somewhere and unregister them here? */ - unlock_8390_module(); + int i; + for (i = 0; i < 15; i++) { + struct net_device *dev = dev_mac890[i]; + if (dev) { + unregister_netdev(dev); + kfree(dev->priv); + free_netdev(dev); + } + } } #endif /* MODULE */ -int __init mac8390_initdev(struct net_device * dev, struct nubus_dev * ndev, +static int __init mac8390_initdev(struct net_device * dev, struct nubus_dev * ndev, enum mac8390_type type) { static u32 fwrd4_offsets[16]={ @@ -499,6 +520,8 @@ int __init mac8390_initdev(struct net_device * dev, struct nubus_dev * ndev, break; default: printk(KERN_ERR "Card type %s is unsupported, sorry\n", cardname[type]); + kfree(dev->priv); + dev->priv = NULL; return -ENODEV; } @@ -529,7 +552,6 @@ static int mac8390_open(struct net_device *dev) printk ("%s: unable to get IRQ %d.\n", dev->name, dev->irq); return -EAGAIN; } - MOD_INC_USE_COUNT; return 0; } @@ -537,7 +559,6 @@ static int mac8390_close(struct net_device *dev) { free_irq(dev->irq, dev); ei_close(dev); - MOD_DEC_USE_COUNT; return 0; } -- 2.30.9