Source-Changes-HG archive

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

[src/trunk]: src/sys/dev/acpi Simplify by using a static array for the refere...



details:   https://anonhg.NetBSD.org/src/rev/1b6f7ff59a1c
branches:  trunk
changeset: 764230:1b6f7ff59a1c
user:      jruoho <jruoho%NetBSD.org@localhost>
date:      Thu Apr 14 06:25:25 2011 +0000

description:
Simplify by using a static array for the reference counting.

diffstat:

 sys/dev/acpi/acpi_power.c |  114 +++++++++++++++++++--------------------------
 1 files changed, 49 insertions(+), 65 deletions(-)

diffs (203 lines):

diff -r 37783d0854d9 -r 1b6f7ff59a1c sys/dev/acpi/acpi_power.c
--- a/sys/dev/acpi/acpi_power.c Thu Apr 14 06:12:21 2011 +0000
+++ b/sys/dev/acpi/acpi_power.c Thu Apr 14 06:25:25 2011 +0000
@@ -1,7 +1,7 @@
-/* $NetBSD: acpi_power.c,v 1.29 2011/01/09 16:22:07 jruoho Exp $ */
+/* $NetBSD: acpi_power.c,v 1.30 2011/04/14 06:25:25 jruoho Exp $ */
 
 /*-
- * Copyright (c) 2009, 2010 The NetBSD Foundation, Inc.
+ * Copyright (c) 2009, 2010, 2011 The NetBSD Foundation, Inc.
  * All rights reserved.
  *
  * This code is derived from software contributed to The NetBSD Foundation
@@ -56,7 +56,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: acpi_power.c,v 1.29 2011/01/09 16:22:07 jruoho Exp $");
+__KERNEL_RCSID(0, "$NetBSD: acpi_power.c,v 1.30 2011/04/14 06:25:25 jruoho Exp $");
 
 #include <sys/param.h>
 #include <sys/kmem.h>
@@ -74,27 +74,15 @@
 #define        ACPI_STA_POW_OFF                0x00
 #define        ACPI_STA_POW_ON                 0x01
 
-/*
- * References.
- */
-struct acpi_power_ref {
-       ACPI_HANDLE                     ref_handle;
-
-       SIMPLEQ_ENTRY(acpi_power_ref)   ref_list;
-};
-
-/*
- * Resources.
- */
 struct acpi_power_res {
        ACPI_HANDLE                     res_handle;
        ACPI_INTEGER                    res_level;
        ACPI_INTEGER                    res_order;
+       ACPI_HANDLE                     res_ref[5];
        char                            res_name[5];
        kmutex_t                        res_mutex;
 
        TAILQ_ENTRY(acpi_power_res)     res_list;
-       SIMPLEQ_HEAD(, acpi_power_ref)  ref_head;
 };
 
 static TAILQ_HEAD(, acpi_power_res) res_head =
@@ -128,6 +116,7 @@
        ACPI_OBJECT *obj;
        ACPI_BUFFER buf;
        ACPI_STATUS rv;
+       size_t i;
 
        rv = acpi_eval_struct(hdl, NULL, &buf);
 
@@ -155,7 +144,9 @@
        (void)strlcpy(res->res_name,
            acpi_xname(hdl), sizeof(res->res_name));
 
-       SIMPLEQ_INIT(&res->ref_head);
+       for (i = 0; i < __arraycount(res->res_ref); i++)
+               res->res_ref[i] = NULL;
+
        mutex_init(&res->res_mutex, MUTEX_DEFAULT, IPL_NONE);
 
        /*
@@ -481,8 +472,13 @@
        if (res == NULL)
                return AE_NOT_FOUND;
 
+       if (ref == NULL)
+               return AE_BAD_PARAMETER;
+
        /*
-        * (De)reference the resource.
+        * Adjust the reference counting. This is
+        * necessary since a single power resource
+        * can be shared by multiple devices.
         */
        switch (on) {
 
@@ -510,82 +506,70 @@
 }
 
 static ACPI_STATUS
-acpi_power_res_ref(struct acpi_power_res *res, ACPI_HANDLE hdl)
+acpi_power_res_ref(struct acpi_power_res *res, ACPI_HANDLE ref)
 {
-       struct acpi_power_ref *ref, *tmp;
-
-       ref = kmem_zalloc(sizeof(*ref), KM_SLEEP);
-
-       if (ref == NULL)
-               return AE_NO_MEMORY;
+       size_t i, j = SIZE_MAX;
 
        mutex_enter(&res->res_mutex);
 
-       SIMPLEQ_FOREACH(tmp, &res->ref_head, ref_list) {
+       for (i = 0; i < __arraycount(res->res_ref); i++) {
 
-               if (tmp->ref_handle == hdl)
-                       goto out;
+               /*
+                * Do not error out if the handle
+                * has already been referenced.
+                */
+               if (res->res_ref[i] == ref) {
+                       mutex_exit(&res->res_mutex);
+                       return AE_OK;
+               }
+
+               if (j == SIZE_MAX && res->res_ref[i] == NULL)
+                       j = i;
        }
 
-       ref->ref_handle = hdl;
-       SIMPLEQ_INSERT_TAIL(&res->ref_head, ref, ref_list);
+       if (j == SIZE_MAX) {
+               mutex_exit(&res->res_mutex);
+               return AE_LIMIT;
+       }
+
+       res->res_ref[j] = ref;
        mutex_exit(&res->res_mutex);
 
        ACPI_DEBUG_PRINT((ACPI_DB_INFO, "%s referenced "
-               "by %s\n", res->res_name, acpi_xname(hdl)));
-
-       return AE_OK;
-
-out:
-       mutex_exit(&res->res_mutex);
-       kmem_free(ref, sizeof(*ref));
-
-       ACPI_DEBUG_PRINT((ACPI_DB_INFO, "%s already referenced "
-               "by %s?\n", res->res_name, acpi_xname(hdl)));
+               "by %s\n", res->res_name, acpi_xname(ref)));
 
        return AE_OK;
 }
 
 static ACPI_STATUS
-acpi_power_res_deref(struct acpi_power_res *res, ACPI_HANDLE hdl)
+acpi_power_res_deref(struct acpi_power_res *res, ACPI_HANDLE ref)
 {
-       struct acpi_power_ref *ref;
+       size_t i;
 
        mutex_enter(&res->res_mutex);
 
-       if (SIMPLEQ_EMPTY(&res->ref_head) != 0) {
+       for (i = 0; i < __arraycount(res->res_ref); i++) {
+
+               if (res->res_ref[i] != ref)
+                       continue;
+
+               res->res_ref[i] = NULL;
                mutex_exit(&res->res_mutex);
+
+               ACPI_DEBUG_PRINT((ACPI_DB_INFO, "%s dereferenced "
+                       "by %s\n", res->res_name, acpi_xname(ref)));
+
                return AE_OK;
        }
 
-       SIMPLEQ_FOREACH(ref, &res->ref_head, ref_list) {
-
-               if (ref->ref_handle == hdl) {
-                       SIMPLEQ_REMOVE(&res->ref_head,
-                           ref, acpi_power_ref, ref_list);
-                       mutex_exit(&res->res_mutex);
-                       kmem_free(ref, sizeof(*ref));
-                       mutex_enter(&res->res_mutex);
-                       break;
-               }
-       }
-
        /*
-        * If the queue remains non-empty,
+        * If the array remains to be non-empty,
         * something else is using the resource
         * and hence it can not be turned off.
         */
-       if (SIMPLEQ_EMPTY(&res->ref_head) == 0) {
-               mutex_exit(&res->res_mutex);
-               return AE_ABORT_METHOD;
-       }
-
        mutex_exit(&res->res_mutex);
 
-       ACPI_DEBUG_PRINT((ACPI_DB_INFO, "%s dereferenced "
-               "by %s\n", res->res_name, acpi_xname(hdl)));
-
-       return AE_OK;
+       return AE_ABORT_METHOD;
 }
 
 static ACPI_STATUS



Home | Main Index | Thread Index | Old Index