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 *);

Reply via email to