Commit fc9e0793 authored by Stephen Hemminger's avatar Stephen Hemminger

[NET]: Convert cops over to new initialization.

More from Al
NE12-cops
* switched cops to dynamic allocation
* cops: embedded ->priv
* cops: fixed ->irq clobbering on autoprobe
Added
* free_netdev
parent 51845e3a
...@@ -101,6 +101,9 @@ extern int mc32_probe(struct net_device *dev); ...@@ -101,6 +101,9 @@ extern int mc32_probe(struct net_device *dev);
#ifdef CONFIG_SDLA #ifdef CONFIG_SDLA
extern struct net_device *sdla_init(void); extern struct net_device *sdla_init(void);
#endif #endif
#ifdef CONFIG_COPS
extern struct net_device *cops_probe(int unit);
#endif
/* Detachable devices ("pocket adaptors") */ /* Detachable devices ("pocket adaptors") */
extern int de620_probe(struct net_device *); extern int de620_probe(struct net_device *);
...@@ -388,6 +391,11 @@ static int __init ethif_probe(struct net_device *dev) ...@@ -388,6 +391,11 @@ static int __init ethif_probe(struct net_device *dev)
/* Statically configured drivers -- order matters here. */ /* Statically configured drivers -- order matters here. */
void probe_old_netdevs(void) void probe_old_netdevs(void)
{ {
#ifdef CONFIG_COPS
cops_probe(0);
cops_probe(1);
cops_probe(2);
#endif
#ifdef CONFIG_SDLA #ifdef CONFIG_SDLA
sdla_init(); sdla_init();
#endif #endif
...@@ -405,27 +413,6 @@ static struct net_device dev_ltpc = { ...@@ -405,27 +413,6 @@ static struct net_device dev_ltpc = {
#define NEXT_DEV (&dev_ltpc) #define NEXT_DEV (&dev_ltpc)
#endif /* LTPC */ #endif /* LTPC */
#if defined(CONFIG_COPS)
extern int cops_probe(struct net_device *);
static struct net_device cops2_dev = {
.name = "lt2",
.next = NEXT_DEV,
.init = cops_probe,
};
static struct net_device cops1_dev = {
.name = "lt1",
.next = &cops2_dev,
.init = cops_probe,
};
static struct net_device cops0_dev = {
.name = "lt0",
.next = &cops1_dev,
.init = cops_probe,
};
#undef NEXT_DEV
#define NEXT_DEV (&cops0_dev)
#endif /* COPS */
static struct net_device eth7_dev = { static struct net_device eth7_dev = {
.name = "eth%d", .name = "eth%d",
.next = NEXT_DEV, .next = NEXT_DEV,
......
...@@ -92,12 +92,8 @@ static int board_type = DAYNA; /* Module exported */ ...@@ -92,12 +92,8 @@ static int board_type = DAYNA; /* Module exported */
static int board_type = TANGENT; static int board_type = TANGENT;
#endif #endif
#ifdef MODULE
static int io = 0x240; /* Default IO for Dayna */ static int io = 0x240; /* Default IO for Dayna */
static int irq = 5; /* Default IRQ */ static int irq = 5; /* Default IRQ */
#else
static int io; /* Default IO for Dayna */
#endif
/* /*
* COPS Autoprobe information. * COPS Autoprobe information.
...@@ -146,7 +142,7 @@ static int io; /* Default IO for Dayna */ ...@@ -146,7 +142,7 @@ static int io; /* Default IO for Dayna */
* Zero terminated list of IO ports to probe. * Zero terminated list of IO ports to probe.
*/ */
static unsigned int cops_portlist[] = { static unsigned int ports[] = {
0x240, 0x340, 0x200, 0x210, 0x220, 0x230, 0x260, 0x240, 0x340, 0x200, 0x210, 0x220, 0x230, 0x260,
0x2A0, 0x300, 0x310, 0x320, 0x330, 0x350, 0x360, 0x2A0, 0x300, 0x310, 0x320, 0x330, 0x350, 0x360,
0 0
...@@ -184,7 +180,6 @@ struct cops_local ...@@ -184,7 +180,6 @@ struct cops_local
}; };
/* Index to functions, as function prototypes. */ /* Index to functions, as function prototypes. */
extern int cops_probe (struct net_device *dev);
static int cops_probe1 (struct net_device *dev, int ioaddr); static int cops_probe1 (struct net_device *dev, int ioaddr);
static int cops_irq (int ioaddr, int board); static int cops_irq (int ioaddr, int board);
...@@ -208,6 +203,12 @@ static int cops_ioctl (struct net_device *dev, struct ifreq *rq, int cmd); ...@@ -208,6 +203,12 @@ static int cops_ioctl (struct net_device *dev, struct ifreq *rq, int cmd);
static int cops_close (struct net_device *dev); static int cops_close (struct net_device *dev);
static struct net_device_stats *cops_get_stats (struct net_device *dev); static struct net_device_stats *cops_get_stats (struct net_device *dev);
static void cleanup_card(struct net_device *dev)
{
if (dev->irq)
free_irq(dev->irq, dev);
release_region(dev->base_addr, COPS_IO_EXTENT);
}
/* /*
* 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.
...@@ -215,31 +216,54 @@ static struct net_device_stats *cops_get_stats (struct net_device *dev); ...@@ -215,31 +216,54 @@ static struct net_device_stats *cops_get_stats (struct net_device *dev);
* If dev->base_addr in [1..0x1ff], always return failure. * If dev->base_addr in [1..0x1ff], always return failure.
* otherwise go with what we pass in. * otherwise go with what we pass in.
*/ */
int __init cops_probe(struct net_device *dev) struct net_device * __init cops_probe(int unit)
{ {
int i; struct net_device *dev;
int base_addr = dev->base_addr; unsigned *port;
int base_addr;
int err = 0;
dev = alloc_netdev(sizeof(struct cops_local), "lt%d", ltalk_setup);
if (!dev)
return ERR_PTR(-ENOMEM);
if (unit >= 0) {
sprintf(dev->name, "lt%d", unit);
netdev_boot_setup_check(dev);
irq = dev->irq;
base_addr = dev->base_addr;
} else {
base_addr = dev->base_addr = io;
}
SET_MODULE_OWNER(dev); SET_MODULE_OWNER(dev);
if(base_addr == 0 && io) if (base_addr > 0x1ff) { /* Check a single specified location. */
base_addr=io; err = cops_probe1(dev, base_addr);
} else if (base_addr != 0) { /* Don't probe at all. */
if(base_addr > 0x1ff) /* Check a single specified location. */ err = -ENXIO;
return cops_probe1(dev, base_addr); } else {
else if(base_addr != 0) /* Don't probe at all. */
return -ENXIO;
/* FIXME Does this really work for cards which generate irq? /* FIXME Does this really work for cards which generate irq?
* It's definitely N.G. for polled Tangent. sh * It's definitely N.G. for polled Tangent. sh
* Dayna cards don't autoprobe well at all, but if your card is * Dayna cards don't autoprobe well at all, but if your card is
* at IRQ 5 & IO 0x240 we find it every time. ;) JS * at IRQ 5 & IO 0x240 we find it every time. ;) JS
*/ */
for(i=0; cops_portlist[i]; i++) for (port = ports; *port && cops_probe1(dev, *port) < 0; port++)
if(cops_probe1(dev, cops_portlist[i]) == 0) ;
return 0; if (!*port)
err = -ENODEV;
return -ENODEV; }
if (err)
goto out;
err = register_netdev(dev);
if (err)
goto out1;
return dev;
out1:
cleanup_card(dev);
out:
kfree(dev);
return ERR_PTR(err);
} }
/* /*
...@@ -268,16 +292,15 @@ static int __init cops_probe1(struct net_device *dev, int ioaddr) ...@@ -268,16 +292,15 @@ static int __init cops_probe1(struct net_device *dev, int ioaddr)
* interrupts are typically not reported by the boards, and we must * interrupts are typically not reported by the boards, and we must
* used AutoIRQ to find them. * used AutoIRQ to find them.
*/ */
dev->irq = irq;
switch (dev->irq) switch (dev->irq)
{ {
case 0: case 0:
/* COPS AutoIRQ routine */ /* COPS AutoIRQ routine */
dev->irq = cops_irq(ioaddr, board); dev->irq = cops_irq(ioaddr, board);
if(!dev->irq) { if (dev->irq)
retval = -EINVAL; /* No IRQ found on this port */ break;
goto err_out; /* No IRQ found on this port, fallthrough */
}
case 1: case 1:
retval = -EINVAL; retval = -EINVAL;
goto err_out; goto err_out;
...@@ -302,7 +325,7 @@ static int __init cops_probe1(struct net_device *dev, int ioaddr) ...@@ -302,7 +325,7 @@ static int __init cops_probe1(struct net_device *dev, int ioaddr)
} }
/* Reserve any actual interrupt. */ /* Reserve any actual interrupt. */
if(dev->irq) { if (dev->irq) {
retval = request_irq(dev->irq, &cops_interrupt, 0, dev->name, dev); retval = request_irq(dev->irq, &cops_interrupt, 0, dev->name, dev);
if (retval) if (retval)
goto err_out; goto err_out;
...@@ -310,15 +333,6 @@ static int __init cops_probe1(struct net_device *dev, int ioaddr) ...@@ -310,15 +333,6 @@ static int __init cops_probe1(struct net_device *dev, int ioaddr)
dev->base_addr = ioaddr; dev->base_addr = ioaddr;
/* Initialize the private device structure. */
dev->priv = kmalloc(sizeof(struct cops_local), GFP_KERNEL);
if(dev->priv == NULL) {
if (dev->irq)
free_irq(dev->irq, dev);
retval = -ENOMEM;
goto err_out;
}
lp = (struct cops_local *)dev->priv; lp = (struct cops_local *)dev->priv;
memset(lp, 0, sizeof(struct cops_local)); memset(lp, 0, sizeof(struct cops_local));
spin_lock_init(&lp->lock); spin_lock_init(&lp->lock);
...@@ -326,9 +340,6 @@ static int __init cops_probe1(struct net_device *dev, int ioaddr) ...@@ -326,9 +340,6 @@ static int __init cops_probe1(struct net_device *dev, int ioaddr)
/* Copy local board variable to lp struct. */ /* Copy local board variable to lp struct. */
lp->board = board; lp->board = board;
/* Fill in the fields of the device structure with LocalTalk values. */
ltalk_setup(dev);
dev->hard_start_xmit = cops_send_packet; dev->hard_start_xmit = cops_send_packet;
dev->tx_timeout = cops_timeout; dev->tx_timeout = cops_timeout;
dev->watchdog_timeo = HZ * 2; dev->watchdog_timeo = HZ * 2;
...@@ -1013,7 +1024,7 @@ static struct net_device_stats *cops_get_stats(struct net_device *dev) ...@@ -1013,7 +1024,7 @@ static struct net_device_stats *cops_get_stats(struct net_device *dev)
} }
#ifdef MODULE #ifdef MODULE
static struct net_device cops0_dev = { .init = cops_probe }; static struct net_device *cops_dev;
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
MODULE_PARM(io, "i"); MODULE_PARM(io, "i");
...@@ -1022,33 +1033,20 @@ MODULE_PARM(board_type, "i"); ...@@ -1022,33 +1033,20 @@ MODULE_PARM(board_type, "i");
int init_module(void) int init_module(void)
{ {
int result, err; if (io == 0)
if(io == 0)
printk(KERN_WARNING "%s: You shouldn't autoprobe with insmod\n", printk(KERN_WARNING "%s: You shouldn't autoprobe with insmod\n",
cardname); cardname);
cops_dev = cops_probe(-1);
/* Copy the parameters from insmod into the device structure. */ if (IS_ERR(cops_dev))
cops0_dev.base_addr = io; return PTR_ERR(cops_dev);
cops0_dev.irq = irq;
err=dev_alloc_name(&cops0_dev, "lt%d");
if(err < 0)
return err;
if((result = register_netdev(&cops0_dev)) != 0)
return result;
return 0; return 0;
} }
void cleanup_module(void) void cleanup_module(void)
{ {
unregister_netdev(&cops0_dev); unregister_netdev(cops_dev);
kfree(cops0_dev.priv); cleanup_card(cops_dev);
if(cops0_dev.irq) free_netdev(cops_dev);
free_irq(cops0_dev.irq, &cops0_dev);
release_region(cops0_dev.base_addr, COPS_IO_EXTENT);
} }
#endif /* MODULE */ #endif /* MODULE */
......
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