Commit 73e8eeef authored by Stephen Hemminger's avatar Stephen Hemminger

[PATCH] (35/42) mvme147

NE60-mvme147lance
	* switched to dynamic allocation
	* fixed resource leaks on failure exits
parent 31052a4d
...@@ -83,7 +83,7 @@ extern int pamsnet_probe(struct net_device *); ...@@ -83,7 +83,7 @@ extern int pamsnet_probe(struct net_device *);
extern struct net_device *cs89x0_probe(int unit); extern struct net_device *cs89x0_probe(int unit);
extern int hplance_probe(struct net_device *dev); extern int hplance_probe(struct net_device *dev);
extern struct net_device *bagetlance_probe(int unit); extern struct net_device *bagetlance_probe(int unit);
extern int mvme147lance_probe(struct net_device *dev); extern struct net_device *mvme147lance_probe(int unit);
extern struct net_device *tc515_probe(int unit); extern struct net_device *tc515_probe(int unit);
extern struct net_device *lance_probe(int unit); extern struct net_device *lance_probe(int unit);
extern struct net_device *mace_probe(struct net_device *dev); extern struct net_device *mace_probe(struct net_device *dev);
...@@ -316,14 +316,14 @@ static struct devprobe m68k_probes[] __initdata = { ...@@ -316,14 +316,14 @@ static struct devprobe m68k_probes[] __initdata = {
#endif #endif
#ifdef CONFIG_HPLANCE /* HP300 internal Ethernet */ #ifdef CONFIG_HPLANCE /* HP300 internal Ethernet */
{hplance_probe, 0}, {hplance_probe, 0},
#endif
#ifdef CONFIG_MVME147_NET /* MVME147 internal Ethernet */
{mvme147lance_probe, 0},
#endif #endif
{NULL, 0}, {NULL, 0},
}; };
static struct devprobe2 m68k_probes2[] __initdata = { static struct devprobe2 m68k_probes2[] __initdata = {
#ifdef CONFIG_MVME147_NET /* MVME147 internal Ethernet */
{mvme147lance_probe, 0},
#endif
#ifdef CONFIG_MACMACE /* Mac 68k Quadra AV builtin Ethernet */ #ifdef CONFIG_MACMACE /* Mac 68k Quadra AV builtin Ethernet */
{mace_probe, 0}, {mace_probe, 0},
#endif #endif
......
...@@ -49,7 +49,6 @@ struct m147lance_private { ...@@ -49,7 +49,6 @@ struct m147lance_private {
* plus board-specific init, open and close actions. * plus board-specific init, open and close actions.
* Oh, and we need to tell the generic code how to read and write LANCE registers... * Oh, and we need to tell the generic code how to read and write LANCE registers...
*/ */
int mvme147lance_probe(struct net_device *dev);
static int m147lance_open(struct net_device *dev); static int m147lance_open(struct net_device *dev);
static int m147lance_close(struct net_device *dev); static int m147lance_close(struct net_device *dev);
static void m147lance_writerap(struct m147lance_private *lp, unsigned short value); static void m147lance_writerap(struct m147lance_private *lp, unsigned short value);
...@@ -60,13 +59,10 @@ typedef void (*writerap_t)(void *, unsigned short); ...@@ -60,13 +59,10 @@ typedef void (*writerap_t)(void *, unsigned short);
typedef void (*writerdp_t)(void *, unsigned short); typedef void (*writerdp_t)(void *, unsigned short);
typedef unsigned short (*readrdp_t)(void *); typedef unsigned short (*readrdp_t)(void *);
#ifdef MODULE
static struct m147lance_private *root_m147lance_dev;
#endif
/* Initialise the one and only on-board 7990 */ /* Initialise the one and only on-board 7990 */
int __init mvme147lance_probe(struct net_device *dev) struct net_device * __init mvme147lance_probe(int unit)
{ {
struct net_device *dev;
static int called; static int called;
static const char name[] = "MVME147 LANCE"; static const char name[] = "MVME147 LANCE";
struct m147lance_private *lp; struct m147lance_private *lp;
...@@ -74,15 +70,17 @@ int __init mvme147lance_probe(struct net_device *dev) ...@@ -74,15 +70,17 @@ int __init mvme147lance_probe(struct net_device *dev)
u_long address; u_long address;
if (!MACH_IS_MVME147 || called) if (!MACH_IS_MVME147 || called)
return -ENODEV; return ERR_PTR(-ENODEV);
called++; called++;
SET_MODULE_OWNER(dev); dev = alloc_etherdev(sizeof(struct m147lance_private));
if (!dev)
return ERR_PTR(-ENOMEM);
dev->priv = kmalloc(sizeof(struct m147lance_private), GFP_KERNEL); if (unit >= 0)
if (dev->priv == NULL) sprintf(dev->name, "eth%d", unit);
return -ENOMEM;
memset(dev->priv, 0, sizeof(struct m147lance_private)); SET_MODULE_OWNER(dev);
/* Fill the dev fields */ /* Fill the dev fields */
dev->base_addr = (unsigned long)MVME147_LANCE_BASE; dev->base_addr = (unsigned long)MVME147_LANCE_BASE;
...@@ -118,7 +116,8 @@ int __init mvme147lance_probe(struct net_device *dev) ...@@ -118,7 +116,8 @@ int __init mvme147lance_probe(struct net_device *dev)
if (!lp->ram) if (!lp->ram)
{ {
printk("%s: No memory for LANCE buffers\n", dev->name); printk("%s: No memory for LANCE buffers\n", dev->name);
return -ENODEV; free_netdev(dev);
return ERR_PTR(-ENOMEM);
} }
lp->lance.name = (char*)name; /* discards const, shut up gcc */ lp->lance.name = (char*)name; /* discards const, shut up gcc */
...@@ -134,15 +133,15 @@ int __init mvme147lance_probe(struct net_device *dev) ...@@ -134,15 +133,15 @@ int __init mvme147lance_probe(struct net_device *dev)
lp->lance.lance_log_tx_bufs = LANCE_LOG_TX_BUFFERS; lp->lance.lance_log_tx_bufs = LANCE_LOG_TX_BUFFERS;
lp->lance.rx_ring_mod_mask = RX_RING_MOD_MASK; lp->lance.rx_ring_mod_mask = RX_RING_MOD_MASK;
lp->lance.tx_ring_mod_mask = TX_RING_MOD_MASK; lp->lance.tx_ring_mod_mask = TX_RING_MOD_MASK;
ether_setup(dev);
#ifdef MODULE err = register_netdev(dev);
dev->ifindex = dev_new_index(); if (err) {
lp->next_module = root_m147lance_dev; free_pages(lp->ram, 3);
root_m147lance_dev = lp; free_netdev(dev);
#endif /* MODULE */ return ERR_PTR(err);
}
return 0; return dev;
} }
static void m147lance_writerap(struct m147lance_private *lp, unsigned short value) static void m147lance_writerap(struct m147lance_private *lp, unsigned short value)
...@@ -185,23 +184,21 @@ static int m147lance_close(struct net_device *dev) ...@@ -185,23 +184,21 @@ static int m147lance_close(struct net_device *dev)
#ifdef MODULE #ifdef MODULE
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
static struct net_device *dev_mvme147_lance;
int init_module(void) int init_module(void)
{ {
root_lance_dev = NULL; dev_mvme147_lance = mvme147lance_probe(-1);
return mvme147lance_probe(NULL); if (IS_ERR(dev_mvme147_lance))
return PTR_ERR(dev_mvme147_lance);
return 0;
} }
void cleanup_module(void) void cleanup_module(void)
{ {
/* Walk the chain of devices, unregistering them */ struct m147lance_private *lp = dev_mvme147_lance->priv;
struct m147lance_private *lp; unregister_netdev(dev_mvme147_lance);
while (root_m147lance_dev) {
lp = root_m147lance_dev->next_module;
unregister_netdev(root_lance_dev->dev);
free_pages(lp->ram, 3); free_pages(lp->ram, 3);
free_netdev(root_lance_dev->dev); free_netdev(dev_mvme147_lance);
root_lance_dev = lp;
}
} }
#endif /* MODULE */ #endif /* MODULE */
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