Please test: modularized pcnet32 driver

Adam J. Richter (adam@yggdrasil.com)
Thu, 28 May 1998 18:40:01 -0700


I have attached below a patch that modularizes the pcnet32
ethernet driver. It is a patch against 2.1.104pre1, but should patch
with a few lines offset against 2.1.103. I would appreciate it if
somebody would give this a whirl and let me know if it works. I
know that the modularized driver builds against my 2.1.104pre1,
and successfully reports that I do not have a pcnet32 so it is
(correctly) refusing to load. This version does not have any
command line parameters, so your card must be a pcnet32 that
is detected by the automatic probes that it does.

Anyhow, please let me know if you try this on a machine
that does have a pcnet32 card in it.

Adam J. Richter __ ______________ 4880 Stevens Creek Blvd, Suite 205
adam@yggdrasil.com \ / San Jose, California 95129-1034
+1 408 261-6630 | g g d r a s i l United States of America
fax +1 408 261-6631 "Free Software For The Rest Of Us."
----------------------------CUT HERE-------------------------------
--- /tmp/linux-2.1.104pre1/drivers/net/Config.in Thu May 28 18:34:42 1998
+++ linux/drivers/net/Config.in Thu May 28 17:16:10 1998
@@ -94,7 +94,7 @@
fi
bool 'EISA, VLB, PCI and on board controllers' CONFIG_NET_EISA
if [ "$CONFIG_NET_EISA" = "y" ]; then
- bool 'AMD PCnet32 (VLB and PCI) support' CONFIG_PCNET32
+ tristate 'AMD PCnet32 (VLB and PCI) support' CONFIG_PCNET32
if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
tristate 'Ansel Communications EISA 3200 support (EXPERIMENTAL)' CONFIG_AC3200
fi
--- /tmp/linux-2.1.104pre1/drivers/net/Makefile Thu May 14 10:35:55 1998
+++ linux/drivers/net/Makefile Thu May 28 18:01:25 1998
@@ -305,6 +305,10 @@

ifeq ($(CONFIG_PCNET32),y)
L_OBJS += pcnet32.o
+else
+ ifeq ($(CONFIG_PCNET32),m)
+ M_OBJS += pcnet32.o
+endif
endif

ifeq ($(CONFIG_DEFXX),y)
--- /tmp/linux-2.1.104pre1/drivers/net/pcnet32.c Thu Apr 2 09:12:24 1998
+++ linux/drivers/net/pcnet32.c Thu May 28 18:25:34 1998
@@ -15,6 +15,7 @@

static const char *version = "pcnet32.c:v0.23 8.2.97 tsbogend@alpha.franken.de\n";

+#include <linux/module.h>
#include <linux/config.h>
#include <linux/kernel.h>
#include <linux/sched.h>
@@ -152,7 +153,10 @@
struct net_device_stats stats;
char tx_full;
unsigned long lock;
- char shared_irq; /* shared irq possible */
+ char shared_irq; /* shared irq possible */
+#ifdef MODULE
+ struct device *next_dev;
+#endif /* MODULE */
};

int pcnet32_probe(struct device *dev);
@@ -166,6 +170,11 @@
static struct net_device_stats *pcnet32_get_stats(struct device *dev);
static void pcnet32_set_multicast_list(struct device *dev);

+#ifdef MODULE
+/* For now, we allow only one device. */
+static struct device *pcnet32_dev = NULL;
+#endif /* MODULE */
+


__initfunc(int pcnet32_probe (struct device *dev))
@@ -283,8 +292,10 @@

/* We should have a "dev" from Space.c or the static module table. */
if (dev == NULL) {
- printk(KERN_ERR "pcnet32.c: Passed a NULL device.\n");
- dev = init_etherdev(0, 0);
+#ifndef MODULE
+ printk(KERN_ERR "pcnet32.c: Passed a NULL device.\n");
+#endif
+ dev = init_etherdev(0, 0);
}

printk("%s: %s at %#3x,", dev->name, chipname, ioaddr);
@@ -349,11 +360,15 @@
if (dev->irq)
printk(", probed IRQ %d.\n", dev->irq);
else {
- printk(", failed to detect IRQ line.\n");
+ printk(", failed to detect IRQ line.\n"); /* FIXME: Deallocate allocated memory? */
return ENODEV;
}
}

+#ifdef MODULE
+ lp->next_dev = pcnet32_dev;
+ pcnet32_dev = dev;
+#endif
outw(0x0002, ioaddr+PCNET32_ADDR);
/* only touch autoselect bit */
outw(inw(ioaddr+PCNET32_BUS_IF) | 0x0002, ioaddr+PCNET32_BUS_IF);
@@ -902,6 +917,31 @@

}

+#ifdef MODULE
+/* Parameter that may be passed into the module. */
+static int debug = -1;
+static int irq[] = {-1, -1, -1, -1, -1, -1, -1, -1};
+
+int
+init_module(void)
+{
+ return pcnet32_probe(0) == 0 ? 0 : -ENODEV;
+}
+
+void
+cleanup_module(void)
+{
+ while (pcnet32_dev) {
+ struct device *next_dev = ((struct pcnet32_private *)pcnet32_dev->priv)->next_dev;
+ unregister_netdev(pcnet32_dev);
+ free_irq(pcnet32_dev->irq, pcnet32_dev);
+ release_region(pcnet32_dev->base_addr, PCNET32_TOTAL_SIZE);
+ kfree(pcnet32_dev->priv);
+ kfree(pcnet32_dev);
+ pcnet32_dev = next_dev;
+ }
+}
+#endif /* MODULE */

/*
* Local variables:

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu