Commit e77928f2 authored by Stephen Hemminger's avatar Stephen Hemminger

[PATCH] (40/42) sun3_82586

NE66-sun3_82586
	* switched to dynamic allocation
	* fixed resource leaks on failure exits
parent e068921c
...@@ -76,7 +76,7 @@ extern struct net_device *seeq8005_probe(int unit); ...@@ -76,7 +76,7 @@ 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 int atarilance_probe(struct net_device *);
extern int sun3lance_probe(struct net_device *); extern int sun3lance_probe(struct net_device *);
extern int sun3_82586_probe(struct net_device *); 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);
extern struct net_device *bionet_probe(int unit); extern struct net_device *bionet_probe(int unit);
extern struct net_device *pamsnet_probe(int unit); extern struct net_device *pamsnet_probe(int unit);
...@@ -301,14 +301,14 @@ static struct devprobe m68k_probes[] __initdata = { ...@@ -301,14 +301,14 @@ static struct devprobe m68k_probes[] __initdata = {
#endif #endif
#ifdef CONFIG_SUN3LANCE /* sun3 onboard Lance chip */ #ifdef CONFIG_SUN3LANCE /* sun3 onboard Lance chip */
{sun3lance_probe, 0}, {sun3lance_probe, 0},
#endif
#ifdef CONFIG_SUN3_82586 /* sun3 onboard Intel 82586 chip */
{sun3_82586_probe, 0},
#endif #endif
{NULL, 0}, {NULL, 0},
}; };
static struct devprobe2 m68k_probes2[] __initdata = { static struct devprobe2 m68k_probes2[] __initdata = {
#ifdef CONFIG_SUN3_82586 /* sun3 onboard Intel 82586 chip */
{sun3_82586_probe, 0},
#endif
#ifdef CONFIG_APNE /* A1200 PCMCIA NE2000 */ #ifdef CONFIG_APNE /* A1200 PCMCIA NE2000 */
{apne_probe, 0}, {apne_probe, 0},
#endif #endif
......
...@@ -277,10 +277,12 @@ static void alloc586(struct net_device *dev) ...@@ -277,10 +277,12 @@ static void alloc586(struct net_device *dev)
memset((char *)p->scb,0,sizeof(struct scb_struct)); memset((char *)p->scb,0,sizeof(struct scb_struct));
} }
int __init sun3_82586_probe(struct net_device *dev) struct net_device * __init sun3_82586_probe(int unit)
{ {
struct net_device *dev;
unsigned long ioaddr; unsigned long ioaddr;
static int found = 0; static int found = 0;
int err = -ENOMEM;
/* check that this machine has an onboard 82586 */ /* check that this machine has an onboard 82586 */
switch(idprom->id_machtype) { switch(idprom->id_machtype) {
...@@ -290,31 +292,51 @@ int __init sun3_82586_probe(struct net_device *dev) ...@@ -290,31 +292,51 @@ int __init sun3_82586_probe(struct net_device *dev)
break; break;
default: default:
return(-ENODEV); return ERR_PTR(-ENODEV);
} }
if(found) if (found)
return -ENODEV; return ERR_PTR(-ENODEV);
ioaddr = (unsigned long)ioremap(IE_OBIO, PAGE_SIZE); ioaddr = (unsigned long)ioremap(IE_OBIO, PAGE_SIZE);
if (!ioaddr)
return ERR_PTR(-ENOMEM);
found = 1; found = 1;
dev = alloc_etherdev(sizeof(struct priv));
if (!dev)
goto out;
if (unit >= 0) {
sprintf(dev->name, "eth%d", unit);
netdev_boot_setup_check(dev);
}
SET_MODULE_OWNER(dev); SET_MODULE_OWNER(dev);
dev->irq = IE_IRQ; dev->irq = IE_IRQ;
dev->base_addr = ioaddr; dev->base_addr = ioaddr;
if(sun3_82586_probe1(dev, ioaddr) == 0) err = sun3_82586_probe1(dev, ioaddr);
return 0; if (err)
goto out1;
return -ENODEV; err = register_netdev(dev);
if (err)
goto out2;
return dev;
out2:
release_region(ioaddr, SUN3_82586_TOTAL_SIZE);
out1:
free_netdev(dev);
out:
iounmap(ioaddr);
return ERR_PTR(err);
} }
static int __init sun3_82586_probe1(struct net_device *dev,int ioaddr) static int __init sun3_82586_probe1(struct net_device *dev,int ioaddr)
{ {
int i, size, retval; int i, size, retval;
// if (!request_region(ioaddr, SUN3_82586_TOTAL_SIZE, dev->name)) if (!request_region(ioaddr, SUN3_82586_TOTAL_SIZE, dev->name))
// return -EBUSY; return -EBUSY;
/* copy in the ethernet address from the prom */ /* copy in the ethernet address from the prom */
for(i = 0; i < 6 ; i++) for(i = 0; i < 6 ; i++)
...@@ -341,16 +363,6 @@ static int __init sun3_82586_probe1(struct net_device *dev,int ioaddr) ...@@ -341,16 +363,6 @@ static int __init sun3_82586_probe1(struct net_device *dev,int ioaddr)
goto out; goto out;
} }
dev->priv = (void *) kmalloc(sizeof(struct priv),GFP_KERNEL);
if(dev->priv == NULL) {
printk("%s: Ooops .. can't allocate private driver memory.\n",dev->name);
retval = -ENOMEM;
goto out;
}
/* warning: we don't free it on errors */
memset((char *) dev->priv,0,sizeof(struct priv));
((struct priv *) (dev->priv))->memtop = (char *)dvma_btov(dev->mem_start); ((struct priv *) (dev->priv))->memtop = (char *)dvma_btov(dev->mem_start);
((struct priv *) (dev->priv))->base = (unsigned long) dvma_btov(0); ((struct priv *) (dev->priv))->base = (unsigned long) dvma_btov(0);
alloc586(dev); alloc586(dev);
...@@ -374,11 +386,9 @@ static int __init sun3_82586_probe1(struct net_device *dev,int ioaddr) ...@@ -374,11 +386,9 @@ static int __init sun3_82586_probe1(struct net_device *dev,int ioaddr)
dev->set_multicast_list = set_multicast_list; dev->set_multicast_list = set_multicast_list;
dev->if_port = 0; dev->if_port = 0;
ether_setup(dev);
return 0; return 0;
out: out:
release_region(ioaddr, SUN3_82586_TOTAL_SIZE);
return retval; return retval;
} }
...@@ -1138,21 +1148,23 @@ static void set_multicast_list(struct net_device *dev) ...@@ -1138,21 +1148,23 @@ static void set_multicast_list(struct net_device *dev)
#ifdef MODULE #ifdef MODULE
#error This code is not currently supported as a module #error This code is not currently supported as a module
static struct net_device dev_sun3_82586; static struct net_device *dev_sun3_82586;
int init_module(void) int init_module(void)
{ {
dev_sun3_82586.init = sun3_82586_probe; dev_sun3_82586 = sun3_82586_probe(-1);
if (register_netdev(&dev_sun3_82586) != 0) if (IS_ERR(dev_sun3_82586))
return -EIO; return PTR_ERR(dev_sun3_82586);
return 0; return 0;
} }
void cleanup_module(void) void cleanup_module(void)
{ {
unregister_netdev(&dev_sun3_82586); unsigned long ioaddr = dev_sun3_82586->base_addr;
kfree(dev_sun3_82586.priv); unregister_netdev(dev_sun3_82586);
dev_sun3_82586.priv = NULL; release_region(ioaddr, SUN3_82586_TOTAL_SIZE);
iounmap(ioaddr);
free_netdev(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