Skip site navigation (1)Skip section navigation (2)
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>