Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 9 Oct 1996 13:26:51 +0900 (JST)
From:      Naoki Hamada <nao@sbl.cl.nec.co.jp>
To:        imb@asstdc.com.au
Cc:        current@freebsd.org
Subject:   3c589b + ep driver
Message-ID:  <199610090426.NAA20434@sirius.sbl.cl.nec.co.jp>

next in thread | raw e-mail | index | archive | help
michael wrote:
>The following patch seems to work for me .. I'd appreciate comments from
>others whether it helps or not. Note that I am not in favour of adding more
>loops which cannot be guaranteed to terminate so this patch is experimental
>only,

I found that the ep driver does not properly handle commands which
take time more than a I/O cycle. What about the following patch? (This 
patch is 961006-SNAP based. Still applicable to the current, I hope.)

-nao

diff -ur ep.orig/if_ep.c ep/if_ep.c
--- ep.orig/if_ep.c	Wed Oct  9 13:04:24 1996
+++ ep/if_ep.c	Wed Oct  9 13:02:07 1996
@@ -728,7 +728,6 @@
 	*/
 
     s = splimp();
-    while (inw(BASE + EP_STATUS) & S_COMMAND_IN_PROGRESS);
 
     GO_WINDOW(0);
     outw(BASE + EP_COMMAND, STOP_TRANSCEIVER);
@@ -749,7 +748,9 @@
 	outb(BASE + EP_W2_ADDR_0 + i, sc->arpcom.ac_enaddr[i]);
 
     outw(BASE + EP_COMMAND, RX_RESET);
+    EP_BUSY_WAIT;
     outw(BASE + EP_COMMAND, TX_RESET);
+    EP_BUSY_WAIT;
 
     /* Window 1 is operating window */
     GO_WINDOW(1);
@@ -1082,6 +1083,7 @@
 		if (status & TXS_SUCCES_INTR_REQ);
 		else if (status & (TXS_UNDERRUN | TXS_JABBER | TXS_MAX_COLLISION)) {
 		    outw(BASE + EP_COMMAND, TX_RESET);
+		    EP_BUSY_WAIT;
 		    if (status & TXS_UNDERRUN) {
 			if (sc->tx_rate > 1) {
 			    sc->tx_rate--;	/* Actually in steps of 1/64 */
@@ -1289,6 +1291,7 @@
     }
 all_pkt:
     outw(BASE + EP_COMMAND, RX_DISCARD_TOP_PACK);
+    EP_BUSY_WAIT;
     /*
      * recompute average packet's length, the factor used is 1/8 to go down
      * and 1/32 to go up
@@ -1333,7 +1336,6 @@
 #ifdef EP_LOCAL_STATS
 	    sc->rx_bpf_disc++;
 #endif
-	    while (inw(BASE + EP_STATUS) & S_COMMAND_IN_PROGRESS);
 	    outw(BASE + EP_COMMAND, SET_RX_EARLY_THRESH | delta);
 	    return;
 	}
@@ -1346,12 +1348,12 @@
     if (!sc->mb[sc->next_mb])
 	epmbuffill((caddr_t) sc, 0);
     sc->top = 0;
-    while (inw(BASE + EP_STATUS) & S_COMMAND_IN_PROGRESS);
     outw(BASE + EP_COMMAND, SET_RX_EARLY_THRESH | delta);
     return;
 
 out:
     outw(BASE + EP_COMMAND, RX_DISCARD_TOP_PACK);
+    EP_BUSY_WAIT;
     if (sc->top) {
 	m_freem(sc->top);
 	sc->top = 0;
@@ -1364,7 +1366,6 @@
 	delta = MIN_RX_EARLY_THRESHF;
     ep_fset(F_RX_FIRST);
     ep_frst(F_RX_TRAILER);
-    while (inw(BASE + EP_STATUS) & S_COMMAND_IN_PROGRESS);
     outw(BASE + EP_COMMAND, SET_RX_EARLY_THRESH |
 	 (sc->rx_early_thresh = delta));
 }
@@ -1529,11 +1530,13 @@
 
     outw(BASE + EP_COMMAND, RX_DISABLE);
     outw(BASE + EP_COMMAND, RX_DISCARD_TOP_PACK);
-    while (inw(BASE + EP_STATUS) & S_COMMAND_IN_PROGRESS);
+    EP_BUSY_WAIT;
     outw(BASE + EP_COMMAND, TX_DISABLE);
     outw(BASE + EP_COMMAND, STOP_TRANSCEIVER);
     outw(BASE + EP_COMMAND, RX_RESET);
+    EP_BUSY_WAIT;
     outw(BASE + EP_COMMAND, TX_RESET);
+    EP_BUSY_WAIT;
     outw(BASE + EP_COMMAND, C_INTR_LATCH);
     outw(BASE + EP_COMMAND, SET_RD_0_MASK);
     outw(BASE + EP_COMMAND, SET_INTR_MASK);
diff -ur ep.orig/if_epreg.h ep/if_epreg.h
--- ep.orig/if_epreg.h	Wed Oct  9 13:04:24 1996
+++ ep/if_epreg.h	Wed Oct  9 10:10:53 1996
@@ -142,6 +142,7 @@
  */
 #define is_eeprom_busy(b) (inw((b)+EP_W0_EEPROM_COMMAND)&EEPROM_BUSY)
 #define GO_WINDOW(x)      outw(BASE+EP_COMMAND, WINDOW_SELECT|(x))
+#define EP_BUSY_WAIT	while (inw(BASE + EP_STATUS) & S_COMMAND_IN_PROGRESS);
 
 /**************************************************************************
  *									  *



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199610090426.NAA20434>