Module Name: src Committed By: riastradh Date: Tue Apr 1 17:48:39 UTC 2014
Modified Files: src/sys/conf: files src/sys/dev/acpi: apple_smc_acpi.c src/sys/dev/ic: apple_smc.c apple_smc.h apple_smc_fan.c apple_smc_temp.c apple_smcvar.h src/sys/modules/apple_smc: Makefile Added Files: src/sys/modules/apple_smc_acpi: Makefile apple_smc_acpi.ioconf src/sys/modules/apple_smc_fan: Makefile apple_smc_fan.ioconf src/sys/modules/apple_smc_temp: Makefile apple_smc_temp.ioconf Log Message: 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. To generate a diff of this commit: cvs rdiff -u -r1.1088 -r1.1089 src/sys/conf/files cvs rdiff -u -r1.1 -r1.2 src/sys/dev/acpi/apple_smc_acpi.c cvs rdiff -u -r1.1 -r1.2 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 cvs rdiff -u -r1.1 -r1.2 src/sys/modules/apple_smc/Makefile cvs rdiff -u -r0 -r1.1 src/sys/modules/apple_smc_acpi/Makefile \ src/sys/modules/apple_smc_acpi/apple_smc_acpi.ioconf cvs rdiff -u -r0 -r1.1 src/sys/modules/apple_smc_fan/Makefile \ src/sys/modules/apple_smc_fan/apple_smc_fan.ioconf cvs rdiff -u -r0 -r1.1 src/sys/modules/apple_smc_temp/Makefile \ src/sys/modules/apple_smc_temp/apple_smc_temp.ioconf Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/conf/files diff -u src/sys/conf/files:1.1088 src/sys/conf/files:1.1089 --- src/sys/conf/files:1.1088 Tue Apr 1 17:47:36 2014 +++ src/sys/conf/files Tue Apr 1 17:48:39 2014 @@ -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 @@ file dev/ic/lan9118.c smsh # 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 @@ device applesmctemp: applesmc, sysmon_en 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 Index: src/sys/dev/acpi/apple_smc_acpi.c diff -u src/sys/dev/acpi/apple_smc_acpi.c:1.1 src/sys/dev/acpi/apple_smc_acpi.c:1.2 --- src/sys/dev/acpi/apple_smc_acpi.c:1.1 Tue Apr 1 17:47:36 2014 +++ src/sys/dev/acpi/apple_smc_acpi.c Tue Apr 1 17:48:39 2014 @@ -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 @@ struct apple_smc_acpi_softc { 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 @@ apple_smc_acpi_detach(device_t self, int 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; + } +} Index: src/sys/dev/ic/apple_smc.c diff -u src/sys/dev/ic/apple_smc.c:1.1 src/sys/dev/ic/apple_smc.c:1.2 --- src/sys/dev/ic/apple_smc.c:1.1 Tue Apr 1 17:47:36 2014 +++ src/sys/dev/ic/apple_smc.c Tue Apr 1 17:48:39 2014 @@ -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 @@ __KERNEL_RCSID(0, "$NetBSD: apple_smc.c, #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,51 +74,157 @@ static int apple_smc_input(struct apple_ 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[]; +}; -void -apple_smc_attach(struct apple_smc_tag *smc) +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; - mutex_init(&smc->smc_lock, MUTEX_DEFAULT, IPL_NONE); + return strncmp(a->asd_name, b->asd_name, APPLE_SMC_DEVICE_NAME_SIZE); +} -#if 0 /* XXX sysctl */ - apple_smc_sysctl_setup(smc); +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); - (void)apple_smc_rescan(smc, NULL, NULL); + /* Success! */ + return 0; } int -apple_smc_rescan(struct apple_smc_tag *smc, const char *ifattr, - const int *locators) +apple_smc_register_device(const char name[APPLE_SMC_DEVICE_NAME_SIZE]) { - struct apple_smc_attach_args asa; + int error; - (void)locators; /* ignore */ + /* Paranoia about null termination. */ + KASSERT(name[strnlen(name, (sizeof(name) - 1))] == '\0'); - (void)memset(&asa, 0, sizeof asa); - asa.asa_smc = smc; -#if 0 /* XXX sysctl */ - asa.asa_sysctlnode = smc->smc_sysctlnode; -#endif + /* 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; + } - apple_smc_rescan1(smc, &asa, ifattr, "applesmcfan", &smc->smc_fan); - apple_smc_rescan1(smc, &asa, ifattr, "applesmctemp", &smc->smc_temp); -#if 0 /* XXX accelerometer */ - apple_smc_rescan1(smc, &asa, ifattr, "applesmcaccel", - &smc->smc_accelfan); -#endif + /* 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; + } - return 0; + /* Success! */ + apple_smc_n_registered_devices++; + error = 0; + +out: + rw_exit(&apple_smc_registered_devices_lock); + return error; } -static void -apple_smc_rescan1(struct apple_smc_tag *smc, struct apple_smc_attach_args *asa, - const char *ifattr, const char *ifa_conf, device_t *devp) +void +apple_smc_unregister_device(const char name[APPLE_SMC_DEVICE_NAME_SIZE]) { - if (ifattr_match(ifattr, ifa_conf) && *devp == NULL) - *devp = config_found_ia(smc->smc_dev, ifa_conf, asa, NULL); + 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); } int @@ -130,6 +243,109 @@ apple_smc_detach(struct apple_smc_tag *s return 0; } +int +apple_smc_rescan(struct apple_smc_tag *smc, const char *ifattr, + const int *locators __unused) +{ + 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)memset(&asa, 0, sizeof asa); + asa.asa_smc = smc; +#if 0 /* XXX sysctl */ + asa.asa_sysctlnode = smc->smc_sysctlnode; +#endif + + /* + * Go through all the registered SMC devices and try to attach + * them. + * + * XXX Horrible quadratic-time loop to avoid holding the rwlock + * during allocation. Fortunately, there are not likely to be + * many of these devices. + */ +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) + 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) + 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; + } + rw_exit(&apple_smc_registered_devices_lock); + + /* Success! */ + return 0; +} + +void +apple_smc_child_detached(struct apple_smc_tag *smc, device_t child) +{ + 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 apple_smc_bus_read_1(struct apple_smc_tag *smc, bus_size_t reg) { @@ -203,15 +419,7 @@ apple_smc_write_data(struct apple_smc_ta return apple_smc_write(smc, APPLE_SMC_DATA, data); } - -struct apple_smc_key { - char ask_name[4 + 1]; - struct apple_smc_desc ask_desc; -#ifdef DIAGNOSTIC - struct apple_smc_tag *ask_smc; -#endif -}; - + static int apple_smc_begin(struct apple_smc_tag *smc, uint8_t cmd, const char *key, uint8_t size) @@ -288,6 +496,14 @@ out: mutex_exit(&smc->smc_lock); return error; } + +struct apple_smc_key { + char ask_name[4 + 1]; + struct apple_smc_desc ask_desc; +#ifdef DIAGNOSTIC + struct apple_smc_tag *ask_smc; +#endif +}; const char * apple_smc_key_name(const struct apple_smc_key *key) @@ -430,7 +646,7 @@ apple_smc_key_search(struct apple_smc_ta *result = start; return 0; } - + int apple_smc_read_key(struct apple_smc_tag *smc, const struct apple_smc_key *key, void *buffer, uint8_t size) @@ -522,3 +738,21 @@ apple_smc_write_key_4(struct apple_smc_t return apple_smc_write_key(smc, key, &v_be, 4); } + +MODULE(MODULE_CLASS_MISC, apple_smc, NULL) + +static int +apple_smc_modcmd(modcmd_t cmd, void *data __unused) +{ + + switch (cmd) { + case MODULE_CMD_INIT: + return apple_smc_init(); + + case MODULE_CMD_FINI: + return apple_smc_fini(); + + default: + return ENOTTY; + } +} Index: src/sys/dev/ic/apple_smc.h diff -u src/sys/dev/ic/apple_smc.h:1.1 src/sys/dev/ic/apple_smc.h:1.2 --- src/sys/dev/ic/apple_smc.h:1.1 Tue Apr 1 17:47:36 2014 +++ src/sys/dev/ic/apple_smc.h Tue Apr 1 17:48:39 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: apple_smc.h,v 1.1 2014/04/01 17:47:36 riastradh Exp $ */ +/* $NetBSD: apple_smc.h,v 1.2 2014/04/01 17:48:39 riastradh Exp $ */ /* * Apple System Management Controller Interface @@ -42,6 +42,7 @@ struct apple_smc_tag; struct apple_smc_attach_args { struct apple_smc_tag *asa_smc; + const char *asa_device; }; struct apple_smc_key; @@ -106,4 +107,9 @@ 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.1 src/sys/dev/ic/apple_smc_fan.c:1.2 --- src/sys/dev/ic/apple_smc_fan.c:1.1 Tue Apr 1 17:47:36 2014 +++ src/sys/dev/ic/apple_smc_fan.c Tue Apr 1 17:48:39 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: apple_smc_fan.c,v 1.1 2014/04/01 17:47:36 riastradh Exp $ */ +/* $NetBSD: apple_smc_fan.c,v 1.2 2014/04/01 17:48:39 riastradh Exp $ */ /* * Apple System Management Controller: Fans @@ -34,12 +34,13 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: apple_smc_fan.c,v 1.1 2014/04/01 17:47:36 riastradh Exp $"); +__KERNEL_RCSID(0, "$NetBSD: apple_smc_fan.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/kmem.h> +#include <sys/module.h> #if 0 /* XXX sysctl */ #include <sys/sysctl.h> #endif @@ -49,6 +50,8 @@ __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 { @@ -115,6 +118,9 @@ 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) @@ -404,3 +410,46 @@ apple_smc_fan_sysctl_setup_1(struct appl { } #endif + +MODULE(MODULE_CLASS_DRIVER, apple_smc_fan, "apple_smc"); + +#ifdef _MODULE +#include "ioconf.c" +#endif + +static int +apple_smc_fan_modcmd(modcmd_t cmd, void *arg __unused) +{ + int error; + + 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); + return error; + } +#endif + return 0; + + case MODULE_CMD_FINI: +#ifdef _MODULE + error = config_fini_component(cfdriver_ioconf_apple_smc_fan, + cfattach_ioconf_apple_smc_fan, + cfdata_ioconf_apple_smc_fan); + if (error) + return error; +#endif + apple_smc_unregister_device(APPLE_SMC_DEVICE); + return 0; + + default: + return ENOTTY; + } +} Index: src/sys/dev/ic/apple_smc_temp.c diff -u src/sys/dev/ic/apple_smc_temp.c:1.1 src/sys/dev/ic/apple_smc_temp.c:1.2 --- src/sys/dev/ic/apple_smc_temp.c:1.1 Tue Apr 1 17:47:36 2014 +++ src/sys/dev/ic/apple_smc_temp.c Tue Apr 1 17:48:39 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: apple_smc_temp.c,v 1.1 2014/04/01 17:47:36 riastradh Exp $ */ +/* $NetBSD: apple_smc_temp.c,v 1.2 2014/04/01 17:48:39 riastradh Exp $ */ /* * Apple System Management Controller: Temperature Sensors @@ -34,18 +34,21 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: apple_smc_temp.c,v 1.1 2014/04/01 17:47:36 riastradh Exp $"); +__KERNEL_RCSID(0, "$NetBSD: apple_smc_temp.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/kmem.h> +#include <sys/module.h> #include <sys/systm.h> #include <dev/ic/apple_smc.h> #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; @@ -90,6 +93,9 @@ 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; @@ -359,3 +365,46 @@ apple_smc_bound_temp_sensors(struct appl return 0; } + +MODULE(MODULE_CLASS_DRIVER, apple_smc_temp, "apple_smc"); + +#ifdef _MODULE +#include "ioconf.c" +#endif + +static int +apple_smc_temp_modcmd(modcmd_t cmd, void *arg __unused) +{ + int error; + + 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); + return error; + } +#endif + return 0; + + case MODULE_CMD_FINI: +#ifdef _MODULE + error = config_fini_component(cfdriver_ioconf_apple_smc_temp, + cfattach_ioconf_apple_smc_temp, + cfdata_ioconf_apple_smc_temp); + if (error) + return error; +#endif + apple_smc_unregister_device(APPLE_SMC_DEVICE); + return 0; + + default: + return ENOTTY; + } +} Index: src/sys/dev/ic/apple_smcvar.h diff -u src/sys/dev/ic/apple_smcvar.h:1.1 src/sys/dev/ic/apple_smcvar.h:1.2 --- src/sys/dev/ic/apple_smcvar.h:1.1 Tue Apr 1 17:47:36 2014 +++ src/sys/dev/ic/apple_smcvar.h Tue Apr 1 17:48:39 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: apple_smcvar.h,v 1.1 2014/04/01 17:47:36 riastradh Exp $ */ +/* $NetBSD: apple_smcvar.h,v 1.2 2014/04/01 17:48:39 riastradh Exp $ */ /* * Apple System Management Controller State @@ -39,8 +39,9 @@ #include <sys/param.h> #include <sys/types.h> #include <sys/bus.h> -#include <sys/device.h> +#include <sys/device_if.h> #include <sys/mutex.h> +#include <sys/rbtree.h> struct apple_smc_tag { device_t smc_dev; @@ -55,16 +56,12 @@ struct apple_smc_tag { const struct sysctlnode *smc_sysctlnode; #endif - device_t smc_fan; - device_t smc_temp; -#if 0 /* XXX accelerometer */ - device_t smc_accel; -#endif + rb_tree_t smc_devices; }; -void apple_smc_attach(struct apple_smc_tag *); -int apple_smc_rescan(struct apple_smc_tag *, const char *, - const int *); -int apple_smc_detach(struct apple_smc_tag *, int); +void apple_smc_attach(struct apple_smc_tag *); +int apple_smc_detach(struct apple_smc_tag *, int); +int apple_smc_rescan(struct apple_smc_tag *, const char *, const int *); +void apple_smc_child_detached(struct apple_smc_tag *, device_t); #endif /* _DEV_IC_APPLE_SMCVAR_H_ */ Index: src/sys/modules/apple_smc/Makefile diff -u src/sys/modules/apple_smc/Makefile:1.1 src/sys/modules/apple_smc/Makefile:1.2 --- src/sys/modules/apple_smc/Makefile:1.1 Tue Apr 1 17:47:36 2014 +++ src/sys/modules/apple_smc/Makefile Tue Apr 1 17:48:39 2014 @@ -1,13 +1,11 @@ -# $NetBSD: Makefile,v 1.1 2014/04/01 17:47:36 riastradh Exp $ +# $NetBSD: Makefile,v 1.2 2014/04/01 17:48:39 riastradh Exp $ .include "../Makefile.inc" .PATH: ${S}/dev/ic -.PATH: ${S}/dev/acpi KMOD= apple_smc -IOCONF= apple_smc.ioconf -SRCS= apple_smc.c apple_smc_acpi.c apple_smc_fan.c apple_smc_temp.c +SRCS= apple_smc.c WARNS= 4 Added files: Index: src/sys/modules/apple_smc_acpi/Makefile diff -u /dev/null src/sys/modules/apple_smc_acpi/Makefile:1.1 --- /dev/null Tue Apr 1 17:48:39 2014 +++ src/sys/modules/apple_smc_acpi/Makefile Tue Apr 1 17:48:39 2014 @@ -0,0 +1,15 @@ +# $NetBSD: Makefile,v 1.1 2014/04/01 17:48:39 riastradh Exp $ + +.include "../Makefile.inc" + +.PATH: ${S}/dev/acpi + +KMOD= apple_smc_acpi +IOCONF= apple_smc_acpi.ioconf +SRCS= apple_smc_acpi.c + +WARNS= 4 + +CPPFLAGS+= -DDIAGNOSTIC + +.include <bsd.kmodule.mk> Index: src/sys/modules/apple_smc_acpi/apple_smc_acpi.ioconf diff -u /dev/null src/sys/modules/apple_smc_acpi/apple_smc_acpi.ioconf:1.1 --- /dev/null Tue Apr 1 17:48:39 2014 +++ src/sys/modules/apple_smc_acpi/apple_smc_acpi.ioconf Tue Apr 1 17:48:39 2014 @@ -0,0 +1,10 @@ +# $NetBSD: apple_smc_acpi.ioconf,v 1.1 2014/04/01 17:48:39 riastradh Exp $ + +ioconf apple_smc_acpi + +include "conf/files" +include "dev/acpi/files.acpi" + +pseudo-root acpi* + +applesmc* at acpi? Index: src/sys/modules/apple_smc_fan/Makefile diff -u /dev/null src/sys/modules/apple_smc_fan/Makefile:1.1 --- /dev/null Tue Apr 1 17:48:39 2014 +++ src/sys/modules/apple_smc_fan/Makefile Tue Apr 1 17:48:39 2014 @@ -0,0 +1,15 @@ +# $NetBSD: Makefile,v 1.1 2014/04/01 17:48:39 riastradh Exp $ + +.include "../Makefile.inc" + +.PATH: ${S}/dev/ic + +KMOD= apple_smc_fan +IOCONF= apple_smc_fan.ioconf +SRCS= apple_smc_fan.c + +WARNS= 4 + +CPPFLAGS+= -DDIAGNOSTIC + +.include <bsd.kmodule.mk> Index: src/sys/modules/apple_smc_fan/apple_smc_fan.ioconf diff -u /dev/null src/sys/modules/apple_smc_fan/apple_smc_fan.ioconf:1.1 --- /dev/null Tue Apr 1 17:48:39 2014 +++ src/sys/modules/apple_smc_fan/apple_smc_fan.ioconf Tue Apr 1 17:48:39 2014 @@ -0,0 +1,9 @@ +# $NetBSD: apple_smc_fan.ioconf,v 1.1 2014/04/01 17:48:39 riastradh Exp $ + +ioconf apple_smc_fan + +include "conf/files" + +pseudo-root applesmcbus* + +applesmcfan* at applesmcbus? Index: src/sys/modules/apple_smc_temp/Makefile diff -u /dev/null src/sys/modules/apple_smc_temp/Makefile:1.1 --- /dev/null Tue Apr 1 17:48:39 2014 +++ src/sys/modules/apple_smc_temp/Makefile Tue Apr 1 17:48:39 2014 @@ -0,0 +1,15 @@ +# $NetBSD: Makefile,v 1.1 2014/04/01 17:48:39 riastradh Exp $ + +.include "../Makefile.inc" + +.PATH: ${S}/dev/ic + +KMOD= apple_smc_temp +IOCONF= apple_smc_temp.ioconf +SRCS= apple_smc_temp.c + +WARNS= 4 + +CPPFLAGS+= -DDIAGNOSTIC + +.include <bsd.kmodule.mk> Index: src/sys/modules/apple_smc_temp/apple_smc_temp.ioconf diff -u /dev/null src/sys/modules/apple_smc_temp/apple_smc_temp.ioconf:1.1 --- /dev/null Tue Apr 1 17:48:39 2014 +++ src/sys/modules/apple_smc_temp/apple_smc_temp.ioconf Tue Apr 1 17:48:39 2014 @@ -0,0 +1,9 @@ +# $NetBSD: apple_smc_temp.ioconf,v 1.1 2014/04/01 17:48:39 riastradh Exp $ + +ioconf apple_smc_temp + +include "conf/files" + +pseudo-root applesmcbus* + +applesmctemp* at applesmcbus?