Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/dev cleanup attach procedure, use tsleep() instead of lo...
details: https://anonhg.NetBSD.org/src/rev/2c5ce87ca3cc
branches: trunk
changeset: 500835:2c5ce87ca3cc
user: onoe <onoe%NetBSD.org@localhost>
date: Tue Dec 19 08:00:55 2000 +0000
description:
cleanup attach procedure, use tsleep() instead of long delay (and ignore
timeouts).
stop driver after suspend.
XXX: should use command interrupt but no document...
XXX: status update sometimes failed perhaps due to collision.
(RID 0xff50 or 0xff68 access failed)
diffstat:
sys/dev/ic/an.c | 190 ++++++++++++++++++++++-----------------
sys/dev/ic/anreg.h | 4 +-
sys/dev/ic/anvar.h | 19 +--
sys/dev/pcmcia/if_an_pcmcia.c | 202 ++++++++++++-----------------------------
4 files changed, 176 insertions(+), 239 deletions(-)
diffs (truncated from 767 to 300 lines):
diff -r 3962f6980a67 -r 2c5ce87ca3cc sys/dev/ic/an.c
--- a/sys/dev/ic/an.c Tue Dec 19 06:23:26 2000 +0000
+++ b/sys/dev/ic/an.c Tue Dec 19 08:00:55 2000 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: an.c,v 1.8 2000/12/14 06:27:24 thorpej Exp $ */
+/* $NetBSD: an.c,v 1.9 2000/12/19 08:00:55 onoe Exp $ */
/*
* Copyright (c) 1997, 1998, 1999
* Bill Paul <wpaul%ctr.columbia.edu@localhost>. All rights reserved.
@@ -142,6 +142,7 @@
/* These are global because we need them in sys/pci/if_an_p.c. */
static void an_reset __P((struct an_softc *));
+static void an_wait __P((struct an_softc *));
static int an_ioctl __P((struct ifnet *, u_long, caddr_t));
static int an_init __P((struct ifnet *));
static void an_stop __P((struct ifnet *, int));
@@ -172,57 +173,23 @@
static void an_media_status __P((struct ifnet *ifp, struct ifmediareq *imr));
#endif
-/*
- * We probe for an Aironet 4500/4800 card by attempting to
- * read the default SSID list. On reset, the first entry in
- * the SSID list will contain the name "tsunami." If we don't
- * find this, then there's no card present.
- */
-int an_probe(sc)
- struct an_softc *sc;
-{
- struct an_ltv_ssidlist ssid;
-
- bzero((char *)&ssid, sizeof(ssid));
-
- ssid.an_len = sizeof(ssid);
- ssid.an_type = AN_RID_SSIDLIST;
-
- /* Make sure interrupts are disabled. */
- CSR_WRITE_2(sc, AN_INT_EN, 0);
- CSR_WRITE_2(sc, AN_EVENT_ACK, 0xFFFF);
-
- an_reset(sc);
-
- if (an_cmd(sc, AN_CMD_READCFG, 0))
- return ENXIO;
-
- if (an_read_record(sc, (struct an_ltv_gen *)&ssid))
- return ENXIO;
-
- /* See if the ssid matches what we expect ... but doesn't have to */
- if (strcmp(ssid.an_ssid1, AN_DEF_SSID))
- return ENXIO;
-
- return 0;
-}
-
-int an_attach(sc)
- struct an_softc *sc;
+int
+an_attach(struct an_softc *sc)
{
struct ifnet *ifp = &sc->arpcom.ec_if;
+ int i, s;
#ifdef IFM_IEEE80211
- int i, mtype;
+ int mtype;
struct ifmediareq imr;
#endif
+ s = splnet();
sc->an_associated = 0;
-
- /* Reset the NIC. */
- an_reset(sc);
+ an_wait(sc);
/* Load factory config */
if (an_cmd(sc, AN_CMD_READCFG, 0)) {
+ splx(s);
printf("%s: failed to load config data\n", sc->an_dev.dv_xname);
return(EIO);
}
@@ -231,6 +198,7 @@
sc->an_config.an_type = AN_RID_GENCONFIG;
sc->an_config.an_len = sizeof(struct an_ltv_genconfig);
if (an_read_record(sc, (struct an_ltv_gen *)&sc->an_config)) {
+ splx(s);
printf("%s: read record failed\n", sc->an_dev.dv_xname);
return(EIO);
}
@@ -239,6 +207,7 @@
sc->an_caps.an_type = AN_RID_CAPABILITIES;
sc->an_caps.an_len = sizeof(struct an_ltv_caps);
if (an_read_record(sc, (struct an_ltv_gen *)&sc->an_caps)) {
+ splx(s);
printf("%s: read record failed\n", sc->an_dev.dv_xname);
return(EIO);
}
@@ -247,6 +216,7 @@
sc->an_ssidlist.an_type = AN_RID_SSIDLIST;
sc->an_ssidlist.an_len = sizeof(struct an_ltv_ssidlist);
if (an_read_record(sc, (struct an_ltv_gen *)&sc->an_ssidlist)) {
+ splx(s);
printf("%s: read record failed\n", sc->an_dev.dv_xname);
return(EIO);
}
@@ -255,6 +225,7 @@
sc->an_aplist.an_type = AN_RID_APLIST;
sc->an_aplist.an_len = sizeof(struct an_ltv_aplist);
if (an_read_record(sc, (struct an_ltv_gen *)&sc->an_aplist)) {
+ splx(s);
printf("%s: read record failed\n", sc->an_dev.dv_xname);
return(EIO);
}
@@ -326,13 +297,13 @@
ifmedia_set(&sc->sc_media, imr.ifm_active);
#endif
callout_init(&sc->an_stat_ch);
+ splx(s);
return(0);
}
int
-an_detach(sc)
- struct an_softc *sc;
+an_detach(struct an_softc *sc)
{
struct ifnet *ifp = &sc->arpcom.ec_if;
int s;
@@ -347,9 +318,7 @@
}
int
-an_activate(self, act)
- struct device *self;
- enum devact act;
+an_activate(struct device *self, enum devact act)
{
struct an_softc *sc = (struct an_softc *)self;
int s, error = 0;
@@ -369,6 +338,41 @@
return error;
}
+void
+an_power(int why, void *arg)
+{
+ int s;
+ struct an_softc *sc = arg;
+ struct ifnet *ifp = &sc->arpcom.ec_if;
+
+ if (!sc->sc_enabled)
+ return;
+
+ s = splnet();
+ switch (why) {
+ case PWR_SUSPEND:
+ case PWR_STANDBY:
+ an_stop(ifp, 0);
+ break;
+ case PWR_RESUME:
+ break;
+ case PWR_SOFTSUSPEND:
+ case PWR_SOFTSTANDBY:
+ case PWR_SOFTRESUME:
+ break;
+ }
+ splx(s);
+}
+
+void
+an_shutdown(void *arg)
+{
+ struct an_softc *sc = arg;
+
+ an_stop(&sc->arpcom.ec_if, 1);
+ return;
+}
+
static void an_rxeof(sc)
struct an_softc *sc;
{
@@ -533,15 +537,12 @@
return;
}
-int an_intr(xsc)
- void *xsc;
+int an_intr(void *arg)
{
- struct an_softc *sc;
+ struct an_softc *sc = arg;
struct ifnet *ifp;
u_int16_t status;
- sc = (struct an_softc*)xsc;
-
if (!sc->sc_enabled)
return 0;
@@ -589,6 +590,11 @@
if (status & AN_EV_ALLOC)
CSR_WRITE_2(sc, AN_EVENT_ACK, AN_EV_ALLOC);
+ if (status & AN_EV_CMD) {
+ wakeup(sc);
+ CSR_WRITE_2(sc, AN_EVENT_ACK, AN_EV_CMD);
+ }
+
/* Re-enable interrupts. */
CSR_WRITE_2(sc, AN_INT_EN, AN_INTRS);
@@ -598,12 +604,10 @@
return 1;
}
-static int an_cmd(sc, cmd, val)
- struct an_softc *sc;
- int cmd;
- int val;
+static int
+an_cmd(struct an_softc *sc, int cmd, int val)
{
- int i, s = 0;
+ int i;
CSR_WRITE_2(sc, AN_PARAM0, val);
CSR_WRITE_2(sc, AN_PARAM1, 0);
@@ -613,18 +617,14 @@
for (i = 0; i < AN_TIMEOUT; i++) {
if (CSR_READ_2(sc, AN_EVENT_STAT) & AN_EV_CMD)
break;
- else {
- if (CSR_READ_2(sc, AN_COMMAND) == cmd)
- CSR_WRITE_2(sc, AN_COMMAND, cmd);
- }
}
for (i = 0; i < AN_TIMEOUT; i++) {
CSR_READ_2(sc, AN_RESP0);
CSR_READ_2(sc, AN_RESP1);
CSR_READ_2(sc, AN_RESP2);
- s = CSR_READ_2(sc, AN_STATUS);
- if ((s & AN_STAT_CMD_CODE) == (cmd & AN_STAT_CMD_CODE))
+ if ((CSR_READ_2(sc, AN_STATUS) & AN_STAT_CMD_CODE) ==
+ (cmd & AN_STAT_CMD_CODE))
break;
}
@@ -645,12 +645,12 @@
* most reliable method I've found to really kick the NIC in the
* head and force it to reboot correctly.
*/
-static void an_reset(sc)
- struct an_softc *sc;
+static void
+an_reset(struct an_softc *sc)
{
if (!sc->sc_enabled)
return;
-
+
an_cmd(sc, AN_CMD_ENABLE, 0);
an_cmd(sc, AN_CMD_FW_RESTART, 0);
an_cmd(sc, AN_CMD_NOOP2, 0);
@@ -664,6 +664,26 @@
}
/*
+ * Wait for firmware come up after power enabled.
+ */
+static void
+an_wait(struct an_softc *sc)
+{
+ int i;
+
+ if (!sc->sc_enabled)
+ return;
+
+ CSR_WRITE_2(sc, AN_COMMAND, AN_CMD_NOOP2);
+ for (i = 0; i < 3*hz; i++) {
+ if (CSR_READ_2(sc, AN_EVENT_STAT) & AN_EV_CMD)
+ break;
+ (void)tsleep(sc, PWAIT, "anatch", 1);
+ }
+ CSR_WRITE_2(sc, AN_EVENT_ACK, AN_EV_CMD);
+}
+
+/*
* Read an LTV record from the NIC.
*/
static int an_read_record(sc, ltv)
@@ -678,13 +698,15 @@
/* Tell the NIC to enter record read mode. */
if (an_cmd(sc, AN_CMD_ACCESS|AN_ACCESS_READ, ltv->an_type)) {
- printf("%s: RID access failed\n", sc->an_dev.dv_xname);
+ printf("%s: RID 0x%04x access failed\n", sc->an_dev.dv_xname,
+ ltv->an_type);
Home |
Main Index |
Thread Index |
Old Index