patch-1.3.42 linux/drivers/net/hp.c
Next file: linux/drivers/net/ne.c
Previous file: linux/drivers/net/hp-plus.c
Back to the patch index
Back to the overall index
- Lines: 176
- Date:
Tue Nov 14 07:48:52 1995
- Orig file:
v1.3.41/linux/drivers/net/hp.c
- Orig date:
Thu Nov 9 11:23:49 1995
diff -u --recursive --new-file v1.3.41/linux/drivers/net/hp.c linux/drivers/net/hp.c
@@ -57,6 +57,8 @@
int hp_probe(struct device *dev);
int hp_probe1(struct device *dev, int ioaddr);
+static int hp_open(struct device *dev);
+static int hp_close(struct device *dev);
static void hp_reset_8390(struct device *dev);
static void hp_get_8390_hdr(struct device *dev, struct e8390_pkt_hdr *hdr,
int ring_page);
@@ -106,6 +108,7 @@
{
int i, board_id, wordmode;
const char *name;
+ static unsigned version_printed = 0;
/* Check for the HP physical address, 08 00 09 xx xx xx. */
/* This really isn't good enough: we may pick up HP LANCE boards
@@ -126,9 +129,15 @@
wordmode = 0;
}
- 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("hp.c: Passed a NULL device.\n");
+ dev = init_etherdev(0, 0);
+ }
+ if (ei_debug && version_printed++ == 0)
+ printk(version);
+
printk("%s: %s (ID %02x) at %#3x,", dev->name, name, board_id, ioaddr);
for(i = 0; i < ETHER_ADDR_LEN; i++)
@@ -167,16 +176,20 @@
}
}
+ /* 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;
+ }
+
/* Grab the region so we can find another board if something fails. */
request_region(ioaddr, HP_IO_EXTENT,"hp");
- if (ei_debug > 1)
- printk(version);
-
/* Set the base address to point to the NIC, not the "real" base! */
dev->base_addr = ioaddr + NIC_OFFSET;
-
- ethdev_init(dev);
+ dev->open = &hp_open;
+ dev->stop = &hp_close;
ei_status.name = name;
ei_status.word16 = wordmode;
@@ -193,6 +206,22 @@
return 0;
}
+static int
+hp_open(struct device *dev)
+{
+ ei_open(dev);
+ MOD_INC_USE_COUNT;
+ return 0;
+}
+
+static int
+hp_close(struct device *dev)
+{
+ ei_close(dev);
+ MOD_DEC_USE_COUNT;
+ return 0;
+}
+
static void
hp_reset_8390(struct device *dev)
{
@@ -348,39 +377,66 @@
}
#ifdef MODULE
-static char devicename[9] = { 0, };
-static struct device dev_hp = {
- devicename, /* device name is inserted by linux/drivers/net/net_init.c */
- 0, 0, 0, 0,
- 0, 0,
- 0, 0, 0, NULL, hp_probe };
-
-static int io = 300;
-static int irq = 0;
-
-int init_module(void)
-{
- if (io == 0)
- printk("hp: You should not use auto-probing with insmod!\n");
- dev_hp.base_addr = io;
- dev_hp.irq = irq;
- if (register_netdev(&dev_hp) != 0) {
- printk("hp: register_netdev() returned non-zero.\n");
- return -EIO;
+#define MAX_HP_CARDS 4 /* Max number of HP cards per module */
+#define NAMELEN 8 /* # of chars for storing dev->name */
+static char namelist[NAMELEN * MAX_HP_CARDS] = { 0, };
+static struct device dev_hp[MAX_HP_CARDS] = {
+ {
+ NULL, /* assign a chunk of namelist[] below */
+ 0, 0, 0, 0,
+ 0, 0,
+ 0, 0, 0, NULL, NULL
+ },
+};
+
+static int io[MAX_HP_CARDS] = { 0, };
+static int irq[MAX_HP_CARDS] = { 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)
+{
+ int this_dev, found = 0;
+
+ for (this_dev = 0; this_dev < MAX_HP_CARDS; this_dev++) {
+ struct device *dev = &dev_hp[this_dev];
+ dev->name = namelist+(NAMELEN*this_dev);
+ dev->irq = irq[this_dev];
+ dev->base_addr = io[this_dev];
+ dev->init = hp_probe;
+ if (io[this_dev] == 0) {
+ if (this_dev != 0) break; /* only autoprobe 1st one */
+ printk(KERN_NOTICE "hp.c: Presently autoprobing (not recommended) for a single card.\n");
+ }
+ if (register_netdev(dev) != 0) {
+ printk(KERN_WARNING "hp.c: No HP 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)
{
- int ioaddr = dev_hp.base_addr - NIC_OFFSET;
-
- unregister_netdev(&dev_hp);
+ int this_dev;
- /* If we don't do this, we can't re-insmod it later. */
- free_irq(dev_hp.irq);
- release_region(ioaddr, HP_IO_EXTENT);
+ for (this_dev = 0; this_dev < MAX_HP_CARDS; this_dev++) {
+ struct device *dev = &dev_hp[this_dev];
+ if (dev->priv != NULL) {
+ int ioaddr = dev->base_addr - NIC_OFFSET;
+ kfree(dev->priv);
+ dev->priv = NULL;
+ free_irq(dev->irq);
+ irq2dev_map[dev->irq] = NULL;
+ release_region(ioaddr, HP_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