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>