summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNiklas Hallqvist <niklas@cvs.openbsd.org>2001-03-19 20:13:45 +0000
committerNiklas Hallqvist <niklas@cvs.openbsd.org>2001-03-19 20:13:45 +0000
commit44386d4a80b5c66ce4025d5eea2efc0c9517b513 (patch)
treee940edf44cac4791aaac99ea5442fd9fceb7a542
parentd9b6a0a4699a337f8fba16b5eb2e6721765f5b53 (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.c41
-rw-r--r--sys/dev/pcmcia/if_wireg.h4
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