patch-1.3.37 linux/drivers/net/wd.c
Next file: linux/drivers/pci/pci.c
Previous file: linux/drivers/net/ppp.c
Back to the patch index
Back to the overall index
- Lines: 130
- Date:
Sat Oct 28 15:18:23 1995
- Orig file:
v1.3.36/linux/drivers/net/wd.c
- Orig date:
Tue Oct 10 18:46:37 1995
diff -u --recursive --new-file v1.3.36/linux/drivers/net/wd.c linux/drivers/net/wd.c
@@ -15,6 +15,11 @@
This is a driver for WD8003 and WD8013 "compatible" ethercards.
Thanks to Russ Nelson (nelson@crnwyr.com) for loaning me a WD8013.
+
+ Changelog:
+
+ Paul Gortmaker : multiple card support for module users
+
*/
static const char *version =
@@ -110,6 +115,7 @@
int ancient = 0; /* An old card without config registers. */
int word16 = 0; /* 0 = 8 bit, 1 = 16 bit */
const char *model_name;
+ static unsigned version_printed = 0;
for (i = 0; i < 8; i++)
checksum += inb(ioaddr + 8 + i);
@@ -121,6 +127,9 @@
if (dev == NULL)
dev = init_etherdev(0, sizeof(struct ei_device));
+ if (ei_debug && version_printed++ == 0)
+ printk(version);
+
printk("%s: WD80x3 at %#3x, ", dev->name, ioaddr);
for (i = 0; i < 6; i++)
printk(" %2.2X", dev->dev_addr[i] = inb(ioaddr + 8 + i));
@@ -257,8 +266,6 @@
printk(" %s, IRQ %d, shared memory at %#lx-%#lx.\n",
model_name, dev->irq, dev->mem_start, dev->mem_end-1);
- if (ei_debug > 0)
- printk(version);
ei_status.reset_8390 = &wd_reset_8390;
ei_status.block_input = &wd_block_input;
@@ -408,44 +415,61 @@
#ifdef MODULE
+#define MAX_WD_MODS 4 /* Max number of wd modules allowed */
+#define NAMELEN 9 /* # of chars for storing dev->name */
char kernel_version[] = UTS_RELEASE;
-static char devicename[9] = { 0, };
-static struct device dev_wd80x3 = {
- devicename, /* device name is inserted by linux/drivers/net/net_init.c */
- 0, 0, 0, 0,
- 0, 0,
- 0, 0, 0, NULL, wd_probe };
-
-int io = 0x300;
-int irq = 0;
-int mem = 0;
-
-int init_module(void)
+static char namelist[NAMELEN * MAX_WD_MODS] = { 0, };
+static struct device dev_wd80x3[MAX_WD_MODS] = {
+ {
+ NULL, /* assign a chunk of namelist[] below */
+ 0, 0, 0, 0,
+ 0, 0,
+ 0, 0, 0, NULL, NULL
+ },
+};
+
+static int io[MAX_WD_MODS] = { 0, };
+static int irq[MAX_WD_MODS] = { 0, };
+static int mem[MAX_WD_MODS] = { 0, };
+
+/* This is set up so that only a single autoprobe takes place per call.
+ISA device autoprobes on a running machine are not recommended. */
+int
+init_module(void)
{
- if (io == 0)
- printk("wd: You should not use auto-probing with insmod!\n");
- dev_wd80x3.base_addr = io;
- dev_wd80x3.irq = irq;
- dev_wd80x3.mem_start = mem;
- if (register_netdev(&dev_wd80x3) != 0)
- return -EIO;
+ int this_dev;
+
+ for (this_dev = 0; this_dev < MAX_WD_MODS; this_dev++) {
+ dev_wd80x3[this_dev].name = namelist+(NAMELEN*this_dev);
+ dev_wd80x3[this_dev].irq = irq[this_dev];
+ dev_wd80x3[this_dev].base_addr = io[this_dev];
+ dev_wd80x3[this_dev].mem_start = mem[this_dev];
+ dev_wd80x3[this_dev].init = wd_probe;
+ if (io[this_dev] == 0) {
+ if (this_dev != 0) break; /* only autoprobe 1st one */
+ printk(KERN_NOTICE "wd.c: Presently autoprobing (not recommended) for a single card.\n");
+ }
+ if (register_netdev(&dev_wd80x3[this_dev]) != 0) {
+ printk(KERN_WARNING "modules: No wd80x3 card found (i/o = 0x%x).\n", io[this_dev]);
+ return -EIO;
+ }
+ }
+
return 0;
}
void
cleanup_module(void)
{
- if (MOD_IN_USE)
- printk("wd80x3: device busy, remove delayed\n");
- else
- {
- int ioaddr = dev_wd80x3.base_addr - WD_NIC_OFFSET;
+ int this_dev;
- unregister_netdev(&dev_wd80x3);
-
- /* If we don't do this, we can't re-insmod it later. */
- free_irq(dev_wd80x3.irq);
- release_region(ioaddr, WD_IO_EXTENT);
+ for (this_dev = 0; this_dev < MAX_WD_MODS; this_dev++) {
+ if (dev_wd80x3[this_dev].priv != NULL) {
+ int ioaddr = dev_wd80x3[this_dev].base_addr - WD_NIC_OFFSET;
+ unregister_netdev(&dev_wd80x3[this_dev]);
+ free_irq(dev_wd80x3[this_dev].irq);
+ release_region(ioaddr, WD_IO_EXTENT);
+ }
}
}
#endif /* MODULE */
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov
with Sam's (original) version of this