Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys Rework Apple SMC attachment goo and split into multiple ...
details: https://anonhg.NetBSD.org/src/rev/fe76a469dce3
branches: trunk
changeset: 795111:fe76a469dce3
user: riastradh <riastradh%NetBSD.org@localhost>
date: Tue Apr 01 17:48:39 2014 +0000
description:
Rework Apple SMC attachment goo and split into multiple modules.
The four modules are apple_smc for the core functions, apple_smc_acpi
for attachment at acpi, and apple_smc_fan & apple_smc_temp for stuff
on the SMC.
Seems like there's a lot more bookkeeping necessary to maintain
children of an applesmc device implemented by loadable modules.
Maybe there's a better way I just haven't figured out yet.
diffstat:
sys/conf/files | 7 +-
sys/dev/acpi/apple_smc_acpi.c | 72 ++++-
sys/dev/ic/apple_smc.c | 330 +++++++++++++++++++---
sys/dev/ic/apple_smc.h | 8 +-
sys/dev/ic/apple_smc_fan.c | 53 +++-
sys/dev/ic/apple_smc_temp.c | 53 +++-
sys/dev/ic/apple_smcvar.h | 19 +-
sys/modules/apple_smc/Makefile | 6 +-
sys/modules/apple_smc_acpi/Makefile | 15 +
sys/modules/apple_smc_acpi/apple_smc_acpi.ioconf | 10 +
sys/modules/apple_smc_fan/Makefile | 15 +
sys/modules/apple_smc_fan/apple_smc_fan.ioconf | 9 +
sys/modules/apple_smc_temp/Makefile | 15 +
sys/modules/apple_smc_temp/apple_smc_temp.ioconf | 9 +
14 files changed, 545 insertions(+), 76 deletions(-)
diffs (truncated from 902 to 300 lines):
diff -r 460fd99ae4e2 -r fe76a469dce3 sys/conf/files
--- a/sys/conf/files Tue Apr 01 17:47:36 2014 +0000
+++ b/sys/conf/files Tue Apr 01 17:48:39 2014 +0000
@@ -1,4 +1,4 @@
-# $NetBSD: files,v 1.1088 2014/04/01 17:47:36 riastradh Exp $
+# $NetBSD: files,v 1.1089 2014/04/01 17:48:39 riastradh Exp $
# @(#)files.newconf 7.5 (Berkeley) 5/10/93
version 20100430
@@ -1097,7 +1097,8 @@
# Apple System Management Controller
#
-device applesmc {}
+define applesmcbus { }
+device applesmc { }: applesmcbus
file dev/ic/apple_smc.c applesmc
# Apple SMC fan sensors and control
@@ -1110,7 +1111,7 @@
attach applesmctemp at applesmc with apple_smc_temp
file dev/ic/apple_smc_temp.c applesmctemp
-# Apple SMC accelerometer
+# Apple SMC accelerometer (not yet implemented!)
#device applesmcaccel: applesmc, sysmon_envsys
#attach applesmcaccel at applesmc with apple_smc_accel
#file dev/ic/apple_smc_accel.c applesmcaccel
diff -r 460fd99ae4e2 -r fe76a469dce3 sys/dev/acpi/apple_smc_acpi.c
--- a/sys/dev/acpi/apple_smc_acpi.c Tue Apr 01 17:47:36 2014 +0000
+++ b/sys/dev/acpi/apple_smc_acpi.c Tue Apr 01 17:48:39 2014 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: apple_smc_acpi.c,v 1.1 2014/04/01 17:47:36 riastradh Exp $ */
+/* $NetBSD: apple_smc_acpi.c,v 1.2 2014/04/01 17:48:39 riastradh Exp $ */
/*
* Apple System Management Controller: ACPI Attachment
@@ -31,10 +31,12 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: apple_smc_acpi.c,v 1.1 2014/04/01 17:47:36 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: apple_smc_acpi.c,v 1.2 2014/04/01 17:48:39 riastradh Exp $");
#include <sys/types.h>
#include <sys/param.h>
+#include <sys/bus.h>
+#include <sys/module.h>
#include <dev/acpi/acpireg.h>
#include <dev/acpi/acpivar.h>
@@ -52,9 +54,16 @@
static int apple_smc_acpi_match(device_t, cfdata_t, void *);
static void apple_smc_acpi_attach(device_t, device_t, void *);
static int apple_smc_acpi_detach(device_t, int);
-
-CFATTACH_DECL_NEW(apple_smc_acpi, sizeof(struct apple_smc_acpi_softc),
- apple_smc_acpi_match, apple_smc_acpi_attach, apple_smc_acpi_detach, NULL);
+static int apple_smc_acpi_rescan(device_t, const char *, const int *);
+static void apple_smc_acpi_child_detached(device_t, device_t);
+
+CFATTACH_DECL2_NEW(apple_smc_acpi, sizeof(struct apple_smc_acpi_softc),
+ apple_smc_acpi_match,
+ apple_smc_acpi_attach,
+ apple_smc_acpi_detach,
+ NULL /* activate */,
+ apple_smc_acpi_rescan,
+ apple_smc_acpi_child_detached);
static const char *const apple_smc_ids[] = {
"APP0001",
@@ -143,3 +152,56 @@
return 0;
}
+
+static int
+apple_smc_acpi_rescan(device_t self, const char *ifattr, const int *locs)
+{
+ struct apple_smc_acpi_softc *const sc = device_private(self);
+
+ return apple_smc_rescan(&sc->sc_smc, ifattr, locs);
+}
+
+static void
+apple_smc_acpi_child_detached(device_t self, device_t child)
+{
+ struct apple_smc_acpi_softc *const sc = device_private(self);
+
+ apple_smc_child_detached(&sc->sc_smc, child);
+}
+
+MODULE(MODULE_CLASS_DRIVER, apple_smc_acpi, "apple_smc");
+
+#ifdef _MODULE
+#include "ioconf.c"
+#endif
+
+static int
+apple_smc_acpi_modcmd(modcmd_t cmd, void *arg __unused)
+{
+ int error;
+
+ switch (cmd) {
+ case MODULE_CMD_INIT:
+#ifdef _MODULE
+ error = config_init_component(cfdriver_ioconf_apple_smc_acpi,
+ cfattach_ioconf_apple_smc_acpi,
+ cfdata_ioconf_apple_smc_acpi);
+ if (error)
+ return error;
+#endif
+ return 0;
+
+ case MODULE_CMD_FINI:
+#ifdef _MODULE
+ error = config_fini_component(cfdriver_ioconf_apple_smc_acpi,
+ cfattach_ioconf_apple_smc_acpi,
+ cfdata_ioconf_apple_smc_acpi);
+ if (error)
+ return error;
+#endif
+ return 0;
+
+ default:
+ return ENOTTY;
+ }
+}
diff -r 460fd99ae4e2 -r fe76a469dce3 sys/dev/ic/apple_smc.c
--- a/sys/dev/ic/apple_smc.c Tue Apr 01 17:47:36 2014 +0000
+++ b/sys/dev/ic/apple_smc.c Tue Apr 01 17:48:39 2014 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: apple_smc.c,v 1.1 2014/04/01 17:47:36 riastradh Exp $ */
+/* $NetBSD: apple_smc.c,v 1.2 2014/04/01 17:48:39 riastradh Exp $ */
/*
* Apple System Management Controller
@@ -34,14 +34,17 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: apple_smc.c,v 1.1 2014/04/01 17:47:36 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: apple_smc.c,v 1.2 2014/04/01 17:48:39 riastradh Exp $");
#include <sys/types.h>
#include <sys/param.h>
#include <sys/device.h>
#include <sys/errno.h>
#include <sys/kmem.h>
+#include <sys/module.h>
#include <sys/mutex.h>
+#include <sys/rbtree.h>
+#include <sys/rwlock.h>
#if 0 /* XXX sysctl */
#include <sys/sysctl.h>
#endif
@@ -51,9 +54,13 @@
#include <dev/ic/apple_smcreg.h>
#include <dev/ic/apple_smcvar.h>
-static void apple_smc_rescan1(struct apple_smc_tag *,
- struct apple_smc_attach_args *,
- const char *, const char *, device_t *);
+#define APPLE_SMC_BUS "applesmcbus"
+
+static int apple_smc_dev_compare_nodes(void *, const void *,
+ const void *);
+static int apple_smc_dev_compare_key(void *, const void *, const void *);
+static int apple_smc_init(void);
+static int apple_smc_fini(void);
static uint8_t apple_smc_bus_read_1(struct apple_smc_tag *, bus_size_t);
static void apple_smc_bus_write_1(struct apple_smc_tag *, bus_size_t,
uint8_t);
@@ -67,12 +74,151 @@
const char *, void *, uint8_t);
static int apple_smc_output(struct apple_smc_tag *, uint8_t,
const char *, const void *, uint8_t);
+
+struct apple_smc_dev {
+ char asd_name[APPLE_SMC_DEVICE_NAME_SIZE];
+ rb_node_t asd_node;
+ device_t asd_dev[];
+};
+static int
+apple_smc_dev_compare_nodes(void *context __unused, const void *va,
+ const void *vb)
+{
+ const struct apple_smc_dev *const a = va;
+ const struct apple_smc_dev *const b = vb;
+
+ return strncmp(a->asd_name, b->asd_name, APPLE_SMC_DEVICE_NAME_SIZE);
+}
+
+static int
+apple_smc_dev_compare_key(void *context __unused, const void *vn,
+ const void *vk)
+{
+ const struct apple_smc_dev *const dev = vn;
+ const char *const key = vk;
+
+ return strncmp(dev->asd_name, key, APPLE_SMC_DEVICE_NAME_SIZE);
+}
+
+static krwlock_t apple_smc_registered_devices_lock;
+static rb_tree_t apple_smc_registered_devices;
+static unsigned int apple_smc_n_registered_devices;
+
+static const rb_tree_ops_t apple_smc_dev_tree_ops = {
+ .rbto_compare_nodes = &apple_smc_dev_compare_nodes,
+ .rbto_compare_key = &apple_smc_dev_compare_key,
+ .rbto_node_offset = offsetof(struct apple_smc_dev, asd_node),
+};
+
+static int
+apple_smc_init(void)
+{
+
+ rw_init(&apple_smc_registered_devices_lock);
+ rb_tree_init(&apple_smc_registered_devices, &apple_smc_dev_tree_ops);
+ apple_smc_n_registered_devices = 0;
+
+ /* Success! */
+ return 0;
+}
+
+static int
+apple_smc_fini(void)
+{
+
+ /* Refuse to unload if there remain any registered devices. */
+ if (apple_smc_n_registered_devices)
+ return EBUSY;
+
+ /* The tree should be empty in this case. */
+ KASSERT(rb_tree_iterate(&apple_smc_registered_devices, NULL,
+ RB_DIR_RIGHT) == NULL);
+
+#if 0 /* XXX no rb_tree_destroy */
+ rb_tree_destroy(&apple_smc_registered_devices);
+#endif
+ rw_destroy(&apple_smc_registered_devices_lock);
+
+ /* Success! */
+ return 0;
+}
+
+int
+apple_smc_register_device(const char name[APPLE_SMC_DEVICE_NAME_SIZE])
+{
+ int error;
+
+ /* Paranoia about null termination. */
+ KASSERT(name[strnlen(name, (sizeof(name) - 1))] == '\0');
+
+ /* Make a new record for the registration. */
+ struct apple_smc_dev *const dev =
+ kmem_alloc(offsetof(struct apple_smc_dev, asd_dev[0]), KM_SLEEP);
+ (void)strlcpy(dev->asd_name, name, sizeof(dev->asd_name));
+
+ rw_enter(&apple_smc_registered_devices_lock, RW_WRITER);
+
+ /* Fail if there are too many. We really oughtn't get here. */
+ if (apple_smc_n_registered_devices == UINT_MAX) {
+ error = ENOMEM;
+ goto out;
+ }
+
+ /* Fail if the name is already registered. */
+ struct apple_smc_dev *const collision =
+ rb_tree_insert_node(&apple_smc_registered_devices, dev);
+ if (collision != dev) {
+ kmem_free(dev, offsetof(struct apple_smc_dev, asd_dev[0]));
+ error = EEXIST;
+ goto out;
+ }
+
+ /* Success! */
+ apple_smc_n_registered_devices++;
+ error = 0;
+
+out:
+ rw_exit(&apple_smc_registered_devices_lock);
+ return error;
+}
+
+void
+apple_smc_unregister_device(const char name[APPLE_SMC_DEVICE_NAME_SIZE])
+{
+
+ KASSERT(name[strnlen(name, (sizeof(name) - 1))] == '\0');
+
+ rw_enter(&apple_smc_registered_devices_lock, RW_WRITER);
+
+ /* Find the node. */
+ struct apple_smc_dev *const dev =
+ rb_tree_find_node(&apple_smc_registered_devices, name);
+ if (dev == NULL) {
+ printf("%s: device was never registered: %s\n", __func__,
+ name);
Home |
Main Index |
Thread Index |
Old Index