Add devctl(4) notify support to ACPI. Various subsystems now notify

userland whenever events occur.  See the example in devd.conf below
to see how to use it.
This commit is contained in:
Nate Lawson 2003-10-25 05:03:25 +00:00
parent c365ed47e4
commit 9b937d4836
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=121493
8 changed files with 65 additions and 3 deletions

View File

@ -93,4 +93,30 @@ detach 10 {
action "/etc/pccard_ether $device-name stop";
};
# Examples of notify hooks. A notify is a generic way for a kernel
# subsystem to send event notification to userland.
#
# Here are some examples of ACPI notify handlers. ACPI subsystems that
# generate notifies include the AC adapter, power/sleep buttons,
# control method batteries, lid switch, and thermal zones.
#
# Information returned is not always the same as the ACPI notify
# events. See the ACPI specification for more information about
# notifies. Here is the information returned for each subsystem:
#
# ACAD: AC line state (0 is offline, 1 is online)
# Button: Button pressed (0 for power, 1 for sleep)
# CMBAT: ACPI battery events
# Lid: Lid state (0 is closed, 1 is open)
# Thermal: ACPI thermal zone events
#
# This example calls a script when the AC state changes, passing the
# notify value as the first argument. If the state is 0x00, it might
# call some sysctls to implement economy mode. If 0x01, it might set
# the mode to performance.
notify 10 {
match "system" "ACPI";
match "subsystem" "ACAD";
action "/etc/acpi_ac $notify";
};
*/

View File

@ -51,6 +51,7 @@
#include "acpi.h"
#include <dev/acpica/acpivar.h>
#include <dev/acpica/acpiio.h>
#include <contrib/dev/acpica/acnamesp.h>
MALLOC_DEFINE(M_ACPIDEV, "acpidev", "ACPI devices");
@ -2054,6 +2055,27 @@ acpi_sleep_state_sysctl(SYSCTL_HANDLER_ARGS)
return (error);
}
/* Inform devctl(4) when we receive a Notify. */
void
acpi_UserNotify(const char *subsystem, ACPI_HANDLE h, uint8_t notify)
{
char notify_buf[16];
ACPI_BUFFER handle_buf;
ACPI_STATUS status;
if (subsystem == NULL)
return;
handle_buf.Pointer = NULL;
handle_buf.Length = ACPI_ALLOCATE_BUFFER;
status = AcpiNsHandleToPathname(h, &handle_buf);
if (ACPI_FAILURE(status))
return;
snprintf(notify_buf, sizeof(notify_buf), "notify=0x%02x", notify);
devctl_notify("ACPI", subsystem, handle_buf.Pointer, notify_buf);
AcpiOsFree(handle_buf.Pointer);
}
#ifdef ACPI_DEBUG
/*
* Support for parsing debug options from the kernel environment.

View File

@ -39,7 +39,7 @@
#include <sys/conf.h>
#include <sys/power.h>
#include "acpi.h"
#include "acpi.h"
#include <dev/acpica/acpivar.h>
#include <dev/acpica/acpiio.h>
@ -108,6 +108,8 @@ acpi_acad_get_status(void *context)
POWER_PROFILE_ECONOMY);
ACPI_VPRINT(dev, acpi_device_get_parent_softc(dev),
"%s Line\n", sc->status ? "On" : "Off");
acpi_UserNotify("ACAD", h, sc->status);
}
}

View File

@ -175,6 +175,8 @@ acpi_button_notify_pressed_for_sleep(void *arg)
if (acpi_sc == NULL)
return_VOID;
acpi_UserNotify("Button", sc->button_handle, sc->button_type);
switch (sc->button_type) {
case ACPI_POWER_BUTTON:
ACPI_VPRINT(sc->button_dev, acpi_sc, "power button pressed\n");
@ -202,6 +204,8 @@ acpi_button_notify_pressed_for_wakeup(void *arg)
if (acpi_sc == NULL)
return_VOID;
acpi_UserNotify("Button", sc->button_handle, sc->button_type);
switch (sc->button_type) {
case ACPI_POWER_BUTTON:
ACPI_VPRINT(sc->button_dev, acpi_sc, "wakeup by power button\n");

View File

@ -295,6 +295,8 @@ acpi_cmbat_notify_handler(ACPI_HANDLE h, UINT32 notify, void *context)
if ((sc = device_get_softc(dev)) == NULL)
return;
acpi_UserNotify("CMBAT", h, notify);
switch (notify) {
case ACPI_NOTIFY_DEVICE_CHECK:
case ACPI_BATTERY_BST_CHANGE:

View File

@ -54,7 +54,8 @@ static int acpi_lid_attach(device_t dev);
static int acpi_lid_suspend(device_t dev);
static int acpi_lid_resume(device_t dev);
static void acpi_lid_notify_status_changed(void *arg);
static void acpi_lid_notify_handler(ACPI_HANDLE h,UINT32 notify, void *context);
static void acpi_lid_notify_handler(ACPI_HANDLE h, UINT32 notify,
void *context);
static device_method_t acpi_lid_methods[] = {
/* Device interface */
@ -149,6 +150,8 @@ acpi_lid_notify_status_changed(void *arg)
ACPI_VPRINT(sc->lid_dev, acpi_sc, "Lid %s\n",
sc->lid_status ? "opened" : "closed");
acpi_UserNotify("Lid", sc->lid_handle, sc->lid_status);
if (sc->lid_status == 0)
EVENTHANDLER_INVOKE(acpi_sleep_event, acpi_sc->acpi_lid_switch_sx);
else
@ -178,4 +181,3 @@ acpi_lid_notify_handler(ACPI_HANDLE h, UINT32 notify, void *context)
return_VOID;
}

View File

@ -727,6 +727,8 @@ acpi_tz_notify_handler(ACPI_HANDLE h, UINT32 notify, void *context)
break;
}
acpi_UserNotify("Thermal", h, notify);
return_VOID;
}

View File

@ -188,6 +188,8 @@ extern ACPI_STATUS acpi_SetIntrModel(int model);
extern ACPI_STATUS acpi_SetSleepState(struct acpi_softc *sc, int state);
extern ACPI_STATUS acpi_Enable(struct acpi_softc *sc);
extern ACPI_STATUS acpi_Disable(struct acpi_softc *sc);
extern void acpi_UserNotify(const char *subsystem, ACPI_HANDLE h,
uint8_t notify);
struct acpi_parse_resource_set {
void (*set_init)(device_t dev, void **context);