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