Source-Changes-HG archive

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

[src/trunk]: src As proposed on tech-net@, introduce a new switch type, PSWIT...



details:   https://anonhg.NetBSD.org/src/rev/55fde1cc5dd8
branches:  trunk
changeset: 335427:55fde1cc5dd8
user:      bouyer <bouyer%NetBSD.org@localhost>
date:      Tue Jan 06 15:39:54 2015 +0000

description:
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.

diffstat:

 share/man/man9/sysmon_pswitch.9 |   5 +-
 sys/dev/pci/if_wpi.c            |  74 +++++++++++++++++++++++++++++++++++++++-
 sys/dev/pci/if_wpivar.h         |  11 +++++-
 sys/dev/sysmon/sysmon_power.c   |   5 +-
 sys/sys/power.h                 |   7 +++-
 5 files changed, 93 insertions(+), 9 deletions(-)

diffs (259 lines):

diff -r dc551cba698d -r 55fde1cc5dd8 share/man/man9/sysmon_pswitch.9
--- a/share/man/man9/sysmon_pswitch.9   Tue Jan 06 15:13:16 2015 +0000
+++ b/share/man/man9/sysmon_pswitch.9   Tue Jan 06 15:39:54 2015 +0000
@@ -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 @@
 .It PSWITCH_TYPE_RESET
 .It PSWITCH_TYPE_ACADAPTER
 .It PSWITCH_TYPE_HOTKEY
+.It PSWITCH_TYPE_RADIO
 .El
 .Pp
 If the type is
diff -r dc551cba698d -r 55fde1cc5dd8 sys/dev/pci/if_wpi.c
--- a/sys/dev/pci/if_wpi.c      Tue Jan 06 15:13:16 2015 +0000
+++ b/sys/dev/pci/if_wpi.c      Tue Jan 06 15:39:54 2015 +0000
@@ -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 @@
 #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 @@
 #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 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 @@
        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 @@
                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 @@
                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 @@
 
                        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 @@
        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 @@
        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 @@
 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);
+       }
+}
+
diff -r dc551cba698d -r 55fde1cc5dd8 sys/dev/pci/if_wpivar.h
--- a/sys/dev/pci/if_wpivar.h   Tue Jan 06 15:13:16 2015 +0000
+++ b/sys/dev/pci/if_wpivar.h   Tue Jan 06 15:39:54 2015 +0000
@@ -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 @@
        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;
 };
diff -r dc551cba698d -r 55fde1cc5dd8 sys/dev/sysmon/sysmon_power.c
--- a/sys/dev/sysmon/sysmon_power.c     Tue Jan 06 15:13:16 2015 +0000
+++ b/sys/dev/sysmon/sysmon_power.c     Tue Jan 06 15:39:54 2015 +0000
@@ -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 @@
        { PSWITCH_TYPE_RESET,           "reset_button" },
        { PSWITCH_TYPE_ACADAPTER,       "acadapter" },
        { PSWITCH_TYPE_HOTKEY,          "hotkey_button" },
+       { PSWITCH_TYPE_RADIO,           "radio_button" },
        { -1, NULL }
 };
 
diff -r dc551cba698d -r 55fde1cc5dd8 sys/sys/power.h
--- a/sys/sys/power.h   Tue Jan 06 15:13:16 2015 +0000
+++ b/sys/sys/power.h   Tue Jan 06 15:39:54 2015 +0000
@@ -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 */



Home | Main Index | Thread Index | Old Index