Adapt the elink_reset() and elink_idseq() routines for <machine/bus.h>.

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.
This commit is contained in:
thorpej 1996-04-30 22:16:27 +00:00
parent a787e8f99b
commit 91b4a6d401
2 changed files with 65 additions and 16 deletions

View File

@ -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 <sys/types.h>
#include <machine/pio.h>
#include <sys/param.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()
elink_reset(bc, ioh, bus)
bus_chipset_tag_t bc;
bus_io_handle_t ioh;
int bus;
{
static int x = 0;
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;

View File

@ -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));