diff options
author | Niklas Hallqvist <niklas@cvs.openbsd.org> | 2001-03-19 20:13:45 +0000 |
---|---|---|
committer | Niklas Hallqvist <niklas@cvs.openbsd.org> | 2001-03-19 20:13:45 +0000 |
commit | 44386d4a80b5c66ce4025d5eea2efc0c9517b513 (patch) | |
tree | e940edf44cac4791aaac99ea5442fd9fceb7a542 | |
parent | d9b6a0a4699a337f8fba16b5eb2e6721765f5b53 (diff) |
Sniffed glue. Reinstate Mickey's time-bound loops but fix
the race in wi_inquire that made them stall machines for up to 500ms.
Also lower the maximum wait-time for commands to 50ms, and check for
actually timed out commands in wi_inquire.
-rw-r--r-- | sys/dev/pcmcia/if_wi.c | 41 | ||||
-rw-r--r-- | sys/dev/pcmcia/if_wireg.h | 4 |
2 files changed, 25 insertions, 20 deletions
diff --git a/sys/dev/pcmcia/if_wi.c b/sys/dev/pcmcia/if_wi.c index 4401409d46c..25b4544d8d2 100644 --- a/sys/dev/pcmcia/if_wi.c +++ b/sys/dev/pcmcia/if_wi.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_wi.c,v 1.25 2001/03/17 18:54:52 deraadt Exp $ */ +/* $OpenBSD: if_wi.c,v 1.26 2001/03/19 20:13:43 niklas Exp $ */ /* * Copyright (c) 1997, 1998, 1999 @@ -50,7 +50,7 @@ * without an NDA (if at all). What they do release is an API library * called the HCF (Hardware Control Functions) which is supposed to * do the device-specific operations of a device driver for you. The - * publically available version of the HCF library (the 'HCF Light') is + * publically available version of the HCF library (the 'HCF Light') is * a) extremely gross, b) lacks certain features, particularly support * for 802.11 frames, and c) is contaminated by the GNU Public License. * @@ -133,7 +133,7 @@ u_int32_t widebug = WIDEBUG; #if !defined(lint) && !defined(__OpenBSD__) static const char rcsid[] = - "$OpenBSD: if_wi.c,v 1.25 2001/03/17 18:54:52 deraadt Exp $"; + "$OpenBSD: if_wi.c,v 1.26 2001/03/19 20:13:43 niklas Exp $"; #endif /* lint */ #ifdef foo @@ -187,7 +187,7 @@ wi_pcmcia_match(parent, match, aux) void *match, *aux; { struct pcmcia_attach_args *pa = aux; - + if (pa->pf->function != PCMCIA_FUNCTION_NETWORK) return (0); @@ -600,6 +600,7 @@ wi_inquire(xsc) { struct wi_softc *sc; struct ifnet *ifp; + int s, rv; sc = xsc; ifp = &sc->arpcom.ac_if; @@ -610,7 +611,12 @@ wi_inquire(xsc) if (ifp->if_flags & IFF_OACTIVE) return; - wi_cmd(sc, WI_CMD_INQUIRE, WI_INFO_COUNTERS); + s = splnet(); + rv = wi_cmd(sc, WI_CMD_INQUIRE, WI_INFO_COUNTERS); + splx(s); + if (rv) + printf(WI_PRT_FMT ": wi_cmd failed with %d\n", WI_PRT_ARG(sc), + rv); return; } @@ -665,7 +671,7 @@ wi_cmd(sc, cmd, val) CSR_WRITE_2(sc, WI_PARAM0, val); CSR_WRITE_2(sc, WI_COMMAND, cmd); - for (i = 0; i < WI_TIMEOUT; i++) { + for (i = WI_TIMEOUT; i--; DELAY(10)) { /* * Wait for 'command complete' bit to be * set in the event status register. @@ -685,7 +691,7 @@ wi_cmd(sc, cmd, val) } } - if (i == WI_TIMEOUT) + if (i < 0) return(ETIMEDOUT); return(0); @@ -803,12 +809,11 @@ wi_seek(sc, id, off, chan) CSR_WRITE_2(sc, selreg, id); CSR_WRITE_2(sc, offreg, off); - for (i = 0; i < WI_TIMEOUT; i++) { + for (i = WI_TIMEOUT; i--; DELAY(10)) if (!(CSR_READ_2(sc, offreg) & (WI_OFF_BUSY|WI_OFF_ERR))) break; - } - if (i == WI_TIMEOUT) + if (i < 0) return(ETIMEDOUT); return(0); @@ -900,12 +905,12 @@ wi_alloc_nicmem(sc, len, id) return(ENOMEM); } - for (i = 0; i < WI_TIMEOUT; i++) { + for (i = WI_TIMEOUT; i--; DELAY(10)) { if (CSR_READ_2(sc, WI_EVENT_STAT) & WI_EV_ALLOC) break; } - if (i == WI_TIMEOUT) + if (i < 0) return(ETIMEDOUT); CSR_WRITE_2(sc, WI_EVENT_ACK, WI_EV_ALLOC); @@ -983,7 +988,7 @@ wi_setdef(sc, wreq) sdl = (struct sockaddr_dl *)ifa->ifa_addr; bcopy((char *)&wreq->wi_val, LLADDR(sdl), ETHER_ADDR_LEN); bcopy((char *)&wreq->wi_val, (char *)&sc->arpcom.ac_enaddr, - ETHER_ADDR_LEN); + ETHER_ADDR_LEN); break; case WI_RID_PORTTYPE: sc->wi_ptype = wreq->wi_val[0]; @@ -1068,7 +1073,7 @@ wi_ioctl(ifp, command, data) } DPRINTF (WID_IOCTL, ("wi_ioctl: command %lu data %p\n", - command, data)); + command, data)); if ((error = ether_ioctl(ifp, &sc->arpcom, command, data)) > 0) { splx(s); @@ -1128,7 +1133,7 @@ wi_ioctl(ifp, command, data) if (error == ENETRESET) { /* * Multicast list has changed; set the hardware filter - * accordingly. + * accordingly. */ wi_setmulti(sc); error = 0; @@ -1146,10 +1151,10 @@ wi_ioctl(ifp, command, data) /* For non-root user, return all-zeroes keys */ if (suser(p->p_ucred, &p->p_acflag)) bzero((char *)&wreq, - sizeof(struct wi_ltv_keys)); + sizeof(struct wi_ltv_keys)); else bcopy((char *)&sc->wi_keys, (char *)&wreq, - sizeof(struct wi_ltv_keys)); + sizeof(struct wi_ltv_keys)); } else { if (wi_read_record(sc, (struct wi_ltv_gen *)&wreq)) { error = EINVAL; @@ -1430,7 +1435,7 @@ wi_mgmt_xmit(sc, data, len) return(0); } -STATIC void +STATIC void wi_stop(sc) struct wi_softc *sc; { diff --git a/sys/dev/pcmcia/if_wireg.h b/sys/dev/pcmcia/if_wireg.h index c211af8f5a5..225e6a323d4 100644 --- a/sys/dev/pcmcia/if_wireg.h +++ b/sys/dev/pcmcia/if_wireg.h @@ -1,4 +1,4 @@ -/* $OpenBSD: if_wireg.h,v 1.7 2001/03/11 08:41:29 mickey Exp $ */ +/* $OpenBSD: if_wireg.h,v 1.8 2001/03/19 20:13:44 niklas Exp $ */ /* * Copyright (c) 1997, 1998, 1999 @@ -117,7 +117,7 @@ struct wi_softc { struct timeout sc_timo; }; -#define WI_TIMEOUT 50000 +#define WI_TIMEOUT 5000 /* XXX just a guess at a good value. */ #define WI_PORT0 0 #define WI_PORT1 1 |