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>
index | next in thread | raw e-mail
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);
help
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199612020431.NAA20284>
