Date: Mon, 2 Dec 1996 13:31:28 +0900 (JST) From: Naoki Hamada <nao@sbl.cl.nec.co.jp> To: hackers@FreeBSD.ORG Subject: Etherlink 16 and Etherlink III ISA Message-ID: <199612020431.NAA20284@sirius.sbl.cl.nec.co.jp>
next in thread | raw e-mail | index | archive | help
Probing Etherlink 16 (3C507, if_ie) and Etherlink III ISA (3C509, if_ep) failes when there is some device at the I/O port 0x100. This is because the drivers can detect the board only through the port 0x100, though all the port 0x1x0 (0 =< x =< 0xf) can be an 'ID port'. So here is a patch, which actually solved the problem. -nao diff -ur sys-2.2-ALPHA/i386/isa/elink.c sys/i386/isa/elink.c --- sys-2.2-ALPHA/i386/isa/elink.c Tue May 30 17:01:36 1995 +++ sys/i386/isa/elink.c Mon Dec 2 13:05:26 1996 @@ -40,6 +40,30 @@ #include <i386/isa/elink.h> +static u_int elink_id_port; + +/* + * Set a valid id port address to 'elink_id_port' and return it. + * If none, return 0. + */ +u_int +elink_init() +{ + u_int i; + for (i = 0x100; i < 0x200; i += 0x10) { + outb(0, i); + outb(0xff, i); + if (inb(i) == 0xff) { + break; /* no device present */ + } + } + if (i == 0x200) { + return (0); + } + elink_id_port = i; + return (i); +} + /* * Issue a `global reset' to all cards. We have to be careful to do this only * once during autoconfig, to prevent resetting boards that have already been @@ -52,7 +76,7 @@ if (x == 0) { x = 1; - outb(ELINK_ID_PORT, ELINK_RESET); + outb(elink_id_port, ELINK_RESET); } } @@ -69,7 +93,7 @@ c = 0xff; for (i = 255; i; i--) { - outb(ELINK_ID_PORT, c); + outb(elink_id_port, c); if (c & 0x80) { c <<= 1; c ^= p; diff -ur sys-2.2-ALPHA/i386/isa/elink.h sys/i386/isa/elink.h --- sys-2.2-ALPHA/i386/isa/elink.h Thu Aug 25 07:32:42 1994 +++ sys/i386/isa/elink.h Mon Dec 2 13:02:24 1996 @@ -29,11 +29,11 @@ * $Id: elink.h,v 1.1 1994/08/24 22:32:42 ats Exp $ */ -#define ELINK_ID_PORT 0x100 #define ELINK_RESET 0xc0 #define ELINK_507_POLY 0xe7 #define ELINK_509_POLY 0xcf +u_int elink_init __P((void)); void elink_reset __P((void)); void elink_idseq __P((u_char p)); diff -ur sys-2.2-ALPHA/i386/isa/if_ep.c sys/i386/isa/if_ep.c --- sys-2.2-ALPHA/i386/isa/if_ep.c Sat Sep 7 08:07:33 1996 +++ sys/i386/isa/if_ep.c Mon Dec 2 13:03:40 1996 @@ -332,13 +332,20 @@ ep_look_for_board_at(is) struct isa_device *is; { - int data, i, j, id_port = ELINK_ID_PORT; + int data, i, j, io_base; + u_int id_port; int count = 0; if (ep_current_tag == (EP_LAST_TAG + 1)) { /* Come here just one time */ ep_current_tag--; + + id_port = elink_init(); + if (id_port == 0) { + printf("warning: no id port available for ep!\n"); + return (0); + } /* Look for the ISA boards. Init and leave them actived */ outb(id_port, 0); diff -ur sys-2.2-ALPHA/i386/isa/if_ie.c sys/i386/isa/if_ie.c --- sys-2.2-ALPHA/i386/isa/if_ie.c Sat Sep 7 08:07:36 1996 +++ sys/i386/isa/if_ie.c Mon Dec 2 13:02:25 1996 @@ -397,6 +397,7 @@ struct ie_softc *sc = &ie_softc[dvp->id_unit]; u_char c; int i; + u_int id_port; u_char signature[] = "*3COM*"; int unit = dvp->id_unit; @@ -409,11 +410,16 @@ sc->ie_chan_attn = el_chan_attn; /* Reset and put card in CONFIG state without changing address. */ + id_port = elink_init(); + if (id_port == 0) { + printf("ie%d: no id port available!\n", unit); + return 0; + } elink_reset(); - outb(ELINK_ID_PORT, 0x00); + outb(id_port, 0x00); elink_idseq(ELINK_507_POLY); elink_idseq(ELINK_507_POLY); - outb(ELINK_ID_PORT, 0xff); + outb(id_port, 0xff); c = inb(PORT + IE507_MADDR); if(c & 0x20) { @@ -424,9 +430,9 @@ } /* go to RUN state */ - outb(ELINK_ID_PORT, 0x00); + outb(id_port, 0x00); elink_idseq(ELINK_507_POLY); - outb(ELINK_ID_PORT, 0x00); + outb(id_port, 0x00); outb(PORT + IE507_CTRL, EL_CTRL_NRST);
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199612020431.NAA20284>