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