Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/dev/ic Polish the Apple SMC code with commentary and lit...



details:   https://anonhg.NetBSD.org/src/rev/7c266972b82e
branches:  trunk
changeset: 328373:7c266972b82e
user:      riastradh <riastradh%NetBSD.org@localhost>
date:      Tue Apr 01 17:49:05 2014 +0000

description:
Polish the Apple SMC code with commentary and little fixes.

diffstat:

 sys/dev/ic/apple_smc.c      |   99 ++++++++++++++++++++++++++-----
 sys/dev/ic/apple_smc_fan.c  |   64 +++++++++++++++++---
 sys/dev/ic/apple_smc_temp.c |  138 +++++++++++++++++++++++++++++++++++--------
 sys/dev/ic/apple_smcvar.h   |    6 +-
 4 files changed, 250 insertions(+), 57 deletions(-)

diffs (truncated from 1057 to 300 lines):

diff -r b4810710a2d6 -r 7c266972b82e sys/dev/ic/apple_smc.c
--- a/sys/dev/ic/apple_smc.c    Tue Apr 01 17:48:52 2014 +0000
+++ b/sys/dev/ic/apple_smc.c    Tue Apr 01 17:49:05 2014 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: apple_smc.c,v 1.3 2014/04/01 17:48:52 riastradh Exp $  */
+/*     $NetBSD: apple_smc.c,v 1.4 2014/04/01 17:49:05 riastradh Exp $  */
 
 /*
  * Apple System Management Controller
@@ -34,7 +34,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: apple_smc.c,v 1.3 2014/04/01 17:48:52 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: apple_smc.c,v 1.4 2014/04/01 17:49:05 riastradh Exp $");
 
 #include <sys/types.h>
 #include <sys/param.h>
@@ -75,12 +75,12 @@
 apple_smc_attach(struct apple_smc_tag *smc)
 {
 
-       mutex_init(&smc->smc_lock, MUTEX_DEFAULT, IPL_NONE);
-
+       mutex_init(&smc->smc_io_lock, MUTEX_DEFAULT, IPL_NONE);
 #if 0                          /* XXX sysctl */
        apple_smc_sysctl_setup(smc);
 #endif
 
+       /* Attach any children.  */
         (void)apple_smc_rescan(smc, APPLE_SMC_BUS, NULL);
 }
 
@@ -89,6 +89,7 @@
 {
        int error;
 
+       /* Fail if we can't detach all our children.  */
        error = config_detach_children(smc->smc_dev, flags);
        if (error)
                return error;
@@ -96,6 +97,7 @@
 #if 0                          /* XXX sysctl */
        sysctl_teardown(&smc->smc_log);
 #endif
+       mutex_destroy(&smc->smc_io_lock);
 
        return 0;
 }
@@ -105,6 +107,7 @@
     const int *locators)
 {
 
+       /* Let autoconf(9) do the work of finding new children.  */
        (void)config_search_loc(&apple_smc_search, smc->smc_dev, APPLE_SMC_BUS,
            locators, smc);
        return 0;
@@ -154,6 +157,7 @@
 apple_smc_child_detached(struct apple_smc_tag *smc __unused,
     device_t child __unused)
 {
+       /* We keep no books about our children.  */
 }
 
 static uint8_t
@@ -181,8 +185,12 @@
        uint8_t status;
        unsigned int i;
 
-       KASSERT(mutex_owned(&smc->smc_lock));
+       KASSERT(mutex_owned(&smc->smc_io_lock));
 
+       /*
+        * Wait until the status register says there's data to read and
+        * read it.
+        */
        for (i = 0; i < 100; i++) {
                status = apple_smc_bus_read_1(smc, APPLE_SMC_CSR);
                if (status & APPLE_SMC_STATUS_READ_READY) {
@@ -201,14 +209,20 @@
        uint8_t status;
        unsigned int i;
 
-       KASSERT(mutex_owned(&smc->smc_lock));
+       KASSERT(mutex_owned(&smc->smc_io_lock));
 
+       /*
+        * Write the byte and then wait until the status register says
+        * it has been accepted.
+        */
        apple_smc_bus_write_1(smc, reg, byte);
        for (i = 0; i < 100; i++) {
                status = apple_smc_bus_read_1(smc, APPLE_SMC_CSR);
                if (status & APPLE_SMC_STATUS_WRITE_ACCEPTED)
                        return 0;
                DELAY(100);
+
+               /* Write again if it hasn't been acknowledged at all.  */
                if (!(status & APPLE_SMC_STATUS_WRITE_PENDING))
                        apple_smc_bus_write_1(smc, reg, byte);
        }
@@ -237,18 +251,21 @@
        unsigned int i;
        int error;
 
-       KASSERT(mutex_owned(&smc->smc_lock));
+       KASSERT(mutex_owned(&smc->smc_io_lock));
 
+       /* Write the command first.  */
        error = apple_smc_write_cmd(smc, cmd);
        if (error)
                return error;
 
+       /* Write the key next.  */
        for (i = 0; i < 4; i++) {
                error = apple_smc_write_data(smc, key[i]);
                if (error)
                        return error;
        }
 
+       /* Finally, report how many bytes of data we want to send/receive.  */
        error = apple_smc_write_data(smc, size);
        if (error)
                return error;
@@ -264,11 +281,15 @@
        uint8_t i;
        int error;
 
-       mutex_enter(&smc->smc_lock);
+       /* Grab the SMC I/O lock.  */
+       mutex_enter(&smc->smc_io_lock);
+
+       /* Initiate the command with this key.  */
        error = apple_smc_begin(smc, cmd, key, size);
        if (error)
                goto out;
 
+       /* Read each byte of data in sequence.  */
        for (i = 0; i < size; i++) {
                error = apple_smc_read_data(smc, &bytes[i]);
                if (error)
@@ -278,8 +299,7 @@
        /* Success!  */
        error = 0;
 
-out:
-       mutex_exit(&smc->smc_lock);
+out:   mutex_exit(&smc->smc_io_lock);
        return error;
 }
 
@@ -291,19 +311,25 @@
        uint8_t i;
        int error;
 
-       mutex_enter(&smc->smc_lock);
+       /* Grab the SMC I/O lock.  */
+       mutex_enter(&smc->smc_io_lock);
+
+       /* Initiate the command with this key.  */
        error = apple_smc_begin(smc, cmd, key, size);
        if (error)
                goto out;
 
+       /* Write each byte of data in sequence.  */
        for (i = 0; i < size; i++) {
                error = apple_smc_write_data(smc, bytes[i]);
                if (error)
                        goto out;
        }
 
-out:
-       mutex_exit(&smc->smc_lock);
+       /* Success!  */
+       error = 0;
+
+out:   mutex_exit(&smc->smc_io_lock);
        return error;
 }
 
@@ -344,27 +370,34 @@
        struct apple_smc_key *key;
        int error;
 
+       /* Paranoia: type must be NULL or 4 non-null characters long.  */
        if ((type != NULL) && (strlen(type) != 4))
                return EINVAL;
 
+       /* Create a new key.  XXX Consider caching these.  */
        key = kmem_alloc(sizeof(*key), KM_SLEEP);
 #ifdef DIAGNOSTIC
        key->ask_smc = smc;
 #endif
 
+       /* Ask the SMC what the name of the key by this number is.  */
        index_be.u32 = htobe32(index);
        error = apple_smc_input(smc, APPLE_SMC_CMD_NTH_KEY, index_be.name,
            key->ask_name, 4);
        if (error)
                goto fail;
+
+       /* Null-terminate the name. */
        key->ask_name[4] = '\0';
 
+       /* Ask the SMC for a description of this key by name.  */
        CTASSERT(sizeof(key->ask_desc) == 6);
        error = apple_smc_input(smc, APPLE_SMC_CMD_KEY_DESC, key->ask_name,
            &key->ask_desc, 6);
        if (error)
                goto fail;
 
+       /* Fail with EINVAL if the types don't match.  */
        if ((type != NULL) && (0 != memcmp(key->ask_desc.asd_type, type, 4))) {
                error = EINVAL;
                goto fail;
@@ -374,8 +407,7 @@
        *keyp = key;
        return 0;
 
-fail:
-       kmem_free(key, sizeof(*key));
+fail:  kmem_free(key, sizeof(*key));
        return error;
 }
 
@@ -386,36 +418,43 @@
        struct apple_smc_key *key;
        int error;
 
+       /* Paranoia: name must be 4 non-null characters long.  */
        KASSERT(name != NULL);
        if (strlen(name) != 4)
                return EINVAL;
 
+       /* Paranoia: type must be NULL or 4 non-null characters long.  */
        if ((type != NULL) && (strlen(type) != 4))
                return EINVAL;
 
+       /* Create a new key.  XXX Consider caching these.  */
        key = kmem_alloc(sizeof(*key), KM_SLEEP);
 #ifdef DIAGNOSTIC
        key->ask_smc = smc;
 #endif
+
+       /* Use the specified name, and make sure it's null-terminated.  */
        (void)memcpy(key->ask_name, name, 4);
        key->ask_name[4] = '\0';
 
+       /* Ask the SMC for a description of this key by name.  */
        CTASSERT(sizeof(key->ask_desc) == 6);
        error = apple_smc_input(smc, APPLE_SMC_CMD_KEY_DESC, key->ask_name,
            &key->ask_desc, 6);
        if (error)
                goto fail;
 
+       /* Fail with EINVAL if the types don't match.  */
        if ((type != NULL) && (0 != memcmp(key->ask_desc.asd_type, type, 4))) {
                error = EINVAL;
                goto fail;
        }
 
+       /* Success!  */
        *keyp = key;
        return 0;
 
-fail:
-       kmem_free(key, sizeof(*key));
+fail:  kmem_free(key, sizeof(*key));
        return error;
 }
 
@@ -424,11 +463,14 @@
 {
 
 #ifdef DIAGNOSTIC
+       /* Make sure the caller didn't mix up SMC tags.  */
        if (key->ask_smc != smc)
                aprint_error_dev(smc->smc_dev,
                    "releasing key with wrong tag: %p != %p",
                    smc, key->ask_smc);
 #endif
+
+       /* Nothing to do but free the key's memory.  */
        kmem_free(key, sizeof(*key));
 }
 
@@ -440,6 +482,7 @@
        uint32_t start = 0, end = apple_smc_nkeys(smc), median;
        int error;
 
+       /* Do a binary search on the SMC's key space.  */
        while (start < end) {
                median = (start + ((end - start) / 2));
                error = apple_smc_nth_key(smc, median, NULL, &key);
@@ -453,6 +496,7 @@
                apple_smc_release_key(smc, key);
        }
 
+       /* Success!  */
        *result = start;



Home | Main Index | Thread Index | Old Index