Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 19 Nov 2001 22:14:07 -0700
From:      Warner Losh <imp@harmony.village.org>
To:        YAMAMOTO Shigeru <shigeru@iij.ad.jp>, freebsd-mobile@FreeBSD.ORG
Cc:        Ian Dowse <iedowse@FreeBSD.ORG>
Subject:   Re: 2 patches for NEWCARD 
Message-ID:  <200111200514.fAK5E7780325@harmony.village.org>
In-Reply-To: Your message of "Mon, 19 Nov 2001 21:54:37 MST." <200111200454.fAK4sb780192@harmony.village.org> 
References:  <200111200454.fAK4sb780192@harmony.village.org>  <20011119.171129.72757009.shigeru@iij.ad.jp> 

next in thread | previous in thread | raw e-mail | index | archive | help
: : other is to ignore ghost interrupt at ed driver when removing PC Card.
: 
: This looks good.  I'll commit it.

Actually, it looks like a little more protection is needed for an edge
case.  The loop to reset the isr bits on the AX88190 needs to be
bounded, or we run the risk of locking up there.  What do you think of
the following patch instead?

Warner

Index: if_ed.c
===================================================================
RCS file: /home/imp/FreeBSD/CVS/src/sys/dev/ed/if_ed.c,v
retrieving revision 1.206
diff -u -r1.206 if_ed.c
--- if_ed.c	2001/11/04 22:56:20	1.206
+++ if_ed.c	2001/11/20 05:05:23
@@ -2285,6 +2285,7 @@
 	struct ed_softc *sc = (struct ed_softc*) arg;
 	struct ifnet *ifp = (struct ifnet *)sc;
 	u_char  isr;
+	int	count;
 
 	if (sc->gone)
 		return;
@@ -2294,9 +2295,12 @@
 	ed_nic_outb(sc, ED_P0_CR, sc->cr_proto | ED_CR_STA);
 
 	/*
-	 * loop until there are no more new interrupts
+	 * loop until there are no more new interrupts.  When the card
+	 * goes away, the hardware will read back 0xff.  Looking at
+	 * the interrupts, it would appear that 0xff is impossible,
+	 * or at least extremely unlikely.
 	 */
-	while ((isr = ed_nic_inb(sc, ED_P0_ISR)) != 0) {
+	while ((isr = ed_nic_inb(sc, ED_P0_ISR)) != 0 && isr != 0xff) {
 
 		/*
 		 * reset all the bits that we are 'acknowledging' by writing a
@@ -2305,12 +2309,21 @@
 		 */
 		ed_nic_outb(sc, ED_P0_ISR, isr);
 
-		/* XXX workaround for AX88190 */
+		/* 
+		 * XXX workaround for AX88190
+		 * We limit this to 5000 iterations.  At 1us per inb/outb,
+		 * this translates to about 15ms, which should be plenty
+		 * of time, and also gives protection in the card eject
+		 * case.
+		 */
 		if (sc->chip_type == ED_CHIP_TYPE_AX88190) {
-			while (ed_nic_inb(sc, ED_P0_ISR) & isr) {
+			count = 5000;		/* 15ms */
+			while (count-- && (ed_nic_inb(sc, ED_P0_ISR) & isr)) {
 				ed_nic_outb(sc, ED_P0_ISR,0);
 				ed_nic_outb(sc, ED_P0_ISR,isr);
 			}
+			if (count == 0)
+				break;
 		}
 
 		/*

To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-mobile" in the body of the message




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