Commit 84e78fd3 authored by Stephen Hemminger's avatar Stephen Hemminger

[PATCH] (4/42) eth16i

NE28-eth16i
	* switched eth16i to dynamic allocation
	* eth16i: embedded ->priv
	* eth16i: fixed resource leaks on failure exits
parent fdc7e3e8
...@@ -54,7 +54,7 @@ extern struct net_device *eepro_probe(int unit); ...@@ -54,7 +54,7 @@ extern struct net_device *eepro_probe(int unit);
extern int at1500_probe(struct net_device *); extern int at1500_probe(struct net_device *);
extern int at1700_probe(struct net_device *); extern int at1700_probe(struct net_device *);
extern int fmv18x_probe(struct net_device *); extern int fmv18x_probe(struct net_device *);
extern int eth16i_probe(struct net_device *); extern struct net_device *eth16i_probe(int unit);
extern struct net_device *i82596_probe(int unit); extern struct net_device *i82596_probe(int unit);
extern struct net_device *ewrk3_probe(int unit); extern struct net_device *ewrk3_probe(int unit);
extern struct net_device *el1_probe(int unit); extern struct net_device *el1_probe(int unit);
...@@ -246,14 +246,14 @@ static struct devprobe isa_probes[] __initdata = { ...@@ -246,14 +246,14 @@ static struct devprobe isa_probes[] __initdata = {
#endif #endif
#ifdef CONFIG_FMV18X /* Fujitsu FMV-181/182 */ #ifdef CONFIG_FMV18X /* Fujitsu FMV-181/182 */
{fmv18x_probe, 0}, {fmv18x_probe, 0},
#endif
#ifdef CONFIG_ETH16I
{eth16i_probe, 0}, /* ICL EtherTeam 16i/32 */
#endif #endif
{NULL, 0}, {NULL, 0},
}; };
static struct devprobe2 isa_probes2[] __initdata = { static struct devprobe2 isa_probes2[] __initdata = {
#ifdef CONFIG_ETH16I
{eth16i_probe, 0}, /* ICL EtherTeam 16i/32 */
#endif
#ifdef CONFIG_EEXPRESS /* Intel EtherExpress */ #ifdef CONFIG_EEXPRESS /* Intel EtherExpress */
{express_probe, 0}, {express_probe, 0},
#endif #endif
......
...@@ -369,7 +369,6 @@ static unsigned int eth32i_irqmap[] __initdata = { 3, 5, 7, 9, 10, 11, 12, 15, 0 ...@@ -369,7 +369,6 @@ static unsigned int eth32i_irqmap[] __initdata = { 3, 5, 7, 9, 10, 11, 12, 15, 0
#define NUM_OF_EISA_IRQS 8 #define NUM_OF_EISA_IRQS 8
static unsigned int eth16i_tx_buf_map[] = { 2048, 2048, 4096, 8192 }; static unsigned int eth16i_tx_buf_map[] = { 2048, 2048, 4096, 8192 };
static unsigned int boot = 1;
/* Use 0 for production, 1 for verification, >2 for debug */ /* Use 0 for production, 1 for verification, >2 for debug */
#ifndef ETH16I_DEBUG #ifndef ETH16I_DEBUG
...@@ -395,8 +394,6 @@ struct eth16i_local { ...@@ -395,8 +394,6 @@ struct eth16i_local {
/* Function prototypes */ /* Function prototypes */
extern int eth16i_probe(struct net_device *dev);
static int eth16i_probe1(struct net_device *dev, int ioaddr); static int eth16i_probe1(struct net_device *dev, int ioaddr);
static int eth16i_check_signature(int ioaddr); static int eth16i_check_signature(int ioaddr);
static int eth16i_probe_port(int ioaddr); static int eth16i_probe_port(int ioaddr);
...@@ -418,7 +415,7 @@ static void eth16i_timeout(struct net_device *dev); ...@@ -418,7 +415,7 @@ static void eth16i_timeout(struct net_device *dev);
static void eth16i_skip_packet(struct net_device *dev); static void eth16i_skip_packet(struct net_device *dev);
static void eth16i_multicast(struct net_device *dev); static void eth16i_multicast(struct net_device *dev);
static void eth16i_select_regbank(unsigned char regbank, int ioaddr); static void eth16i_select_regbank(unsigned char regbank, int ioaddr);
static void eth16i_initialize(struct net_device *dev); static void eth16i_initialize(struct net_device *dev, int boot);
#if 0 #if 0
static int eth16i_set_irq(struct net_device *dev); static int eth16i_set_irq(struct net_device *dev);
...@@ -432,7 +429,7 @@ static struct net_device_stats *eth16i_get_stats(struct net_device *dev); ...@@ -432,7 +429,7 @@ static struct net_device_stats *eth16i_get_stats(struct net_device *dev);
static char cardname[] __initdata = "ICL EtherTeam 16i/32"; static char cardname[] __initdata = "ICL EtherTeam 16i/32";
int __init eth16i_probe(struct net_device *dev) static int __init do_eth16i_probe(struct net_device *dev)
{ {
int i; int i;
int ioaddr; int ioaddr;
...@@ -461,14 +458,38 @@ int __init eth16i_probe(struct net_device *dev) ...@@ -461,14 +458,38 @@ int __init eth16i_probe(struct net_device *dev)
return -ENODEV; return -ENODEV;
} }
struct net_device * __init eth16i_probe(int unit)
{
struct net_device *dev = alloc_etherdev(sizeof(struct eth16i_local));
int err;
if (!dev)
return ERR_PTR(-ENOMEM);
sprintf(dev->name, "eth%d", unit);
netdev_boot_setup_check(dev);
err = do_eth16i_probe(dev);
if (err)
goto out;
err = register_netdev(dev);
if (err)
goto out1;
return dev;
out1:
free_irq(dev->irq, dev);
release_region(dev->base_addr, ETH16I_IO_EXTENT);
out:
free_netdev(dev);
return ERR_PTR(err);
}
static int __init eth16i_probe1(struct net_device *dev, int ioaddr) static int __init eth16i_probe1(struct net_device *dev, int ioaddr)
{ {
struct eth16i_local *lp; struct eth16i_local *lp = dev->priv;
static unsigned version_printed; static unsigned version_printed;
int retval; int retval;
boot = 1; /* To inform initilization that we are in boot probe */
/* Let's grab the region */ /* Let's grab the region */
if (!request_region(ioaddr, ETH16I_IO_EXTENT, dev->name)) if (!request_region(ioaddr, ETH16I_IO_EXTENT, dev->name))
return -EBUSY; return -EBUSY;
...@@ -531,22 +552,13 @@ static int __init eth16i_probe1(struct net_device *dev, int ioaddr) ...@@ -531,22 +552,13 @@ static int __init eth16i_probe1(struct net_device *dev, int ioaddr)
eth16i_select_regbank(TRANSCEIVER_MODE_RB, ioaddr); eth16i_select_regbank(TRANSCEIVER_MODE_RB, ioaddr);
outb(0x38, ioaddr + TRANSCEIVER_MODE_REG); outb(0x38, ioaddr + TRANSCEIVER_MODE_REG);
eth16i_initialize(dev); /* Initialize rest of the chip's registers */ eth16i_initialize(dev, 1); /* Initialize rest of the chip's registers */
/* Now let's same some energy by shutting down the chip ;) */ /* Now let's same some energy by shutting down the chip ;) */
BITCLR(ioaddr + CONFIG_REG_1, POWERUP); BITCLR(ioaddr + CONFIG_REG_1, POWERUP);
/* Initialize the device structure */ /* Initialize the device structure */
if(dev->priv == NULL) { memset(lp, 0, sizeof(struct eth16i_local));
dev->priv = kmalloc(sizeof(struct eth16i_local), GFP_KERNEL);
if(dev->priv == NULL) {
free_irq(dev->irq, dev);
retval = -ENOMEM;
goto out;
}
}
memset(dev->priv, 0, sizeof(struct eth16i_local));
dev->open = eth16i_open; dev->open = eth16i_open;
dev->stop = eth16i_close; dev->stop = eth16i_close;
dev->hard_start_xmit = eth16i_tx; dev->hard_start_xmit = eth16i_tx;
...@@ -554,15 +566,7 @@ static int __init eth16i_probe1(struct net_device *dev, int ioaddr) ...@@ -554,15 +566,7 @@ static int __init eth16i_probe1(struct net_device *dev, int ioaddr)
dev->set_multicast_list = eth16i_multicast; dev->set_multicast_list = eth16i_multicast;
dev->tx_timeout = eth16i_timeout; dev->tx_timeout = eth16i_timeout;
dev->watchdog_timeo = TX_TIMEOUT; dev->watchdog_timeo = TX_TIMEOUT;
lp = (struct eth16i_local *)dev->priv;
spin_lock_init(&lp->lock); spin_lock_init(&lp->lock);
/* Fill in the fields of the device structure with ethernet values. */
ether_setup(dev);
boot = 0;
return 0; return 0;
out: out:
release_region(ioaddr, ETH16I_IO_EXTENT); release_region(ioaddr, ETH16I_IO_EXTENT);
...@@ -570,7 +574,7 @@ static int __init eth16i_probe1(struct net_device *dev, int ioaddr) ...@@ -570,7 +574,7 @@ static int __init eth16i_probe1(struct net_device *dev, int ioaddr)
} }
static void eth16i_initialize(struct net_device *dev) static void eth16i_initialize(struct net_device *dev, int boot)
{ {
int ioaddr = dev->base_addr; int ioaddr = dev->base_addr;
int i, node_w = 0; int i, node_w = 0;
...@@ -953,7 +957,7 @@ static int eth16i_open(struct net_device *dev) ...@@ -953,7 +957,7 @@ static int eth16i_open(struct net_device *dev)
outb(0xc0 | POWERUP, ioaddr + CONFIG_REG_1); outb(0xc0 | POWERUP, ioaddr + CONFIG_REG_1);
/* Initialize the chip */ /* Initialize the chip */
eth16i_initialize(dev); eth16i_initialize(dev, 0);
/* Set the transmit buffer size */ /* Set the transmit buffer size */
lp->tx_buf_size = eth16i_tx_buf_map[ETH16I_TX_BUF_SIZE & 0x03]; lp->tx_buf_size = eth16i_tx_buf_map[ETH16I_TX_BUF_SIZE & 0x03];
...@@ -1401,7 +1405,7 @@ static ushort eth16i_parse_mediatype(const char* s) ...@@ -1401,7 +1405,7 @@ static ushort eth16i_parse_mediatype(const char* s)
#define MAX_ETH16I_CARDS 4 /* Max number of Eth16i cards per module */ #define MAX_ETH16I_CARDS 4 /* Max number of Eth16i cards per module */
static struct net_device dev_eth16i[MAX_ETH16I_CARDS]; static struct net_device *dev_eth16i[MAX_ETH16I_CARDS];
static int io[MAX_ETH16I_CARDS]; static int io[MAX_ETH16I_CARDS];
#if 0 #if 0
static int irq[MAX_ETH16I_CARDS]; static int irq[MAX_ETH16I_CARDS];
...@@ -1431,14 +1435,14 @@ MODULE_PARM_DESC(debug, "eth16i debug level (0-6)"); ...@@ -1431,14 +1435,14 @@ MODULE_PARM_DESC(debug, "eth16i debug level (0-6)");
int init_module(void) int init_module(void)
{ {
int this_dev, found = 0; int this_dev, found = 0;
struct net_device *dev;
for (this_dev = 0; this_dev < MAX_ETH16I_CARDS; this_dev++) {
dev = alloc_etherdev(sizeof(struct eth16i_local));
if (!dev)
break;
for(this_dev = 0; this_dev < MAX_ETH16I_CARDS; this_dev++)
{
struct net_device *dev = &dev_eth16i[this_dev];
dev->irq = 0; /* irq[this_dev]; */
dev->base_addr = io[this_dev]; dev->base_addr = io[this_dev];
dev->init = eth16i_probe;
if(debug != -1) if(debug != -1)
eth16i_debug = debug; eth16i_debug = debug;
...@@ -1448,44 +1452,43 @@ int init_module(void) ...@@ -1448,44 +1452,43 @@ int init_module(void)
dev->if_port = eth16i_parse_mediatype(mediatype[this_dev]); dev->if_port = eth16i_parse_mediatype(mediatype[this_dev]);
if(io[this_dev] == 0) if(io[this_dev] == 0) {
{ if(this_dev != 0) /* Only autoprobe 1st one */
if(this_dev != 0) break; /* Only autoprobe 1st one */ break;
printk(KERN_NOTICE "eth16i.c: Presently autoprobing (not recommended) for a single card.\n"); printk(KERN_NOTICE "eth16i.c: Presently autoprobing (not recommended) for a single card.\n");
} }
if(register_netdev(dev) != 0) if (do_eth16i_probe(dev) == 0) {
{ if (register_netdev(dev) == 0) {
printk(KERN_WARNING "eth16i.c No Eth16i card found (i/o = 0x%x).\n", dev_eth16i[found++] = dev;
io[this_dev]); continue;
}
if(found != 0) return 0; free_irq(dev->irq, dev);
return -ENXIO; release_region(dev->base_addr, ETH16I_IO_EXTENT);
} }
printk(KERN_WARNING "eth16i.c No Eth16i card found (i/o = 0x%x).\n",
found++; io[this_dev]);
free_netdev(dev);
break;
} }
return 0; if (found)
return 0;
return -ENXIO;
} }
void cleanup_module(void) void cleanup_module(void)
{ {
int this_dev; int this_dev;
for(this_dev = 0; this_dev < MAX_ETH16I_CARDS; this_dev++) for(this_dev = 0; this_dev < MAX_ETH16I_CARDS; this_dev++) {
{ struct net_device *dev = dev_eth16i[this_dev];
struct net_device* dev = &dev_eth16i[this_dev];
if(dev->priv != NULL) if(dev->priv) {
{
unregister_netdev(dev); unregister_netdev(dev);
kfree(dev->priv);
dev->priv = NULL;
free_irq(dev->irq, dev); free_irq(dev->irq, dev);
release_region(dev->base_addr, ETH16I_IO_EXTENT); release_region(dev->base_addr, ETH16I_IO_EXTENT);
free_netdev(dev);
} }
} }
} }
......
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