Re: [acpi-jp 1925] Re: acpid implementation?

2002-11-09 Thread Takanori Watanabe
In message [EMAIL PROTECTED], Terry Lambert wrote:
Hiten Pandya wrote:
  I have been searching mailing lists and my friend Google for information
  about a acpid (like apmd) implementation for FreeBSD, but I have found
  nothing.
 
  Does one exist anywhere, or has anyone started out on something without
  telling anyone? :)
 
 Why do you need an acpid?

Power profiles, for one.

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.


Next way is that make /dev/acpictl node that can open
exclusively and catch the power event by it, like apmd.

The last way is that extend /dev/devctl interface and
devd(8) that can handle power event.

To Unsubscribe: send mail to [EMAIL PROTECTED]
with unsubscribe freebsd-current in the body of the message



Re: [acpi-jp 1925] Re: acpid implementation?

2002-11-09 Thread Ian Dowse
In message [EMAIL PROTECTED], 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 -  1.80
+++ acpi.c  9 Nov 2002 20:20:10 -
@@ -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_tacpiopen;
 static d_close_t   acpiclose;
+static d_read_tacpiread;
 static d_ioctl_t   acpiioctl;
+static d_poll_tacpipoll;
 
 #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;
+intbytes, 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;
+intrevents;
+
+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 -  1.37
+++ acpivar.h   9 Nov 2002 20:20:10 -
@@ -30,6 +30,7 @@
 
 #include bus_if.h
 #include sys/eventhandler.h
+#include sys/selinfo.h
 #include sys/sysctl.h
 #if __FreeBSD_version = 50
 #include sys/lock.h
@@ -50,6 +51,11 @@
 intacpi_enabled;
 intacpi_sstate;
 intacpi_sleep_disabled;
+
+#define ACPI_USER_EVENTQ_LEN   4
+intacpi_usereventq[ACPI_USER_EVENTQ_LEN];
+intacpi_usereventq_len;
+struct selinfo acpi_selp;
 
 struct