As proposed on tech-net@, introduce a new switch type, PSWITCH_TYPE_RADIO,
to be used to report to userland hardware radio switch changes. powerd(8) will call a "radio_button" script to handle the event. This script can e.g. start or stop wpa_supplicant. Update wpi(4) to report PSWITCH_TYPE_RADIO events to sysmon.
This commit is contained in:
parent
87706a3247
commit
87fe8c7aca
|
@ -1,4 +1,4 @@
|
|||
.\" $NetBSD: sysmon_pswitch.9,v 1.5 2014/03/18 18:20:40 riastradh Exp $
|
||||
.\" $NetBSD: sysmon_pswitch.9,v 1.6 2015/01/06 15:39:54 bouyer Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 2010 The NetBSD Foundation, Inc.
|
||||
.\" All rights reserved.
|
||||
|
@ -27,7 +27,7 @@
|
|||
.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
.\" POSSIBILITY OF SUCH DAMAGE.
|
||||
.\"
|
||||
.Dd January 26, 2010
|
||||
.Dd January 6, 2015
|
||||
.Dt SYSMON_PSWITCH 9
|
||||
.Os
|
||||
.Sh NAME
|
||||
|
@ -75,6 +75,7 @@ The following types are defined:
|
|||
.It PSWITCH_TYPE_RESET
|
||||
.It PSWITCH_TYPE_ACADAPTER
|
||||
.It PSWITCH_TYPE_HOTKEY
|
||||
.It PSWITCH_TYPE_RADIO
|
||||
.El
|
||||
.Pp
|
||||
If the type is
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: if_wpi.c,v 1.69 2014/12/19 11:54:02 bouyer Exp $ */
|
||||
/* $NetBSD: if_wpi.c,v 1.70 2015/01/06 15:39:54 bouyer Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2006, 2007
|
||||
|
@ -18,7 +18,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: if_wpi.c,v 1.69 2014/12/19 11:54:02 bouyer Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: if_wpi.c,v 1.70 2015/01/06 15:39:54 bouyer Exp $");
|
||||
|
||||
/*
|
||||
* Driver for Intel PRO/Wireless 3945ABG 802.11 network adapters.
|
||||
|
@ -39,6 +39,7 @@ __KERNEL_RCSID(0, "$NetBSD: if_wpi.c,v 1.69 2014/12/19 11:54:02 bouyer Exp $");
|
|||
#include <sys/kauth.h>
|
||||
#include <sys/callout.h>
|
||||
#include <sys/proc.h>
|
||||
#include <sys/kthread.h>
|
||||
|
||||
#include <sys/bus.h>
|
||||
#include <machine/endian.h>
|
||||
|
@ -48,6 +49,8 @@ __KERNEL_RCSID(0, "$NetBSD: if_wpi.c,v 1.69 2014/12/19 11:54:02 bouyer Exp $");
|
|||
#include <dev/pci/pcivar.h>
|
||||
#include <dev/pci/pcidevs.h>
|
||||
|
||||
#include <dev/sysmon/sysmonvar.h>
|
||||
|
||||
#include <net/bpf.h>
|
||||
#include <net/if.h>
|
||||
#include <net/if_arp.h>
|
||||
|
@ -153,6 +156,7 @@ static void wpi_stop(struct ifnet *, int);
|
|||
static bool wpi_resume(device_t, const pmf_qual_t *);
|
||||
static int wpi_getrfkill(struct wpi_softc *);
|
||||
static void wpi_sysctlattach(struct wpi_softc *);
|
||||
static void wpi_rsw_thread(void *);
|
||||
|
||||
#ifdef WPI_DEBUG
|
||||
#define DPRINTF(x) do { if (wpi_debug > 0) printf x; } while (0)
|
||||
|
@ -214,6 +218,22 @@ wpi_attach(device_t parent __unused, device_t self, void *aux)
|
|||
sc->sc_pct = pa->pa_pc;
|
||||
sc->sc_pcitag = pa->pa_tag;
|
||||
|
||||
sc->sc_rsw_status = WPI_RSW_UNKNOWN;
|
||||
sc->sc_rsw.smpsw_name = device_xname(self);
|
||||
sc->sc_rsw.smpsw_type = PSWITCH_TYPE_RADIO;
|
||||
error = sysmon_pswitch_register(&sc->sc_rsw);
|
||||
if (error) {
|
||||
aprint_error_dev(self,
|
||||
"unable to register radio switch with sysmon\n");
|
||||
return;
|
||||
}
|
||||
mutex_init(&sc->sc_rsw_mtx, MUTEX_DEFAULT, IPL_NONE);
|
||||
cv_init(&sc->sc_rsw_cv, "wpirsw");
|
||||
if (kthread_create(PRI_NONE, 0, NULL,
|
||||
wpi_rsw_thread, sc, &sc->sc_rsw_lwp, "%s", device_xname(self))) {
|
||||
aprint_error_dev(self, "couldn't create switch thread\n");
|
||||
}
|
||||
|
||||
callout_init(&sc->calib_to, 0);
|
||||
callout_setfunc(&sc->calib_to, wpi_calib_timeout, sc);
|
||||
|
||||
|
@ -411,6 +431,13 @@ wpi_detach(device_t self, int flags __unused)
|
|||
pci_intr_disestablish(sc->sc_pct, sc->sc_ih);
|
||||
sc->sc_ih = NULL;
|
||||
}
|
||||
mutex_enter(&sc->sc_rsw_mtx);
|
||||
sc->sc_dying = 1;
|
||||
cv_signal(&sc->sc_rsw_cv);
|
||||
while (sc->sc_rsw_lwp != NULL)
|
||||
cv_wait(&sc->sc_rsw_cv, &sc->sc_rsw_mtx);
|
||||
mutex_exit(&sc->sc_rsw_mtx);
|
||||
sysmon_pswitch_unregister(&sc->sc_rsw);
|
||||
|
||||
bus_space_unmap(sc->sc_st, sc->sc_sh, sc->sc_sz);
|
||||
|
||||
|
@ -418,7 +445,8 @@ wpi_detach(device_t self, int flags __unused)
|
|||
sc->fw_used = false;
|
||||
wpi_release_firmware();
|
||||
}
|
||||
|
||||
cv_destroy(&sc->sc_rsw_cv);
|
||||
mutex_destroy(&sc->sc_rsw_mtx);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1688,6 +1716,8 @@ wpi_notif_intr(struct wpi_softc *sc)
|
|||
|
||||
if (le32toh(*status) & 1) {
|
||||
/* the radio button has to be pushed */
|
||||
/* wake up thread to signal powerd */
|
||||
cv_signal(&sc->sc_rsw_cv);
|
||||
aprint_error_dev(sc->sc_dev,
|
||||
"Radio transmitter is off\n");
|
||||
/* turn the interface down */
|
||||
|
@ -3276,6 +3306,23 @@ wpi_getrfkill(struct wpi_softc *sc)
|
|||
tmp = wpi_mem_read(sc, WPI_MEM_RFKILL);
|
||||
wpi_mem_unlock(sc);
|
||||
|
||||
KASSERT(mutex_owned(&sc->sc_rsw_mtx));
|
||||
if (tmp & 0x01) {
|
||||
/* switch is on */
|
||||
if (sc->sc_rsw_status != WPI_RSW_ON) {
|
||||
sc->sc_rsw_status = WPI_RSW_ON;
|
||||
sysmon_pswitch_event(&sc->sc_rsw,
|
||||
PSWITCH_EVENT_PRESSED);
|
||||
}
|
||||
} else {
|
||||
/* switch is off */
|
||||
if (sc->sc_rsw_status != WPI_RSW_OFF) {
|
||||
sc->sc_rsw_status = WPI_RSW_OFF;
|
||||
sysmon_pswitch_event(&sc->sc_rsw,
|
||||
PSWITCH_EVENT_RELEASED);
|
||||
}
|
||||
}
|
||||
|
||||
return !(tmp & 0x01);
|
||||
}
|
||||
|
||||
|
@ -3289,7 +3336,9 @@ wpi_sysctl_radio(SYSCTLFN_ARGS)
|
|||
node = *rnode;
|
||||
sc = (struct wpi_softc *)node.sysctl_data;
|
||||
|
||||
mutex_enter(&sc->sc_rsw_mtx);
|
||||
val = !wpi_getrfkill(sc);
|
||||
mutex_exit(&sc->sc_rsw_mtx);
|
||||
|
||||
node.sysctl_data = &val;
|
||||
error = sysctl_lookup(SYSCTLFN_CALL(&node));
|
||||
|
@ -3334,3 +3383,22 @@ wpi_sysctlattach(struct wpi_softc *sc)
|
|||
err:
|
||||
aprint_error("%s: sysctl_createv failed (rc = %d)\n", __func__, rc);
|
||||
}
|
||||
|
||||
static void
|
||||
wpi_rsw_thread(void *arg)
|
||||
{
|
||||
struct wpi_softc *sc = (struct wpi_softc *)arg;
|
||||
|
||||
mutex_enter(&sc->sc_rsw_mtx);
|
||||
for (;;) {
|
||||
cv_timedwait(&sc->sc_rsw_cv, &sc->sc_rsw_mtx, hz);
|
||||
if (sc->sc_dying) {
|
||||
sc->sc_rsw_lwp = NULL;
|
||||
cv_broadcast(&sc->sc_rsw_cv);
|
||||
mutex_exit(&sc->sc_rsw_mtx);
|
||||
kthread_exit(0);
|
||||
}
|
||||
wpi_getrfkill(sc);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: if_wpivar.h,v 1.18 2014/08/09 15:07:06 jmcneill Exp $ */
|
||||
/* $NetBSD: if_wpivar.h,v 1.19 2015/01/06 15:39:54 bouyer Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2006
|
||||
|
@ -187,4 +187,13 @@ struct wpi_softc {
|
|||
bool is_scanning;
|
||||
|
||||
struct sysctllog *sc_sysctllog;
|
||||
struct sysmon_pswitch sc_rsw; /* for radio switch events */
|
||||
int sc_rsw_status;
|
||||
#define WPI_RSW_UNKNOWN 0
|
||||
#define WPI_RSW_OFF 1
|
||||
#define WPI_RSW_ON 2
|
||||
struct lwp *sc_rsw_lwp;
|
||||
struct kmutex sc_rsw_mtx;
|
||||
struct kcondvar sc_rsw_cv;
|
||||
int sc_dying;
|
||||
};
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: sysmon_power.c,v 1.48 2014/11/21 23:28:57 joerg Exp $ */
|
||||
/* $NetBSD: sysmon_power.c,v 1.49 2015/01/06 15:39:54 bouyer Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2007 Juan Romero Pardines.
|
||||
|
@ -69,7 +69,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: sysmon_power.c,v 1.48 2014/11/21 23:28:57 joerg Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: sysmon_power.c,v 1.49 2015/01/06 15:39:54 bouyer Exp $");
|
||||
|
||||
#include "opt_compat_netbsd.h"
|
||||
#include <sys/param.h>
|
||||
|
@ -121,6 +121,7 @@ static const struct power_event_description pswitch_type_desc[] = {
|
|||
{ PSWITCH_TYPE_RESET, "reset_button" },
|
||||
{ PSWITCH_TYPE_ACADAPTER, "acadapter" },
|
||||
{ PSWITCH_TYPE_HOTKEY, "hotkey_button" },
|
||||
{ PSWITCH_TYPE_RADIO, "radio_button" },
|
||||
{ -1, NULL }
|
||||
};
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: power.h,v 1.19 2013/03/30 19:05:20 christos Exp $ */
|
||||
/* $NetBSD: power.h,v 1.20 2015/01/06 15:39:54 bouyer Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2003 Wasabi Systems, Inc.
|
||||
|
@ -83,6 +83,10 @@
|
|||
* of switch has state. We know if it is open
|
||||
* or closed.
|
||||
*
|
||||
* Radio switch This is e.g. the switch of the transmitter
|
||||
* of a wifi interface. We know if it is
|
||||
* on or off.
|
||||
*
|
||||
*/
|
||||
|
||||
#define PSWITCH_TYPE_POWER 0 /* power button */
|
||||
|
@ -111,6 +115,7 @@
|
|||
#define PSWITCH_HK_VOLUME_DOWN "volume-down"
|
||||
#define PSWITCH_HK_VOLUME_MUTE "volume-mute"
|
||||
#endif /* THINKPAD_NORMAL_HOTKEYS */
|
||||
#define PSWITCH_TYPE_RADIO 6 /* radio switch */
|
||||
|
||||
#define PSWITCH_EVENT_PRESSED 0 /* button pressed, lid closed, AC off */
|
||||
#define PSWITCH_EVENT_RELEASED 1 /* button released, lid open, AC on */
|
||||
|
|
Loading…
Reference in New Issue