Date: Sat, 09 Nov 2002 20:33:03 +0000 From: Ian Dowse <iedowse@maths.tcd.ie> To: Takanori Watanabe <takawata@axe-inc.co.jp> Cc: acpi-jp@jp.FreeBSD.org, current@freebsd.org, Frode Nordahl <frode@nordahl.net> Subject: Re: [acpi-jp 1925] Re: acpid implementation? Message-ID: <200211092033.aa99235@salmon.maths.tcd.ie> In-Reply-To: Your message of "Sun, 10 Nov 2002 04:22:45 %2B0900." <200211091922.EAA09939@axe-inc.co.jp>
next in thread | previous in thread | raw e-mail | index | archive | help
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 <sys/param.h> #include <sys/kernel.h> +#include <sys/poll.h> #include <sys/proc.h> #include <sys/malloc.h> #include <sys/bus.h> @@ -42,6 +43,7 @@ #include <sys/ctype.h> #include <sys/linker.h> #include <sys/power.h> +#include <sys/uio.h> #include <machine/clock.h> #include <machine/resource.h> @@ -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 <sys/eventhandler.h> +#include <sys/selinfo.h> #include <sys/sysctl.h> #if __FreeBSD_version >= 500000 #include <sys/lock.h> @@ -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
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200211092033.aa99235>