Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/dev/ic Rework Apple SMC device attachment goo again.
details: https://anonhg.NetBSD.org/src/rev/7007c9b35689
branches: trunk
changeset: 795112:7007c9b35689
user: riastradh <riastradh%NetBSD.org@localhost>
date: Tue Apr 01 17:48:52 2014 +0000
description:
Rework Apple SMC device attachment goo again.
Less bookkeeping at the expense of iteration over all devices when
rescanning applesmc.
diffstat:
sys/dev/ic/apple_smc.c | 282 +++++++------------------------------------
sys/dev/ic/apple_smc.h | 8 +-
sys/dev/ic/apple_smc_fan.c | 17 +--
sys/dev/ic/apple_smc_temp.c | 17 +--
sys/dev/ic/apple_smcvar.h | 5 +-
5 files changed, 54 insertions(+), 275 deletions(-)
diffs (truncated from 539 to 300 lines):
diff -r fe76a469dce3 -r 7007c9b35689 sys/dev/ic/apple_smc.c
--- a/sys/dev/ic/apple_smc.c Tue Apr 01 17:48:39 2014 +0000
+++ b/sys/dev/ic/apple_smc.c Tue Apr 01 17:48:52 2014 +0000
@@ -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 @@
#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 @@
#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_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 @@
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;
+
+ (void)config_search_loc(&apple_smc_search, smc->smc_dev, APPLE_SMC_BUS,
+ locators, smc);
+ return 0;
+}
- if (!ifattr_match(ifattr, APPLE_SMC_BUS))
- 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;
+ if (!device_is_a(dev, cf->cf_name))
continue;
+ attached = true;
+ break;
+ }
+ deviter_release(&di);
+ if (attached)
+ return 0;
- /* 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)
- 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);
+ /* If this device doesn't match, don't attach it. */
+ if (!config_match(parent, cf, aux))
+ return 0;
- /* 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);
Home |
Main Index |
Thread Index |
Old Index