Commit a662493a authored by Alexander Viro's avatar Alexander Viro Committed by Stephen Hemminger

[netdrvr ibmtr, ibmtr_cs] cleanup and leak fixes.

parent 375e13ca
...@@ -336,7 +336,7 @@ static void __init ethif_probe2(int unit) ...@@ -336,7 +336,7 @@ static void __init ethif_probe2(int unit)
#ifdef CONFIG_TR #ifdef CONFIG_TR
/* Token-ring device probe */ /* Token-ring device probe */
extern int ibmtr_probe(struct net_device *); extern int ibmtr_probe_card(struct net_device *);
extern struct net_device *sk_isa_probe(int unit); extern struct net_device *sk_isa_probe(int unit);
extern struct net_device *proteon_probe(int unit); extern struct net_device *proteon_probe(int unit);
extern struct net_device *smctr_probe(int unit); extern struct net_device *smctr_probe(int unit);
...@@ -356,26 +356,19 @@ static struct devprobe2 tr_probes2[] __initdata = { ...@@ -356,26 +356,19 @@ static struct devprobe2 tr_probes2[] __initdata = {
static __init int trif_probe(int unit) static __init int trif_probe(int unit)
{ {
struct net_device *dev;
int err = -ENODEV; int err = -ENODEV;
#ifdef CONFIG_IBMTR
dev = alloc_trdev(0); struct net_device *dev = alloc_trdev(0);
if (!dev) if (!dev)
return -ENOMEM; return -ENOMEM;
sprintf(dev->name, "tr%d", unit); sprintf(dev->name, "tr%d", unit);
netdev_boot_setup_check(dev); netdev_boot_setup_check(dev);
if ( err = ibmtr_probe_card(dev);
#ifdef CONFIG_IBMTR
ibmtr_probe(dev) == 0 ||
#endif
0 )
err = register_netdev(dev);
if (err) if (err)
free_netdev(dev); free_netdev(dev);
#endif
return err; return err;
} }
static void __init trif_probe2(int unit) static void __init trif_probe2(int unit)
......
...@@ -125,8 +125,7 @@ static void ibmtr_detach(dev_link_t *); ...@@ -125,8 +125,7 @@ static void ibmtr_detach(dev_link_t *);
static dev_link_t *dev_list; static dev_link_t *dev_list;
extern int ibmtr_probe(struct net_device *dev); extern int ibmtr_probe_card(struct net_device *dev);
extern int trdev_init(struct net_device *dev);
extern irqreturn_t tok_interrupt (int irq, void *dev_id, struct pt_regs *regs); extern irqreturn_t tok_interrupt (int irq, void *dev_id, struct pt_regs *regs);
/*====================================================================*/ /*====================================================================*/
...@@ -199,7 +198,6 @@ static dev_link_t *ibmtr_attach(void) ...@@ -199,7 +198,6 @@ static dev_link_t *ibmtr_attach(void)
link->irq.Instance = info->dev = dev; link->irq.Instance = info->dev = dev;
dev->init = &ibmtr_probe;
SET_ETHTOOL_OPS(dev, &netdev_ethtool_ops); SET_ETHTOOL_OPS(dev, &netdev_ethtool_ops);
/* Register with Card Services */ /* Register with Card Services */
...@@ -253,6 +251,10 @@ static void ibmtr_detach(dev_link_t *link) ...@@ -253,6 +251,10 @@ static void ibmtr_detach(dev_link_t *link)
return; return;
dev = info->dev; dev = info->dev;
if (link->dev)
unregister_netdev(dev);
{ {
struct tok_info *ti = (struct tok_info *)dev->priv; struct tok_info *ti = (struct tok_info *)dev->priv;
del_timer_sync(&(ti->tr_timer)); del_timer_sync(&(ti->tr_timer));
...@@ -265,7 +267,6 @@ static void ibmtr_detach(dev_link_t *link) ...@@ -265,7 +267,6 @@ static void ibmtr_detach(dev_link_t *link)
/* Unlink device structure, free bits */ /* Unlink device structure, free bits */
*linkp = link->next; *linkp = link->next;
unregister_netdev(dev);
free_netdev(dev); free_netdev(dev);
kfree(info); kfree(info);
} /* ibmtr_detach */ } /* ibmtr_detach */
...@@ -368,7 +369,7 @@ static void ibmtr_config(dev_link_t *link) ...@@ -368,7 +369,7 @@ static void ibmtr_config(dev_link_t *link)
Adapters Technical Reference" SC30-3585 for this info. */ Adapters Technical Reference" SC30-3585 for this info. */
ibmtr_hw_setup(dev, mmiobase); ibmtr_hw_setup(dev, mmiobase);
i = register_netdev(dev); i = ibmtr_probe_card(dev);
if (i != 0) { if (i != 0) {
printk(KERN_NOTICE "ibmtr_cs: register_netdev() failed\n"); printk(KERN_NOTICE "ibmtr_cs: register_netdev() failed\n");
...@@ -471,7 +472,7 @@ static int ibmtr_event(event_t event, int priority, ...@@ -471,7 +472,7 @@ static int ibmtr_event(event_t event, int priority,
if (link->state & DEV_CONFIG) { if (link->state & DEV_CONFIG) {
CardServices(RequestConfiguration, link->handle, &link->conf); CardServices(RequestConfiguration, link->handle, &link->conf);
if (link->open) { if (link->open) {
(dev->init)(dev); ibmtr_probe(dev); /* really? */
netif_device_attach(dev); netif_device_attach(dev);
} }
} }
......
...@@ -187,7 +187,7 @@ char __devinit *adapter_def(char type) ...@@ -187,7 +187,7 @@ char __devinit *adapter_def(char type)
#define TRC_INITV 0x02 /* verbose init trace points */ #define TRC_INITV 0x02 /* verbose init trace points */
unsigned char ibmtr_debug_trace = 0; unsigned char ibmtr_debug_trace = 0;
int ibmtr_probe(struct net_device *dev); static int ibmtr_probe(struct net_device *dev);
static int ibmtr_probe1(struct net_device *dev, int ioaddr); static int ibmtr_probe1(struct net_device *dev, int ioaddr);
static unsigned char get_sram_size(struct tok_info *adapt_info); static unsigned char get_sram_size(struct tok_info *adapt_info);
static int trdev_init(struct net_device *dev); static int trdev_init(struct net_device *dev);
...@@ -313,6 +313,39 @@ static void __devinit find_turbo_adapters(int *iolist) { ...@@ -313,6 +313,39 @@ static void __devinit find_turbo_adapters(int *iolist) {
} }
} }
static void ibmtr_cleanup_card(struct net_device *dev)
{
if (dev->base_addr) {
outb(0,dev->base_addr+ADAPTRESET);
schedule_timeout(TR_RST_TIME); /* wait 50ms */
outb(0,dev->base_addr+ADAPTRESETREL);
}
#ifndef PCMCIA
free_irq(dev->irq, dev);
release_region(dev->base_addr, IBMTR_IO_EXTENT);
{
struct tok_info *ti = (struct tok_info *) dev->priv;
iounmap((u32 *)ti->mmio);
iounmap((u32 *)ti->sram_virt);
}
#endif
}
int ibmtr_probe_card(struct net_device *dev)
{
int err = ibmtr_probe(dev);
if (!err) {
err = register_netdev(dev);
if (err)
ibmtr_cleanup_card(dev);
}
return err;
}
/**************************************************************************** /****************************************************************************
* ibmtr_probe(): Routine specified in the network device structure * ibmtr_probe(): Routine specified in the network device structure
* to probe for an IBM Token Ring Adapter. Routine outline: * to probe for an IBM Token Ring Adapter. Routine outline:
...@@ -325,7 +358,7 @@ static void __devinit find_turbo_adapters(int *iolist) { ...@@ -325,7 +358,7 @@ static void __devinit find_turbo_adapters(int *iolist) {
* which references it. * which references it.
****************************************************************************/ ****************************************************************************/
int __devinit ibmtr_probe(struct net_device *dev) static int ibmtr_probe(struct net_device *dev)
{ {
int i; int i;
int base_addr = dev->base_addr; int base_addr = dev->base_addr;
...@@ -1925,23 +1958,24 @@ static int __init ibmtr_init(void) ...@@ -1925,23 +1958,24 @@ static int __init ibmtr_init(void)
find_turbo_adapters(io); find_turbo_adapters(io);
for (i = 0; io[i] && (i < IBMTR_MAX_ADAPTERS); i++) { for (i = 0; io[i] && (i < IBMTR_MAX_ADAPTERS); i++) {
struct net_device *dev;
irq[i] = 0; irq[i] = 0;
mem[i] = 0; mem[i] = 0;
dev_ibmtr[i] = alloc_trdev(sizeof(struct tok_info)); dev = alloc_trdev(sizeof(struct tok_info));
if (dev_ibmtr[i] == NULL) { if (dev == NULL) {
if (i == 0) if (i == 0)
return -ENOMEM; return -ENOMEM;
break; break;
} }
dev_ibmtr[i]->base_addr = io[i]; dev->base_addr = io[i];
dev_ibmtr[i]->irq = irq[i]; dev->irq = irq[i];
dev_ibmtr[i]->mem_start = mem[i]; dev->mem_start = mem[i];
dev_ibmtr[i]->init = &ibmtr_probe;
if (register_netdev(dev_ibmtr[i]) != 0) { if (ibmtr_probe_card(dev)) {
free_netdev(dev_ibmtr[i]); free_netdev(dev);
dev_ibmtr[i] = NULL;
continue; continue;
} }
dev_ibmtr[i] = dev;
count++; count++;
} }
if (count) return 0; if (count) return 0;
...@@ -1957,27 +1991,9 @@ static void __exit ibmtr_cleanup(void) ...@@ -1957,27 +1991,9 @@ static void __exit ibmtr_cleanup(void)
for (i = 0; i < IBMTR_MAX_ADAPTERS; i++){ for (i = 0; i < IBMTR_MAX_ADAPTERS; i++){
if (!dev_ibmtr[i]) if (!dev_ibmtr[i])
continue; continue;
if (dev_ibmtr[i]->base_addr) {
outb(0,dev_ibmtr[i]->base_addr+ADAPTRESET);
schedule_timeout(TR_RST_TIME); /* wait 50ms */
outb(0,dev_ibmtr[i]->base_addr+ADAPTRESETREL);
}
unregister_netdev(dev_ibmtr[i]); unregister_netdev(dev_ibmtr[i]);
free_irq(dev_ibmtr[i]->irq, dev_ibmtr[i]); ibmtr_cleanup_card(dev_ibmtr[i]);
release_region(dev_ibmtr[i]->base_addr, IBMTR_IO_EXTENT);
#ifndef PCMCIA
{
struct tok_info *ti = (struct tok_info *)
dev_ibmtr[i]->priv;
iounmap((u32 *)ti->mmio);
iounmap((u32 *)ti->sram_virt);
}
#endif
free_netdev(dev_ibmtr[i]); free_netdev(dev_ibmtr[i]);
dev_ibmtr[i] = NULL;
} }
} }
module_exit(ibmtr_cleanup); module_exit(ibmtr_cleanup);
......
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