* [PATCH] (3/42) eexpress
@ 2003-11-13 0:40 Stephen Hemminger
0 siblings, 0 replies; only message in thread
From: Stephen Hemminger @ 2003-11-13 0:40 UTC (permalink / raw)
To: jgarzik; +Cc: netdev
Based on viro NE27-eexpress
* switched eexpress to dynamic allocation
* eexpress: embedded ->priv
* eexpress: fixed clobbering on autoprobe
* eexpress: fixed IO without request_region()
* eexpress: fixed resource leaks on failure exits
diff -Nru a/drivers/net/Space.c b/drivers/net/Space.c
--- a/drivers/net/Space.c Tue Nov 11 09:35:27 2003
+++ b/drivers/net/Space.c Tue Nov 11 09:35:27 2003
@@ -49,7 +49,7 @@
extern int ne_probe(struct net_device *dev);
extern int hp_probe(struct net_device *dev);
extern int hp_plus_probe(struct net_device *dev);
-extern int express_probe(struct net_device *);
+extern struct net_device *express_probe(int unit);
extern struct net_device *eepro_probe(int unit);
extern int at1500_probe(struct net_device *);
extern int at1700_probe(struct net_device *);
@@ -250,13 +250,13 @@
#ifdef CONFIG_ETH16I
{eth16i_probe, 0}, /* ICL EtherTeam 16i/32 */
#endif
-#ifdef CONFIG_EEXPRESS /* Intel EtherExpress */
- {express_probe, 0},
-#endif
{NULL, 0},
};
static struct devprobe2 isa_probes2[] __initdata = {
+#ifdef CONFIG_EEXPRESS /* Intel EtherExpress */
+ {express_probe, 0},
+#endif
#ifdef CONFIG_EEXPRESS_PRO /* Intel EtherExpress Pro/10 */
{eepro_probe, 0},
#endif
diff -Nru a/drivers/net/eexpress.c b/drivers/net/eexpress.c
--- a/drivers/net/eexpress.c Tue Nov 11 09:35:27 2003
+++ b/drivers/net/eexpress.c Tue Nov 11 09:35:27 2003
@@ -244,7 +244,6 @@
* Prototypes for Linux interface
*/
-extern int express_probe(struct net_device *dev);
static int eexp_open(struct net_device *dev);
static int eexp_close(struct net_device *dev);
static void eexp_timeout(struct net_device *dev);
@@ -334,11 +333,13 @@
* checks for presence of EtherExpress card
*/
-int __init express_probe(struct net_device *dev)
+static int __init do_express_probe(struct net_device *dev)
{
unsigned short *port;
static unsigned short ports[] = { 0x240,0x300,0x310,0x270,0x320,0x340,0 };
unsigned short ioaddr = dev->base_addr;
+ int dev_irq = dev->irq;
+ int err;
SET_MODULE_OWNER(dev);
@@ -391,27 +392,58 @@
}
}
#endif
- if (ioaddr&0xfe00)
- return eexp_hw_probe(dev,ioaddr);
- else if (ioaddr)
+ if (ioaddr&0xfe00) {
+ if (!request_region(ioaddr, EEXP_IO_EXTENT, "EtherExpress"))
+ return -EBUSY;
+ err = eexp_hw_probe(dev,ioaddr);
+ release_region(ioaddr, EEXP_IO_EXTENT);
+ return err;
+ } else if (ioaddr)
return -ENXIO;
for (port=&ports[0] ; *port ; port++ )
{
unsigned short sum = 0;
int i;
+ if (!request_region(*port, EEXP_IO_EXTENT, "EtherExpress"))
+ continue;
for ( i=0 ; i<4 ; i++ )
{
unsigned short t;
t = inb(*port + ID_PORT);
sum |= (t>>4) << ((t & 0x03)<<2);
}
- if (sum==0xbaba && !eexp_hw_probe(dev,*port))
+ if (sum==0xbaba && !eexp_hw_probe(dev,*port)) {
+ release_region(*port, EEXP_IO_EXTENT);
return 0;
+ }
+ release_region(*port, EEXP_IO_EXTENT);
+ dev->irq = dev_irq;
}
return -ENODEV;
}
+struct net_device * __init express_probe(int unit)
+{
+ struct net_device *dev = alloc_etherdev(sizeof(struct net_local));
+ int err;
+
+ if (!dev)
+ return ERR_PTR(-ENOMEM);
+
+ sprintf(dev->name, "eth%d", unit);
+ netdev_boot_setup_check(dev);
+
+ err = do_express_probe(dev);
+ if (!err) {
+ err = register_netdev(dev);
+ if (!err)
+ return dev;
+ }
+ free_netdev(dev);
+ return ERR_PTR(err);
+}
+
/*
* open and initialize the adapter, ready for use
*/
@@ -1058,7 +1090,7 @@
unsigned int memory_size;
int i;
unsigned short xsum = 0;
- struct net_local *lp;
+ struct net_local *lp = dev->priv;
printk("%s: EtherExpress 16 at %#x ",dev->name,ioaddr);
@@ -1108,17 +1140,18 @@
buswidth = !((setupval & 0x400) >> 10);
}
- dev->priv = lp = kmalloc(sizeof(struct net_local), GFP_KERNEL);
- if (!dev->priv)
- return -ENOMEM;
-
- memset(dev->priv, 0, sizeof(struct net_local));
+ memset(lp, 0, sizeof(struct net_local));
spin_lock_init(&lp->lock);
printk("(IRQ %d, %s connector, %d-bit bus", dev->irq,
eexp_ifmap[dev->if_port], buswidth?8:16);
+ if (!request_region(dev->base_addr + 0x300e, 1, "EtherExpress"))
+ return -EBUSY;
+
eexp_hw_set_interface(dev);
+
+ release_region(dev->base_addr + 0x300e, 1);
/* Find out how much RAM we have on the card */
outw(0, dev->base_addr + WRITE_PTR);
@@ -1156,7 +1189,6 @@
break;
default:
printk(") bad memory size (%dk).\n", memory_size);
- kfree(dev->priv);
return -ENODEV;
break;
}
@@ -1171,7 +1203,6 @@
dev->set_multicast_list = &eexp_set_multicast;
dev->tx_timeout = eexp_timeout;
dev->watchdog_timeo = 2*HZ;
- ether_setup(dev);
return 0;
}
@@ -1654,7 +1685,7 @@
#define EEXP_MAX_CARDS 4 /* max number of cards to support */
-static struct net_device dev_eexp[EEXP_MAX_CARDS];
+static struct net_device *dev_eexp[EEXP_MAX_CARDS];
static int irq[EEXP_MAX_CARDS];
static int io[EEXP_MAX_CARDS];
@@ -1671,25 +1702,30 @@
*/
int init_module(void)
{
+ struct net_device *dev;
int this_dev, found = 0;
for (this_dev = 0; this_dev < EEXP_MAX_CARDS; this_dev++) {
- struct net_device *dev = &dev_eexp[this_dev];
+ dev = alloc_etherdev(sizeof(struct net_local));
dev->irq = irq[this_dev];
dev->base_addr = io[this_dev];
- dev->init = express_probe;
if (io[this_dev] == 0) {
- if (this_dev) break;
+ if (this_dev)
+ break;
printk(KERN_NOTICE "eexpress.c: Module autoprobe not recommended, give io=xx.\n");
}
- if (register_netdev(dev) != 0) {
- printk(KERN_WARNING "eexpress.c: Failed to register card at 0x%x.\n", io[this_dev]);
- if (found != 0) return 0;
- return -ENXIO;
+ if (do_express_probe(dev) == 0 && register_netdev(dev) == 0) {
+ dev_eexp[this_dev] = dev;
+ found++;
+ continue;
}
- found++;
+ printk(KERN_WARNING "eexpress.c: Failed to register card at 0x%x.\n", io[this_dev]);
+ free_netdev(dev);
+ break;
}
- return 0;
+ if (found)
+ return 0;
+ return -ENXIO;
}
void cleanup_module(void)
@@ -1697,11 +1733,10 @@
int this_dev;
for (this_dev = 0; this_dev < EEXP_MAX_CARDS; this_dev++) {
- struct net_device *dev = &dev_eexp[this_dev];
- if (dev->priv != NULL) {
+ struct net_device *dev = dev_eexp[this_dev];
+ if (dev) {
unregister_netdev(dev);
- kfree(dev->priv);
- dev->priv = NULL;
+ free_netdev(dev);
}
}
}
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2003-11-13 0:40 UTC | newest]
Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2003-11-13 0:40 [PATCH] (3/42) eexpress Stephen Hemminger
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).