Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/dev/isa - add power management code.



details:   https://anonhg.NetBSD.org/src/rev/a7ef0bb59b72
branches:  trunk
changeset: 518211:a7ef0bb59b72
user:      yamt <yamt%NetBSD.org@localhost>
date:      Mon Nov 26 11:14:50 2001 +0000

description:
- add power management code.
- use ether_ioctl instead of its own code.
  (make ifconfig down works properly.)

diffstat:

 sys/dev/isa/cs89x0.c    |  220 ++++++++++++++++++++++++++++++++---------------
 sys/dev/isa/cs89x0var.h |   11 ++-
 2 files changed, 159 insertions(+), 72 deletions(-)

diffs (truncated from 389 to 300 lines):

diff -r f9c05da25e76 -r a7ef0bb59b72 sys/dev/isa/cs89x0.c
--- a/sys/dev/isa/cs89x0.c      Mon Nov 26 10:39:29 2001 +0000
+++ b/sys/dev/isa/cs89x0.c      Mon Nov 26 11:14:50 2001 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: cs89x0.c,v 1.21 2001/11/24 20:18:55 yamt Exp $ */
+/*     $NetBSD: cs89x0.c,v 1.22 2001/11/26 11:14:50 yamt Exp $ */
 
 /*
  * Copyright 1997
@@ -186,7 +186,7 @@
 */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: cs89x0.c,v 1.21 2001/11/24 20:18:55 yamt Exp $");
+__KERNEL_RCSID(0, "$NetBSD: cs89x0.c,v 1.22 2001/11/26 11:14:50 yamt Exp $");
 
 #include "opt_inet.h"
 
@@ -249,7 +249,7 @@
 int    cs_get_params __P((struct cs_softc *));
 int    cs_get_enaddr __P((struct cs_softc *));
 int    cs_reset_chip __P((struct cs_softc *));
-int    cs_init __P((struct cs_softc *));
+int    cs_init __P((struct ifnet *));
 void   cs_reset __P((void *));
 int    cs_ioctl __P((struct ifnet *, u_long, caddr_t));
 void   cs_initChip __P((struct cs_softc *));
@@ -270,6 +270,11 @@
 int    cs_mediachange __P((struct ifnet *));
 void   cs_mediastatus __P((struct ifnet *, struct ifmediareq *));
 
+static int cs_enable __P((struct cs_softc *));
+static void cs_disable __P((struct cs_softc *));
+static void cs_stop __P((struct ifnet *, int));
+static void cs_power __P((int, void *));
+
 /*
  * GLOBAL DECLARATIONS
  */
@@ -377,7 +382,9 @@
        strcpy(ifp->if_xname, sc->sc_dev.dv_xname);
        ifp->if_softc = sc;
        ifp->if_start = cs_start_output;
+       ifp->if_init = cs_init;
        ifp->if_ioctl = cs_ioctl;
+       ifp->if_stop = cs_stop;
        ifp->if_watchdog = NULL;        /* no watchdog at this stage */
        ifp->if_flags = IFF_SIMPLEX | IFF_NOTRAILERS |
            IFF_BROADCAST | IFF_MULTICAST;
@@ -511,6 +518,11 @@
                return 1;
        }
 
+       sc->sc_powerhook = powerhook_establish(cs_power, sc);
+       if (sc->sc_powerhook == 0)
+               printf("%s: warning: powerhook_establish failed\n",
+                       sc->sc_dev.dv_xname);
+
        return 0;
 }
 
@@ -520,6 +532,11 @@
 {
        struct ifnet *ifp = &sc->sc_ethercom.ec_if;
 
+       if (sc->sc_powerhook) {
+               powerhook_disestablish(sc->sc_powerhook);
+               sc->sc_powerhook = 0;
+       }
+
        if (sc->sc_cfgflags & CFGFLG_ATTACHED) {
 #if NRND > 0
                rnd_detach_source(&sc->rnd_source);
@@ -1027,16 +1044,24 @@
 }
 
 int 
-cs_init(sc)
-       struct cs_softc *sc;
+cs_init(ifp)
+       struct ifnet *ifp;
 {
        int intState;
        int error = CS_OK;
+       struct cs_softc *sc = ifp->if_softc;
+
+       if (cs_enable(sc))
+               goto out;
+
+       cs_stop(ifp, 0);
 
        intState = splnet();
 
+#if 0
        /* Mark the interface as down */
        sc->sc_ethercom.ec_if.if_flags &= ~(IFF_UP | IFF_RUNNING);
+#endif
 
 #ifdef CS_DEBUG
        /* Enable debugging */
@@ -1048,8 +1073,8 @@
                /* Initialize the chip */
                cs_initChip(sc);
 
-               /* Mark the interface as up and running */
-               sc->sc_ethercom.ec_if.if_flags |= (IFF_UP | IFF_RUNNING);
+               /* Mark the interface as running */
+               sc->sc_ethercom.ec_if.if_flags |= IFF_RUNNING;
                sc->sc_ethercom.ec_if.if_flags &= ~IFF_OACTIVE;
                sc->sc_ethercom.ec_if.if_timer = 0;
 
@@ -1060,7 +1085,10 @@
        }
 
        splx(intState);
-       return error;
+out:
+       if (error == CS_OK)
+               return 0;
+       return EIO;
 }
 
 void 
@@ -1209,7 +1237,6 @@
        caddr_t data;
 {
        struct cs_softc *sc = ifp->if_softc;
-       struct ifaddr *ifa = (struct ifaddr *) data;
        struct ifreq *ifr = (struct ifreq *) data;
        int state;
        int result;
@@ -1219,70 +1246,23 @@
        result = 0;             /* only set if something goes wrong */
 
        switch (cmd) {
-       case SIOCSIFADDR:
-               ifp->if_flags |= IFF_UP;
-
-               switch (ifa->ifa_addr->sa_family) {
-#ifdef INET
-               case AF_INET:
-                       cs_init(sc);
-                       arp_ifinit(ifp, ifa);
-                       break;
-#endif
-               default:
-                       cs_init(sc);
-                       break;
-               }
-               break;
-
-       case SIOCSIFFLAGS:
-               if ((ifp->if_flags & IFF_UP) == 0 &&
-                   (ifp->if_flags & IFF_RUNNING) != 0) {
-                       /*
-                        * If interface is marked down and it is running,
-                        * then stop it.
-                        */
-                       cs_reset_chip(sc);
-                       ifp->if_flags &= ~IFF_RUNNING;
-               } else if ((ifp->if_flags & IFF_UP) != 0 &&
-                          (ifp->if_flags & IFF_RUNNING) == 0) {
-                       /*
-                        * If interface is marked up and it is stopped,
-                        * start it.
-                        */
-                       cs_init(sc);
-               } else {
-                       /*
-                        * Reset the interface to pick up any changes in
-                        * any other flags that affect hardware registers.
-                        */
-                       cs_init(sc);
-               }
-               break;
-
-       case SIOCADDMULTI:
-       case SIOCDELMULTI:
-               result = (cmd == SIOCADDMULTI) ?
-                   ether_addmulti(ifr, &sc->sc_ethercom) :
-                   ether_delmulti(ifr, &sc->sc_ethercom);
-
-               if (result == ENETRESET) {
-                       /*
-                        * Multicast list has changed; set the hardware filter
-                        * accordingly.
-                        */
-                       cs_init(sc);
-                       result = 0;
-               }
-               break;
-
        case SIOCGIFMEDIA:
        case SIOCSIFMEDIA:
                result = ifmedia_ioctl(ifp, ifr, &sc->sc_media, cmd);
                break;
 
        default:
-               result = EINVAL;
+               result = ether_ioctl(ifp, cmd, data);
+               if (result == ENETRESET) {
+                       if (CS_IS_ENABLED(sc)) {
+                               /*
+                                * Multicast list has changed.  Set the
+                                * hardware filter accordingly.
+                                */
+                               cs_set_ladr_filt(sc, &sc->sc_ethercom);
+                       }
+                       result = 0;
+               }
                break;
        }
 
@@ -1300,7 +1280,7 @@
         * Current media is already set up.  Just reset the interface
         * to let the new value take hold.
         */
-       cs_init((struct cs_softc *)ifp->if_softc);
+       cs_init(ifp);
        return (0);
 }
 
@@ -1804,7 +1784,7 @@
                                isa_dmaabort(sc->sc_ic, sc->sc_drq);
 
                                /* now reset the chip and reinitialise */
-                               cs_init(sc);
+                               cs_init(&sc->sc_ethercom.ec_if);
                                return;
                        }
                        /* Check the status of the received packet. */
@@ -1830,7 +1810,7 @@
                                         * now reset the chip and
                                         * reinitialise
                                         */
-                                       cs_init(sc);
+                                       cs_init(&sc->sc_ethercom.ec_if);
                                        return;
                                }
                                /*
@@ -1852,7 +1832,7 @@
                                         * now reset the chip and
                                         * reinitialise
                                         */
-                                       cs_init(sc);
+                                       cs_init(&sc->sc_ethercom.ec_if);
                                        return;
                                }
                                m->m_pkthdr.rcvif = ifp;
@@ -2308,3 +2288,101 @@
                }
        }
 }
+
+static int
+cs_enable(sc)
+       struct cs_softc *sc;
+{
+       if (!CS_IS_ENABLED(sc) && sc->sc_enable) {
+               int error;
+
+               error = (*sc->sc_enable)(sc);
+               if (error)
+                       return error;
+
+               sc->sc_cfgflags |= CFGFLG_ENABLED;
+       }
+
+       return 0;
+}
+
+static void
+cs_disable(sc)
+       struct cs_softc *sc;
+{
+       if (CS_IS_ENABLED(sc) && sc->sc_disable) {
+               (*sc->sc_disable)(sc);
+
+               sc->sc_cfgflags &= ~CFGFLG_ENABLED;
+       }
+}
+
+static void
+cs_stop(ifp, disable)
+       struct ifnet *ifp;
+       int disable;
+{
+       struct cs_softc *sc = ifp->if_softc;
+
+       CS_WRITE_PACKET_PAGE(sc, PKTPG_RX_CFG, 0);
+       CS_WRITE_PACKET_PAGE(sc, PKTPG_TX_CFG, 0);
+       CS_WRITE_PACKET_PAGE(sc, PKTPG_BUF_CFG, 0);
+       CS_WRITE_PACKET_PAGE(sc, PKTPG_BUS_CTL, 0);
+
+       if (disable) {
+               cs_disable(sc);
+       }
+
+       ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE);
+}



Home | Main Index | Thread Index | Old Index