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:
parent
fe809f14f2
commit
bb8b57703e
@ -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";
|
||||
};
|
||||
*/
|
||||
|
@ -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.
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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");
|
||||
|
@ -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:
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -727,6 +727,8 @@ acpi_tz_notify_handler(ACPI_HANDLE h, UINT32 notify, void *context)
|
||||
break;
|
||||
}
|
||||
|
||||
acpi_UserNotify("Thermal", h, notify);
|
||||
|
||||
return_VOID;
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user