Commit fd60992e authored by Stephen Hemminger's avatar Stephen Hemminger

[PATCH] (08/12) Probe2 -- 3c507

Originally by Al Viro (NE19-3c507)
	* switched 3c507 to dynamic allocation
	* 3c507: embedded ->priv
	* 3c507: fixed clobbering on autoprobe
	* NB: 3c507.c buggers port 0x100 without claiming it.  Most likely it
	  should be doing request_region() there.
Updated to apply agains jgarzik/net-drivers-2.5-exp
parent 97da4b3b
...@@ -74,10 +74,6 @@ static unsigned int net_debug = NET_DEBUG; ...@@ -74,10 +74,6 @@ static unsigned int net_debug = NET_DEBUG;
#define debug net_debug #define debug net_debug
/* A zero-terminated list of common I/O addresses to be probed. */
static unsigned int netcard_portlist[] __initdata =
{ 0x300, 0x320, 0x340, 0x280, 0};
/* /*
Details of the i82586. Details of the i82586.
...@@ -286,8 +282,6 @@ static unsigned short init_words[] = { ...@@ -286,8 +282,6 @@ static unsigned short init_words[] = {
/* Index to functions, as function prototypes. */ /* Index to functions, as function prototypes. */
extern int el16_probe(struct net_device *dev); /* Called from Space.c */
static int el16_probe1(struct net_device *dev, int ioaddr); static int el16_probe1(struct net_device *dev, int ioaddr);
static int el16_open(struct net_device *dev); static int el16_open(struct net_device *dev);
static int el16_send_packet(struct sk_buff *skb, struct net_device *dev); static int el16_send_packet(struct sk_buff *skb, struct net_device *dev);
...@@ -301,6 +295,10 @@ static void hardware_send_packet(struct net_device *dev, void *buf, short length ...@@ -301,6 +295,10 @@ static void hardware_send_packet(struct net_device *dev, void *buf, short length
static void init_82586_mem(struct net_device *dev); static void init_82586_mem(struct net_device *dev);
static struct ethtool_ops netdev_ethtool_ops; static struct ethtool_ops netdev_ethtool_ops;
static int io = 0x300;
static int irq;
static int mem_start;
/* Check for a network adaptor of this type, and return '0' iff one exists. /* Check for a network adaptor of this type, and return '0' iff one exists.
If dev->base_addr == 0, probe all likely locations. If dev->base_addr == 0, probe all likely locations.
...@@ -309,23 +307,50 @@ static struct ethtool_ops netdev_ethtool_ops; ...@@ -309,23 +307,50 @@ static struct ethtool_ops netdev_ethtool_ops;
device and return success. device and return success.
*/ */
int __init el16_probe(struct net_device *dev) struct net_device * __init el16_probe(int unit)
{ {
int base_addr = dev->base_addr; struct net_device *dev = alloc_etherdev(sizeof(struct net_local));
int i; static unsigned ports[] = { 0x300, 0x320, 0x340, 0x280, 0};
unsigned *port;
int err = -ENODEV;
if (!dev)
return ERR_PTR(-ENODEV);
if (unit >= 0) {
sprintf(dev->name, "eth%d", unit);
netdev_boot_setup_check(dev);
io = dev->base_addr;
irq = dev->irq;
mem_start = dev->mem_start & 15;
}
SET_MODULE_OWNER(dev); SET_MODULE_OWNER(dev);
if (base_addr > 0x1ff) /* Check a single specified location. */ if (io > 0x1ff) /* Check a single specified location. */
return el16_probe1(dev, base_addr); err = el16_probe1(dev, io);
else if (base_addr != 0) else if (io != 0)
return -ENXIO; /* Don't probe at all. */ err = -ENXIO; /* Don't probe at all. */
else {
for (i = 0; netcard_portlist[i]; i++) for (port = ports; *port; port++) {
if (el16_probe1(dev, netcard_portlist[i]) == 0) err = el16_probe1(dev, io);
return 0; if (!err)
break;
}
}
return -ENODEV; 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, EL16_IO_EXTENT);
out:
free_netdev(dev);
return ERR_PTR(err);
} }
static int __init el16_probe1(struct net_device *dev, int ioaddr) static int __init el16_probe1(struct net_device *dev, int ioaddr)
...@@ -383,8 +408,8 @@ static int __init el16_probe1(struct net_device *dev, int ioaddr) ...@@ -383,8 +408,8 @@ static int __init el16_probe1(struct net_device *dev, int ioaddr)
printk(" %02x", dev->dev_addr[i]); printk(" %02x", dev->dev_addr[i]);
} }
if ((dev->mem_start & 0xf) > 0) if (mem_start)
net_debug = dev->mem_start & 7; net_debug = mem_start & 7;
#ifdef MEM_BASE #ifdef MEM_BASE
dev->mem_start = MEM_BASE; dev->mem_start = MEM_BASE;
...@@ -416,27 +441,18 @@ static int __init el16_probe1(struct net_device *dev, int ioaddr) ...@@ -416,27 +441,18 @@ static int __init el16_probe1(struct net_device *dev, int ioaddr)
if (net_debug) if (net_debug)
printk(version); printk(version);
/* Initialize the device structure. */ lp = dev->priv;
lp = dev->priv = kmalloc(sizeof(struct net_local), GFP_KERNEL); memset(lp, 0, sizeof(*lp));
if (dev->priv == NULL) {
retval = -ENOMEM;
goto out;
}
memset(dev->priv, 0, sizeof(struct net_local));
spin_lock_init(&lp->lock); spin_lock_init(&lp->lock);
dev->open = el16_open; dev->open = el16_open;
dev->stop = el16_close; dev->stop = el16_close;
dev->hard_start_xmit = el16_send_packet; dev->hard_start_xmit = el16_send_packet;
dev->get_stats = el16_get_stats; dev->get_stats = el16_get_stats;
dev->tx_timeout = el16_tx_timeout; dev->tx_timeout = el16_tx_timeout;
dev->watchdog_timeo = TX_TIMEOUT; dev->watchdog_timeo = TX_TIMEOUT;
dev->ethtool_ops = &netdev_ethtool_ops; dev->ethtool_ops = &netdev_ethtool_ops;
dev->flags &= ~IFF_MULTICAST; /* Multicast doesn't work */
ether_setup(dev); /* Generic ethernet behaviour */
dev->flags&=~IFF_MULTICAST; /* Multicast doesn't work */
return 0; return 0;
out: out:
release_region(ioaddr, EL16_IO_EXTENT); release_region(ioaddr, EL16_IO_EXTENT);
...@@ -899,9 +915,7 @@ static struct ethtool_ops netdev_ethtool_ops = { ...@@ -899,9 +915,7 @@ static struct ethtool_ops netdev_ethtool_ops = {
}; };
#ifdef MODULE #ifdef MODULE
static struct net_device dev_3c507; static struct net_device *dev_3c507;
static int io = 0x300;
static int irq;
MODULE_PARM(io, "i"); MODULE_PARM(io, "i");
MODULE_PARM(irq, "i"); MODULE_PARM(irq, "i");
MODULE_PARM_DESC(io, "EtherLink16 I/O base address"); MODULE_PARM_DESC(io, "EtherLink16 I/O base address");
...@@ -911,26 +925,18 @@ int init_module(void) ...@@ -911,26 +925,18 @@ int init_module(void)
{ {
if (io == 0) if (io == 0)
printk("3c507: You should not use auto-probing with insmod!\n"); printk("3c507: You should not use auto-probing with insmod!\n");
dev_3c507.base_addr = io; dev_3c507 = el16_probe(-1);
dev_3c507.irq = irq; return IS_ERR(dev_3c507) ? PTR_ERR(dev_3c507) : 0;
dev_3c507.init = el16_probe;
if (register_netdev(&dev_3c507) != 0) {
printk("3c507: register_netdev() returned non-zero.\n");
return -EIO;
}
return 0;
} }
void void
cleanup_module(void) cleanup_module(void)
{ {
unregister_netdev(&dev_3c507); struct net_device *dev = dev_3c507;
kfree(dev_3c507.priv); unregister_netdev(dev);
dev_3c507.priv = NULL; free_irq(dev->irq, dev);
release_region(dev->base_addr, EL16_IO_EXTENT);
/* If we don't do this, we can't re-insmod it later. */ free_netdev(dev);
free_irq(dev_3c507.irq, &dev_3c507);
release_region(dev_3c507.base_addr, EL16_IO_EXTENT);
} }
#endif /* MODULE */ #endif /* MODULE */
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
......
...@@ -60,7 +60,7 @@ extern int ewrk3_probe(struct net_device *); ...@@ -60,7 +60,7 @@ extern int ewrk3_probe(struct net_device *);
extern int el1_probe(struct net_device *); extern int el1_probe(struct net_device *);
extern int wavelan_probe(struct net_device *); extern int wavelan_probe(struct net_device *);
extern int arlan_probe(struct net_device *); extern int arlan_probe(struct net_device *);
extern int el16_probe(struct net_device *); extern struct net_device *el16_probe(int unit);
extern int elmc_probe(struct net_device *); extern int elmc_probe(struct net_device *);
extern int skmca_probe(struct net_device *); extern int skmca_probe(struct net_device *);
extern struct net_device *elplus_probe(int unit); extern struct net_device *elplus_probe(int unit);
...@@ -270,14 +270,14 @@ static struct devprobe isa_probes[] __initdata = { ...@@ -270,14 +270,14 @@ static struct devprobe isa_probes[] __initdata = {
#endif #endif
#ifdef CONFIG_ARLAN /* Aironet */ #ifdef CONFIG_ARLAN /* Aironet */
{arlan_probe, 0}, {arlan_probe, 0},
#endif
#ifdef CONFIG_EL16 /* 3c507 */
{el16_probe, 0},
#endif #endif
{NULL, 0}, {NULL, 0},
}; };
static struct devprobe2 isa_probes2[] __initdata = { static struct devprobe2 isa_probes2[] __initdata = {
#ifdef CONFIG_EL16 /* 3c507 */
{el16_probe, 0},
#endif
#ifdef CONFIG_ELPLUS /* 3c505 */ #ifdef CONFIG_ELPLUS /* 3c505 */
{elplus_probe, 0}, {elplus_probe, 0},
#endif #endif
......
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