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
c365ed47e4
commit
9b937d4836
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=121493
@ -93,4 +93,30 @@ detach 10 {
|
|||||||
action "/etc/pccard_ether $device-name stop";
|
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 "acpi.h"
|
||||||
#include <dev/acpica/acpivar.h>
|
#include <dev/acpica/acpivar.h>
|
||||||
#include <dev/acpica/acpiio.h>
|
#include <dev/acpica/acpiio.h>
|
||||||
|
#include <contrib/dev/acpica/acnamesp.h>
|
||||||
|
|
||||||
MALLOC_DEFINE(M_ACPIDEV, "acpidev", "ACPI devices");
|
MALLOC_DEFINE(M_ACPIDEV, "acpidev", "ACPI devices");
|
||||||
|
|
||||||
@ -2054,6 +2055,27 @@ acpi_sleep_state_sysctl(SYSCTL_HANDLER_ARGS)
|
|||||||
return (error);
|
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
|
#ifdef ACPI_DEBUG
|
||||||
/*
|
/*
|
||||||
* Support for parsing debug options from the kernel environment.
|
* Support for parsing debug options from the kernel environment.
|
||||||
|
@ -39,7 +39,7 @@
|
|||||||
#include <sys/conf.h>
|
#include <sys/conf.h>
|
||||||
#include <sys/power.h>
|
#include <sys/power.h>
|
||||||
|
|
||||||
#include "acpi.h"
|
#include "acpi.h"
|
||||||
#include <dev/acpica/acpivar.h>
|
#include <dev/acpica/acpivar.h>
|
||||||
#include <dev/acpica/acpiio.h>
|
#include <dev/acpica/acpiio.h>
|
||||||
|
|
||||||
@ -108,6 +108,8 @@ acpi_acad_get_status(void *context)
|
|||||||
POWER_PROFILE_ECONOMY);
|
POWER_PROFILE_ECONOMY);
|
||||||
ACPI_VPRINT(dev, acpi_device_get_parent_softc(dev),
|
ACPI_VPRINT(dev, acpi_device_get_parent_softc(dev),
|
||||||
"%s Line\n", sc->status ? "On" : "Off");
|
"%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)
|
if (acpi_sc == NULL)
|
||||||
return_VOID;
|
return_VOID;
|
||||||
|
|
||||||
|
acpi_UserNotify("Button", sc->button_handle, sc->button_type);
|
||||||
|
|
||||||
switch (sc->button_type) {
|
switch (sc->button_type) {
|
||||||
case ACPI_POWER_BUTTON:
|
case ACPI_POWER_BUTTON:
|
||||||
ACPI_VPRINT(sc->button_dev, acpi_sc, "power button pressed\n");
|
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)
|
if (acpi_sc == NULL)
|
||||||
return_VOID;
|
return_VOID;
|
||||||
|
|
||||||
|
acpi_UserNotify("Button", sc->button_handle, sc->button_type);
|
||||||
|
|
||||||
switch (sc->button_type) {
|
switch (sc->button_type) {
|
||||||
case ACPI_POWER_BUTTON:
|
case ACPI_POWER_BUTTON:
|
||||||
ACPI_VPRINT(sc->button_dev, acpi_sc, "wakeup by power button\n");
|
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)
|
if ((sc = device_get_softc(dev)) == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
acpi_UserNotify("CMBAT", h, notify);
|
||||||
|
|
||||||
switch (notify) {
|
switch (notify) {
|
||||||
case ACPI_NOTIFY_DEVICE_CHECK:
|
case ACPI_NOTIFY_DEVICE_CHECK:
|
||||||
case ACPI_BATTERY_BST_CHANGE:
|
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_suspend(device_t dev);
|
||||||
static int acpi_lid_resume(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_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[] = {
|
static device_method_t acpi_lid_methods[] = {
|
||||||
/* Device interface */
|
/* Device interface */
|
||||||
@ -149,6 +150,8 @@ acpi_lid_notify_status_changed(void *arg)
|
|||||||
ACPI_VPRINT(sc->lid_dev, acpi_sc, "Lid %s\n",
|
ACPI_VPRINT(sc->lid_dev, acpi_sc, "Lid %s\n",
|
||||||
sc->lid_status ? "opened" : "closed");
|
sc->lid_status ? "opened" : "closed");
|
||||||
|
|
||||||
|
acpi_UserNotify("Lid", sc->lid_handle, sc->lid_status);
|
||||||
|
|
||||||
if (sc->lid_status == 0)
|
if (sc->lid_status == 0)
|
||||||
EVENTHANDLER_INVOKE(acpi_sleep_event, acpi_sc->acpi_lid_switch_sx);
|
EVENTHANDLER_INVOKE(acpi_sleep_event, acpi_sc->acpi_lid_switch_sx);
|
||||||
else
|
else
|
||||||
@ -178,4 +181,3 @@ acpi_lid_notify_handler(ACPI_HANDLE h, UINT32 notify, void *context)
|
|||||||
|
|
||||||
return_VOID;
|
return_VOID;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -727,6 +727,8 @@ acpi_tz_notify_handler(ACPI_HANDLE h, UINT32 notify, void *context)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
acpi_UserNotify("Thermal", h, notify);
|
||||||
|
|
||||||
return_VOID;
|
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_SetSleepState(struct acpi_softc *sc, int state);
|
||||||
extern ACPI_STATUS acpi_Enable(struct acpi_softc *sc);
|
extern ACPI_STATUS acpi_Enable(struct acpi_softc *sc);
|
||||||
extern ACPI_STATUS acpi_Disable(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 {
|
struct acpi_parse_resource_set {
|
||||||
void (*set_init)(device_t dev, void **context);
|
void (*set_init)(device_t dev, void **context);
|
||||||
|
Loading…
Reference in New Issue
Block a user