[Midnightbsd-cvs] src [10112] trunk/sys/dev/acpi_support/atk0110.c: update acpi support

laffer1 at midnightbsd.org laffer1 at midnightbsd.org
Sun May 27 19:55:15 EDT 2018


Revision: 10112
          http://svnweb.midnightbsd.org/src/?rev=10112
Author:   laffer1
Date:     2018-05-27 19:55:14 -0400 (Sun, 27 May 2018)
Log Message:
-----------
update acpi support

Modified Paths:
--------------
    trunk/sys/dev/acpi_support/acpi_asus.c
    trunk/sys/dev/acpi_support/acpi_fujitsu.c
    trunk/sys/dev/acpi_support/acpi_hp.c
    trunk/sys/dev/acpi_support/acpi_ibm.c
    trunk/sys/dev/acpi_support/acpi_panasonic.c
    trunk/sys/dev/acpi_support/acpi_sony.c
    trunk/sys/dev/acpi_support/acpi_toshiba.c
    trunk/sys/dev/acpi_support/acpi_wmi.c
    trunk/sys/dev/acpi_support/acpi_wmi_if.m
    trunk/sys/dev/acpi_support/atk0110.c

Added Paths:
-----------
    trunk/sys/dev/acpi_support/acpi_asus_wmi.c
    trunk/sys/dev/acpi_support/acpi_rapidstart.c

Property Changed:
----------------
    trunk/sys/dev/acpi_support/acpi_wmi_if.m

Modified: trunk/sys/dev/acpi_support/acpi_asus.c
===================================================================
--- trunk/sys/dev/acpi_support/acpi_asus.c	2018-05-27 23:54:55 UTC (rev 10111)
+++ trunk/sys/dev/acpi_support/acpi_asus.c	2018-05-27 23:55:14 UTC (rev 10112)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*-
  * Copyright (c) 2004, 2005 Philip Paeps <philip at FreeBSD.org>
  * All rights reserved.
@@ -25,7 +26,7 @@
  */
 
 #include <sys/cdefs.h>
-__MBSDID("$MidnightBSD$");
+__FBSDID("$FreeBSD: stable/10/sys/dev/acpi_support/acpi_asus.c 273736 2014-10-27 14:38:00Z hselasky $");
 
 /*
  * Driver for extra ACPI-controlled gadgets (hotkeys, leds, etc) found on
@@ -465,43 +466,39 @@
 	char	*name;
 	char	*description;
 	int	method;
-	int	flags;
+	int	flag_anybody;
 } acpi_asus_sysctls[] = {
 	{
 		.name		= "lcd_backlight",
 		.method		= ACPI_ASUS_METHOD_LCD,
 		.description	= "state of the lcd backlight",
-		.flags 		= CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_ANYBODY
+		.flag_anybody	= 1
 	},
 	{
 		.name		= "lcd_brightness",
 		.method		= ACPI_ASUS_METHOD_BRN,
 		.description	= "brightness of the lcd panel",
-		.flags 		= CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_ANYBODY
+		.flag_anybody	= 1
 	},
 	{
 		.name		= "video_output",
 		.method		= ACPI_ASUS_METHOD_DISP,
 		.description	= "display output state",
-		.flags 		= CTLTYPE_INT | CTLFLAG_RW
 	},
 	{
 		.name		= "camera",
 		.method		= ACPI_ASUS_METHOD_CAMERA,
 		.description	= "internal camera state",  
-		.flags 		= CTLTYPE_INT | CTLFLAG_RW
 	},
 	{
 		.name		= "cardreader",
 		.method		= ACPI_ASUS_METHOD_CARDRD,
 		.description	= "internal card reader state",
-		.flags 		= CTLTYPE_INT | CTLFLAG_RW
 	},
 	{
 		.name		= "wlan",
 		.method		= ACPI_ASUS_METHOD_WLAN,
 		.description	= "wireless lan state",
-		.flags		= CTLTYPE_INT | CTLFLAG_RW
 	},
 
 	{ .name = NULL }
@@ -741,12 +738,21 @@
 		if (!acpi_asus_sysctl_init(sc, acpi_asus_sysctls[i].method))
 			continue;
 
-		SYSCTL_ADD_PROC(&sc->sysctl_ctx,
-		    SYSCTL_CHILDREN(sc->sysctl_tree), OID_AUTO,
-		    acpi_asus_sysctls[i].name,
-		    acpi_asus_sysctls[i].flags,
-		    sc, i, acpi_asus_sysctl, "I",
-		    acpi_asus_sysctls[i].description);
+		if (acpi_asus_sysctls[i].flag_anybody != 0) {
+			SYSCTL_ADD_PROC(&sc->sysctl_ctx,
+			    SYSCTL_CHILDREN(sc->sysctl_tree), OID_AUTO,
+			    acpi_asus_sysctls[i].name,
+			    CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_ANYBODY,
+			    sc, i, acpi_asus_sysctl, "I",
+			    acpi_asus_sysctls[i].description);
+		} else {
+			SYSCTL_ADD_PROC(&sc->sysctl_ctx,
+			    SYSCTL_CHILDREN(sc->sysctl_tree), OID_AUTO,
+			    acpi_asus_sysctls[i].name,
+			    CTLTYPE_INT | CTLFLAG_RW,
+			    sc, i, acpi_asus_sysctl, "I",
+			    acpi_asus_sysctls[i].description);
+		}
 	}
 
 	/* Attach leds */

Added: trunk/sys/dev/acpi_support/acpi_asus_wmi.c
===================================================================
--- trunk/sys/dev/acpi_support/acpi_asus_wmi.c	                        (rev 0)
+++ trunk/sys/dev/acpi_support/acpi_asus_wmi.c	2018-05-27 23:55:14 UTC (rev 10112)
@@ -0,0 +1,638 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2012 Alexander Motin <mav at FreeBSD.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/sys/dev/acpi_support/acpi_asus_wmi.c 273736 2014-10-27 14:38:00Z hselasky $");
+
+#include "opt_acpi.h"
+#include <sys/param.h>
+#include <sys/conf.h>
+#include <sys/uio.h>
+#include <sys/proc.h>
+#include <sys/kernel.h>
+#include <sys/bus.h>
+#include <sys/sbuf.h>
+#include <sys/module.h>
+#include <sys/sysctl.h>
+
+#include <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/include/accommon.h>
+#include <dev/acpica/acpivar.h>
+#include "acpi_wmi_if.h"
+
+#define _COMPONENT	ACPI_OEM
+ACPI_MODULE_NAME("ASUS-WMI")
+
+#define ACPI_ASUS_WMI_MGMT_GUID 	"97845ED0-4E6D-11DE-8A39-0800200C9A66"
+#define ACPI_ASUS_WMI_EVENT_GUID	"0B3CBB35-E3C2-45ED-91C2-4C5A6D195D1C"
+#define ACPI_EEEPC_WMI_EVENT_GUID	"ABBC0F72-8EA1-11D1-00A0-C90629100000"
+
+/* WMI Methods */
+#define ASUS_WMI_METHODID_SPEC          0x43455053
+#define ASUS_WMI_METHODID_SFUN          0x4E554653
+#define ASUS_WMI_METHODID_DSTS          0x53544344
+#define ASUS_WMI_METHODID_DSTS2         0x53545344
+#define ASUS_WMI_METHODID_DEVS          0x53564544
+#define ASUS_WMI_METHODID_INIT          0x54494E49
+#define ASUS_WMI_METHODID_HKEY          0x59454B48
+
+#define ASUS_WMI_UNSUPPORTED_METHOD     0xFFFFFFFE
+
+/* Wireless */
+#define ASUS_WMI_DEVID_HW_SWITCH        0x00010001
+#define ASUS_WMI_DEVID_WIRELESS_LED     0x00010002
+#define ASUS_WMI_DEVID_CWAP             0x00010003
+#define ASUS_WMI_DEVID_WLAN             0x00010011
+#define ASUS_WMI_DEVID_BLUETOOTH        0x00010013
+#define ASUS_WMI_DEVID_GPS              0x00010015
+#define ASUS_WMI_DEVID_WIMAX            0x00010017
+#define ASUS_WMI_DEVID_WWAN3G           0x00010019
+#define ASUS_WMI_DEVID_UWB              0x00010021
+
+/* LEDs */
+#define ASUS_WMI_DEVID_LED1             0x00020011
+#define ASUS_WMI_DEVID_LED2             0x00020012
+#define ASUS_WMI_DEVID_LED3             0x00020013
+#define ASUS_WMI_DEVID_LED4             0x00020014
+#define ASUS_WMI_DEVID_LED5             0x00020015
+#define ASUS_WMI_DEVID_LED6             0x00020016
+
+/* Backlight and Brightness */
+#define ASUS_WMI_DEVID_BACKLIGHT        0x00050011
+#define ASUS_WMI_DEVID_BRIGHTNESS       0x00050012
+#define ASUS_WMI_DEVID_KBD_BACKLIGHT    0x00050021
+#define ASUS_WMI_DEVID_LIGHT_SENSOR     0x00050022
+
+/* Misc */
+#define ASUS_WMI_DEVID_CAMERA           0x00060013
+#define ASUS_WMI_DEVID_CARDREADER       0x00080013
+#define ASUS_WMI_DEVID_TOUCHPAD         0x00100011
+#define ASUS_WMI_DEVID_TOUCHPAD_LED     0x00100012
+#define ASUS_WMI_DEVID_THERMAL_CTRL     0x00110011
+#define ASUS_WMI_DEVID_FAN_CTRL         0x00110012
+#define ASUS_WMI_DEVID_PROCESSOR_STATE  0x00120012
+
+/* DSTS masks */
+#define ASUS_WMI_DSTS_STATUS_BIT        0x00000001
+#define ASUS_WMI_DSTS_UNKNOWN_BIT       0x00000002
+#define ASUS_WMI_DSTS_PRESENCE_BIT      0x00010000
+#define ASUS_WMI_DSTS_USER_BIT          0x00020000
+#define ASUS_WMI_DSTS_BIOS_BIT          0x00040000
+#define ASUS_WMI_DSTS_BRIGHTNESS_MASK   0x000000FF
+#define ASUS_WMI_DSTS_MAX_BRIGTH_MASK   0x0000FF00
+
+
+struct acpi_asus_wmi_softc {
+	device_t	dev;
+	device_t	wmi_dev;
+	const char	*notify_guid;
+	struct sysctl_ctx_list	*sysctl_ctx;
+	struct sysctl_oid	*sysctl_tree;
+	int		dsts_id;
+	int		handle_keys;
+};
+
+static struct {
+	char	*name;
+	int	dev_id;
+	char	*description;
+	int	flag_rdonly;
+} acpi_asus_wmi_sysctls[] = {
+	{
+		.name		= "hw_switch",
+		.dev_id		= ASUS_WMI_DEVID_HW_SWITCH,
+		.description	= "hw_switch",
+	},
+	{
+		.name		= "wireless_led",
+		.dev_id		= ASUS_WMI_DEVID_WIRELESS_LED,
+		.description	= "Wireless LED control",
+	},
+	{
+		.name		= "cwap",
+		.dev_id		= ASUS_WMI_DEVID_CWAP,
+		.description	= "Alt+F2 function",
+	},
+	{
+		.name		= "wlan",
+		.dev_id		= ASUS_WMI_DEVID_WLAN,
+		.description	= "WLAN power control",
+	},
+	{
+		.name		= "bluetooth",
+		.dev_id		= ASUS_WMI_DEVID_BLUETOOTH,
+		.description	= "Bluetooth power control",
+	},
+	{
+		.name		= "gps",
+		.dev_id		= ASUS_WMI_DEVID_GPS,
+		.description	= "GPS power control",
+	},
+	{
+		.name		= "wimax",
+		.dev_id		= ASUS_WMI_DEVID_WIMAX,
+		.description	= "WiMAX power control",
+	},
+	{
+		.name		= "wwan3g",
+		.dev_id		= ASUS_WMI_DEVID_WWAN3G,
+		.description	= "WWAN-3G power control",
+	},
+	{
+		.name		= "uwb",
+		.dev_id		= ASUS_WMI_DEVID_UWB,
+		.description	= "UWB power control",
+	},
+	{
+		.name		= "led1",
+		.dev_id		= ASUS_WMI_DEVID_LED1,
+		.description	= "LED1 control",
+	},
+	{
+		.name		= "led2",
+		.dev_id		= ASUS_WMI_DEVID_LED2,
+		.description	= "LED2 control",
+	},
+	{
+		.name		= "led3",
+		.dev_id		= ASUS_WMI_DEVID_LED3,
+		.description	= "LED3 control",
+	},
+	{
+		.name		= "led4",
+		.dev_id		= ASUS_WMI_DEVID_LED4,
+		.description	= "LED4 control",
+	},
+	{
+		.name		= "led5",
+		.dev_id		= ASUS_WMI_DEVID_LED5,
+		.description	= "LED5 control",
+	},
+	{
+		.name		= "led6",
+		.dev_id		= ASUS_WMI_DEVID_LED6,
+		.description	= "LED6 control",
+	},
+	{
+		.name		= "backlight",
+		.dev_id		= ASUS_WMI_DEVID_BACKLIGHT,
+		.description	= "LCD backlight on/off control",
+	},
+	{
+		.name		= "brightness",
+		.dev_id		= ASUS_WMI_DEVID_BRIGHTNESS,
+		.description	= "LCD backlight brightness control",
+	},
+	{
+		.name		= "kbd_backlight",
+		.dev_id		= ASUS_WMI_DEVID_KBD_BACKLIGHT,
+		.description	= "Keyboard backlight brightness control",
+	},
+	{
+		.name		= "light_sensor",
+		.dev_id		= ASUS_WMI_DEVID_LIGHT_SENSOR,
+		.description	= "Ambient light sensor",
+	},
+	{
+		.name		= "camera",
+		.dev_id		= ASUS_WMI_DEVID_CAMERA,
+		.description	= "Camera power control",
+	},
+	{
+		.name		= "cardreader",
+		.dev_id		= ASUS_WMI_DEVID_CARDREADER,
+		.description	= "Cardreader power control",
+	},
+	{
+		.name		= "touchpad",
+		.dev_id		= ASUS_WMI_DEVID_TOUCHPAD,
+		.description	= "Touchpad control",
+	},
+	{
+		.name		= "touchpad_led",
+		.dev_id		= ASUS_WMI_DEVID_TOUCHPAD_LED,
+		.description	= "Touchpad LED control",
+	},
+	{
+		.name		= "themperature",
+		.dev_id		= ASUS_WMI_DEVID_THERMAL_CTRL,
+		.description	= "Temperature (C)",
+		.flag_rdonly	= 1
+	},
+	{
+		.name		= "fan_speed",
+		.dev_id		= ASUS_WMI_DEVID_FAN_CTRL,
+		.description	= "Fan speed (0-3)",
+		.flag_rdonly	= 1
+	},
+	{
+		.name		= "processor_state",
+		.dev_id		= ASUS_WMI_DEVID_PROCESSOR_STATE,
+		.flag_rdonly	= 1
+	},
+	{ NULL, 0, NULL, 0 }
+};
+
+ACPI_SERIAL_DECL(asus_wmi, "ASUS WMI device");
+
+static void	acpi_asus_wmi_identify(driver_t *driver, device_t parent);
+static int	acpi_asus_wmi_probe(device_t dev);
+static int	acpi_asus_wmi_attach(device_t dev);
+static int	acpi_asus_wmi_detach(device_t dev);
+
+static int	acpi_asus_wmi_sysctl(SYSCTL_HANDLER_ARGS);
+static int	acpi_asus_wmi_sysctl_set(struct acpi_asus_wmi_softc *sc, int dev_id,
+		    int arg, int oldarg);
+static int	acpi_asus_wmi_sysctl_get(struct acpi_asus_wmi_softc *sc, int dev_id);
+static int	acpi_asus_wmi_evaluate_method(device_t wmi_dev, int method,
+		    UINT32 arg0, UINT32 arg1, UINT32 *retval);
+static int	acpi_wpi_asus_get_devstate(struct acpi_asus_wmi_softc *sc,
+		    UINT32 dev_id, UINT32 *retval);
+static int	acpi_wpi_asus_set_devstate(struct acpi_asus_wmi_softc *sc,
+		    UINT32 dev_id, UINT32 ctrl_param, UINT32 *retval);
+static void	acpi_asus_wmi_notify(ACPI_HANDLE h, UINT32 notify, void *context);
+
+static device_method_t acpi_asus_wmi_methods[] = {
+	DEVMETHOD(device_identify, acpi_asus_wmi_identify),
+	DEVMETHOD(device_probe, acpi_asus_wmi_probe),
+	DEVMETHOD(device_attach, acpi_asus_wmi_attach),
+	DEVMETHOD(device_detach, acpi_asus_wmi_detach),
+
+	DEVMETHOD_END
+};
+
+static driver_t	acpi_asus_wmi_driver = {
+	"acpi_asus_wmi",
+	acpi_asus_wmi_methods,
+	sizeof(struct acpi_asus_wmi_softc),
+};
+
+static devclass_t acpi_asus_wmi_devclass;
+
+DRIVER_MODULE(acpi_asus_wmi, acpi_wmi, acpi_asus_wmi_driver,
+    acpi_asus_wmi_devclass, 0, 0);
+MODULE_DEPEND(acpi_asus_wmi, acpi_wmi, 1, 1, 1);
+MODULE_DEPEND(acpi_asus_wmi, acpi, 1, 1, 1);
+
+static void
+acpi_asus_wmi_identify(driver_t *driver, device_t parent)
+{
+
+	/* Don't do anything if driver is disabled. */
+	if (acpi_disabled("asus_wmi"))
+		return;
+
+	/* Add only a single device instance. */
+	if (device_find_child(parent, "acpi_asus_wmi", -1) != NULL)
+		return;
+
+	/* Check management GUID to see whether system is compatible. */
+	if (!ACPI_WMI_PROVIDES_GUID_STRING(parent,
+	    ACPI_ASUS_WMI_MGMT_GUID))
+		return;
+
+	if (BUS_ADD_CHILD(parent, 0, "acpi_asus_wmi", -1) == NULL)
+		device_printf(parent, "add acpi_asus_wmi child failed\n");
+}
+
+static int
+acpi_asus_wmi_probe(device_t dev)
+{
+
+	if (!ACPI_WMI_PROVIDES_GUID_STRING(device_get_parent(dev),
+	    ACPI_ASUS_WMI_MGMT_GUID))
+		return (EINVAL);
+	device_set_desc(dev, "ASUS WMI device");
+	return (0);
+}
+
+static int
+acpi_asus_wmi_attach(device_t dev)
+{
+	struct acpi_asus_wmi_softc	*sc;
+	UINT32			val;
+	int			dev_id, i;
+
+	ACPI_FUNCTION_TRACE((char *)(uintptr_t) __func__);
+
+	sc = device_get_softc(dev);
+	sc->dev = dev;
+	sc->wmi_dev = device_get_parent(dev);
+	sc->handle_keys = 1;
+
+	/* Check management GUID. */
+	if (!ACPI_WMI_PROVIDES_GUID_STRING(sc->wmi_dev,
+	    ACPI_ASUS_WMI_MGMT_GUID)) {
+		device_printf(dev,
+		    "WMI device does not provide the ASUS management GUID\n");
+		return (EINVAL);
+	}
+
+	/* Find proper DSTS method. */
+	sc->dsts_id = ASUS_WMI_METHODID_DSTS;
+next:
+	for (i = 0; acpi_asus_wmi_sysctls[i].name != NULL; ++i) {
+		dev_id = acpi_asus_wmi_sysctls[i].dev_id;
+		if (acpi_wpi_asus_get_devstate(sc, dev_id, &val))
+			continue;
+		break;
+	}
+	if (acpi_asus_wmi_sysctls[i].name == NULL) {
+		if (sc->dsts_id == ASUS_WMI_METHODID_DSTS) {
+			sc->dsts_id = ASUS_WMI_METHODID_DSTS2;
+			goto next;
+		} else {
+			device_printf(dev, "Can not detect DSTS method ID\n");
+			return (EINVAL);
+		}
+	}
+
+	/* Find proper and attach to notufy GUID. */
+	if (ACPI_WMI_PROVIDES_GUID_STRING(sc->wmi_dev,
+	    ACPI_ASUS_WMI_EVENT_GUID))
+		sc->notify_guid = ACPI_ASUS_WMI_EVENT_GUID;
+	else if (ACPI_WMI_PROVIDES_GUID_STRING(sc->wmi_dev,
+	    ACPI_EEEPC_WMI_EVENT_GUID))
+		sc->notify_guid = ACPI_EEEPC_WMI_EVENT_GUID;
+	else
+		sc->notify_guid = NULL;
+	if (sc->notify_guid != NULL) {
+		if (ACPI_WMI_INSTALL_EVENT_HANDLER(sc->wmi_dev,
+		    sc->notify_guid, acpi_asus_wmi_notify, dev))
+			sc->notify_guid = NULL;
+	}
+	if (sc->notify_guid == NULL)
+		device_printf(dev, "Could not install event handler!\n");
+
+	/* Initialize. */
+	if (!acpi_asus_wmi_evaluate_method(sc->wmi_dev,
+	    ASUS_WMI_METHODID_INIT, 0, 0, &val) && bootverbose)
+		device_printf(dev, "Initialization: %#x\n", val);
+	if (!acpi_asus_wmi_evaluate_method(sc->wmi_dev,
+	    ASUS_WMI_METHODID_SPEC, 0, 0x9, &val) && bootverbose)
+		device_printf(dev, "WMI BIOS version: %d.%d\n",
+		    val >> 16, val & 0xFF);
+	if (!acpi_asus_wmi_evaluate_method(sc->wmi_dev,
+	    ASUS_WMI_METHODID_SFUN, 0, 0, &val) && bootverbose)
+		device_printf(dev, "SFUN value: %#x\n", val);
+
+	ACPI_SERIAL_BEGIN(asus_wmi);
+
+	sc->sysctl_ctx = device_get_sysctl_ctx(dev);
+	sc->sysctl_tree = device_get_sysctl_tree(dev);
+	SYSCTL_ADD_INT(sc->sysctl_ctx,
+	    SYSCTL_CHILDREN(sc->sysctl_tree), OID_AUTO,
+	    "handle_keys", CTLFLAG_RW, &sc->handle_keys,
+	    0, "Handle some hardware keys inside the driver");
+	for (i = 0; acpi_asus_wmi_sysctls[i].name != NULL; ++i) {
+		dev_id = acpi_asus_wmi_sysctls[i].dev_id;
+		if (acpi_wpi_asus_get_devstate(sc, dev_id, &val))
+			continue;
+		switch (dev_id) {
+		case ASUS_WMI_DEVID_THERMAL_CTRL:
+		case ASUS_WMI_DEVID_PROCESSOR_STATE:
+		case ASUS_WMI_DEVID_FAN_CTRL:
+		case ASUS_WMI_DEVID_BRIGHTNESS:
+			if (val == 0)
+				continue;
+			break;
+		default:
+			if ((val & ASUS_WMI_DSTS_PRESENCE_BIT) == 0)
+				continue;
+			break;
+		}
+
+		if (acpi_asus_wmi_sysctls[i].flag_rdonly != 0) {
+			SYSCTL_ADD_PROC(sc->sysctl_ctx,
+			    SYSCTL_CHILDREN(sc->sysctl_tree), OID_AUTO,
+			    acpi_asus_wmi_sysctls[i].name,
+			    CTLTYPE_INT | CTLFLAG_RD,
+			    sc, i, acpi_asus_wmi_sysctl, "I",
+			    acpi_asus_wmi_sysctls[i].description);
+		} else {
+			SYSCTL_ADD_PROC(sc->sysctl_ctx,
+			    SYSCTL_CHILDREN(sc->sysctl_tree), OID_AUTO,
+			    acpi_asus_wmi_sysctls[i].name,
+			    CTLTYPE_INT | CTLFLAG_RW,
+			    sc, i, acpi_asus_wmi_sysctl, "I",
+			    acpi_asus_wmi_sysctls[i].description);
+		}
+	}
+	ACPI_SERIAL_END(asus_wmi);
+
+	return (0);
+}
+
+static int
+acpi_asus_wmi_detach(device_t dev)
+{
+	struct acpi_asus_wmi_softc *sc = device_get_softc(dev);
+	
+	ACPI_FUNCTION_TRACE((char *)(uintptr_t) __func__);
+
+	if (sc->notify_guid)
+		ACPI_WMI_REMOVE_EVENT_HANDLER(dev, sc->notify_guid);
+
+	return (0);
+}
+
+static int
+acpi_asus_wmi_sysctl(SYSCTL_HANDLER_ARGS)
+{
+	struct acpi_asus_wmi_softc	*sc;
+	int			arg;
+	int			oldarg;
+	int			error = 0;
+	int			function;
+	int			dev_id;
+	
+	ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__);
+
+	sc = (struct acpi_asus_wmi_softc *)oidp->oid_arg1;
+	function = oidp->oid_arg2;
+	dev_id = acpi_asus_wmi_sysctls[function].dev_id;
+
+	ACPI_SERIAL_BEGIN(asus_wmi);
+	arg = acpi_asus_wmi_sysctl_get(sc, dev_id);
+	oldarg = arg;
+	error = sysctl_handle_int(oidp, &arg, 0, req);
+	if (!error && req->newptr != NULL)
+		error = acpi_asus_wmi_sysctl_set(sc, dev_id, arg, oldarg);
+	ACPI_SERIAL_END(asus_wmi);
+
+	return (error);
+}
+
+static int
+acpi_asus_wmi_sysctl_get(struct acpi_asus_wmi_softc *sc, int dev_id)
+{
+	UINT32	val = 0;
+
+	ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__);
+	ACPI_SERIAL_ASSERT(asus_wmi);
+
+	acpi_wpi_asus_get_devstate(sc, dev_id, &val);
+
+	switch(dev_id) {
+	case ASUS_WMI_DEVID_THERMAL_CTRL:
+		val = (val - 2732 + 5) / 10;
+		break;
+	case ASUS_WMI_DEVID_PROCESSOR_STATE:
+	case ASUS_WMI_DEVID_FAN_CTRL:
+		break;
+	case ASUS_WMI_DEVID_BRIGHTNESS:
+		val &= ASUS_WMI_DSTS_BRIGHTNESS_MASK;
+		break;
+	case ASUS_WMI_DEVID_KBD_BACKLIGHT:
+		val &= 0x7;
+		break;
+	default:
+		if (val & ASUS_WMI_DSTS_UNKNOWN_BIT)
+			val = -1;
+		else
+			val = !!(val & ASUS_WMI_DSTS_STATUS_BIT);
+		break;
+	}
+
+	return (val);
+}
+
+static int
+acpi_asus_wmi_sysctl_set(struct acpi_asus_wmi_softc *sc, int dev_id, int arg, int oldarg)
+{
+	ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__);
+	ACPI_SERIAL_ASSERT(asus_wmi);
+
+	switch(dev_id) {
+	case ASUS_WMI_DEVID_KBD_BACKLIGHT:
+		arg = min(0x7, arg);
+		if (arg != 0)
+			arg |= 0x80;
+		break;
+	}
+
+	acpi_wpi_asus_set_devstate(sc, dev_id, arg, NULL);
+
+	return (0);
+}
+
+static __inline void
+acpi_asus_wmi_free_buffer(ACPI_BUFFER* buf) {
+	if (buf && buf->Pointer) {
+		AcpiOsFree(buf->Pointer);
+	}
+}
+
+static void
+acpi_asus_wmi_notify(ACPI_HANDLE h, UINT32 notify, void *context)
+{
+	device_t dev = context;
+	ACPI_FUNCTION_TRACE_U32((char *)(uintptr_t)__func__, notify);
+	UINT32 val;
+	int code = 0;
+
+	struct acpi_asus_wmi_softc *sc = device_get_softc(dev);
+	ACPI_BUFFER response = { ACPI_ALLOCATE_BUFFER, NULL };
+	ACPI_OBJECT *obj;
+	ACPI_WMI_GET_EVENT_DATA(sc->wmi_dev, notify, &response);
+	obj = (ACPI_OBJECT*) response.Pointer;
+	if (obj && obj->Type == ACPI_TYPE_INTEGER) {
+		code = obj->Integer.Value;
+		acpi_UserNotify("ASUS", ACPI_ROOT_OBJECT,
+		    code);
+	}
+	if (code && sc->handle_keys) {
+		/* Keyboard backlight control. */
+		if (code == 0xc4 || code == 0xc5) {
+			acpi_wpi_asus_get_devstate(sc,
+			    ASUS_WMI_DEVID_KBD_BACKLIGHT, &val);
+			val &= 0x7;
+			if (code == 0xc4) {
+				if (val < 0x7)
+					val++;
+			} else if (val > 0)
+				val--;
+			if (val != 0)
+				val |= 0x80;
+			acpi_wpi_asus_set_devstate(sc,
+			    ASUS_WMI_DEVID_KBD_BACKLIGHT, val, NULL);
+		}
+		/* Touchpad control. */
+		if (code == 0x6b) {
+			acpi_wpi_asus_get_devstate(sc,
+			    ASUS_WMI_DEVID_TOUCHPAD, &val);
+			val = !(val & 1);
+			acpi_wpi_asus_set_devstate(sc,
+			    ASUS_WMI_DEVID_TOUCHPAD, val, NULL);
+		}
+	}
+	acpi_asus_wmi_free_buffer(&response);
+}
+
+static int
+acpi_asus_wmi_evaluate_method(device_t wmi_dev, int method,
+    UINT32 arg0, UINT32 arg1, UINT32 *retval)
+{
+	UINT32		params[2] = { arg0, arg1 };
+	UINT32		result;
+	ACPI_OBJECT	*obj;
+	ACPI_BUFFER	in = { sizeof(params), &params };
+	ACPI_BUFFER	out = { ACPI_ALLOCATE_BUFFER, NULL };
+	
+	if (ACPI_FAILURE(ACPI_WMI_EVALUATE_CALL(wmi_dev,
+	    ACPI_ASUS_WMI_MGMT_GUID, 1, method, &in, &out))) {
+		acpi_asus_wmi_free_buffer(&out);
+		return (-EINVAL);
+	}
+	obj = out.Pointer;
+	if (obj && obj->Type == ACPI_TYPE_INTEGER)
+		result = (UINT32) obj->Integer.Value;
+	else
+		result = 0;
+	acpi_asus_wmi_free_buffer(&out);
+	if (retval)
+		*retval = result;
+	return (result == ASUS_WMI_UNSUPPORTED_METHOD ? -ENODEV : 0);
+}
+
+static int
+acpi_wpi_asus_get_devstate(struct acpi_asus_wmi_softc *sc,
+    UINT32 dev_id, UINT32 *retval)
+{
+
+	return (acpi_asus_wmi_evaluate_method(sc->wmi_dev,
+	    sc->dsts_id, dev_id, 0, retval));
+}
+
+static int
+acpi_wpi_asus_set_devstate(struct acpi_asus_wmi_softc *sc,
+    UINT32 dev_id, UINT32 ctrl_param, UINT32 *retval)
+{
+
+	return (acpi_asus_wmi_evaluate_method(sc->wmi_dev,
+	    ASUS_WMI_METHODID_DEVS, dev_id, ctrl_param, retval));
+}


Property changes on: trunk/sys/dev/acpi_support/acpi_asus_wmi.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Modified: trunk/sys/dev/acpi_support/acpi_fujitsu.c
===================================================================
--- trunk/sys/dev/acpi_support/acpi_fujitsu.c	2018-05-27 23:54:55 UTC (rev 10111)
+++ trunk/sys/dev/acpi_support/acpi_fujitsu.c	2018-05-27 23:55:14 UTC (rev 10112)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*-
  * Copyright (c) 2002 Sean Bullington <seanATstalker.org>
  *               2003-2008 Anish Mistry <amistry at am-productions.biz>
@@ -28,7 +29,7 @@
  */
 
 #include <sys/cdefs.h>
-__MBSDID("$MidnightBSD$");
+__FBSDID("$FreeBSD: stable/10/sys/dev/acpi_support/acpi_fujitsu.c 246128 2013-01-30 18:01:20Z sbz $");
 
 #include "opt_acpi.h"
 #include <sys/param.h>
@@ -154,7 +155,8 @@
 	DEVMETHOD(device_detach,	acpi_fujitsu_detach),
 	DEVMETHOD(device_suspend,	acpi_fujitsu_suspend),
 	DEVMETHOD(device_resume,	acpi_fujitsu_resume),
-	{0, 0}
+
+	DEVMETHOD_END
 };
 
 static driver_t acpi_fujitsu_driver = {

Modified: trunk/sys/dev/acpi_support/acpi_hp.c
===================================================================
--- trunk/sys/dev/acpi_support/acpi_hp.c	2018-05-27 23:54:55 UTC (rev 10111)
+++ trunk/sys/dev/acpi_support/acpi_hp.c	2018-05-27 23:55:14 UTC (rev 10112)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*-
  * Copyright (c) 2009 Michael Gmelin <freebsd at grem.de>
  * All rights reserved.
@@ -25,7 +26,7 @@
  */
 
 #include <sys/cdefs.h>
-__MBSDID("$MidnightBSD$");
+__FBSDID("$FreeBSD: stable/10/sys/dev/acpi_support/acpi_hp.c 273736 2014-10-27 14:38:00Z hselasky $");
 
 /*
  * Driver for extra ACPI-controlled features found on HP laptops
@@ -152,49 +153,45 @@
 	char	*name;
 	int	method;
 	char	*description;
-	int	access;
+	int	flag_rdonly;
 } acpi_hp_sysctls[] = {
 	{
 		.name		= "wlan_enabled",
 		.method		= ACPI_HP_METHOD_WLAN_ENABLED,
 		.description	= "Enable/Disable WLAN (WiFi)",
-		.access		= CTLTYPE_INT | CTLFLAG_RW
 	},
 	{
 		.name		= "wlan_radio",
 		.method		= ACPI_HP_METHOD_WLAN_RADIO,
 		.description	= "WLAN radio status",
-		.access		= CTLTYPE_INT | CTLFLAG_RD
+		.flag_rdonly	= 1
 	},
 	{
 		.name		= "wlan_on_air",
 		.method		= ACPI_HP_METHOD_WLAN_ON_AIR,
 		.description	= "WLAN radio ready to use (enabled and radio)",
-		.access		= CTLTYPE_INT | CTLFLAG_RD
+		.flag_rdonly	= 1
 	},
 	{
 		.name		= "wlan_enable_if_radio_on",
 		.method		= ACPI_HP_METHOD_WLAN_ENABLE_IF_RADIO_ON,
 		.description	= "Enable WLAN if radio is turned on",
-		.access		= CTLTYPE_INT | CTLFLAG_RW
 	},
 	{
 		.name		= "wlan_disable_if_radio_off",
 		.method		= ACPI_HP_METHOD_WLAN_DISABLE_IF_RADIO_OFF,
 		.description	= "Disable WLAN if radio is turned off",
-		.access		= CTLTYPE_INT | CTLFLAG_RW
 	},
 	{
 		.name		= "bt_enabled",
 		.method		= ACPI_HP_METHOD_BLUETOOTH_ENABLED,
 		.description	= "Enable/Disable Bluetooth",
-		.access		= CTLTYPE_INT | CTLFLAG_RW
 	},
 	{
 		.name		= "bt_radio",
 		.method		= ACPI_HP_METHOD_BLUETOOTH_RADIO,
 		.description	= "Bluetooth radio status",
-		.access		= CTLTYPE_INT | CTLFLAG_RD
+		.flag_rdonly	= 1
 	},
 	{
 		.name		= "bt_on_air",
@@ -201,73 +198,67 @@
 		.method		= ACPI_HP_METHOD_BLUETOOTH_ON_AIR,
 		.description	= "Bluetooth radio ready to use"
 				    " (enabled and radio)",
-		.access		= CTLTYPE_INT | CTLFLAG_RD
+		.flag_rdonly	= 1
 	},
 	{
 		.name		= "bt_enable_if_radio_on",
 		.method		= ACPI_HP_METHOD_BLUETOOTH_ENABLE_IF_RADIO_ON,
 		.description	= "Enable bluetooth if radio is turned on",
-		.access		= CTLTYPE_INT | CTLFLAG_RW
 	},
 	{
 		.name		= "bt_disable_if_radio_off",
 		.method		= ACPI_HP_METHOD_BLUETOOTH_DISABLE_IF_RADIO_OFF,
 		.description	= "Disable bluetooth if radio is turned off",
-		.access		= CTLTYPE_INT | CTLFLAG_RW
 	},
 	{
 		.name		= "wwan_enabled",
 		.method		= ACPI_HP_METHOD_WWAN_ENABLED,
 		.description	= "Enable/Disable WWAN (UMTS)",
-		.access		= CTLTYPE_INT | CTLFLAG_RW
 	},
 	{
 		.name		= "wwan_radio",
 		.method		= ACPI_HP_METHOD_WWAN_RADIO,
 		.description	= "WWAN radio status",
-		.access		= CTLTYPE_INT | CTLFLAG_RD
+		.flag_rdonly	= 1
 	},
 	{
 		.name		= "wwan_on_air",
 		.method		= ACPI_HP_METHOD_WWAN_ON_AIR,
 		.description	= "WWAN radio ready to use (enabled and radio)",
-		.access		= CTLTYPE_INT | CTLFLAG_RD
+		.flag_rdonly	= 1
 	},
 	{
 		.name		= "wwan_enable_if_radio_on",
 		.method		= ACPI_HP_METHOD_WWAN_ENABLE_IF_RADIO_ON,
 		.description	= "Enable WWAN if radio is turned on",
-		.access		= CTLTYPE_INT | CTLFLAG_RW
 	},
 	{
 		.name		= "wwan_disable_if_radio_off",
 		.method		= ACPI_HP_METHOD_WWAN_DISABLE_IF_RADIO_OFF,
 		.description	= "Disable WWAN if radio is turned off",
-		.access		= CTLTYPE_INT | CTLFLAG_RW
 	},
 	{
 		.name		= "als_enabled",
 		.method		= ACPI_HP_METHOD_ALS,
 		.description	= "Enable/Disable ALS (Ambient light sensor)",
-		.access		= CTLTYPE_INT | CTLFLAG_RW
 	},
 	{
 		.name		= "display",
 		.method		= ACPI_HP_METHOD_DISPLAY,
 		.description	= "Display status",
-		.access		= CTLTYPE_INT | CTLFLAG_RD
+		.flag_rdonly	= 1
 	},
 	{
 		.name		= "hdd_temperature",
 		.method		= ACPI_HP_METHOD_HDDTEMP,
 		.description	= "HDD temperature",
-		.access		= CTLTYPE_INT | CTLFLAG_RD
+		.flag_rdonly	= 1
 	},
 	{
 		.name		= "is_docked",
 		.method		= ACPI_HP_METHOD_DOCK,
 		.description	= "Docking station status",
-		.access		= CTLTYPE_INT | CTLFLAG_RD
+		.flag_rdonly	= 1
 	},
 	{
 		.name		= "cmi_detail",
@@ -274,13 +265,11 @@
 		.method		= ACPI_HP_METHOD_CMI_DETAIL,
 		.description	= "Details shown in CMI output "
 				    "(cat /dev/hpcmi)",
-		.access		= CTLTYPE_INT | CTLFLAG_RW
 	},
 	{
 		.name		= "verbose",
 		.method		= ACPI_HP_METHOD_VERBOSE,
 		.description	= "Verbosity level",
-		.access		= CTLTYPE_INT | CTLFLAG_RW
 	},
 
 	{ NULL, 0, NULL, 0 }
@@ -324,7 +313,8 @@
 	DEVMETHOD(device_probe, acpi_hp_probe),
 	DEVMETHOD(device_attach, acpi_hp_attach),
 	DEVMETHOD(device_detach, acpi_hp_detach),
-	{0, 0}
+
+	DEVMETHOD_END
 };
 
 static driver_t	acpi_hp_driver = {
@@ -559,11 +549,19 @@
 			sc->was_wwan_on_air = arg;
 		}
 
-		SYSCTL_ADD_PROC(sc->sysctl_ctx,
-		SYSCTL_CHILDREN(sc->sysctl_tree), OID_AUTO,
-			acpi_hp_sysctls[i].name, acpi_hp_sysctls[i].access,
-			sc, i, acpi_hp_sysctl, "I",
-			acpi_hp_sysctls[i].description);
+		if (acpi_hp_sysctls[i].flag_rdonly != 0) {
+			SYSCTL_ADD_PROC(sc->sysctl_ctx,
+			    SYSCTL_CHILDREN(sc->sysctl_tree), OID_AUTO,
+			    acpi_hp_sysctls[i].name, CTLTYPE_INT | CTLFLAG_RD,
+			    sc, i, acpi_hp_sysctl, "I",
+			    acpi_hp_sysctls[i].description);
+		} else {
+			SYSCTL_ADD_PROC(sc->sysctl_ctx,
+			    SYSCTL_CHILDREN(sc->sysctl_tree), OID_AUTO,
+			    acpi_hp_sysctls[i].name, CTLTYPE_INT | CTLFLAG_RW,
+			    sc, i, acpi_hp_sysctl, "I",
+			    acpi_hp_sysctls[i].description);
+		}
 	}
 	ACPI_SERIAL_END(hp);
 
@@ -573,18 +571,17 @@
 static int
 acpi_hp_detach(device_t dev)
 {
-	int	ret;
+	struct acpi_hp_softc *sc;
 	
 	ACPI_FUNCTION_TRACE((char *)(uintptr_t) __func__);
-	struct acpi_hp_softc *sc = device_get_softc(dev);
-	if (sc->has_cmi && sc->hpcmi_open_pid != 0) {
-		ret = EBUSY;
-	}
-	else {
-		if (sc->has_notify) {
-			ACPI_WMI_REMOVE_EVENT_HANDLER(dev,
-			    ACPI_HP_WMI_EVENT_GUID);
-		}
+	sc = device_get_softc(dev);
+	if (sc->has_cmi && sc->hpcmi_open_pid != 0)
+		return (EBUSY);
+
+	if (sc->has_notify)
+		ACPI_WMI_REMOVE_EVENT_HANDLER(dev, ACPI_HP_WMI_EVENT_GUID);
+
+	if (sc->has_cmi) {
 		if (sc->hpcmi_bufptr != -1) {
 			sbuf_delete(&sc->hpcmi_sbuf);
 			sc->hpcmi_bufptr = -1;
@@ -591,10 +588,9 @@
 		}
 		sc->hpcmi_open_pid = 0;
 		destroy_dev(sc->hpcmi_dev_t);
-		ret = 0;
 	}
 
-	return (ret);
+	return (0);
 }
 
 static int

Modified: trunk/sys/dev/acpi_support/acpi_ibm.c
===================================================================
--- trunk/sys/dev/acpi_support/acpi_ibm.c	2018-05-27 23:54:55 UTC (rev 10111)
+++ trunk/sys/dev/acpi_support/acpi_ibm.c	2018-05-27 23:55:14 UTC (rev 10112)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*-
  * Copyright (c) 2004 Takanori Watanabe
  * Copyright (c) 2005 Markus Brueffer <markus at FreeBSD.org>
@@ -26,7 +27,7 @@
  */
 
 #include <sys/cdefs.h>
-__MBSDID("$MidnightBSD$");
+__FBSDID("$FreeBSD: stable/10/sys/dev/acpi_support/acpi_ibm.c 273847 2014-10-30 08:04:48Z hselasky $");
 
 /*
  * Driver for extra ACPI-controlled gadgets found on IBM ThinkPad laptops.
@@ -192,79 +193,70 @@
 	char	*name;
 	int	method;
 	char	*description;
-	int	access;
+	int	flag_rdonly;
 } acpi_ibm_sysctls[] = {
 	{
 		.name		= "events",
 		.method		= ACPI_IBM_METHOD_EVENTS,
 		.description	= "ACPI events enable",
-		.access		= CTLTYPE_INT | CTLFLAG_RW
 	},
 	{
 		.name		= "eventmask",
 		.method		= ACPI_IBM_METHOD_EVENTMASK,
 		.description	= "ACPI eventmask",
-		.access		= CTLTYPE_INT | CTLFLAG_RW
 	},
 	{
 		.name		= "hotkey",
 		.method		= ACPI_IBM_METHOD_HOTKEY,
 		.description	= "Key Status",
-		.access		= CTLTYPE_INT | CTLFLAG_RD
+		.flag_rdonly	= 1
 	},
 	{
 		.name		= "lcd_brightness",
 		.method		= ACPI_IBM_METHOD_BRIGHTNESS,
 		.description	= "LCD Brightness",
-		.access		= CTLTYPE_INT | CTLFLAG_RW
 	},
 	{
 		.name		= "volume",
 		.method		= ACPI_IBM_METHOD_VOLUME,
 		.description	= "Volume",
-		.access		= CTLTYPE_INT | CTLFLAG_RW
 	},
 	{
 		.name		= "mute",
 		.method		= ACPI_IBM_METHOD_MUTE,
 		.description	= "Mute",
-		.access		= CTLTYPE_INT | CTLFLAG_RW
 	},
 	{
 		.name		= "thinklight",
 		.method		= ACPI_IBM_METHOD_THINKLIGHT,
 		.description	= "Thinklight enable",
-		.access		= CTLTYPE_INT | CTLFLAG_RW
 	},
 	{
 		.name		= "bluetooth",
 		.method		= ACPI_IBM_METHOD_BLUETOOTH,
 		.description	= "Bluetooth enable",
-		.access		= CTLTYPE_INT | CTLFLAG_RW
 	},
 	{
 		.name		= "wlan",
 		.method		= ACPI_IBM_METHOD_WLAN,
 		.description	= "WLAN enable",
-		.access		= CTLTYPE_INT | CTLFLAG_RD
+		.flag_rdonly	= 1
 	},
 	{
 		.name		= "fan_speed",
 		.method		= ACPI_IBM_METHOD_FANSPEED,
 		.description	= "Fan speed",
-		.access		= CTLTYPE_INT | CTLFLAG_RD
+		.flag_rdonly	= 1
 	},
 	{
 		.name		= "fan_level",
 		.method		= ACPI_IBM_METHOD_FANLEVEL,
 		.description	= "Fan level",
-		.access		= CTLTYPE_INT | CTLFLAG_RW
 	},
 	{
 		.name		= "fan",
 		.method		= ACPI_IBM_METHOD_FANSTATUS,
 		.description	= "Fan enable",
-		.access		= CTLTYPE_INT | CTLFLAG_RW
 	},
 
 	{ NULL, 0, NULL, 0 }
@@ -303,7 +295,7 @@
 	DEVMETHOD(device_detach, acpi_ibm_detach),
 	DEVMETHOD(device_resume, acpi_ibm_resume),
 
-	{0, 0}
+	DEVMETHOD_END
 };
 
 static driver_t	acpi_ibm_driver = {
@@ -415,11 +407,19 @@
 		if (!acpi_ibm_sysctl_init(sc, acpi_ibm_sysctls[i].method))
 			continue;
 
-		SYSCTL_ADD_PROC(sc->sysctl_ctx,
-		    SYSCTL_CHILDREN(sc->sysctl_tree), OID_AUTO,
-		    acpi_ibm_sysctls[i].name, acpi_ibm_sysctls[i].access,
-		    sc, i, acpi_ibm_sysctl, "I",
-		    acpi_ibm_sysctls[i].description);
+		if (acpi_ibm_sysctls[i].flag_rdonly != 0) {
+			SYSCTL_ADD_PROC(sc->sysctl_ctx,
+			    SYSCTL_CHILDREN(sc->sysctl_tree), OID_AUTO,
+			    acpi_ibm_sysctls[i].name, CTLTYPE_INT | CTLFLAG_RD,
+			    sc, i, acpi_ibm_sysctl, "I",
+			    acpi_ibm_sysctls[i].description);
+		} else {
+			SYSCTL_ADD_PROC(sc->sysctl_ctx,
+			    SYSCTL_CHILDREN(sc->sysctl_tree), OID_AUTO,
+			    acpi_ibm_sysctls[i].name, CTLTYPE_INT | CTLFLAG_RW,
+			    sc, i, acpi_ibm_sysctl, "I",
+			    acpi_ibm_sysctls[i].description);
+		}
 	}
 
 	/* Hook up thermal node */
@@ -483,15 +483,10 @@
 	for (int i = 0; acpi_ibm_sysctls[i].name != NULL; i++) {
 		int val;
 
-		if ((acpi_ibm_sysctls[i].access & CTLFLAG_RD) == 0) {
-			continue;
-		}
-
 		val = acpi_ibm_sysctl_get(sc, i);
 
-		if ((acpi_ibm_sysctls[i].access & CTLFLAG_WR) == 0) {
+		if (acpi_ibm_sysctls[i].flag_rdonly != 0)
 			continue;
-		}
 
 		acpi_ibm_sysctl_set(sc, i, val);
 	}
@@ -905,6 +900,7 @@
 	char			*cp, *ep;
 	int			l, val;
 	unsigned int		handler_events;
+	char			temp[128];
 
 	ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__);
 
@@ -926,17 +922,18 @@
 
 	sbuf_trim(&sb);
 	sbuf_finish(&sb);
-
-	/* Copy out the old values to the user. */
-	error = SYSCTL_OUT(req, sbuf_data(&sb), sbuf_len(&sb));
+	strlcpy(temp, sbuf_data(&sb), sizeof(temp));
 	sbuf_delete(&sb);
 
+	error = sysctl_handle_string(oidp, temp, sizeof(temp), req);
+
+	/* Check for error or no change */
 	if (error != 0 || req->newptr == NULL)
 		goto out;
 
 	/* If the user is setting a string, parse it. */
 	handler_events = 0;
-	cp = (char *)req->newptr;
+	cp = temp;
 	while (*cp) {
 		if (isspace(*cp)) {
 			cp++;

Modified: trunk/sys/dev/acpi_support/acpi_panasonic.c
===================================================================
--- trunk/sys/dev/acpi_support/acpi_panasonic.c	2018-05-27 23:54:55 UTC (rev 10111)
+++ trunk/sys/dev/acpi_support/acpi_panasonic.c	2018-05-27 23:55:14 UTC (rev 10112)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*-
  * Copyright (c) 2003 OGAWA Takaya <t-ogawa at triaez.kaisei.org>
  * Copyright (c) 2004 TAKAHASHI Yoshihiro <nyan at FreeBSD.org>
@@ -27,7 +28,7 @@
  */
 
 #include <sys/cdefs.h>
-__MBSDID("$MidnightBSD$");
+__FBSDID("$FreeBSD: stable/10/sys/dev/acpi_support/acpi_panasonic.c 246128 2013-01-30 18:01:20Z sbz $");
 
 #include "opt_acpi.h"
 #include <sys/param.h>
@@ -118,7 +119,7 @@
 	DEVMETHOD(device_detach,	acpi_panasonic_detach),
 	DEVMETHOD(device_shutdown,	acpi_panasonic_shutdown),
 
-	{0, 0}
+	DEVMETHOD_END
 };
 
 static driver_t acpi_panasonic_driver = {

Added: trunk/sys/dev/acpi_support/acpi_rapidstart.c
===================================================================
--- trunk/sys/dev/acpi_support/acpi_rapidstart.c	                        (rev 0)
+++ trunk/sys/dev/acpi_support/acpi_rapidstart.c	2018-05-27 23:55:14 UTC (rev 10112)
@@ -0,0 +1,143 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2013 Takanori Watanabe
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/sys/dev/acpi_support/acpi_rapidstart.c 273736 2014-10-27 14:38:00Z hselasky $");
+
+#include "opt_acpi.h"
+#include <sys/param.h>
+#include <sys/kernel.h>
+#include <sys/bus.h>
+
+#include <contrib/dev/acpica/include/acpi.h>
+
+#include "acpi_if.h"
+#include <sys/module.h>
+#include <dev/acpica/acpivar.h>
+#include <sys/sysctl.h>
+static int sysctl_acpi_rapidstart_gen_handler(SYSCTL_HANDLER_ARGS);
+
+
+static struct acpi_rapidstart_name_list
+{
+	char *nodename;
+	char *getmethod;
+	char *setmethod;
+	char *comment;
+} acpi_rapidstart_oids[] ={
+	{"ffs","GFFS","SFFS","Flash Fast Store Flag"},
+	{"ftv","GFTV","SFTV","Time value"},
+	{NULL, NULL, NULL, NULL}
+};
+
+struct acpi_rapidstart_softc {
+	struct sysctl_ctx_list	*sysctl_ctx;
+	struct sysctl_oid	*sysctl_tree;
+
+};
+static char    *rapidstart_ids[] = {"INT3392", NULL};
+static int
+acpi_rapidstart_probe(device_t dev)
+{
+	if (acpi_disabled("rapidstart") ||
+	    ACPI_ID_PROBE(device_get_parent(dev), dev, rapidstart_ids) == NULL ||
+	    device_get_unit(dev) != 0)
+		return (ENXIO);
+
+	device_set_desc(dev, "Intel Rapid Start ACPI device");
+
+	return (0);
+	
+}
+
+static int
+acpi_rapidstart_attach(device_t dev)
+{
+	struct acpi_rapidstart_softc *sc;
+	int i;
+
+	sc = device_get_softc(dev);
+	
+	sc->sysctl_ctx = device_get_sysctl_ctx(dev);
+	sc->sysctl_tree = device_get_sysctl_tree(dev);
+	for (i = 0 ; acpi_rapidstart_oids[i].nodename != NULL; i++){
+		if (acpi_rapidstart_oids[i].setmethod != NULL) {
+			SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev),
+			    SYSCTL_CHILDREN(device_get_sysctl_tree(dev)),
+			    i, acpi_rapidstart_oids[i].nodename,
+			    CTLTYPE_INT | CTLFLAG_RW,
+			    dev, i, sysctl_acpi_rapidstart_gen_handler, "I",
+			    acpi_rapidstart_oids[i].comment);
+		} else {
+			SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev),
+			    SYSCTL_CHILDREN(device_get_sysctl_tree(dev)),
+			    i, acpi_rapidstart_oids[i].nodename,
+			    CTLTYPE_INT | CTLFLAG_RD,
+			    dev, i, sysctl_acpi_rapidstart_gen_handler, "I",
+			    acpi_rapidstart_oids[i].comment);
+		}
+	}
+	return (0);
+}
+
+static int 
+sysctl_acpi_rapidstart_gen_handler(SYSCTL_HANDLER_ARGS)
+{
+	device_t	dev = arg1;
+	int 	function = oidp->oid_arg2;
+	int		error = 0, val;
+
+	acpi_GetInteger(acpi_get_handle(dev),
+	    acpi_rapidstart_oids[function].getmethod, &val);
+	error = sysctl_handle_int(oidp, &val, 0, req);
+	if (error || !req->newptr || !acpi_rapidstart_oids[function].setmethod)
+		return (error);
+	acpi_SetInteger(acpi_get_handle(dev),
+	    acpi_rapidstart_oids[function].setmethod, val);
+	return (0);
+}
+
+static device_method_t acpi_rapidstart_methods[] = {
+	/* Device interface */
+	DEVMETHOD(device_probe, acpi_rapidstart_probe),
+	DEVMETHOD(device_attach, acpi_rapidstart_attach),
+
+	DEVMETHOD_END
+};
+
+static driver_t	acpi_rapidstart_driver = {
+	"acpi_rapidstart",
+	acpi_rapidstart_methods,
+	sizeof(struct acpi_rapidstart_softc),
+};
+
+static devclass_t acpi_rapidstart_devclass;
+
+DRIVER_MODULE(acpi_rapidstart, acpi, acpi_rapidstart_driver, acpi_rapidstart_devclass,
+	      0, 0);
+MODULE_DEPEND(acpi_rapidstart, acpi, 1, 1, 1);
+


Property changes on: trunk/sys/dev/acpi_support/acpi_rapidstart.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Modified: trunk/sys/dev/acpi_support/acpi_sony.c
===================================================================
--- trunk/sys/dev/acpi_support/acpi_sony.c	2018-05-27 23:54:55 UTC (rev 10111)
+++ trunk/sys/dev/acpi_support/acpi_sony.c	2018-05-27 23:55:14 UTC (rev 10112)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*-
  * Copyright (c) 2004 Takanori Watanabe
  * All rights reserved.
@@ -25,7 +26,7 @@
  */
 
 #include <sys/cdefs.h>
-__MBSDID("$MidnightBSD$");
+__FBSDID("$FreeBSD: stable/10/sys/dev/acpi_support/acpi_sony.c 273736 2014-10-27 14:38:00Z hselasky $");
 
 #include "opt_acpi.h"
 #include <sys/param.h>
@@ -95,7 +96,7 @@
 	DEVMETHOD(device_attach, acpi_sony_attach),
 	DEVMETHOD(device_detach, acpi_sony_detach),
 
-	{0, 0}
+	DEVMETHOD_END
 };
 
 static driver_t	acpi_sony_driver = {
@@ -132,13 +133,22 @@
 	sc = device_get_softc(dev);
 	acpi_GetInteger(acpi_get_handle(dev), ACPI_SONY_GET_PID, &sc->pid);
 	device_printf(dev, "PID %x\n", sc->pid);
-	for (i = 0 ; acpi_sony_oids[i].nodename != NULL; i++){
-		SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev),
-		    SYSCTL_CHILDREN(device_get_sysctl_tree(dev)),
-		    i, acpi_sony_oids[i].nodename , CTLTYPE_INT |
-		    ((acpi_sony_oids[i].setmethod)? CTLFLAG_RW: CTLFLAG_RD),
-		    dev, i, sysctl_acpi_sony_gen_handler, "I",
-		    acpi_sony_oids[i].comment);
+	for (i = 0 ; acpi_sony_oids[i].nodename != NULL; i++) {
+		if (acpi_sony_oids[i].setmethod != NULL) {
+			SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev),
+			    SYSCTL_CHILDREN(device_get_sysctl_tree(dev)),
+			    i, acpi_sony_oids[i].nodename ,
+			    CTLTYPE_INT | CTLFLAG_RW,
+			    dev, i, sysctl_acpi_sony_gen_handler, "I",
+			    acpi_sony_oids[i].comment);
+		} else {
+			SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev),
+			    SYSCTL_CHILDREN(device_get_sysctl_tree(dev)),
+			    i, acpi_sony_oids[i].nodename ,
+			    CTLTYPE_INT | CTLFLAG_RD,
+			    dev, i, sysctl_acpi_sony_gen_handler, "I",
+			    acpi_sony_oids[i].comment);
+		}
 	}
 	return (0);
 }

Modified: trunk/sys/dev/acpi_support/acpi_toshiba.c
===================================================================
--- trunk/sys/dev/acpi_support/acpi_toshiba.c	2018-05-27 23:54:55 UTC (rev 10111)
+++ trunk/sys/dev/acpi_support/acpi_toshiba.c	2018-05-27 23:55:14 UTC (rev 10112)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*-
  * Copyright (c) 2003 Hiroyuki Aizu <aizu at navi.org>
  * All rights reserved.
@@ -26,7 +27,7 @@
  */
 
 #include <sys/cdefs.h>
-__MBSDID("$MidnightBSD$");
+__FBSDID("$FreeBSD: stable/10/sys/dev/acpi_support/acpi_toshiba.c 249816 2013-04-23 18:30:33Z jkim $");
 
 #include "opt_acpi.h"
 #include <sys/param.h>

Modified: trunk/sys/dev/acpi_support/acpi_wmi.c
===================================================================
--- trunk/sys/dev/acpi_support/acpi_wmi.c	2018-05-27 23:54:55 UTC (rev 10111)
+++ trunk/sys/dev/acpi_support/acpi_wmi.c	2018-05-27 23:55:14 UTC (rev 10112)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*-
  * Copyright (c) 2009 Michael Gmelin <freebsd at grem.de>
  * All rights reserved.
@@ -25,7 +26,7 @@
  */
 
 #include <sys/cdefs.h>
-__MBSDID("$MidnightBSD$");
+__FBSDID("$FreeBSD: stable/10/sys/dev/acpi_support/acpi_wmi.c 241537 2012-10-14 09:31:11Z avg $");
 
 /*
  * Driver for acpi-wmi mapping, provides an interface for vendor specific

Modified: trunk/sys/dev/acpi_support/acpi_wmi_if.m
===================================================================
--- trunk/sys/dev/acpi_support/acpi_wmi_if.m	2018-05-27 23:54:55 UTC (rev 10111)
+++ trunk/sys/dev/acpi_support/acpi_wmi_if.m	2018-05-27 23:55:14 UTC (rev 10112)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 #-
 # Copyright (c) 2009 Michael Gmelin
 # All rights reserved.
@@ -23,7 +24,7 @@
 # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 # SUCH DAMAGE.
 #
-# $MidnightBSD$
+# $FreeBSD: stable/10/sys/dev/acpi_support/acpi_wmi_if.m 195185 2009-06-30 09:51:41Z rpaulo $
 #
 
 #include <sys/bus.h>


Property changes on: trunk/sys/dev/acpi_support/acpi_wmi_if.m
___________________________________________________________________
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Modified: trunk/sys/dev/acpi_support/atk0110.c
===================================================================
--- trunk/sys/dev/acpi_support/atk0110.c	2018-05-27 23:54:55 UTC (rev 10111)
+++ trunk/sys/dev/acpi_support/atk0110.c	2018-05-27 23:55:14 UTC (rev 10112)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*	$NetBSD: atk0110.c,v 1.4 2010/02/11 06:54:57 cnst Exp $	*/
 /*	$OpenBSD: atk0110.c,v 1.1 2009/07/23 01:38:16 cnst Exp $	*/
 
@@ -18,7 +19,7 @@
  */
 
 #include <sys/cdefs.h>
-__MBSDID("$MidnightBSD$");
+__FBSDID("$FreeBSD: stable/10/sys/dev/acpi_support/atk0110.c 308369 2016-11-06 13:51:50Z avg $");
 
 #include <machine/_inttypes.h>
 #include <sys/param.h>
@@ -28,6 +29,7 @@
 #include <sys/module.h>
 #include <sys/malloc.h>
 #include <sys/sysctl.h>
+#include <sys/stdint.h>
 
 #include <contrib/dev/acpica/include/acpi.h>
 #include <dev/acpica/acpivar.h>
@@ -51,18 +53,23 @@
 #define AIBS_MORE_SENSORS
 #define AIBS_VERBOSE
 
-enum aibs_type {
-	AIBS_VOLT,
-	AIBS_TEMP,
-	AIBS_FAN
-};
+#define	AIBS_GROUP_SENSORS	0x06
 
+#define AIBS_SENS_TYPE(x)	(((x) >> 16) & 0xff)
+#define AIBS_SENS_TYPE_VOLT	2
+#define AIBS_SENS_TYPE_TEMP	3
+#define AIBS_SENS_TYPE_FAN	4
+
+#define	AIBS_SENS_TYPE_VOLT_NAME		"volt"
+#define	AIBS_SENS_TYPE_VOLT_TEMP		"temp"
+#define	AIBS_SENS_TYPE_VOLT_FAN		"fan"
+
 struct aibs_sensor {
 	ACPI_INTEGER	v;
 	ACPI_INTEGER	i;
 	ACPI_INTEGER	l;
 	ACPI_INTEGER	h;
-	enum aibs_type	t;
+	int		t;
 };
 
 struct aibs_softc {
@@ -72,6 +79,13 @@
 	struct aibs_sensor	*sc_asens_volt;
 	struct aibs_sensor	*sc_asens_temp;
 	struct aibs_sensor	*sc_asens_fan;
+	struct aibs_sensor	*sc_asens_all;
+
+	struct sysctl_oid	*sc_volt_sysctl;
+	struct sysctl_oid	*sc_temp_sysctl;
+	struct sysctl_oid	*sc_fan_sysctl;
+
+	bool			sc_ggrp_method;
 };
 
 static int aibs_probe(device_t);
@@ -78,8 +92,10 @@
 static int aibs_attach(device_t);
 static int aibs_detach(device_t);
 static int aibs_sysctl(SYSCTL_HANDLER_ARGS);
+static int aibs_sysctl_ggrp(SYSCTL_HANDLER_ARGS);
 
-static void aibs_attach_sif(struct aibs_softc *, enum aibs_type);
+static int aibs_attach_ggrp(struct aibs_softc *);
+static int aibs_attach_sif(struct aibs_softc *, int);
 
 static device_method_t aibs_methods[] = {
 	DEVMETHOD(device_probe,		aibs_probe),
@@ -97,8 +113,8 @@
 static devclass_t aibs_devclass;
 
 DRIVER_MODULE(aibs, acpi, aibs_driver, aibs_devclass, NULL, NULL);
+MODULE_DEPEND(aibs, acpi, 1, 1, 1);
 
-
 static char* aibs_hids[] = {
 	"ATK0110",
 	NULL
@@ -109,10 +125,10 @@
 {
 	if (acpi_disabled("aibs") ||
 	    ACPI_ID_PROBE(device_get_parent(dev), dev, aibs_hids) == NULL)
-		return ENXIO;
+		return (ENXIO);
 
 	device_set_desc(dev, "ASUSTeK AI Booster (ACPI ASOC ATK0110)");
-	return 0;
+	return (0);
 }
 
 static int
@@ -119,44 +135,230 @@
 aibs_attach(device_t dev)
 {
 	struct aibs_softc *sc = device_get_softc(dev);
+	int err;
 
 	sc->sc_dev = dev;
 	sc->sc_ah = acpi_get_handle(dev);
 
-	aibs_attach_sif(sc, AIBS_VOLT);
-	aibs_attach_sif(sc, AIBS_TEMP);
-	aibs_attach_sif(sc, AIBS_FAN);
+	sc->sc_ggrp_method = false;
+	err = aibs_attach_sif(sc, AIBS_SENS_TYPE_VOLT);
+	if (err == 0)
+		err = aibs_attach_sif(sc, AIBS_SENS_TYPE_TEMP);
+	if (err == 0)
+		err = aibs_attach_sif(sc, AIBS_SENS_TYPE_FAN);
 
-	return 0;
+	if (err == 0)
+		return (0);
+
+	/* Clean up whatever was allocated earlier. */
+	if (sc->sc_volt_sysctl != NULL)
+		sysctl_remove_oid(sc->sc_volt_sysctl, true, true);
+	if (sc->sc_temp_sysctl != NULL)
+		sysctl_remove_oid(sc->sc_temp_sysctl, true, true);
+	if (sc->sc_fan_sysctl != NULL)
+		sysctl_remove_oid(sc->sc_fan_sysctl, true, true);
+	aibs_detach(dev);
+
+	sc->sc_ggrp_method = true;
+	err = aibs_attach_ggrp(sc);
+	return (err);
 }
 
+static int
+aibs_add_sensor(struct aibs_softc *sc, ACPI_OBJECT *o,
+    struct aibs_sensor* sensor, const char ** descr)
+{
+	int		off;
+
+	/*
+	 * Packages for the old and new methods are quite
+	 * similar except that the new package has two
+	 * new (unknown / unused) fields after the name field.
+	 */
+	if (sc->sc_ggrp_method)
+		off = 4;
+	else
+		off = 2;
+
+	if (o->Type != ACPI_TYPE_PACKAGE) {
+		device_printf(sc->sc_dev,
+		    "sensor object is not a package: %i type\n",
+		     o->Type);
+		return (ENXIO);
+	}
+	if (o[0].Package.Count != (off + 3) ||
+	    o->Package.Elements[0].Type != ACPI_TYPE_INTEGER ||
+	    o->Package.Elements[1].Type != ACPI_TYPE_STRING ||
+	    o->Package.Elements[off].Type != ACPI_TYPE_INTEGER ||
+	    o->Package.Elements[off + 1].Type != ACPI_TYPE_INTEGER ||
+	    o->Package.Elements[off + 2].Type != ACPI_TYPE_INTEGER) {
+		device_printf(sc->sc_dev, "unexpected package content\n");
+		return (ENXIO);
+	}
+
+	sensor->i = o->Package.Elements[0].Integer.Value;
+	*descr = o->Package.Elements[1].String.Pointer;
+	sensor->l = o->Package.Elements[off].Integer.Value;
+	sensor->h = o->Package.Elements[off + 1].Integer.Value;
+	/* For the new method the second value is a range size. */
+	if (sc->sc_ggrp_method)
+		sensor->h += sensor->l;
+	sensor->t = AIBS_SENS_TYPE(sensor->i);
+
+	switch (sensor->t) {
+	case AIBS_SENS_TYPE_VOLT:
+	case AIBS_SENS_TYPE_TEMP:
+	case AIBS_SENS_TYPE_FAN:
+		return (0);
+	default:
+		device_printf(sc->sc_dev, "unknown sensor type 0x%x",
+		    sensor->t);
+		return (ENXIO);
+	}
+}
+
 static void
-aibs_attach_sif(struct aibs_softc *sc, enum aibs_type st)
+aibs_sensor_added(struct aibs_softc *sc, struct sysctl_oid *so,
+    const char *type_name, int idx, struct aibs_sensor *sensor,
+    const char *descr)
 {
+	char	sysctl_name[8];
+
+	snprintf(sysctl_name, sizeof(sysctl_name), "%i", idx);
+#ifdef AIBS_VERBOSE
+	device_printf(sc->sc_dev, "%c%i: 0x%08jx %20s %5jd / %5jd\n",
+	    type_name[0], idx,
+	    (uintmax_t)sensor->i, descr, (intmax_t)sensor->l,
+	    (intmax_t)sensor->h);
+#endif
+	SYSCTL_ADD_PROC(device_get_sysctl_ctx(sc->sc_dev),
+	    SYSCTL_CHILDREN(so), idx, sysctl_name,
+	    CTLTYPE_INT | CTLFLAG_RD, sc, (uintptr_t)sensor,
+	    sc->sc_ggrp_method ? aibs_sysctl_ggrp : aibs_sysctl,
+	    sensor->t == AIBS_SENS_TYPE_TEMP ? "IK" : "I", descr);
+}
+
+static int
+aibs_attach_ggrp(struct aibs_softc *sc)
+{
 	ACPI_STATUS		s;
+	ACPI_BUFFER		buf;
+	ACPI_HANDLE		h;
+	ACPI_OBJECT		id;
+	ACPI_OBJECT		*bp;
+	ACPI_OBJECT_LIST	arg;
+	int			i;
+	int			t, v, f;
+	int			err;
+	int			*s_idx;
+	const char		*name;
+	const char		*descr;
+	struct aibs_sensor	*sensor;
+	struct sysctl_oid	**so;
+
+	/* First see if GITM is available. */
+	s = AcpiGetHandle(sc->sc_ah, "GITM", &h);
+	if (ACPI_FAILURE(s)) {
+		if (bootverbose)
+			device_printf(sc->sc_dev, "GITM not found\n");
+		return (ENXIO);
+	}
+
+	/*
+	 * Now call GGRP with the appropriate argument to list sensors.
+	 * The method lists different groups of entities depending on
+	 * the argument.
+	 */
+	id.Integer.Value = AIBS_GROUP_SENSORS;
+	id.Type = ACPI_TYPE_INTEGER;
+	arg.Count = 1;
+	arg.Pointer = &id;
+	buf.Length = ACPI_ALLOCATE_BUFFER;
+	buf.Pointer = NULL;
+	s = AcpiEvaluateObjectTyped(sc->sc_ah, "GGRP", &arg, &buf,
+	    ACPI_TYPE_PACKAGE);
+	if (ACPI_FAILURE(s)) {
+		device_printf(sc->sc_dev, "GGRP not found\n");
+		return (ENXIO);
+	}
+
+	bp = buf.Pointer;
+	sc->sc_asens_all = malloc(sizeof(*sc->sc_asens_all) * bp->Package.Count,
+	    M_DEVBUF, M_WAITOK | M_ZERO);
+	v = t = f = 0;
+	for (i = 0; i < bp->Package.Count; i++) {
+		sensor = &sc->sc_asens_all[i];
+		err = aibs_add_sensor(sc, &bp->Package.Elements[i], sensor,
+		    &descr);
+		if (err != 0)
+			continue;
+
+		switch (sensor->t) {
+		case AIBS_SENS_TYPE_VOLT:
+			name = "volt";
+			so = &sc->sc_volt_sysctl;
+			s_idx = &v;
+			break;
+		case AIBS_SENS_TYPE_TEMP:
+			name = "temp";
+			so = &sc->sc_temp_sysctl;
+			s_idx = &t;
+			break;
+		case AIBS_SENS_TYPE_FAN:
+			name = "fan";
+			so = &sc->sc_fan_sysctl;
+			s_idx = &f;
+			break;
+		default:
+			panic("add_sensor succeeded for unknown sensor type %d",
+			    sensor->t);
+		}
+
+		if (*so == NULL) {
+			/* sysctl subtree for sensors of this type */
+			*so = SYSCTL_ADD_NODE(device_get_sysctl_ctx(sc->sc_dev),
+			    SYSCTL_CHILDREN(device_get_sysctl_tree(sc->sc_dev)),
+			    sensor->t, name, CTLFLAG_RD, NULL, NULL);
+		}
+		aibs_sensor_added(sc, *so, name, *s_idx, sensor, descr);
+		*s_idx += 1;
+	}
+
+	AcpiOsFree(buf.Pointer);
+	return (0);
+}
+
+static int
+aibs_attach_sif(struct aibs_softc *sc, int st)
+{
+	char			name[] = "?SIF";
+	ACPI_STATUS		s;
 	ACPI_BUFFER		b;
 	ACPI_OBJECT		*bp, *o;
-	int			i, n;
 	const char		*node;
-	char			name[] = "?SIF";
 	struct aibs_sensor	*as;
-	struct sysctl_oid	*so;
+	struct sysctl_oid	**so;
+	int			i, n;
+	int err;
 
 	switch (st) {
-	case AIBS_VOLT:
+	case AIBS_SENS_TYPE_VOLT:
 		node = "volt";
 		name[0] = 'V';
+		so = &sc->sc_volt_sysctl;
 		break;
-	case AIBS_TEMP:
+	case AIBS_SENS_TYPE_TEMP:
 		node = "temp";
 		name[0] = 'T';
+		so = &sc->sc_temp_sysctl;
 		break;
-	case AIBS_FAN:
+	case AIBS_SENS_TYPE_FAN:
 		node = "fan";
 		name[0] = 'F';
+		so = &sc->sc_fan_sysctl;
 		break;
 	default:
-		return;
+		panic("Unsupported sensor type %d", st);
 	}
 
 	b.Length = ACPI_ALLOCATE_BUFFER;
@@ -164,7 +366,7 @@
 	    ACPI_TYPE_PACKAGE);
 	if (ACPI_FAILURE(s)) {
 		device_printf(sc->sc_dev, "%s not found\n", name);
-		return;
+		return (ENXIO);
 	}
 
 	bp = b.Pointer;
@@ -172,7 +374,7 @@
 	if (o[0].Type != ACPI_TYPE_INTEGER) {
 		device_printf(sc->sc_dev, "%s[0]: invalid type\n", name);
 		AcpiOsFree(b.Pointer);
-		return;
+		return (ENXIO);
 	}
 
 	n = o[0].Integer.Value;
@@ -179,7 +381,7 @@
 	if (bp->Package.Count - 1 < n) {
 		device_printf(sc->sc_dev, "%s: invalid package\n", name);
 		AcpiOsFree(b.Pointer);
-		return;
+		return (ENXIO);
 	} else if (bp->Package.Count - 1 > n) {
 		int on = n;
 
@@ -193,76 +395,37 @@
 		device_printf(sc->sc_dev, "%s: no members in the package\n",
 		    name);
 		AcpiOsFree(b.Pointer);
-		return;
+		return (ENXIO);
 	}
 
-	as = malloc(sizeof(*as) * n, M_DEVBUF, M_NOWAIT | M_ZERO);
-	if (as == NULL) {
-		device_printf(sc->sc_dev, "%s: malloc fail\n", name);
-		AcpiOsFree(b.Pointer);
-		return;
-	}
+	as = malloc(sizeof(*as) * n, M_DEVBUF, M_WAITOK | M_ZERO);
 	switch (st) {
-	case AIBS_VOLT:
+	case AIBS_SENS_TYPE_VOLT:
 		sc->sc_asens_volt = as;
 		break;
-	case AIBS_TEMP:
+	case AIBS_SENS_TYPE_TEMP:
 		sc->sc_asens_temp = as;
 		break;
-	case AIBS_FAN:
+	case AIBS_SENS_TYPE_FAN:
 		sc->sc_asens_fan = as;
 		break;
 	}
 
 	/* sysctl subtree for sensors of this type */
-	so = SYSCTL_ADD_NODE(device_get_sysctl_ctx(sc->sc_dev),
+	*so = SYSCTL_ADD_NODE(device_get_sysctl_ctx(sc->sc_dev),
 	    SYSCTL_CHILDREN(device_get_sysctl_tree(sc->sc_dev)), st,
 	    node, CTLFLAG_RD, NULL, NULL);
 
 	for (i = 0, o++; i < n; i++, o++) {
-		ACPI_OBJECT	*oi;
-		char		si[3];
-		const char	*desc;
+		const char	*descr;
 
-		/* acpica5 automatically evaluates the referenced package */
-		if (o[0].Type != ACPI_TYPE_PACKAGE) {
-			device_printf(sc->sc_dev,
-			    "%s: %i: not a package: %i type\n",
-			    name, i, o[0].Type);
-			continue;
-		}
-		oi = o[0].Package.Elements;
-		if (o[0].Package.Count != 5 ||
-		    oi[0].Type != ACPI_TYPE_INTEGER ||
-		    oi[1].Type != ACPI_TYPE_STRING ||
-		    oi[2].Type != ACPI_TYPE_INTEGER ||
-		    oi[3].Type != ACPI_TYPE_INTEGER ||
-		    oi[4].Type != ACPI_TYPE_INTEGER) {
-			device_printf(sc->sc_dev,
-			    "%s: %i: invalid package\n",
-			    name, i);
-			continue;
-		}
-		as[i].i = oi[0].Integer.Value;
-		desc = oi[1].String.Pointer;
-		as[i].l = oi[2].Integer.Value;
-		as[i].h = oi[3].Integer.Value;
-		as[i].t = st;
-#ifdef AIBS_VERBOSE
-		device_printf(sc->sc_dev, "%c%i: "
-		    "0x%08"PRIx64" %20s %5"PRIi64" / %5"PRIi64"  "
-		    "0x%"PRIx64"\n",
-		    name[0], i,
-		    as[i].i, desc, (int64_t)as[i].l, (int64_t)as[i].h,
-		    oi[4].Integer.Value);
-#endif
-		snprintf(si, sizeof(si), "%i", i);
-		SYSCTL_ADD_PROC(device_get_sysctl_ctx(sc->sc_dev),
-		    SYSCTL_CHILDREN(so), i, si, CTLTYPE_INT | CTLFLAG_RD,
-		    sc, st, aibs_sysctl, st == AIBS_TEMP ? "IK" : "I", desc);
+		err = aibs_add_sensor(sc, o, &as[i], &descr);
+		if (err == 0)
+			aibs_sensor_added(sc, *so, node, i, &as[i], descr);
 	}
 
 	AcpiOsFree(b.Pointer);
+	return (0);
 }
 
 static int
@@ -276,7 +439,9 @@
 		free(sc->sc_asens_temp, M_DEVBUF);
 	if (sc->sc_asens_fan != NULL)
 		free(sc->sc_asens_fan, M_DEVBUF);
-	return 0;
+	if (sc->sc_asens_all != NULL)
+		free(sc->sc_asens_all, M_DEVBUF);
+	return (0);
 }
 
 #ifdef AIBS_VERBOSE
@@ -289,7 +454,7 @@
 aibs_sysctl(SYSCTL_HANDLER_ARGS)
 {
 	struct aibs_softc	*sc = arg1;
-	enum aibs_type		st = arg2;
+	struct aibs_sensor	*sensor = (void *)arg2;
 	int			i = oidp->oid_number;
 	ACPI_STATUS		rs;
 	ACPI_OBJECT		p, *bp;
@@ -296,32 +461,26 @@
 	ACPI_OBJECT_LIST	mp;
 	ACPI_BUFFER		b;
 	char			*name;
-	struct aibs_sensor	*as;
 	ACPI_INTEGER		v, l, h;
 	int			so[3];
 
-	switch (st) {
-	case AIBS_VOLT:
+	switch (sensor->t) {
+	case AIBS_SENS_TYPE_VOLT:
 		name = "RVLT";
-		as = sc->sc_asens_volt;
 		break;
-	case AIBS_TEMP:
+	case AIBS_SENS_TYPE_TEMP:
 		name = "RTMP";
-		as = sc->sc_asens_temp;
 		break;
-	case AIBS_FAN:
+	case AIBS_SENS_TYPE_FAN:
 		name = "RFAN";
-		as = sc->sc_asens_fan;
 		break;
 	default:
-		return ENOENT;
+		return (ENOENT);
 	}
-	if (as == NULL)
-		return ENOENT;
-	l = as[i].l;
-	h = as[i].h;
+	l = sensor->l;
+	h = sensor->h;
 	p.Type = ACPI_TYPE_INTEGER;
-	p.Integer.Value = as[i].i;
+	p.Integer.Value = sensor->i;
 	mp.Count = 1;
 	mp.Pointer = &p;
 	b.Length = ACPI_ALLOCATE_BUFFER;
@@ -333,7 +492,7 @@
 		    "%s: %i: evaluation failed\n",
 		    name, i);
 		ACPI_SERIAL_END(aibs);
-		return EIO;
+		return (EIO);
 	}
 	bp = b.Pointer;
 	v = bp->Integer.Value;
@@ -340,19 +499,84 @@
 	AcpiOsFree(b.Pointer);
 	ACPI_SERIAL_END(aibs);
 
-	switch (st) {
-	case AIBS_VOLT:
+	switch (sensor->t) {
+	case AIBS_SENS_TYPE_VOLT:
 		break;
-	case AIBS_TEMP:
+	case AIBS_SENS_TYPE_TEMP:
 		v += 2732;
 		l += 2732;
 		h += 2732;
 		break;
-	case AIBS_FAN:
+	case AIBS_SENS_TYPE_FAN:
 		break;
 	}
 	so[0] = v;
 	so[1] = l;
 	so[2] = h;
-	return sysctl_handle_opaque(oidp, &so, sizeof(so), req);
+	return (sysctl_handle_opaque(oidp, &so, sizeof(so), req));
 }
+
+static int
+aibs_sysctl_ggrp(SYSCTL_HANDLER_ARGS)
+{
+	struct aibs_softc	*sc = arg1;
+	struct aibs_sensor	*sensor = (void *)arg2;
+	ACPI_STATUS		rs;
+	ACPI_OBJECT		p, *bp;
+	ACPI_OBJECT_LIST	arg;
+	ACPI_BUFFER		buf;
+	ACPI_INTEGER		v, l, h;
+	int			so[3];
+	uint32_t		*ret;
+	uint32_t		cmd[3];
+
+	cmd[0] = sensor->i;
+	cmd[1] = 0;
+	cmd[2] = 0;
+	p.Type = ACPI_TYPE_BUFFER;
+	p.Buffer.Pointer = (void *)cmd;
+	p.Buffer.Length = sizeof(cmd);
+	arg.Count = 1;
+	arg.Pointer = &p;
+	buf.Pointer = NULL;
+	buf.Length = ACPI_ALLOCATE_BUFFER;
+	ACPI_SERIAL_BEGIN(aibs);
+	rs = AcpiEvaluateObjectTyped(sc->sc_ah, "GITM", &arg, &buf,
+	    ACPI_TYPE_BUFFER);
+	ACPI_SERIAL_END(aibs);
+	if (ACPI_FAILURE(rs)) {
+		device_printf(sc->sc_dev, "GITM evaluation failed\n");
+		return (EIO);
+	}
+	bp = buf.Pointer;
+	if (bp->Buffer.Length < 8) {
+		device_printf(sc->sc_dev, "GITM returned short buffer\n");
+		return (EIO);
+	}
+	ret = (uint32_t *)bp->Buffer.Pointer;
+	if (ret[0] == 0) {
+		device_printf(sc->sc_dev, "GITM returned error status\n");
+		return (EINVAL);
+	}
+	v = ret[1];
+	AcpiOsFree(buf.Pointer);
+
+	l = sensor->l;
+	h = sensor->h;
+
+	switch (sensor->t) {
+	case AIBS_SENS_TYPE_VOLT:
+		break;
+	case AIBS_SENS_TYPE_TEMP:
+		v += 2731;
+		l += 2731;
+		h += 2731;
+		break;
+	case AIBS_SENS_TYPE_FAN:
+		break;
+	}
+	so[0] = v;
+	so[1] = l;
+	so[2] = h;
+	return (sysctl_handle_opaque(oidp, &so, sizeof(so), req));
+}



More information about the Midnightbsd-cvs mailing list