Commit 5a084b66 authored by Alexander Viro's avatar Alexander Viro Committed by Stephen Hemminger

[netdrvr ibmlana] ibmlana switched to sane allocation, leaks fixed

parent a3e292a1
...@@ -906,7 +906,7 @@ static void ibmlana_set_multicast_list(struct net_device *dev) ...@@ -906,7 +906,7 @@ static void ibmlana_set_multicast_list(struct net_device *dev)
static int startslot; /* counts through slots when probing multiple devices */ static int startslot; /* counts through slots when probing multiple devices */
int ibmlana_probe(struct net_device *dev) static int ibmlana_probe(struct net_device *dev)
{ {
int force_detect = 0; int force_detect = 0;
int slot, z; int slot, z;
...@@ -924,34 +924,21 @@ int ibmlana_probe(struct net_device *dev) ...@@ -924,34 +924,21 @@ int ibmlana_probe(struct net_device *dev)
if (dev->mem_start == 1) if (dev->mem_start == 1)
force_detect = 1; force_detect = 1;
/* search through slots */ base = dev->mem_start;
if (dev != NULL) { irq = dev->irq;
base = dev->mem_start;
irq = dev->irq;
}
slot = mca_find_adapter(IBM_LANA_ID, startslot);
while (slot != -1) { for (slot = startslot; (slot = mca_find_adapter(IBM_LANA_ID, slot)) != -1; slot++) {
/* deduce card addresses */ /* deduce card addresses */
getaddrs(slot, &base, &memlen, &iobase, &irq, &medium); getaddrs(slot, &base, &memlen, &iobase, &irq, &medium);
/* slot already in use ? */ /* slot already in use ? */
if (mca_is_adapter_used(slot)) { if (mca_is_adapter_used(slot))
slot = mca_find_adapter(IBM_LANA_ID, slot + 1);
continue; continue;
}
/* were we looking for something different ? */ /* were we looking for something different ? */
if (dev->irq != 0 || dev->mem_start != 0) { if (dev->irq && dev->irq != irq)
if (dev->irq != 0 && dev->irq != irq) { continue;
slot = mca_find_adapter(IBM_LANA_ID, slot + 1); if (dev->mem_start && dev->mem_start != base)
continue; continue;
}
if (dev->mem_start != 0 && dev->mem_start != base)
{
slot = mca_find_adapter(IBM_LANA_ID, slot + 1);
continue;
}
}
/* found something that matches */ /* found something that matches */
break; break;
} }
...@@ -977,16 +964,11 @@ int ibmlana_probe(struct net_device *dev) ...@@ -977,16 +964,11 @@ int ibmlana_probe(struct net_device *dev)
mca_mark_as_used(slot); mca_mark_as_used(slot);
/* allocate structure */ /* allocate structure */
priv = dev->priv = (ibmlana_priv *) kmalloc(sizeof(ibmlana_priv), GFP_KERNEL); priv = dev->priv;
if (!priv) {
release_region(iobase, IBM_LANA_IORANGE);
return -ENOMEM;
}
priv->slot = slot; priv->slot = slot;
priv->realirq = irq; priv->realirq = irq;
priv->medium = medium; priv->medium = medium;
spin_lock_init(&priv->lock); spin_lock_init(&priv->lock);
memset(&priv->stat, 0, sizeof(struct net_device_stats));
/* set base + irq for this device (irq not allocated so far) */ /* set base + irq for this device (irq not allocated so far) */
...@@ -1006,10 +988,6 @@ int ibmlana_probe(struct net_device *dev) ...@@ -1006,10 +988,6 @@ int ibmlana_probe(struct net_device *dev)
dev->set_multicast_list = ibmlana_set_multicast_list; dev->set_multicast_list = ibmlana_set_multicast_list;
dev->flags |= IFF_MULTICAST; dev->flags |= IFF_MULTICAST;
/* generic setup */
ether_setup(dev);
/* copy out MAC address */ /* copy out MAC address */
for (z = 0; z < sizeof(dev->dev_addr); z++) for (z = 0; z < sizeof(dev->dev_addr); z++)
...@@ -1044,7 +1022,7 @@ int ibmlana_probe(struct net_device *dev) ...@@ -1044,7 +1022,7 @@ int ibmlana_probe(struct net_device *dev)
#define DEVMAX 5 #define DEVMAX 5
static struct net_device moddevs[DEVMAX]; static struct net_device *moddevs[DEVMAX];
static int irq; static int irq;
static int io; static int io;
...@@ -1056,41 +1034,47 @@ MODULE_LICENSE("GPL"); ...@@ -1056,41 +1034,47 @@ MODULE_LICENSE("GPL");
int init_module(void) int init_module(void)
{ {
int z, res; int z;
startslot = 0; startslot = 0;
for (z = 0; z < DEVMAX; z++) { for (z = 0; z < DEVMAX; z++) {
moddevs[z].init = ibmlana_probe; struct net_device *dev = alloc_etherdev(sizeof(ibmlana_priv));
moddevs[z].irq = irq; if (!dev)
moddevs[z].base_addr = io; break;
res = register_netdev(moddevs + z); dev->irq = irq;
if (res != 0) dev->base_addr = io;
return (z > 0) ? 0 : -EIO; if (ibmlana_probe(dev)) {
free_netdev(dev);
break;
}
if (register_netdev(dev)) {
ibmlana_priv *priv = dev->priv;
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);
free_netdev(dev);
break;
}
moddevs[z] = dev;
} }
return 0; return (z > 0) ? 0 : -EIO;
} }
void cleanup_module(void) void cleanup_module(void)
{ {
struct net_device *dev;
ibmlana_priv *priv;
int z; int z;
for (z = 0; z < DEVMAX; z++) { for (z = 0; z < DEVMAX; z++) {
dev = moddevs + z; struct net_device *dev = moddevs[z];
if (dev->priv != NULL) { if (dev) {
priv = (ibmlana_priv *) dev->priv; ibmlana_priv *priv = (ibmlana_priv *) dev->priv;
unregister_netdev(dev);
/*DeinitBoard(dev); */ /*DeinitBoard(dev); */
if (dev->irq != 0)
free_irq(dev->irq, dev);
dev->irq = 0;
release_region(dev->base_addr, IBM_LANA_IORANGE); release_region(dev->base_addr, IBM_LANA_IORANGE);
unregister_netdev(dev);
mca_mark_as_unused(priv->slot); mca_mark_as_unused(priv->slot);
mca_set_adapter_name(priv->slot, ""); mca_set_adapter_name(priv->slot, "");
mca_set_adapter_procfn(priv->slot, NULL, NULL); mca_set_adapter_procfn(priv->slot, NULL, NULL);
kfree(dev->priv); free_netdev(dev);
dev->priv = NULL;
} }
} }
} }
......
...@@ -275,7 +275,4 @@ typedef struct { ...@@ -275,7 +275,4 @@ typedef struct {
#endif /* _IBM_LANA_DRIVER_ */ #endif /* _IBM_LANA_DRIVER_ */
extern int ibmlana_probe(struct net_device *);
#endif /* _IBM_LANA_INCLUDE_ */ #endif /* _IBM_LANA_INCLUDE_ */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment