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;
#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.
......@@ -286,8 +282,6 @@ static unsigned short init_words[] = {
/* 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_open(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
static void init_82586_mem(struct net_device *dev);
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.
If dev->base_addr == 0, probe all likely locations.
......@@ -309,23 +307,50 @@ static struct ethtool_ops netdev_ethtool_ops;
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;
int i;
struct net_device *dev = alloc_etherdev(sizeof(struct net_local));
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);
if (base_addr > 0x1ff) /* Check a single specified location. */
return el16_probe1(dev, base_addr);
else if (base_addr != 0)
return -ENXIO; /* Don't probe at all. */
for (i = 0; netcard_portlist[i]; i++)
if (el16_probe1(dev, netcard_portlist[i]) == 0)
return 0;
if (io > 0x1ff) /* Check a single specified location. */
err = el16_probe1(dev, io);
else if (io != 0)
err = -ENXIO; /* Don't probe at all. */
else {
for (port = ports; *port; port++) {
err = el16_probe1(dev, io);
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)
......@@ -383,8 +408,8 @@ static int __init el16_probe1(struct net_device *dev, int ioaddr)
printk(" %02x", dev->dev_addr[i]);
}
if ((dev->mem_start & 0xf) > 0)
net_debug = dev->mem_start & 7;
if (mem_start)
net_debug = mem_start & 7;
#ifdef MEM_BASE
dev->mem_start = MEM_BASE;
......@@ -416,27 +441,18 @@ static int __init el16_probe1(struct net_device *dev, int ioaddr)
if (net_debug)
printk(version);
/* Initialize the device structure. */
lp = dev->priv = kmalloc(sizeof(struct net_local), GFP_KERNEL);
if (dev->priv == NULL) {
retval = -ENOMEM;
goto out;
}
memset(dev->priv, 0, sizeof(struct net_local));
lp = dev->priv;
memset(lp, 0, sizeof(*lp));
spin_lock_init(&lp->lock);
dev->open = el16_open;
dev->stop = el16_close;
dev->open = el16_open;
dev->stop = el16_close;
dev->hard_start_xmit = el16_send_packet;
dev->get_stats = el16_get_stats;
dev->tx_timeout = el16_tx_timeout;
dev->watchdog_timeo = TX_TIMEOUT;
dev->ethtool_ops = &netdev_ethtool_ops;
ether_setup(dev); /* Generic ethernet behaviour */
dev->flags&=~IFF_MULTICAST; /* Multicast doesn't work */
dev->flags &= ~IFF_MULTICAST; /* Multicast doesn't work */
return 0;
out:
release_region(ioaddr, EL16_IO_EXTENT);
......@@ -899,9 +915,7 @@ static struct ethtool_ops netdev_ethtool_ops = {
};
#ifdef MODULE
static struct net_device dev_3c507;
static int io = 0x300;
static int irq;
static struct net_device *dev_3c507;
MODULE_PARM(io, "i");
MODULE_PARM(irq, "i");
MODULE_PARM_DESC(io, "EtherLink16 I/O base address");
......@@ -911,26 +925,18 @@ int init_module(void)
{
if (io == 0)
printk("3c507: You should not use auto-probing with insmod!\n");
dev_3c507.base_addr = io;
dev_3c507.irq = irq;
dev_3c507.init = el16_probe;
if (register_netdev(&dev_3c507) != 0) {
printk("3c507: register_netdev() returned non-zero.\n");
return -EIO;
}
return 0;
dev_3c507 = el16_probe(-1);
return IS_ERR(dev_3c507) ? PTR_ERR(dev_3c507) : 0;
}
void
cleanup_module(void)
{
unregister_netdev(&dev_3c507);
kfree(dev_3c507.priv);
dev_3c507.priv = NULL;
/* If we don't do this, we can't re-insmod it later. */
free_irq(dev_3c507.irq, &dev_3c507);
release_region(dev_3c507.base_addr, EL16_IO_EXTENT);
struct net_device *dev = dev_3c507;
unregister_netdev(dev);
free_irq(dev->irq, dev);
release_region(dev->base_addr, EL16_IO_EXTENT);
free_netdev(dev);
}
#endif /* MODULE */
MODULE_LICENSE("GPL");
......
......@@ -60,7 +60,7 @@ extern int ewrk3_probe(struct net_device *);
extern int el1_probe(struct net_device *);
extern int wavelan_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 skmca_probe(struct net_device *);
extern struct net_device *elplus_probe(int unit);
......@@ -270,14 +270,14 @@ static struct devprobe isa_probes[] __initdata = {
#endif
#ifdef CONFIG_ARLAN /* Aironet */
{arlan_probe, 0},
#endif
#ifdef CONFIG_EL16 /* 3c507 */
{el16_probe, 0},
#endif
{NULL, 0},
};
static struct devprobe2 isa_probes2[] __initdata = {
#ifdef CONFIG_EL16 /* 3c507 */
{el16_probe, 0},
#endif
#ifdef CONFIG_ELPLUS /* 3c505 */
{elplus_probe, 0},
#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