From 91b4a6d40112cf7c6838e436ebe8516912adb8a2 Mon Sep 17 00:00:00 2001 From: thorpej Date: Tue, 30 Apr 1996 22:16:27 +0000 Subject: [PATCH] Adapt the elink_reset() and elink_idseq() routines for . In elink_reset(), since some machines may have more than one ISA bus, implement a way of keeping track of which ISA bus has received an elink_reset(); The static variable which was used previously didn't scale. --- sys/dev/isa/elink.c | 75 +++++++++++++++++++++++++++++++++++++-------- sys/dev/isa/elink.h | 6 ++-- 2 files changed, 65 insertions(+), 16 deletions(-) diff --git a/sys/dev/isa/elink.c b/sys/dev/isa/elink.c index d33a000f21b6..bed475d1b36d 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.8 1996/04/30 22:16:27 thorpej 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,82 @@ * Common code for dealing with 3COM ethernet cards. */ -#include -#include +#include +#include +#include + +#include + #include +/* + * 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 +117,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; diff --git a/sys/dev/isa/elink.h b/sys/dev/isa/elink.h index c2af300887e9..e4934ef09d07 100644 --- a/sys/dev/isa/elink.h +++ b/sys/dev/isa/elink.h @@ -1,4 +1,4 @@ -/* $NetBSD: elink.h,v 1.3 1994/10/27 04:17:11 cgd Exp $ */ +/* $NetBSD: elink.h,v 1.4 1996/04/30 22:16:31 thorpej Exp $ */ /* * Copyright (c) 1994 Charles Hannum. All rights reserved. @@ -35,5 +35,5 @@ #define ELINK_507_POLY 0xe7 #define ELINK_509_POLY 0xcf -void elink_reset __P((void)); -void elink_idseq __P((u_char p)); +void elink_reset __P((bus_chipset_tag_t, bus_io_handle_t, int)); +void elink_idseq __P((bus_chipset_tag_t, bus_io_handle_t, u_char p));