diff options
author | Theo de Raadt <deraadt@cvs.openbsd.org> | 1996-05-07 07:38:52 +0000 |
---|---|---|
committer | Theo de Raadt <deraadt@cvs.openbsd.org> | 1996-05-07 07:38:52 +0000 |
commit | a18dd829375e446ca22af98dc283f34da965edbc (patch) | |
tree | 0c5bbc9a1a0ce73f792bd62db356a18c8af92e32 /sys/dev/isa/elink.c | |
parent | c78ff01b45ca78d491b3e8db520c2cb877a273d4 (diff) |
sync with 0504 -- prototypes and bus.h
Diffstat (limited to 'sys/dev/isa/elink.c')
-rw-r--r-- | sys/dev/isa/elink.c | 76 |
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; |