cleanup mac8390.c: - kill init_etherdev(), use ei_alloc_dev() - remove MOD_(INC|DEC)_USE_COUNT - keep track of the registered devices, unregister 'em on cleanup - don't leak memory if probe fails completely untested, but i'm sure it didn't build before (WTF is lock_8390_module?). --- 1.11/drivers/net/mac8390.c Mon Feb 17 01:17:32 2003 +++ edited/mac8390.c Sun Jun 29 17:42:34 2003 @@ -42,6 +42,8 @@ #include "8390.h" +#define DRVNAME "mac8390" + #if (LINUX_VERSION_CODE < 0x02030e) #define net_device device #endif @@ -124,7 +126,7 @@ 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 int mac8390_probe(void); 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); @@ -170,6 +172,16 @@ static void word_memcpy_tocard(void *tp, const void *fp, int count); static void word_memcpy_fromcard(void *tp, const void *fp, int count); +#ifdef MODULE +/* to keep track of the open devices */ +struct mac8390_list { + struct mac8390_list *next; + struct net_device *dev; +}; + +static struct mac8390_list *dev_list; +#endif /* MODULE */ + enum mac8390_type __init mac8390_ident(struct nubus_dev * dev) { if (dev->dr_sw == NUBUS_DRSW_ASANTE) @@ -225,9 +237,11 @@ static int probed __initdata = 0; -int __init mac8390_probe(struct net_device * dev) +int __init mac8390_probe(void) { volatile unsigned short *i; + struct net_device *dev; + struct mac8390_list *entry; int boards_found = 0; int version_disp = 0; struct nubus_dev * ndev = NULL; @@ -248,18 +262,16 @@ return -ENODEV; while ((ndev = nubus_find_type(NUBUS_CAT_NETWORK, NUBUS_TYPE_ETHERNET, ndev))) { - - dev = NULL; - if ((cardtype = mac8390_ident(ndev)) == MAC8390_NONE) continue; - dev = init_etherdev(dev, 0); + dev = ei_alloc_dev(); if (dev == NULL) { printk(KERN_ERR "Unable to allocate etherdev" "structure!\n"); return -ENOMEM; } + SET_MODULE_OWNER(dev); if (version_disp == 0) { version_disp = 1; @@ -276,14 +288,16 @@ if (nubus_get_func_dir(ndev, &dir) == -1) { printk(KERN_ERR "%s: Unable to get Nubus functional" " directory for slot %X!\n", - dev->name, ndev->board->slot); + DRVNAME, ndev->board->slot); + kfree(dev); continue; } /* Get the MAC address */ if ((nubus_find_rsrc(&dir, NUBUS_RESID_MAC_ADDRESS, &ent)) == -1) { printk(KERN_INFO "%s: Couldn't get MAC address!\n", - dev->name); + DRVNAME); + kfree(dev); continue; } else { nubus_get_rsrc_mem(dev->dev_addr, &ent, 6); @@ -302,7 +316,8 @@ if (nubus_find_rsrc(&dir, NUBUS_RESID_MINOR_BASEOS, &ent) == -1) { printk(KERN_ERR "%s: Memory offset resource" " for slot %X not found!\n", - dev->name, ndev->board->slot); + DRVNAME, ndev->board->slot); + kfree(dev); continue; } nubus_get_rsrc_mem(&offset, &ent, 4); @@ -314,7 +329,7 @@ printk(KERN_INFO "%s: Memory length resource" " for slot %X not found" ", probing\n", - dev->name, ndev->board->slot); + DRVNAME, ndev->board->slot); offset = mac8390_memsize(dev->mem_start); } else { nubus_get_rsrc_mem(&offset, &ent, 4); @@ -358,14 +373,30 @@ printk(KERN_ERR "Card type %s is" " unsupported, sorry\n", cardname[cardtype]); + kfree(dev); return -ENODEV; } } /* Do the nasty 8390 stuff */ - if (mac8390_initdev(dev, ndev, cardtype)) + if (mac8390_initdev(dev, ndev, cardtype)) { + kfree(dev); continue; + } boards_found++; + +#ifdef MODULE + /* add to list */ + entry = kmalloc(sizeof(struct mac8390_list), GFP_KERNEL); + if (!entry) { + unregister_netdev(dev); + kfree(dev); + return -ENOMEM; + } + entry->next = dev_list; + entry->dev = dev; + dev_list = entry; +#endif /* MODULE */ } /* We're outta here */ @@ -382,19 +413,24 @@ int init_module(void) { - if (mac8390_probe(NULL)) { + if (mac8390_probe()) { 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(); + struct mac8390_list *tmp; + while (dev_list) { + unregister_netdev(dev_list->dev); + kfree(dev_list->dev); + + tmp = dev_list->next; + kfree(dev_list); + dev_list = tmp; + } } #endif /* MODULE */ @@ -402,6 +438,8 @@ int __init mac8390_initdev(struct net_device * dev, struct nubus_dev * ndev, enum mac8390_type type) { + int err; + static u32 fwrd4_offsets[16]={ 0, 4, 8, 12, 16, 20, 24, 28, @@ -423,12 +461,6 @@ int access_bitmode; - /* 8390 specific init for dev - allocates dev->priv */ - if (ethdev_init(dev)) { - printk(KERN_ERR "%s: Unable to allocate memory for dev->priv!\n", dev->name); - return -ENOMEM; - } - /* Now fill in our stuff */ dev->open = &mac8390_open; dev->stop = &mac8390_close; @@ -504,6 +536,11 @@ NS8390_init(dev, 0); + /* card is up, register */ + err = register_netdev(dev); + if (err) + return err; + /* Good, done, now spit out some messages */ printk(KERN_INFO "%s: %s in slot %X (type %s)\n", dev->name, ndev->board->name, ndev->board->slot, cardname[type]); @@ -524,20 +561,17 @@ static int mac8390_open(struct net_device *dev) { - ei_open(dev); if (request_irq(dev->irq, ei_interrupt, 0, "8390 Ethernet", dev)) { printk ("%s: unable to get IRQ %d.\n", dev->name, dev->irq); return -EAGAIN; } - MOD_INC_USE_COUNT; - return 0; + return ei_open(dev); } static int mac8390_close(struct net_device *dev) { free_irq(dev->irq, dev); ei_close(dev); - MOD_DEC_USE_COUNT; return 0; } - : send the line "unsubscribe linux-net" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html