Commit a1b7d53c authored by Stephen Hemminger's avatar Stephen Hemminger

[PATCH] (42/42) atari_lance

NE68-atarilance
	* switched to dynamic allocation
	* fixed resource leaks on failure exits
	* also kill off last usage of probe_list
parent 0d9e3bdd
...@@ -74,7 +74,7 @@ extern struct net_device *sonic_probe(int unit); ...@@ -74,7 +74,7 @@ extern struct net_device *sonic_probe(int unit);
extern struct net_device *SK_init(int unit); extern struct net_device *SK_init(int unit);
extern struct net_device *seeq8005_probe(int unit); extern struct net_device *seeq8005_probe(int unit);
extern struct net_device *smc_init(int unit); extern struct net_device *smc_init(int unit);
extern int atarilance_probe(struct net_device *); extern struct net_device *atarilance_probe(struct net_device *);
extern struct net_device *sun3lance_probe(int unit); extern struct net_device *sun3lance_probe(int unit);
extern struct net_device *sun3_82586_probe(int unit); extern struct net_device *sun3_82586_probe(int unit);
extern struct net_device *apne_probe(int unit); extern struct net_device *apne_probe(int unit);
...@@ -103,42 +103,11 @@ extern int iph5526_probe(struct net_device *dev); ...@@ -103,42 +103,11 @@ extern int iph5526_probe(struct net_device *dev);
/* SBNI adapters */ /* SBNI adapters */
extern int sbni_probe(int unit); extern int sbni_probe(int unit);
struct devprobe
{
int (*probe)(struct net_device *dev);
int status; /* non-zero if autoprobe has failed */
};
struct devprobe2 { struct devprobe2 {
struct net_device *(*probe)(int unit); struct net_device *(*probe)(int unit);
int status; /* non-zero if autoprobe has failed */ int status; /* non-zero if autoprobe has failed */
}; };
/*
* probe_list walks a list of probe functions and calls each so long
* as a non-zero ioaddr is given, or as long as it hasn't already failed
* to find a card in the past (as recorded by "status") when asked to
* autoprobe (i.e. a probe that fails to find a card when autoprobing
* will not be asked to autoprobe again). It exits when a card is found.
*/
static int __init probe_list(struct net_device *dev, struct devprobe *plist)
{
struct devprobe *p = plist;
unsigned long base_addr = dev->base_addr;
while (p->probe != NULL) {
if (base_addr && p->probe(dev) == 0) /* probe given addr */
return 0;
else if (p->status == 0) { /* has autoprobe failed yet? */
p->status = p->probe(dev); /* no, try autoprobe */
if (p->status == 0)
return 0;
}
p++;
}
return -ENODEV;
}
static int __init probe_list2(int unit, struct devprobe2 *p, int autoprobe) static int __init probe_list2(int unit, struct devprobe2 *p, int autoprobe)
{ {
struct net_device *dev; struct net_device *dev;
...@@ -295,14 +264,10 @@ static struct devprobe2 parport_probes[] __initdata = { ...@@ -295,14 +264,10 @@ static struct devprobe2 parport_probes[] __initdata = {
{NULL, 0}, {NULL, 0},
}; };
static struct devprobe m68k_probes[] __initdata = { static struct devprobe2 m68k_probes[] __initdata = {
#ifdef CONFIG_ATARILANCE /* Lance-based Atari ethernet boards */ #ifdef CONFIG_ATARILANCE /* Lance-based Atari ethernet boards */
{atarilance_probe, 0}, {atarilance_probe, 0},
#endif #endif
{NULL, 0},
};
static struct devprobe2 m68k_probes2[] __initdata = {
#ifdef CONFIG_SUN3LANCE /* sun3 onboard Lance chip */ #ifdef CONFIG_SUN3LANCE /* sun3 onboard Lance chip */
{sun3lance_probe, 0}, {sun3lance_probe, 0},
#endif #endif
...@@ -354,40 +319,6 @@ static struct devprobe2 mips_probes[] __initdata = { ...@@ -354,40 +319,6 @@ static struct devprobe2 mips_probes[] __initdata = {
* per bus interface. This drives the legacy devices only for now. * per bus interface. This drives the legacy devices only for now.
*/ */
static int __init ethif_probe(int unit)
{
struct net_device *dev;
int err = -ENODEV;
dev = alloc_etherdev(0);
if (!dev)
return -ENOMEM;
sprintf(dev->name, "eth%d", unit);
netdev_boot_setup_check(dev);
/*
* Backwards compatibility - historically an I/O base of 1 was
* used to indicate not to probe for this ethN interface
*/
if (__dev_get_by_name(dev->name) || dev->base_addr == 1) {
free_netdev(dev);
return -ENXIO;
}
/*
* The arch specific probes are 1st so that any on-board ethernet
* will be probed before other ISA/EISA/MCA/PCI bus cards.
*/
if (probe_list(dev, m68k_probes) == 0)
err = register_netdev(dev);
if (err)
free_netdev(dev);
return err;
}
static void __init ethif_probe2(int unit) static void __init ethif_probe2(int unit)
{ {
unsigned long base_addr = netdev_boot_base("eth", unit); unsigned long base_addr = netdev_boot_base("eth", unit);
...@@ -395,7 +326,7 @@ static void __init ethif_probe2(int unit) ...@@ -395,7 +326,7 @@ static void __init ethif_probe2(int unit)
if (base_addr == 1) if (base_addr == 1)
return; return;
probe_list2(unit, m68k_probes2, base_addr == 0) && probe_list2(unit, m68k_probes, base_addr == 0) &&
probe_list2(unit, mips_probes, base_addr == 0) && probe_list2(unit, mips_probes, base_addr == 0) &&
probe_list2(unit, eisa_probes, base_addr == 0) && probe_list2(unit, eisa_probes, base_addr == 0) &&
probe_list2(unit, mca_probes, base_addr == 0) && probe_list2(unit, mca_probes, base_addr == 0) &&
...@@ -484,8 +415,7 @@ static int __init net_olddevs_init(void) ...@@ -484,8 +415,7 @@ static int __init net_olddevs_init(void)
trif_probe2(num); trif_probe2(num);
#endif #endif
for (num = 0; num < 8; ++num) for (num = 0; num < 8; ++num)
if (!ethif_probe(num)) ethif_probe2(num);
ethif_probe2(num);
#ifdef CONFIG_COPS #ifdef CONFIG_COPS
cops_probe(0); cops_probe(0);
......
...@@ -371,26 +371,39 @@ static void *slow_memcpy( void *dst, const void *src, size_t len ) ...@@ -371,26 +371,39 @@ static void *slow_memcpy( void *dst, const void *src, size_t len )
} }
int __init atarilance_probe( struct net_device *dev ) struct net_device * __init atarilance_probe(int unit)
{ {
int i; int i;
static int found; static int found;
struct net_device *dev;
SET_MODULE_OWNER(dev); int err = -ENODEV;
if (!MACH_IS_ATARI || found) if (!MACH_IS_ATARI || found)
/* Assume there's only one board possible... That seems true, since /* Assume there's only one board possible... That seems true, since
* the Riebl/PAM board's address cannot be changed. */ * the Riebl/PAM board's address cannot be changed. */
return( ENODEV ); return ERR_PTR(-ENODEV);
dev = alloc_etherdev(sizeof(struct lance_private));
if (!dev)
return ERR_PTR(-ENOMEM);
if (unit >= 0) {
sprintf(dev->name, "eth%d", unit);
netdev_boot_setup_check(dev);
}
SET_MODULE_OWNER(dev);
for( i = 0; i < N_LANCE_ADDR; ++i ) { for( i = 0; i < N_LANCE_ADDR; ++i ) {
if (lance_probe1( dev, &lance_addr_list[i] )) { if (lance_probe1( dev, &lance_addr_list[i] )) {
found = 1; found = 1;
return( 0 ); err = register_netdev(dev);
if (!err)
return dev;
free_irq(dev->irq, dev);
break;
} }
} }
free_netdev(dev);
return( ENODEV ); return ERR_PTR(err);
} }
...@@ -511,12 +524,6 @@ static unsigned long __init lance_probe1( struct net_device *dev, ...@@ -511,12 +524,6 @@ static unsigned long __init lance_probe1( struct net_device *dev,
return( 0 ); return( 0 );
probe_ok: probe_ok:
init_etherdev( dev, sizeof(struct lance_private) );
if (!dev->priv) {
dev->priv = kmalloc( sizeof(struct lance_private), GFP_KERNEL );
if (!dev->priv)
return 0;
}
lp = (struct lance_private *)dev->priv; lp = (struct lance_private *)dev->priv;
MEM = (struct lance_memory *)memaddr; MEM = (struct lance_memory *)memaddr;
IO = lp->iobase = (struct lance_ioreg *)ioaddr; IO = lp->iobase = (struct lance_ioreg *)ioaddr;
...@@ -1171,26 +1178,21 @@ static int lance_set_mac_address( struct net_device *dev, void *addr ) ...@@ -1171,26 +1178,21 @@ static int lance_set_mac_address( struct net_device *dev, void *addr )
#ifdef MODULE #ifdef MODULE
static struct net_device atarilance_dev; static struct net_device *atarilance_dev;
int init_module(void) int init_module(void)
{
{ int err; atarilance_dev = atarilance_probe(-1);
if (IS_ERR(atarilance_dev))
atarilance_dev.init = atarilance_probe; return PTR_ERR(atarilance_dev);
if ((err = register_netdev( &atarilance_dev ))) { return 0;
if (err == -EIO) {
printk( "No Atari Lance board found. Module not loaded.\n");
}
return( err );
}
return( 0 );
} }
void cleanup_module(void) void cleanup_module(void)
{ {
unregister_netdev( &atarilance_dev ); unregister_netdev(atarilance_dev);
free_irq(atarilance_dev->irq, atarilance_dev);
free_netdev(atarilance_dev);
} }
#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