Commit b87c82c3 authored by Stephen Hemminger's avatar Stephen Hemminger

[PATCH] (29/42) bagetlance

NE54-bagetlance
	* switched bagetlance to dynamic allocation
	* bagetlance: embedded ->priv
	* bagetlance: fixed resource leaks on failure exits
	* bagetlance: fixed resource leaks on rmmod
parent f7db478b
...@@ -82,7 +82,7 @@ extern int bionet_probe(struct net_device *); ...@@ -82,7 +82,7 @@ extern int bionet_probe(struct net_device *);
extern int pamsnet_probe(struct net_device *); 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 int bagetlance_probe(struct net_device *); extern struct net_device *bagetlance_probe(int unit);
extern int mvme147lance_probe(struct net_device *dev); extern int mvme147lance_probe(struct net_device *dev);
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);
...@@ -339,6 +339,10 @@ static struct devprobe mips_probes[] __initdata = { ...@@ -339,6 +339,10 @@ static struct devprobe mips_probes[] __initdata = {
#ifdef CONFIG_MIPS_JAZZ_SONIC #ifdef CONFIG_MIPS_JAZZ_SONIC
{sonic_probe, 0}, {sonic_probe, 0},
#endif #endif
{NULL, 0},
};
static struct devprobe2 mips_probes2[] __initdata = {
#ifdef CONFIG_BAGETLANCE /* Lance-based Baget ethernet boards */ #ifdef CONFIG_BAGETLANCE /* Lance-based Baget ethernet boards */
{bagetlance_probe, 0}, {bagetlance_probe, 0},
#endif #endif
...@@ -392,6 +396,7 @@ static void __init ethif_probe2(int unit) ...@@ -392,6 +396,7 @@ static void __init ethif_probe2(int unit)
if (base_addr == 1) if (base_addr == 1)
return; return;
probe_list2(unit, mips_probes2, 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) &&
probe_list2(unit, isa_probes, base_addr == 0) && probe_list2(unit, isa_probes, base_addr == 0) &&
......
...@@ -465,30 +465,43 @@ void *slow_memcpy( void *dst, const void *src, size_t len ) ...@@ -465,30 +465,43 @@ void *slow_memcpy( void *dst, const void *src, size_t len )
} }
int __init bagetlance_probe( struct net_device *dev ) struct net_device * __init bagetlance_probe(int unit)
{
{ int i; struct net_device *dev;
int i;
static int found; static int found;
int err = -ENODEV;
SET_MODULE_OWNER(dev);
if (found) if (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);
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 ); break;
} }
} }
if (!found)
return( -ENODEV ); goto out;
err = register_netdev(dev);
if (err)
goto out1;
return dev;
out1:
free_irq(dev->irq, dev);
out:
free_netdev(dev);
return ERR_PTR(err);
} }
/* Derived from hwreg_present() in vme/config.c: */ /* Derived from hwreg_present() in vme/config.c: */
static int __init addr_accessible( volatile void *regp, static int __init addr_accessible( volatile void *regp,
...@@ -527,6 +540,7 @@ static int __init lance_probe1( struct net_device *dev, ...@@ -527,6 +540,7 @@ static int __init lance_probe1( struct net_device *dev,
if (!addr_accessible( memaddr, 1, 1 )) goto probe_fail; if (!addr_accessible( memaddr, 1, 1 )) goto probe_fail;
if ((unsigned long)memaddr >= KSEG2) { if ((unsigned long)memaddr >= KSEG2) {
/* FIXME: do we need to undo that on cleanup paths? */
extern int kseg2_alloc_io (unsigned long addr, unsigned long size); extern int kseg2_alloc_io (unsigned long addr, unsigned long size);
if (kseg2_alloc_io((unsigned long)memaddr, BAGET_LANCE_MEM_SIZE)) { if (kseg2_alloc_io((unsigned long)memaddr, BAGET_LANCE_MEM_SIZE)) {
printk("bagetlance: unable map lance memory\n"); printk("bagetlance: unable map lance memory\n");
...@@ -580,12 +594,6 @@ static int __init lance_probe1( struct net_device *dev, ...@@ -580,12 +594,6 @@ static int __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;
...@@ -617,8 +625,9 @@ static int __init lance_probe1( struct net_device *dev, ...@@ -617,8 +625,9 @@ static int __init lance_probe1( struct net_device *dev,
if (lp->cardtype == PAM_CARD || if (lp->cardtype == PAM_CARD ||
memaddr == (unsigned short *)0xffe00000) { memaddr == (unsigned short *)0xffe00000) {
/* PAMs card and Riebl on ST use level 5 autovector */ /* PAMs card and Riebl on ST use level 5 autovector */
request_irq(BAGET_LANCE_IRQ, lance_interrupt, IRQ_TYPE_PRIO, if (request_irq(BAGET_LANCE_IRQ, lance_interrupt, IRQ_TYPE_PRIO,
"PAM/Riebl-ST Ethernet", dev); "PAM/Riebl-ST Ethernet", dev))
goto probe_fail;
dev->irq = (unsigned short)BAGET_LANCE_IRQ; dev->irq = (unsigned short)BAGET_LANCE_IRQ;
} }
else { else {
...@@ -629,10 +638,11 @@ static int __init lance_probe1( struct net_device *dev, ...@@ -629,10 +638,11 @@ static int __init lance_probe1( struct net_device *dev,
unsigned long irq = BAGET_LANCE_IRQ; unsigned long irq = BAGET_LANCE_IRQ;
if (!irq) { if (!irq) {
printk( "Lance: request for VME interrupt failed\n" ); printk( "Lance: request for VME interrupt failed\n" );
return( 0 ); goto probe_fail;
} }
request_irq(irq, lance_interrupt, IRQ_TYPE_PRIO, if (request_irq(irq, lance_interrupt, IRQ_TYPE_PRIO,
"Riebl-VME Ethernet", dev); "Riebl-VME Ethernet", dev))
goto probe_fail;
dev->irq = irq; dev->irq = irq;
} }
...@@ -1331,26 +1341,21 @@ static int lance_set_mac_address( struct net_device *dev, void *addr ) ...@@ -1331,26 +1341,21 @@ static int lance_set_mac_address( struct net_device *dev, void *addr )
#ifdef MODULE #ifdef MODULE
static struct net_device bagetlance_dev; static struct net_device *bagetlance_dev;
int init_module(void) int init_module(void)
{
{ int err; bagetlance_dev = bagetlance_probe(-1);
if (IS_ERR(bagetlance_dev))
bagetlance_dev.init = bagetlance_probe; return PTR_ERR(bagetlance_dev);
if ((err = register_netdev( &bagetlance_dev ))) { return 0;
if (err == -EIO) {
printk( "No Vme Lance board found. Module not loaded.\n");
}
return( err );
}
return( 0 );
} }
void cleanup_module(void) void cleanup_module(void)
{ {
unregister_netdev( &bagetlance_dev ); unregister_netdev(bagetlance_dev);
free_irq(bagetlance_dev->irq, bagetlance_dev);
free_netdev(bagetlance_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