diff options
author | Marcus Glocker <mglocker@cvs.openbsd.org> | 2006-10-09 20:45:28 +0000 |
---|---|---|
committer | Marcus Glocker <mglocker@cvs.openbsd.org> | 2006-10-09 20:45:28 +0000 |
commit | 61baa35a9736a996edde76ac89462a4fccad29d5 (patch) | |
tree | 509470340e6ea73c7664237b59952931f1bd2e5f /sys/dev | |
parent | 4d12400f85ba5fc1e76f23b4fb8735e540bde0a2 (diff) |
Add powerhooks. Tested with a Netgear WG511v1 on my X40.
ok claudio@
Diffstat (limited to 'sys/dev')
-rw-r--r-- | sys/dev/cardbus/if_pgt_cardbus.c | 14 | ||||
-rw-r--r-- | sys/dev/ic/pgt.c | 83 | ||||
-rw-r--r-- | sys/dev/ic/pgtvar.h | 7 |
3 files changed, 88 insertions, 16 deletions
diff --git a/sys/dev/cardbus/if_pgt_cardbus.c b/sys/dev/cardbus/if_pgt_cardbus.c index de27604745c..d181916cd6e 100644 --- a/sys/dev/cardbus/if_pgt_cardbus.c +++ b/sys/dev/cardbus/if_pgt_cardbus.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_pgt_cardbus.c,v 1.3 2006/10/06 21:55:33 mglocker Exp $ */ +/* $OpenBSD: if_pgt_cardbus.c,v 1.4 2006/10/09 20:45:27 mglocker Exp $ */ /* * Copyright (c) 2006 Marcus Glocker <mglocker@openbsd.org> @@ -216,12 +216,12 @@ pgt_cardbus_disable(struct pgt_softc *sc) void pgt_cardbus_power(struct pgt_softc *sc, int why) { - struct pgt_cardbus_softc *csc = (struct pgt_cardbus_softc *)sc; - - if (why == PWR_RESUME) { - /* kick the PCI configuration registers */ - pgt_cardbus_setup(csc); - } + if (why == PWR_RESUME) + if (sc->sc_enable != NULL) + (*sc->sc_enable)(sc); + if (why == PWR_SUSPEND) + if (sc->sc_disable != NULL) + (*sc->sc_disable)(sc); } void diff --git a/sys/dev/ic/pgt.c b/sys/dev/ic/pgt.c index 11d1d5207a5..5d4413b13df 100644 --- a/sys/dev/ic/pgt.c +++ b/sys/dev/ic/pgt.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pgt.c,v 1.30 2006/10/06 21:55:33 mglocker Exp $ */ +/* $OpenBSD: pgt.c,v 1.31 2006/10/09 20:45:27 mglocker Exp $ */ /* * Copyright (c) 2006 Claudio Jeker <claudio@openbsd.org> @@ -133,7 +133,8 @@ int pgt_load_firmware(struct pgt_softc *); void pgt_cleanup_queue(struct pgt_softc *, enum pgt_queue, struct pgt_frag []); int pgt_reset(struct pgt_softc *); -void pgt_disable(struct pgt_softc *, unsigned int); +void pgt_stop(struct pgt_softc *, unsigned int); +void pgt_reboot(struct pgt_softc *); void pgt_init_intr(struct pgt_softc *); void pgt_update_intr(struct pgt_softc *, int); struct mbuf @@ -191,6 +192,8 @@ int pgt_dma_alloc(struct pgt_softc *); int pgt_dma_alloc_queue(struct pgt_softc *sc, enum pgt_queue pq); void pgt_dma_free(struct pgt_softc *); void pgt_dma_free_queue(struct pgt_softc *sc, enum pgt_queue pq); +void pgt_shutdown(void *); +void pgt_power(int, void *); void pgt_write_memory_barrier(struct pgt_softc *sc) @@ -470,7 +473,7 @@ pgt_reset(struct pgt_softc *sc) * we'll spend a minute seeing if we can't do the reset. */ void -pgt_disable(struct pgt_softc *sc, unsigned int flag) +pgt_stop(struct pgt_softc *sc, unsigned int flag) { struct ieee80211com *ic; unsigned int wokeup; @@ -624,13 +627,21 @@ int pgt_detach(struct pgt_softc *sc) { /* stop card */ - pgt_disable(sc, SC_DYING); + pgt_stop(sc, SC_DYING); pgt_reboot(sc); /* disable card if possible */ if (sc->sc_disable != NULL) (*sc->sc_disable)(sc); + /* + * Disable shutdown and power hooks + */ + if (sc->sc_shutdown_hook != NULL) + shutdownhook_disestablish(sc->sc_shutdown_hook); + if (sc->sc_power_hook != NULL) + powerhook_disestablish(sc->sc_power_hook); + ieee80211_ifdetach(&sc->sc_ic.ic_if); if_detach(&sc->sc_ic.ic_if); @@ -1136,7 +1147,7 @@ pgt_per_device_kthread(void *argp) sck->sck_update = 0; pgt_empty_traps(sck); s = splnet(); - pgt_disable(sc, SC_NEEDS_RESET); + pgt_stop(sc, SC_NEEDS_RESET); splx(s); } else if (!TAILQ_EMPTY(&sck->sck_traps)) { DPRINTF(("%s: [thread] got a trap\n", @@ -2012,6 +2023,18 @@ pgt_net_attach(struct pgt_softc *sc) sc->sc_txtap.wt_ihdr.it_present = htole32(PGT_TX_RADIOTAP_PRESENT); #endif + /* + * Enable shutdown and power hooks + */ + sc->sc_shutdown_hook = shutdownhook_establish(pgt_shutdown, sc); + if (sc->sc_shutdown_hook == NULL) + printf("%s: WARNING: unable to establish shutdown hook\n", + sc->sc_dev.dv_xname); + sc->sc_power_hook = powerhook_establish(pgt_power, sc); + if (sc->sc_power_hook == NULL) + printf("%s: WARNING: unable to establish power hook\n", + sc->sc_dev.dv_xname); + return (0); } @@ -2362,7 +2385,7 @@ pgt_ioctl(struct ifnet *ifp, u_long cmd, caddr_t req) } } else { if (ifp->if_flags & IFF_RUNNING) { - pgt_disable(sc, SC_NEEDS_RESET); + pgt_stop(sc, SC_NEEDS_RESET); error = ENETRESET; } } @@ -3271,3 +3294,51 @@ pgt_dma_free_queue(struct pgt_softc *sc, enum pgt_queue pq) free(pd, M_DEVBUF); } } + +void +pgt_shutdown(void *arg) +{ + struct pgt_softc *sc = arg; + + DPRINTF(("%s: %s\n", sc->sc_dev.dv_xname, __func__)); + + pgt_stop(sc, SC_DYING); +} + +void +pgt_power(int why, void *arg) +{ + struct pgt_softc *sc = arg; + struct ifnet *ifp = &sc->sc_ic.ic_if; + int s; + + DPRINTF(("%s: %s(%d)\n", sc->sc_dev.dv_xname, __func__, why)); + + s = splnet(); + + switch (why) { + case PWR_STANDBY: + case PWR_SUSPEND: + pgt_stop(sc, SC_NEEDS_RESET); + pgt_update_hw_from_sw(sc, 0, 0); + + if (sc->sc_power != NULL) + (*sc->sc_power)(sc, why); + break; + case PWR_RESUME: + if (sc->sc_power != NULL) + (*sc->sc_power)(sc, why); + + pgt_stop(sc, SC_NEEDS_RESET); + pgt_update_hw_from_sw(sc, 0, 0); + + if ((ifp->if_flags & IFF_UP) && + !(ifp->if_flags & IFF_RUNNING)) { + pgt_init(ifp); + pgt_update_hw_from_sw(sc, 0, 0); + } + break; + } + + splx(s); +} diff --git a/sys/dev/ic/pgtvar.h b/sys/dev/ic/pgtvar.h index d4c6f9ba860..0407201a561 100644 --- a/sys/dev/ic/pgtvar.h +++ b/sys/dev/ic/pgtvar.h @@ -1,4 +1,4 @@ -/* $OpenBSD: pgtvar.h,v 1.9 2006/10/06 21:55:33 mglocker Exp $ */ +/* $OpenBSD: pgtvar.h,v 1.10 2006/10/09 20:45:27 mglocker Exp $ */ /* * Copyright (c) 2006 Claudio Jeker <claudio@openbsd.org> @@ -178,6 +178,8 @@ struct pgt_softc { int (*sc_enable)(struct pgt_softc *); void (*sc_disable)(struct pgt_softc *); void (*sc_power)(struct pgt_softc *, int); + void *sc_shutdown_hook; /* shutdown hook */ + void *sc_power_hook; /* power mgmt hook */ struct pgt_mgmt_descq sc_mgmtinprog; struct pgt_descq sc_freeq[PGT_QUEUE_COUNT]; @@ -213,8 +215,7 @@ struct pgt_softc { int pgt_intr(void *); void pgt_attach(void *); -int pgt_detach(struct pgt_softc *sc); -void pgt_reboot(struct pgt_softc *); +int pgt_detach(struct pgt_softc *); static __inline int pgt_queue_is_rx(enum pgt_queue pq) |