Module Name: src
Committed By: riastradh
Date: Tue Apr 1 17:48:52 UTC 2014
Modified Files:
src/sys/dev/ic: apple_smc.c apple_smc.h apple_smc_fan.c
apple_smc_temp.c apple_smcvar.h
Log Message:
Rework Apple SMC device attachment goo again.
Less bookkeeping at the expense of iteration over all devices when
rescanning applesmc.
To generate a diff of this commit:
cvs rdiff -u -r1.2 -r1.3 src/sys/dev/ic/apple_smc.c \
src/sys/dev/ic/apple_smc.h src/sys/dev/ic/apple_smc_fan.c \
src/sys/dev/ic/apple_smc_temp.c src/sys/dev/ic/apple_smcvar.h
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/sys/dev/ic/apple_smc.c
diff -u src/sys/dev/ic/apple_smc.c:1.2 src/sys/dev/ic/apple_smc.c:1.3
--- src/sys/dev/ic/apple_smc.c:1.2 Tue Apr 1 17:48:39 2014
+++ src/sys/dev/ic/apple_smc.c Tue Apr 1 17:48:52 2014
@@ -1,4 +1,4 @@
-/* $NetBSD: apple_smc.c,v 1.2 2014/04/01 17:48:39 riastradh Exp $ */
+/* $NetBSD: apple_smc.c,v 1.3 2014/04/01 17:48:52 riastradh Exp $ */
/*
* Apple System Management Controller
@@ -34,7 +34,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: apple_smc.c,v 1.2 2014/04/01 17:48:39 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: apple_smc.c,v 1.3 2014/04/01 17:48:52 riastradh Exp $");
#include <sys/types.h>
#include <sys/param.h>
@@ -43,7 +43,6 @@ __KERNEL_RCSID(0, "$NetBSD: apple_smc.c,
#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>
@@ -54,13 +53,10 @@ __KERNEL_RCSID(0, "$NetBSD: apple_smc.c,
#include <dev/ic/apple_smcreg.h>
#include <dev/ic/apple_smcvar.h>
+/* Must match the config(5) name. */
#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 int apple_smc_search(device_t, cfdata_t, const int *, 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);
@@ -75,156 +71,17 @@ static int apple_smc_input(struct apple_
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);
- goto out;
- }
-
- /* If we found one, this ought to be at least 1. */
- KASSERT(apple_smc_n_registered_devices > 0);
-
- /* Remove it, but wait until unlocked to free it (paranoia). */
- rb_tree_remove_node(&apple_smc_registered_devices, dev);
- apple_smc_n_registered_devices--;
-
-out:
- rw_exit(&apple_smc_registered_devices_lock);
- if (dev != NULL)
- kmem_free(dev, offsetof(struct apple_smc_dev, asd_dev[0]));
-}
-
void
apple_smc_attach(struct apple_smc_tag *smc)
{
mutex_init(&smc->smc_lock, MUTEX_DEFAULT, IPL_NONE);
- rb_tree_init(&smc->smc_devices, &apple_smc_dev_tree_ops);
#if 0 /* XXX sysctl */
apple_smc_sysctl_setup(smc);
#endif
- (void)apple_smc_rescan(smc, NULL, NULL);
+ (void)apple_smc_rescan(smc, APPLE_SMC_BUS, NULL);
}
int
@@ -245,105 +102,58 @@ apple_smc_detach(struct apple_smc_tag *s
int
apple_smc_rescan(struct apple_smc_tag *smc, const char *ifattr,
- const int *locators __unused)
+ const int *locators)
{
- struct apple_smc_attach_args asa;
- struct apple_smc_dev *registered, *attached;
- device_t child;
- if (!ifattr_match(ifattr, APPLE_SMC_BUS))
- return 0;
+ (void)config_search_loc(&apple_smc_search, smc->smc_dev, APPLE_SMC_BUS,
+ locators, smc);
+ return 0;
+}
- (void)memset(&asa, 0, sizeof asa);
- asa.asa_smc = smc;
-#if 0 /* XXX sysctl */
- asa.asa_sysctlnode = smc->smc_sysctlnode;
-#endif
+static int
+apple_smc_search(device_t parent, cfdata_t cf, const int *locators, void *aux)
+{
+ struct apple_smc_tag *const smc = aux;
+ static const struct apple_smc_attach_args zero_asa;
+ struct apple_smc_attach_args asa = zero_asa;
+ device_t dev;
+ deviter_t di;
+ bool attached = false;
/*
- * Go through all the registered SMC devices and try to attach
- * them.
+ * If this device has already attached, don't attach it again.
*
- * XXX Horrible quadratic-time loop to avoid holding the rwlock
- * during allocation. Fortunately, there are not likely to be
- * many of these devices.
+ * XXX This is a pretty silly way to query the children, but
+ * struct device doesn't seem to list its children.
*/
-restart:
- registered = NULL;
- rw_enter(&apple_smc_registered_devices_lock, RW_READER);
- while ((registered = rb_tree_iterate(&apple_smc_registered_devices,
- registered, RB_DIR_RIGHT)) != NULL) {
- char name[APPLE_SMC_DEVICE_NAME_SIZE];
- CTASSERT(sizeof(name) == sizeof(registered->asd_name));
-
- /* Paranoia about null termination. */
- KASSERT(registered->asd_name[strnlen(registered->asd_name,
- (sizeof(registered->asd_name) - 1))] == '\0');
-
- /* Skip it if we already have it attached. */
- attached = rb_tree_find_node(&smc->smc_devices,
- registered->asd_name);
- if (attached != NULL)
+ for (dev = deviter_first(&di, DEVITER_F_LEAVES_FIRST);
+ dev != NULL;
+ dev = deviter_next(&di)) {
+ if (device_parent(dev) != parent)
continue;
-
- /* Try to match it autoconfily. */
- asa.asa_device = registered->asd_name;
- child = config_found_ia(smc->smc_dev, APPLE_SMC_BUS, &asa,
- NULL);
- if (child == NULL)
+ if (!device_is_a(dev, cf->cf_name))
continue;
-
- /* Save the name while we drop the lock. */
- (void)strlcpy(name, registered->asd_name, sizeof(name));
-
- /* Drop the lock so we can allocate. */
- rw_exit(&apple_smc_registered_devices_lock);
-
- /* Create a new record for the attachment. */
- attached = kmem_alloc(offsetof(struct apple_smc_dev,
- asd_dev[1]), KM_SLEEP);
- (void)strlcpy(attached->asd_name, name, sizeof(name));
- attached->asd_dev[0] = child;
-
- /* Store it in the tree. */
- struct apple_smc_dev *const collision __unused =
- rb_tree_insert_node(&smc->smc_devices, attached);
- KASSERT(collision == attached);
-
- /* Start back at the beginning since we dropped the lock. */
- goto restart;
+ attached = true;
+ break;
}
- rw_exit(&apple_smc_registered_devices_lock);
+ deviter_release(&di);
+ if (attached)
+ return 0;
- /* Success! */
- return 0;
+ /* If this device doesn't match, don't attach it. */
+ if (!config_match(parent, cf, aux))
+ return 0;
+
+ /* Looks hunky-dory. Attach. */
+ asa.asa_smc = smc;
+ (void)config_attach_loc(parent, cf, locators, &asa, NULL);
+ return 0;
}
void
-apple_smc_child_detached(struct apple_smc_tag *smc, device_t child)
+apple_smc_child_detached(struct apple_smc_tag *smc __unused,
+ device_t child __unused)
{
- struct apple_smc_dev *dev, *next;
- bool done = false;
-
- /*
- * Go through the list of attached devices safely with respect
- * to removal and remove any matching entries. There should be
- * only one, but paranoia.
- */
- for (dev = rb_tree_iterate(&smc->smc_devices, NULL, RB_DIR_RIGHT);
- (dev != NULL?
- (next = rb_tree_iterate(&smc->smc_devices, dev,
- RB_DIR_RIGHT), true)
- : false);
- dev = next) {
- if (dev->asd_dev[0] != child)
- continue;
- if (done)
- printf("apple smc child doubly attached: %s\n",
- dev->asd_name);
- rb_tree_remove_node(&smc->smc_devices, dev);
- kmem_free(dev, offsetof(struct apple_smc_dev, asd_dev[1]));
- }
}
static uint8_t
@@ -747,10 +557,10 @@ apple_smc_modcmd(modcmd_t cmd, void *dat
switch (cmd) {
case MODULE_CMD_INIT:
- return apple_smc_init();
+ return 0;
case MODULE_CMD_FINI:
- return apple_smc_fini();
+ return 0;
default:
return ENOTTY;
Index: src/sys/dev/ic/apple_smc.h
diff -u src/sys/dev/ic/apple_smc.h:1.2 src/sys/dev/ic/apple_smc.h:1.3
--- src/sys/dev/ic/apple_smc.h:1.2 Tue Apr 1 17:48:39 2014
+++ src/sys/dev/ic/apple_smc.h Tue Apr 1 17:48:52 2014
@@ -1,4 +1,4 @@
-/* $NetBSD: apple_smc.h,v 1.2 2014/04/01 17:48:39 riastradh Exp $ */
+/* $NetBSD: apple_smc.h,v 1.3 2014/04/01 17:48:52 riastradh Exp $ */
/*
* Apple System Management Controller Interface
@@ -42,7 +42,6 @@ struct apple_smc_tag;
struct apple_smc_attach_args {
struct apple_smc_tag *asa_smc;
- const char *asa_device;
};
struct apple_smc_key;
@@ -107,9 +106,4 @@ int apple_smc_write_key_2(struct apple_s
int apple_smc_write_key_4(struct apple_smc_tag *,
const struct apple_smc_key *, uint32_t);
-#define APPLE_SMC_DEVICE_NAME_SIZE 0x20
-
-int apple_smc_register_device(const char[APPLE_SMC_DEVICE_NAME_SIZE]);
-void apple_smc_unregister_device(const char[APPLE_SMC_DEVICE_NAME_SIZE]);
-
#endif /* _DEV_IC_APPLE_SMC_H_ */
Index: src/sys/dev/ic/apple_smc_fan.c
diff -u src/sys/dev/ic/apple_smc_fan.c:1.2 src/sys/dev/ic/apple_smc_fan.c:1.3
--- src/sys/dev/ic/apple_smc_fan.c:1.2 Tue Apr 1 17:48:39 2014
+++ src/sys/dev/ic/apple_smc_fan.c Tue Apr 1 17:48:52 2014
@@ -1,4 +1,4 @@
-/* $NetBSD: apple_smc_fan.c,v 1.2 2014/04/01 17:48:39 riastradh Exp $ */
+/* $NetBSD: apple_smc_fan.c,v 1.3 2014/04/01 17:48:52 riastradh Exp $ */
/*
* Apple System Management Controller: Fans
@@ -34,7 +34,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: apple_smc_fan.c,v 1.2 2014/04/01 17:48:39 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: apple_smc_fan.c,v 1.3 2014/04/01 17:48:52 riastradh Exp $");
#include <sys/types.h>
#include <sys/param.h>
@@ -50,8 +50,6 @@ __KERNEL_RCSID(0, "$NetBSD: apple_smc_fa
#include <dev/sysmon/sysmonvar.h>
-#define APPLE_SMC_DEVICE "applesmcfan"
-
#define APPLE_SMC_NFANS_KEY "FNum"
static const struct fan_sensor {
@@ -118,9 +116,6 @@ apple_smc_fan_match(device_t parent, cfd
int rv = 0;
int error;
- if (strcmp(asa->asa_device, APPLE_SMC_DEVICE) != 0)
- goto out0;
-
error = apple_smc_named_key(asa->asa_smc, APPLE_SMC_NFANS_KEY,
APPLE_SMC_TYPE_UINT8, &nfans_key);
if (error)
@@ -424,17 +419,12 @@ apple_smc_fan_modcmd(modcmd_t cmd, void
switch (cmd) {
case MODULE_CMD_INIT:
- error = apple_smc_register_device(APPLE_SMC_DEVICE);
- if (error)
- return error;
#ifdef _MODULE
error = config_init_component(cfdriver_ioconf_apple_smc_fan,
cfattach_ioconf_apple_smc_fan,
cfdata_ioconf_apple_smc_fan);
- if (error) {
- apple_smc_unregister_device(APPLE_SMC_DEVICE);
+ if (error)
return error;
- }
#endif
return 0;
@@ -446,7 +436,6 @@ apple_smc_fan_modcmd(modcmd_t cmd, void
if (error)
return error;
#endif
- apple_smc_unregister_device(APPLE_SMC_DEVICE);
return 0;
default:
Index: src/sys/dev/ic/apple_smc_temp.c
diff -u src/sys/dev/ic/apple_smc_temp.c:1.2 src/sys/dev/ic/apple_smc_temp.c:1.3
--- src/sys/dev/ic/apple_smc_temp.c:1.2 Tue Apr 1 17:48:39 2014
+++ src/sys/dev/ic/apple_smc_temp.c Tue Apr 1 17:48:52 2014
@@ -1,4 +1,4 @@
-/* $NetBSD: apple_smc_temp.c,v 1.2 2014/04/01 17:48:39 riastradh Exp $ */
+/* $NetBSD: apple_smc_temp.c,v 1.3 2014/04/01 17:48:52 riastradh Exp $ */
/*
* Apple System Management Controller: Temperature Sensors
@@ -34,7 +34,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: apple_smc_temp.c,v 1.2 2014/04/01 17:48:39 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: apple_smc_temp.c,v 1.3 2014/04/01 17:48:52 riastradh Exp $");
#include <sys/types.h>
#include <sys/param.h>
@@ -47,8 +47,6 @@ __KERNEL_RCSID(0, "$NetBSD: apple_smc_te
#include <dev/sysmon/sysmonvar.h>
-#define APPLE_SMC_DEVICE "applesmctemp"
-
struct apple_smc_temp_softc {
device_t sc_dev;
struct apple_smc_tag *sc_smc;
@@ -93,9 +91,6 @@ apple_smc_temp_match(device_t parent, cf
uint32_t nsensors;
int error;
- if (strcmp(asa->asa_device, APPLE_SMC_DEVICE) != 0)
- return 0;
-
error = apple_smc_temp_count_sensors(asa->asa_smc, &nsensors);
if (error)
return 0;
@@ -379,17 +374,12 @@ apple_smc_temp_modcmd(modcmd_t cmd, void
switch (cmd) {
case MODULE_CMD_INIT:
- error = apple_smc_register_device(APPLE_SMC_DEVICE);
- if (error)
- return error;
#ifdef _MODULE
error = config_init_component(cfdriver_ioconf_apple_smc_temp,
cfattach_ioconf_apple_smc_temp,
cfdata_ioconf_apple_smc_temp);
- if (error) {
- apple_smc_unregister_device(APPLE_SMC_DEVICE);
+ if (error)
return error;
- }
#endif
return 0;
@@ -401,7 +391,6 @@ apple_smc_temp_modcmd(modcmd_t cmd, void
if (error)
return error;
#endif
- apple_smc_unregister_device(APPLE_SMC_DEVICE);
return 0;
default:
Index: src/sys/dev/ic/apple_smcvar.h
diff -u src/sys/dev/ic/apple_smcvar.h:1.2 src/sys/dev/ic/apple_smcvar.h:1.3
--- src/sys/dev/ic/apple_smcvar.h:1.2 Tue Apr 1 17:48:39 2014
+++ src/sys/dev/ic/apple_smcvar.h Tue Apr 1 17:48:52 2014
@@ -1,4 +1,4 @@
-/* $NetBSD: apple_smcvar.h,v 1.2 2014/04/01 17:48:39 riastradh Exp $ */
+/* $NetBSD: apple_smcvar.h,v 1.3 2014/04/01 17:48:52 riastradh Exp $ */
/*
* Apple System Management Controller State
@@ -41,7 +41,6 @@
#include <sys/bus.h>
#include <sys/device_if.h>
#include <sys/mutex.h>
-#include <sys/rbtree.h>
struct apple_smc_tag {
device_t smc_dev;
@@ -55,8 +54,6 @@ struct apple_smc_tag {
struct sysctllog *smc_sysctllog;
const struct sysctlnode *smc_sysctlnode;
#endif
-
- rb_tree_t smc_devices;
};
void apple_smc_attach(struct apple_smc_tag *);