summaryrefslogtreecommitdiff
path: root/sys/dev/isa/elink.c
diff options
context:
space:
mode:
authorTheo de Raadt <deraadt@cvs.openbsd.org>1996-05-07 07:38:52 +0000
committerTheo de Raadt <deraadt@cvs.openbsd.org>1996-05-07 07:38:52 +0000
commita18dd829375e446ca22af98dc283f34da965edbc (patch)
tree0c5bbc9a1a0ce73f792bd62db356a18c8af92e32 /sys/dev/isa/elink.c
parentc78ff01b45ca78d491b3e8db520c2cb877a273d4 (diff)
sync with 0504 -- prototypes and bus.h
Diffstat (limited to 'sys/dev/isa/elink.c')
-rw-r--r--sys/dev/isa/elink.c76
1 files changed, 63 insertions, 13 deletions
diff --git a/sys/dev/isa/elink.c b/sys/dev/isa/elink.c
index d33a000f21b..f97d1acff65 100644
--- a/sys/dev/isa/elink.c
+++ b/sys/dev/isa/elink.c
@@ -1,6 +1,7 @@
-/* $NetBSD: elink.c,v 1.7 1995/01/29 07:36:56 cgd Exp $ */
+/* $NetBSD: elink.c,v 1.9 1996/05/03 19:06:27 christos Exp $ */
/*
+ * Copyright (c) 1996 Jason R. Thorpe. All rights reserved.
* Copyright (c) 1994, 1995 Charles Hannum. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -33,34 +34,83 @@
* Common code for dealing with 3COM ethernet cards.
*/
-#include <sys/types.h>
-#include <machine/pio.h>
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/malloc.h>
+#include <sys/queue.h>
+
+#include <machine/bus.h>
+
#include <dev/isa/elink.h>
/*
+ * This list keeps track of which ISAs have gotten an elink_reset().
+ */
+struct elink_done_reset {
+ LIST_ENTRY(elink_done_reset) er_link;
+ int er_bus;
+};
+static LIST_HEAD(, elink_done_reset) elink_all_resets;
+static int elink_all_resets_initialized;
+
+/*
* Issue a `global reset' to all cards, and reset the ID state machines. We
* have to be careful to do the global reset only once during autoconfig, to
* prevent resetting boards that have already been configured.
+ *
+ * The "bus" argument here is the unit number of the ISA bus, e.g. "0"
+ * if the bus is "isa0".
+ *
+ * NOTE: the caller MUST provide an i/o handle for ELINK_ID_PORT!
*/
void
-elink_reset()
-{
- static int x = 0;
+elink_reset(bc, ioh, bus)
+ bus_chipset_tag_t bc;
+ bus_io_handle_t ioh;
+ int bus;
+{
+ struct elink_done_reset *er;
- if (x == 0) {
- x = 1;
- outb(ELINK_ID_PORT, ELINK_RESET);
+ if (elink_all_resets_initialized == 0) {
+ LIST_INIT(&elink_all_resets);
+ elink_all_resets_initialized = 1;
}
- outb(ELINK_ID_PORT, 0x00);
- outb(ELINK_ID_PORT, 0x00);
+
+ /*
+ * Reset these cards if we haven't done so already.
+ */
+ for (er = elink_all_resets.lh_first; er != NULL;
+ er = er->er_link.le_next)
+ if (er->er_bus == bus)
+ goto out;
+
+ /* Mark this bus so we don't do it again. */
+ er = (struct elink_done_reset *)malloc(sizeof(struct elink_done_reset),
+ M_DEVBUF, M_NOWAIT);
+ if (er == NULL)
+ panic("elink_reset: can't allocate state storage");
+
+ er->er_bus = bus;
+ LIST_INSERT_HEAD(&elink_all_resets, er, er_link);
+
+ /* Haven't reset the cards on this bus, yet. */
+ bus_io_write_1(bc, ioh, 0, ELINK_RESET);
+
+ out:
+ bus_io_write_1(bc, ioh, 0, 0x00);
+ bus_io_write_1(bc, ioh, 0, 0x00);
}
/*
* The `ID sequence' is really just snapshots of an 8-bit CRC register as 0
* bits are shifted in. Different board types use different polynomials.
+ *
+ * NOTE: the caller MUST provide an i/o handle for ELINK_ID_PORT!
*/
void
-elink_idseq(p)
+elink_idseq(bc, ioh, p)
+ bus_chipset_tag_t bc;
+ bus_io_handle_t ioh;
register u_char p;
{
register int i;
@@ -68,7 +118,7 @@ elink_idseq(p)
c = 0xff;
for (i = 255; i; i--) {
- outb(ELINK_ID_PORT, c);
+ bus_io_write_1(bc, ioh, 0, c);
if (c & 0x80) {
c <<= 1;
c ^= p;