Source-Changes-HG archive

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

[src/trunk]: src/sys/dev Add power management support to the `tlp' driver. T...



details:   https://anonhg.NetBSD.org/src/rev/20f5f223140d
branches:  trunk
changeset: 483682:20f5f223140d
user:      thorpej <thorpej%NetBSD.org@localhost>
date:      Wed Mar 15 18:39:50 2000 +0000

description:
Add power management support to the `tlp' driver.  The battery on my
laptop lasts a whole lot longer now.

diffstat:

 sys/dev/cardbus/if_tlp_cardbus.c |  116 ++++++++++++++++++++++++++------------
 sys/dev/eisa/if_tlp_eisa.c       |    7 ++-
 sys/dev/ic/tulip.c               |   78 +++++++++++++++++++++++++-
 sys/dev/ic/tulipvar.h            |   10 +++-
 sys/dev/pci/if_tlp_pci.c         |    8 ++-
 5 files changed, 177 insertions(+), 42 deletions(-)

diffs (truncated from 441 to 300 lines):

diff -r 7212fb72376c -r 20f5f223140d sys/dev/cardbus/if_tlp_cardbus.c
--- a/sys/dev/cardbus/if_tlp_cardbus.c  Wed Mar 15 17:08:37 2000 +0000
+++ b/sys/dev/cardbus/if_tlp_cardbus.c  Wed Mar 15 18:39:50 2000 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: if_tlp_cardbus.c,v 1.19 2000/03/14 02:08:21 thorpej Exp $      */
+/*     $NetBSD: if_tlp_cardbus.c,v 1.20 2000/03/15 18:39:52 thorpej Exp $      */
 
 /*-
  * Copyright (c) 1999, 2000 The NetBSD Foundation, Inc.
@@ -40,10 +40,6 @@
 /*
  * CardBus bus front-end for the Digital Semiconductor ``Tulip'' (21x4x)
  * Ethernet controller family driver.
- *
- * TODO:
- *
- *     - power management
  */
 
 #include "opt_inet.h"
@@ -116,13 +112,14 @@
        int     sc_csr;                 /* CSR bits */
        bus_size_t sc_mapsize;          /* the size of mapped bus space
                                           region */
-       int     sc_attached;            /* device is attached */
                                        /* product info */
        const struct tulip_cardbus_product *sc_product;
 
        int     sc_cben;                /* CardBus enables */
        int     sc_bar_reg;             /* which BAR to use */
        pcireg_t sc_bar_val;            /* value of the BAR */
+
+       int     sc_intrline;            /* interrupt line */
 };
 
 int    tlp_cardbus_match __P((struct device *, struct cfdata *, void *));
@@ -153,6 +150,9 @@
 
 void   tlp_cardbus_setup __P((struct tulip_cardbus_softc *));
 
+int    tlp_cardbus_enable __P((struct tulip_softc *));
+void   tlp_cardbus_disable __P((struct tulip_softc *));
+
 void   tlp_cardbus_x3201_reset __P((struct tulip_softc *));
 
 const struct tulip_cardbus_product *tlp_cardbus_lookup
@@ -197,8 +197,6 @@
        struct tulip_softc *sc = &csc->sc_tulip;
        struct cardbus_attach_args *ca = aux;
        cardbus_devfunc_t ct = ca->ca_ct;
-       cardbus_chipset_tag_t cc = ct->ct_cc;
-       cardbus_function_tag_t cf = ct->ct_cf;
        const struct tulip_cardbus_product *tcp;
        u_int8_t enaddr[ETHER_ADDR_LEN];
        bus_addr_t adr;
@@ -223,6 +221,12 @@
        sc->sc_regshift = 3;
 
        /*
+        * Power management hooks.
+        */
+       sc->sc_enable = tlp_cardbus_enable;
+       sc->sc_disable = tlp_cardbus_disable;
+
+       /*
         * Get revision info, and set some chip-specific variables.
         */
        sc->sc_rev = PCI_REVISION(ca->ca_class);
@@ -344,24 +348,18 @@
                return;
        }
 
-       /*
-        * Map and establish the interrupt.
-        */
-       csc->sc_ih = cardbus_intr_establish(cc, cf, ca->ca_intrline, IPL_NET,
-           tlp_intr, sc);
-       if (csc->sc_ih == NULL) {
-               printf("%s: unable to establish interrupt at %d\n",
-                   sc->sc_dev.dv_xname, ca->ca_intrline);
-               return;
-       }
-       printf("%s: interrupting at %d\n", sc->sc_dev.dv_xname,
-           ca->ca_intrline);
+       /* Remember which interrupt line. */
+       csc->sc_intrline = ca->ca_intrline;
 
        /*
         * Finish off the attach.
         */
-       csc->sc_attached = 1;
        tlp_attach(sc, enaddr);
+
+       /*
+        * Power down the socket.
+        */
+       Cardbus_function_disable(csc->sc_ct);
 }
 
 int
@@ -373,38 +371,84 @@
        struct tulip_softc *sc = &csc->sc_tulip;
        struct cardbus_devfunc *ct = csc->sc_ct;
        int rv;
-       int reg;
 
 #if defined(DIAGNOSTIC)
-       if (ct == NULL) {
+       if (ct == NULL)
                panic("%s: data structure lacks\n", sc->sc_dev.dv_xname);
-       }
 #endif
 
-       if (csc->sc_attached) {
-               rv = tlp_detach(sc);
-               if (rv)
-                       return (rv);
-       }
+       rv = tlp_detach(sc);
+       if (rv)
+               return (rv);
 
        /*
         * Unhook the interrupt handler.
         */
-       cardbus_intr_disestablish(ct->ct_cc, ct->ct_cf, csc->sc_ih);
+       if (csc->sc_ih != NULL)
+               cardbus_intr_disestablish(ct->ct_cc, ct->ct_cf, csc->sc_ih);
 
        /*
-        * release bus space and close window
+        * Release bus space and close window.
         */
-       if (csc->sc_csr & PCI_COMMAND_MEM_ENABLE)
-               reg = TULIP_PCI_MMBA;
-       else
-               reg = TULIP_PCI_IOBA;
-       Cardbus_mapreg_unmap(ct, reg, sc->sc_st, sc->sc_sh, 
+       Cardbus_mapreg_unmap(ct, csc->sc_bar_reg, sc->sc_st, sc->sc_sh, 
            csc->sc_mapsize);
 
        return (0);
 }
 
+int
+tlp_cardbus_enable(sc)
+       struct tulip_softc *sc;
+{
+       struct tulip_cardbus_softc *csc = (void *) sc;
+       cardbus_devfunc_t ct = csc->sc_ct;
+       cardbus_chipset_tag_t cc = ct->ct_cc;
+       cardbus_function_tag_t cf = ct->ct_cf;
+
+       /*
+        * Power on the socket.
+        */
+       Cardbus_function_enable(ct);
+
+       /*
+        * Set up the PCI configuration registers.
+        */
+       tlp_cardbus_setup(csc);
+
+       /*
+        * Map and establish the interrupt.
+        */
+       csc->sc_ih = cardbus_intr_establish(cc, cf, csc->sc_intrline, IPL_NET,
+           tlp_intr, sc);
+       if (csc->sc_ih == NULL) {
+               printf("%s: unable to establish interrupt at %d\n",
+                   sc->sc_dev.dv_xname, csc->sc_intrline);
+               Cardbus_function_disable(csc->sc_ct);
+               return (1);
+       }
+       printf("%s: interrupting at %d\n", sc->sc_dev.dv_xname,
+           csc->sc_intrline);
+
+       return (0);
+}
+
+void
+tlp_cardbus_disable(sc)
+       struct tulip_softc *sc;
+{
+       struct tulip_cardbus_softc *csc = (void *) sc;
+       cardbus_devfunc_t ct = csc->sc_ct;
+       cardbus_chipset_tag_t cc = ct->ct_cc;
+       cardbus_function_tag_t cf = ct->ct_cf;
+
+       /* Unhook the interrupt handler. */
+       cardbus_intr_disestablish(cc, cf, csc->sc_ih);
+       csc->sc_ih = NULL;
+
+       /* Power down the socket. */
+       Cardbus_function_disable(ct);
+}
+
 void
 tlp_cardbus_setup(csc)
        struct tulip_cardbus_softc *csc;
diff -r 7212fb72376c -r 20f5f223140d sys/dev/eisa/if_tlp_eisa.c
--- a/sys/dev/eisa/if_tlp_eisa.c        Wed Mar 15 17:08:37 2000 +0000
+++ b/sys/dev/eisa/if_tlp_eisa.c        Wed Mar 15 18:39:50 2000 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: if_tlp_eisa.c,v 1.4 1999/12/11 00:33:00 thorpej Exp $  */
+/*     $NetBSD: if_tlp_eisa.c,v 1.5 2000/03/15 18:39:52 thorpej Exp $  */
 
 /*-
  * Copyright (c) 1999 The NetBSD Foundation, Inc.
@@ -212,6 +212,11 @@
        sc->sc_regshift = 4;
 
        /*
+        * No power management hooks.
+        */
+       sc->sc_flags |= TULIPF_ENABLED;
+
+       /*
         * CBIO must map the EISA slot, and I/O access and Bus Mastering
         * must be enabled.
         */
diff -r 7212fb72376c -r 20f5f223140d sys/dev/ic/tulip.c
--- a/sys/dev/ic/tulip.c        Wed Mar 15 17:08:37 2000 +0000
+++ b/sys/dev/ic/tulip.c        Wed Mar 15 18:39:50 2000 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: tulip.c,v 1.52 2000/03/10 02:46:39 thorpej Exp $       */
+/*     $NetBSD: tulip.c,v 1.53 2000/03/15 18:39:50 thorpej Exp $       */
 
 /*-
  * Copyright (c) 1998, 1999, 2000 The NetBSD Foundation, Inc.
@@ -154,6 +154,9 @@
 void   tlp_srom_idle __P((struct tulip_softc *));
 int    tlp_srom_size __P((struct tulip_softc *));
 
+int    tlp_enable __P((struct tulip_softc *));
+void   tlp_disable __P((struct tulip_softc *));
+
 void   tlp_filter_setup __P((struct tulip_softc *));
 void   tlp_winb_filter_setup __P((struct tulip_softc *));
 void   tlp_al981_filter_setup __P((struct tulip_softc *));
@@ -440,6 +443,13 @@
        }
 
        /*
+        * From this point forward, the attachment cannot fail.  A failure
+        * before this point releases all resources that may have been
+        * allocated.
+        */
+       sc->sc_flags |= TULIPF_ATTACHED;
+
+       /*
         * Reset the chip to a known state.
         */
        tlp_reset(sc);
@@ -555,6 +565,12 @@
        struct tulip_txsoft *txs;
        int i;
 
+       /*
+        * Suceed now if there isn't any work to do.
+        */
+       if ((sc->sc_flags & TULIPF_ATTACHED) == 0)
+               return (0);
+
        /* Unhook our tick handler. */
        if (sc->sc_tick)
                untimeout(sc->sc_tick, sc);
@@ -926,6 +942,8 @@
 
        switch (cmd) {
        case SIOCSIFADDR:
+               if ((error = tlp_enable(sc)) != 0)
+                       break;
                ifp->if_flags |= IFF_UP;
 
                switch (ifa->ifa_addr->sa_family) {
@@ -977,18 +995,23 @@
                         * stop it.
                         */
                        tlp_stop(sc, 1);
+                       tlp_disable(sc);
                } else if ((ifp->if_flags & IFF_UP) != 0 &&
                           (ifp->if_flags & IFF_RUNNING) == 0) {
                        /*
                         * If interfase it marked up and it is stopped, then
                         * start it.
                         */
+                       if ((error = tlp_enable(sc)) != 0)
+                               break;
                        error = tlp_init(sc);
                } else if ((ifp->if_flags & IFF_UP) != 0) {
                        /*
                         * Reset the interface to pick up changes in any other
                         * flags that affect the hardware state.
                         */
+                       if ((error = tlp_enable(sc)) != 0)
+                               break;
                        error = tlp_init(sc);
                }
                break;



Home | Main Index | Thread Index | Old Index