From owner-freebsd-current Tue Oct 8 21:28:48 1996 Return-Path: owner-current Received: (from root@localhost) by freefall.freebsd.org (8.7.5/8.7.3) id VAA04095 for current-outgoing; Tue, 8 Oct 1996 21:28:48 -0700 (PDT) Received: from research.gate.nec.co.jp (research.gate.nec.co.jp [202.32.8.49]) by freefall.freebsd.org (8.7.5/8.7.3) with ESMTP id VAA04090 for ; Tue, 8 Oct 1996 21:28:44 -0700 (PDT) Received: from sbl-gw.sbl.cl.nec.co.jp by research.gate.nec.co.jp (8.7.6+2.6Wbeta7/950912) with ESMTP id NAA18758; Wed, 9 Oct 1996 13:27:07 +0900 (JST) Received: from sirius.sbl.cl.nec.co.jp by sbl-gw.sbl.cl.nec.co.jp (8.7.6+2.6Wbeta7/3.3W6) with ESMTP id NAA03859; Wed, 9 Oct 1996 13:26:51 +0900 (JST) Received: by sirius.sbl.cl.nec.co.jp (8.7.5+2.6Wbeta6/3.3W6) with UUCP id NAA20434; Wed, 9 Oct 1996 13:26:51 +0900 (JST) Date: Wed, 9 Oct 1996 13:26:51 +0900 (JST) From: Naoki Hamada Message-Id: <199610090426.NAA20434@sirius.sbl.cl.nec.co.jp> To: imb@asstdc.com.au CC: current@freebsd.org Subject: 3c589b + ep driver Sender: owner-current@freebsd.org X-Loop: FreeBSD.org Precedence: bulk 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); /************************************************************************** * *