patch-1.3.42 linux/drivers/net/ne.c
Next file: linux/drivers/net/net_init.c
Previous file: linux/drivers/net/hp.c
Back to the patch index
Back to the overall index
- Lines: 252
- Date:
Tue Nov 14 07:48:52 1995
- Orig file:
v1.3.41/linux/drivers/net/ne.c
- Orig date:
Thu Nov 9 11:23:49 1995
diff -u --recursive --new-file v1.3.41/linux/drivers/net/ne.c linux/drivers/net/ne.c
@@ -21,6 +21,7 @@
Paul Gortmaker : use ENISR_RDC to monitor Tx PIO uploads, made
sanity checks and bad clone support optional.
Paul Gortmaker : new reset code, reset card after probe at boot.
+ Paul Gortmaker : multiple card support for module users.
*/
@@ -53,6 +54,9 @@
/* Do we implement the read before write bugfix ? */
/* #define NE_RW_BUGFIX */
+/* Do we have a non std. amount of memory? (in units of 256 byte pages) */
+/* #define PACKETBUF_MEMSIZE 0x40 */
+
/* ---- No user-serviceable parts below ---- */
/* A zero-terminated list of I/O addresses to be probed. */
@@ -89,6 +93,9 @@
int ne_probe(struct device *dev);
static int ne_probe1(struct device *dev, int ioaddr);
+static int ne_open(struct device *dev);
+static int ne_close(struct device *dev);
+
static void ne_reset_8390(struct device *dev);
static void ne_get_8390_hdr(struct device *dev, struct e8390_pkt_hdr *hdr,
int ring_page);
@@ -155,6 +162,7 @@
int start_page, stop_page;
int neX000, ctron;
int reg0 = inb_p(ioaddr);
+ static unsigned version_printed = 0;
if (reg0 == 0xFF)
return ENODEV;
@@ -173,6 +181,9 @@
}
}
+ if (ei_debug && version_printed++ == 0)
+ printk(version);
+
printk("NE*000 ethercard probe at %#3x:", ioaddr);
/* Reset card. Who knows what dain-bramaged state it was left in. */
@@ -236,11 +247,6 @@
stop_page = NE1SM_STOP_PG;
}
- for(i = 0; i < ETHER_ADDR_LEN; i++) {
- dev->dev_addr[i] = SA_prom[i];
- printk(" %2.2x", SA_prom[i]);
- }
-
neX000 = (SA_prom[14] == 0x57 && SA_prom[15] == 0x57);
ctron = (SA_prom[0] == 0x00 && SA_prom[1] == 0x00 && SA_prom[2] == 0x1d);
@@ -248,7 +254,7 @@
if (neX000) {
name = (wordlength == 2) ? "NE2000" : "NE1000";
} else if (ctron) {
- name = "Cabletron";
+ name = (wordlength == 2) ? "Ctron-8" : "Ctron-16";
start_page = 0x01;
stop_page = (wordlength == 2) ? 0x40 : 0x20;
} else {
@@ -279,9 +285,11 @@
}
-
- if (dev == NULL)
- dev = init_etherdev(0, sizeof(struct ei_device));
+ /* We should have a "dev" from Space.c or the static module table. */
+ if (dev == NULL) {
+ printk("ne.c: Passed a NULL device.\n");
+ dev = init_etherdev(0, 0);
+ }
if (dev->irq < 2) {
autoirq_setup(0);
@@ -297,11 +305,16 @@
/* Fixup for users that don't know that IRQ 2 is really IRQ 9,
or don't know which one to set. */
dev->irq = 9;
+
+ if (! dev->irq) {
+ printk(" failed to detect IRQ line.\n");
+ return EAGAIN;
+ }
/* Snarf the interrupt now. There's no point in waiting since we cannot
share and the board will usually be enabled. */
{
- int irqval = request_irq (dev->irq, ei_interrupt, 0, wordlength==2 ? "ne2000":"ne1000");
+ int irqval = request_irq(dev->irq, ei_interrupt, 0, name);
if (irqval) {
printk (" unable to get IRQ %d (irqval=%d).\n", dev->irq, irqval);
return EAGAIN;
@@ -310,18 +323,23 @@
dev->base_addr = ioaddr;
- request_region(ioaddr, NE_IO_EXTENT, wordlength==2 ? "ne2000":"ne1000");
+ /* Allocate dev->priv and fill in 8390 specific dev fields. */
+ if (ethdev_init(dev)) {
+ printk (" unable to get memory for dev->priv.\n");
+ free_irq(dev->irq);
+ return -ENOMEM;
+ }
+
+ request_region(ioaddr, NE_IO_EXTENT, name);
- for(i = 0; i < ETHER_ADDR_LEN; i++)
+ for(i = 0; i < ETHER_ADDR_LEN; i++) {
+ printk(" %2.2x", SA_prom[i]);
dev->dev_addr[i] = SA_prom[i];
+ }
- ethdev_init(dev);
printk("\n%s: %s found at %#x, using IRQ %d.\n",
dev->name, name, ioaddr, dev->irq);
- if (ei_debug > 0)
- printk(version);
-
ei_status.name = name;
ei_status.tx_start_page = start_page;
ei_status.stop_page = stop_page;
@@ -337,10 +355,30 @@
ei_status.block_input = &ne_block_input;
ei_status.block_output = &ne_block_output;
ei_status.get_8390_hdr = &ne_get_8390_hdr;
+ dev->open = &ne_open;
+ dev->stop = &ne_close;
NS8390_init(dev, 0);
return 0;
}
+static int
+ne_open(struct device *dev)
+{
+ ei_open(dev);
+ MOD_INC_USE_COUNT;
+ return 0;
+}
+
+static int
+ne_close(struct device *dev)
+{
+ if (ei_debug > 1)
+ printk("%s: Shutting down ethercard.\n", dev->name);
+ ei_close(dev);
+ MOD_DEC_USE_COUNT;
+ return 0;
+}
+
/* Hard reset the card. This used to pause for the same period that a
8390 reset command required, but that shouldn't be necessary. */
static void
@@ -568,36 +606,71 @@
return;
}
+
#ifdef MODULE
-static char devicename[9] = { 0, };
-static struct device dev_ne2000 = {
- devicename, /* device name is inserted by linux/drivers/net/net_init.c */
- 0, 0, 0, 0,
- 0, 0,
- 0, 0, 0, NULL, ne_probe };
+#define MAX_NE_CARDS 4 /* Max number of NE cards per module */
+#define NAMELEN 8 /* # of chars for storing dev->name */
+static char namelist[NAMELEN * MAX_NE_CARDS] = { 0, };
+static struct device dev_ne[MAX_NE_CARDS] = {
+ {
+ NULL, /* assign a chunk of namelist[] below */
+ 0, 0, 0, 0,
+ 0, 0,
+ 0, 0, 0, NULL, NULL
+ },
+};
+
+static int io[MAX_NE_CARDS] = { 0, };
+static int irq[MAX_NE_CARDS] = { 0, };
-static int io = 0x300;
-static int irq = 0;
+/* This is set up so that no autoprobe takes place. We can't guarantee
+that the ne2k probe is the last 8390 based probe to take place (as it
+is at boot) and so the probe will get confused by any other 8390 cards.
+ISA device autoprobes on a running machine are not recommended anyway. */
-int init_module(void)
+int
+init_module(void)
{
- if (io == 0)
- printk("ne: You should not use auto-probing with insmod!\n");
- dev_ne2000.base_addr = io;
- dev_ne2000.irq = irq;
- if (register_netdev(&dev_ne2000) != 0)
- return -EIO;
+ int this_dev, found = 0;
+
+ for (this_dev = 0; this_dev < MAX_NE_CARDS; this_dev++) {
+ struct device *dev = &dev_ne[this_dev];
+ dev->name = namelist+(NAMELEN*this_dev);
+ dev->irq = irq[this_dev];
+ dev->base_addr = io[this_dev];
+ dev->init = ne_probe;
+ if (io[this_dev] == 0) {
+ if (this_dev != 0) break; /* only complain once */
+ printk(KERN_NOTICE "ne.c: Module autoprobing not allowed. Append \"io=0xNNN\" value(s).\n");
+ return -EPERM;
+ }
+ if (register_netdev(dev) != 0) {
+ printk(KERN_WARNING "ne.c: No NE*000 card found (i/o = 0x%x).\n", io[this_dev]);
+ if (found != 0) return 0; /* Got at least one. */
+ return -ENXIO;
+ }
+ found++;
+ }
+
return 0;
}
void
cleanup_module(void)
{
- unregister_netdev(&dev_ne2000);
+ int this_dev;
- /* If we don't do this, we can't re-insmod it later. */
- free_irq(dev_ne2000.irq);
- release_region(dev_ne2000.base_addr, NE_IO_EXTENT);
+ for (this_dev = 0; this_dev < MAX_NE_CARDS; this_dev++) {
+ struct device *dev = &dev_ne[this_dev];
+ if (dev->priv != NULL) {
+ kfree(dev->priv);
+ dev->priv = NULL;
+ free_irq(dev->irq);
+ irq2dev_map[dev->irq] = NULL;
+ release_region(dev->base_addr, NE_IO_EXTENT);
+ unregister_netdev(dev);
+ }
+ }
}
#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