From owner-freebsd-current Sat Nov 9 12:33:13 2002 Delivered-To: freebsd-current@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 7ACAF37B401 for ; Sat, 9 Nov 2002 12:33:08 -0800 (PST) Received: from salmon.maths.tcd.ie (salmon.maths.tcd.ie [134.226.81.11]) by mx1.FreeBSD.org (Postfix) with SMTP id 3569943E4A for ; Sat, 9 Nov 2002 12:33:07 -0800 (PST) (envelope-from iedowse@maths.tcd.ie) Received: from walton.maths.tcd.ie by salmon.maths.tcd.ie with SMTP id ; 9 Nov 2002 20:33:06 +0000 (GMT) To: Takanori Watanabe Cc: acpi-jp@jp.FreeBSD.org, current@freebsd.org, Frode Nordahl Subject: Re: [acpi-jp 1925] Re: acpid implementation? In-Reply-To: Your message of "Sun, 10 Nov 2002 04:22:45 +0900." <200211091922.EAA09939@axe-inc.co.jp> Date: Sat, 09 Nov 2002 20:33:03 +0000 From: Ian Dowse Message-ID: <200211092033.aa99235@salmon.maths.tcd.ie> Sender: owner-freebsd-current@FreeBSD.ORG Precedence: bulk List-ID: List-Archive: (Web Archive) List-Help: (List Instructions) List-Subscribe: List-Unsubscribe: X-Loop: FreeBSD.ORG In message <200211091922.EAA09939@axe-inc.co.jp>, Takanori Watanabe writes: >It is obious there will be good if we have a way to catch power >event from userland. > >I have some ideas to implement it. >One way is implement with kqueue(2) and /dev/acpi to >get power events. This way does not require daemons >to wait the event exclusively. Each process that requires >to get power event can handle it by the interface. >I wrote the experimental code a years ago. I've been using the following far-from-ideal patch for a while now - it just supplies binary integers to /dev/acpi whenever the sleep state changes. The choice of encoding of data is stupid, and the acpiread() doesn't do blocking - I just use it in a script like while :; do sleep 5 acpidat="`wc -c < /dev/acpi`" if [ "$acpidat" -gt 0 ]; then killall -HUP moused fi done to send a SIGHUP to moused after a resume, which seems to be necessary on my Vaio C1. Ian Index: acpi.c =================================================================== RCS file: /dump/FreeBSD-CVS/src/sys/dev/acpica/acpi.c,v retrieving revision 1.80 diff -u -r1.80 acpi.c --- acpi.c 31 Oct 2002 20:23:41 -0000 1.80 +++ acpi.c 9 Nov 2002 20:20:10 -0000 @@ -32,6 +32,7 @@ #include "opt_acpi.h" #include #include +#include #include #include #include @@ -42,6 +43,7 @@ #include #include #include +#include #include #include @@ -69,16 +71,18 @@ static d_open_t acpiopen; static d_close_t acpiclose; +static d_read_t acpiread; static d_ioctl_t acpiioctl; +static d_poll_t acpipoll; #define CDEV_MAJOR 152 static struct cdevsw acpi_cdevsw = { acpiopen, acpiclose, - noread, + acpiread, nowrite, acpiioctl, - nopoll, + acpipoll, nommap, nostrategy, "acpi", @@ -1327,6 +1331,9 @@ } sc->acpi_sstate = state; + if (sc->acpi_usereventq_len < ACPI_USER_EVENTQ_LEN) + sc->acpi_usereventq[sc->acpi_usereventq_len++] = state; + selwakeup(&sc->acpi_selp); sc->acpi_sleep_disabled = 1; /* @@ -1375,6 +1382,9 @@ AcpiLeaveSleepState((UINT8)state); DEVICE_RESUME(root_bus); sc->acpi_sstate = ACPI_STATE_S0; + if (sc->acpi_usereventq_len < ACPI_USER_EVENTQ_LEN) + sc->acpi_usereventq[sc->acpi_usereventq_len++] = ACPI_STATE_S0; + selwakeup(&sc->acpi_selp); acpi_enable_fixed_events(sc); break; @@ -1808,6 +1818,35 @@ return(0); } +int +acpiread(dev_t dev, struct uio *uio, int flag) +{ + struct acpi_softc *sc; + int bytes, error, events, i; + + ACPI_LOCK; + + sc = dev->si_drv1; + + error = 0; + if (uio->uio_resid >= sizeof(int) && sc->acpi_usereventq_len > 0) { + events = sc->acpi_usereventq_len; + if (events > uio->uio_resid / sizeof(int)) + events = uio->uio_resid / sizeof(int); + bytes = events * sizeof(int); + error = uiomove((caddr_t)sc->acpi_usereventq, bytes, uio); + if (!error) { + for (i = 0; i < sc->acpi_usereventq_len - events; i++) + sc->acpi_usereventq[i] = sc->acpi_usereventq[i + events]; + sc->acpi_usereventq_len -= events; + } + } + + ACPI_UNLOCK; + + return (error); +} + static int acpiioctl(dev_t dev, u_long cmd, caddr_t addr, int flag, d_thread_t *td) { @@ -1871,6 +1910,25 @@ out: ACPI_UNLOCK; return(error); +} + +static int +acpipoll(dev_t dev, int events, d_thread_t *td) +{ + struct acpi_softc *sc; + int revents; + + ACPI_LOCK; + sc = dev->si_drv1; + + revents = events & (POLLOUT | POLLWRNORM); + if ((events & (POLLIN | POLLRDNORM)) && sc->acpi_usereventq_len > 0) { + revents |= (POLLIN | POLLRDNORM); + selrecord(td, &sc->acpi_selp); + } + + ACPI_UNLOCK; + return (revents); } static int Index: acpivar.h =================================================================== RCS file: /dump/FreeBSD-CVS/src/sys/dev/acpica/acpivar.h,v retrieving revision 1.37 diff -u -r1.37 acpivar.h --- acpivar.h 31 Oct 2002 17:58:38 -0000 1.37 +++ acpivar.h 9 Nov 2002 20:20:10 -0000 @@ -30,6 +30,7 @@ #include "bus_if.h" #include +#include #include #if __FreeBSD_version >= 500000 #include @@ -50,6 +51,11 @@ int acpi_enabled; int acpi_sstate; int acpi_sleep_disabled; + +#define ACPI_USER_EVENTQ_LEN 4 + int acpi_usereventq[ACPI_USER_EVENTQ_LEN]; + int acpi_usereventq_len; + struct selinfo acpi_selp; struct sysctl_ctx_list acpi_sysctl_ctx; struct sysctl_oid *acpi_sysctl_tree; To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-current" in the body of the message