Source-Changes-HG archive

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

[src/trunk]: src/sys/dev/acpi In preparation for upcoming changes:



details:   https://anonhg.NetBSD.org/src/rev/c9f818f39a99
branches:  trunk
changeset: 751006:c9f818f39a99
user:      jruoho <jruoho%NetBSD.org@localhost>
date:      Thu Jan 21 08:57:17 2010 +0000

description:
In preparation for upcoming changes:

  * Provide proper definitions and use these.
  * Clarify the evaluation of _STA.
  * Mark the state of a sensor according to the return value from _STA.
  * Share the basic object evaluation in _BIF and _BST.
  * Verify the object types before using the objects.
  * Be aware of bogus values from _BIF and _BST, as noted in the
    specification.

Despite of the list, functional change should be minimal. Ok pgoyette@.

diffstat:

 sys/dev/acpi/acpi_bat.c |  375 ++++++++++++++++++++++++++++++++---------------
 1 files changed, 253 insertions(+), 122 deletions(-)

diffs (truncated from 535 to 300 lines):

diff -r 5b1d5b8b0972 -r c9f818f39a99 sys/dev/acpi/acpi_bat.c
--- a/sys/dev/acpi/acpi_bat.c   Thu Jan 21 08:52:20 2010 +0000
+++ b/sys/dev/acpi/acpi_bat.c   Thu Jan 21 08:57:17 2010 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: acpi_bat.c,v 1.75 2010/01/08 20:40:41 dyoung Exp $     */
+/*     $NetBSD: acpi_bat.c,v 1.76 2010/01/21 08:57:17 jruoho Exp $     */
 
 /*-
  * Copyright (c) 2003 The NetBSD Foundation, Inc.
@@ -79,7 +79,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: acpi_bat.c,v 1.75 2010/01/08 20:40:41 dyoung Exp $");
+__KERNEL_RCSID(0, "$NetBSD: acpi_bat.c,v 1.76 2010/01/21 08:57:17 jruoho Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -95,21 +95,58 @@
 #define _COMPONENT          ACPI_BAT_COMPONENT
 ACPI_MODULE_NAME            ("acpi_bat")
 
-/* sensor indexes */
-#define ACPIBAT_PRESENT                0
-#define ACPIBAT_DCAPACITY      1
-#define ACPIBAT_LFCCAPACITY    2
-#define ACPIBAT_TECHNOLOGY     3
-#define ACPIBAT_DVOLTAGE       4
-#define ACPIBAT_WCAPACITY      5
-#define ACPIBAT_LCAPACITY      6
-#define ACPIBAT_VOLTAGE                7
-#define ACPIBAT_CHARGERATE     8
-#define ACPIBAT_DISCHARGERATE  9
-#define ACPIBAT_CAPACITY       10
-#define ACPIBAT_CHARGING       11
-#define ACPIBAT_CHARGE_STATE   12
-#define ACPIBAT_NSENSORS       13  /* number of sensors */
+/*
+ * Sensor indexes.
+ */
+enum {
+       ACPIBAT_PRESENT          = 0,
+       ACPIBAT_DCAPACITY        = 1,
+       ACPIBAT_LFCCAPACITY      = 2,
+       ACPIBAT_TECHNOLOGY       = 3,
+       ACPIBAT_DVOLTAGE         = 4,
+       ACPIBAT_WCAPACITY        = 5,
+       ACPIBAT_LCAPACITY        = 6,
+       ACPIBAT_VOLTAGE          = 7,
+       ACPIBAT_CHARGERATE       = 8,
+       ACPIBAT_DISCHARGERATE    = 9,
+       ACPIBAT_CAPACITY         = 10,
+       ACPIBAT_CHARGING         = 11,
+       ACPIBAT_CHARGE_STATE     = 12,
+       ACPIBAT_COUNT            = 13
+};
+
+/*
+ * Battery Information, _BIF
+ * (ACPI 3.0, sec. 10.2.2.1).
+ */
+enum {
+       ACPIBAT_BIF_UNIT         = 0,
+       ACPIBAT_BIF_DCAPACITY    = 1,
+       ACPIBAT_BIF_LFCCAPACITY  = 2,
+       ACPIBAT_BIF_TECHNOLOGY   = 3,
+       ACPIBAT_BIF_DVOLTAGE     = 4,
+       ACPIBAT_BIF_WCAPACITY    = 5,
+       ACPIBAT_BIF_LCAPACITY    = 6,
+       ACPIBAT_BIF_GRANULARITY1 = 7,
+       ACPIBAT_BIF_GRANULARITY2 = 8,
+       ACPIBAT_BIF_MODEL        = 9,
+       ACPIBAT_BIF_SERIAL       = 10,
+       ACPIBAT_BIF_TYPE         = 11,
+       ACPIBAT_BIF_OEM          = 12,
+       ACPIBAT_BIF_COUNT        = 13
+};
+
+/*
+ * Battery Status, _BST
+ * (ACPI 3.0, sec. 10.2.2.3).
+ */
+enum {
+       ACPIBAT_BST_STATE        = 0,
+       ACPIBAT_BST_RATE         = 1,
+       ACPIBAT_BST_CAPACITY     = 2,
+       ACPIBAT_BST_VOLTAGE      = 3,
+       ACPIBAT_BST_COUNT        = 4
+};
 
 struct acpibat_softc {
        struct acpi_devnode *sc_node;   /* our ACPI devnode */
@@ -117,7 +154,7 @@
        int sc_available;               /* available information level */
 
        struct sysmon_envsys *sc_sme;
-       envsys_data_t sc_sensor[ACPIBAT_NSENSORS];
+       envsys_data_t sc_sensor[ACPIBAT_COUNT];
        struct timeval sc_lastupdate;
 
        kmutex_t sc_mutex;
@@ -144,11 +181,27 @@
 #define ACPIBAT_ST_CRITICAL    0x00000004  /* battery is critical */
 
 /*
- * Flags for battery status from _STA return
+ * Flags for battery status from _STA return. Note that
+ * this differs from the conventional evaluation of _STA:
+ *
+ *     "Unlike most other devices, when a battery is inserted or
+ *      removed from the system, the device itself (the battery bay)
+ *      is still considered to be present in the system. For most
+ *      systems, the _STA for this device will always return a value
+ *      with bits 0-3 set and will toggle bit 4 to indicate the actual
+ *      presence of a battery. (ACPI 3.0, sec. 10.2.1, p. 320.)"
  */
 #define ACPIBAT_STA_PRESENT    0x00000010  /* battery present */
 
 /*
+ * A value used when _BST or _BIF is teporarily unknown (see ibid.).
+ */
+#define ACPIBAT_VAL_UNKNOWN    0xFFFFFFFF
+
+#define ACPIBAT_VAL_ISVALID(x)                                               \
+       (((x) != ACPIBAT_VAL_UNKNOWN) ? ENVSYS_SVALID : ENVSYS_SINVALID)
+
+/*
  * These flags are used to set internal state in our softc.
  */
 #define        ABAT_F_VERBOSE          0x01    /* verbose events */
@@ -179,6 +232,7 @@
 static void acpibat_clear_info(struct acpibat_softc *);
 static void acpibat_clear_stat(struct acpibat_softc *);
 static int acpibat_battery_present(device_t);
+static ACPI_OBJECT *acpibat_get_object(ACPI_HANDLE, const char *, int);
 static ACPI_STATUS acpibat_get_status(device_t);
 static ACPI_STATUS acpibat_get_info(device_t);
 static void acpibat_print_info(device_t);
@@ -305,73 +359,126 @@
        sc->sc_sensor[ACPIBAT_CHARGING].state = ENVSYS_SINVALID;
 }
 
-
 /*
- * returns 0 for no battery, 1 for present, and -1 on error
+ * acpibat_battery_present:
+ *
+ *     Evaluate whether the battery is present or absent.
+ *
+ *     Returns: 0 for no battery, 1 for present, and -1 on error.
  */
 static int
 acpibat_battery_present(device_t dv)
 {
        struct acpibat_softc *sc = device_private(dv);
-       uint32_t sta;
        ACPI_INTEGER val;
        ACPI_STATUS rv;
+       uint32_t sta;
 
        rv = acpi_eval_integer(sc->sc_node->ad_handle, "_STA", &val);
+
        if (ACPI_FAILURE(rv)) {
-               aprint_error_dev(dv, "failed to evaluate _STA: %s\n",
-                   AcpiFormatException(rv));
+               aprint_error_dev(dv, "failed to evaluate _STA\n");
+               sc->sc_sensor[ACPIBAT_PRESENT].state = ENVSYS_SINVALID;
                return -1;
        }
 
        sta = (uint32_t)val;
 
        sc->sc_available = ABAT_ALV_PRESENCE;
-       if (sta & ACPIBAT_STA_PRESENT) {
-               ABAT_SET(sc, ABAT_F_PRESENT);
-               sc->sc_sensor[ACPIBAT_PRESENT].state = ENVSYS_SVALID;
-               sc->sc_sensor[ACPIBAT_PRESENT].value_cur = 1;
-       } else
+       sc->sc_sensor[ACPIBAT_PRESENT].state = ENVSYS_SVALID;
+
+       if ((sta & ACPIBAT_STA_PRESENT) == 0) {
                sc->sc_sensor[ACPIBAT_PRESENT].value_cur = 0;
+               return 0;
+       }
 
-       return (sta & ACPIBAT_STA_PRESENT) ? 1 : 0;
+       ABAT_SET(sc, ABAT_F_PRESENT);
+       sc->sc_sensor[ACPIBAT_PRESENT].value_cur = 1;
+
+       return 1;
+}
+
+static ACPI_OBJECT *
+acpibat_get_object(ACPI_HANDLE hdl, const char *pth, int count)
+{
+       ACPI_OBJECT *obj;
+       ACPI_BUFFER buf;
+       ACPI_STATUS rv;
+
+       rv = acpi_eval_struct(hdl, pth, &buf);
+
+       if (ACPI_FAILURE(rv))
+               return NULL;
+
+       obj = buf.Pointer;
+
+       if (obj->Type != ACPI_TYPE_PACKAGE) {
+               ACPI_FREE(buf.Pointer);
+               return NULL;
+       }
+
+       if (obj->Package.Count != count) {
+               ACPI_FREE(buf.Pointer);
+               return NULL;
+       }
+
+       return obj;
 }
 
 /*
- * acpibat_get_info
+ * acpibat_get_info:
  *
  *     Get, and possibly display, the battery info.
  */
-
 static ACPI_STATUS
 acpibat_get_info(device_t dv)
 {
        struct acpibat_softc *sc = device_private(dv);
-       ACPI_OBJECT *p1, *p2;
-       ACPI_STATUS rv;
-       ACPI_BUFFER buf;
-       int capunit, rateunit;
+       ACPI_HANDLE hdl = sc->sc_node->ad_handle;
+       int capunit, i, j, rateunit, val;
+       ACPI_OBJECT *elm, *obj;
+       ACPI_STATUS rv = AE_OK;
 
-       rv = acpi_eval_struct(sc->sc_node->ad_handle, "_BIF", &buf);
-       if (ACPI_FAILURE(rv)) {
-               aprint_error_dev(dv, "failed to evaluate _BIF: %s\n",
-                   AcpiFormatException(rv));
-               return rv;
-       }
-       p1 = (ACPI_OBJECT *)buf.Pointer;
+       obj = acpibat_get_object(hdl, "_BIF", ACPIBAT_BIF_COUNT);
 
-       if (p1->Type != ACPI_TYPE_PACKAGE) {
-               aprint_error_dev(dv, "expected PACKAGE, got %d\n", p1->Type);
+       if (obj == NULL) {
+               rv = AE_ERROR;
                goto out;
        }
-       if (p1->Package.Count < 13) {
-               aprint_error_dev(dv, "expected 13 elements, got %d\n",
-                   p1->Package.Count);
-               goto out;
+
+       elm = obj->Package.Elements;
+
+       for (i = ACPIBAT_BIF_UNIT; i < ACPIBAT_BIF_MODEL; i++) {
+
+               if (elm[i].Type != ACPI_TYPE_INTEGER) {
+                       rv = AE_TYPE;
+                       goto out;
+               }
+
+               KDASSERT((uint64_t)elm[i].Integer.Value < INT_MAX);
        }
-       p2 = p1->Package.Elements;
+
+       aprint_verbose_dev(dv, "battery info: ");
+
+       for (i = j = ACPIBAT_BIF_OEM; i > ACPIBAT_BIF_GRANULARITY2; i--) {
+
+               if (elm[i].Type != ACPI_TYPE_STRING)
+                       continue;
+
+               if (elm[i].String.Pointer == NULL)
+                       continue;
 
-       if ((p2[0].Integer.Value & ACPIBAT_PWRUNIT_MA) != 0) {
+               aprint_verbose("%s ", elm[i].String.Pointer);
+
+               j = 0;
+       }
+
+       if (j != 0)
+               aprint_verbose("not available");
+
+       aprint_verbose("\n");
+
+       if ((elm[ACPIBAT_BIF_UNIT].Integer.Value & ACPIBAT_PWRUNIT_MA) != 0) {
                ABAT_SET(sc, ABAT_F_PWRUNIT_MA);
                capunit = ENVSYS_SAMPHOUR;
                rateunit = ENVSYS_SAMPS;
@@ -389,38 +496,60 @@
        sc->sc_sensor[ACPIBAT_DISCHARGERATE].units = rateunit;
        sc->sc_sensor[ACPIBAT_CAPACITY].units = capunit;



Home | Main Index | Thread Index | Old Index