LCOV - code coverage report
Current view: top level - dev/acpi - atk0110.c (source / functions) Hit Total Coverage
Test: 6.4 Lines: 0 256 0.0 %
Date: 2018-10-19 03:25:38 Functions: 0 12 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*      $OpenBSD: atk0110.c,v 1.15 2018/06/29 17:39:18 kettenis Exp $   */
       2             : 
       3             : /*
       4             :  * Copyright (c) 2009 Constantine A. Murenin <cnst+openbsd@bugmail.mojo.ru>
       5             :  *
       6             :  * Permission to use, copy, modify, and distribute this software for any
       7             :  * purpose with or without fee is hereby granted, provided that the above
       8             :  * copyright notice and this permission notice appear in all copies.
       9             :  *
      10             :  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
      11             :  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
      12             :  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
      13             :  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
      14             :  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
      15             :  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
      16             :  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
      17             :  */
      18             : 
      19             : #include <sys/param.h>
      20             : #include <sys/systm.h>
      21             : #include <sys/device.h>
      22             : #include <sys/malloc.h>
      23             : #include <sys/sensors.h>
      24             : 
      25             : #include <dev/acpi/acpireg.h>
      26             : #include <dev/acpi/acpivar.h>
      27             : #include <dev/acpi/acpidev.h>
      28             : #include <dev/acpi/amltypes.h>
      29             : #include <dev/acpi/dsdt.h>
      30             : 
      31             : /*
      32             :  * ASUSTeK AI Booster (ACPI ATK0110).
      33             :  *
      34             :  * The driver was inspired by Takanori Watanabe's acpi_aiboost driver.
      35             :  * http://cvsweb.freebsd.org/src/sys/dev/acpi_support/acpi_aiboost.c
      36             :  *
      37             :  * Special thanks goes to Sam Fourman Jr. for providing access to several
      38             :  * ASUS boxes where the driver could be tested.
      39             :  *
      40             :  *                                                      -- cnst.su.
      41             :  */
      42             : 
      43             : #define ATK_ID_MUX_HWMON        0x00000006
      44             : 
      45             : #define ATK_CLASS(x)            (((x) >> 24) & 0xff)
      46             : #define ATK_CLASS_FREQ_CTL      3
      47             : #define ATK_CLASS_FAN_CTL       4
      48             : #define ATK_CLASS_HWMON         6
      49             : #define ATK_CLASS_MGMT          17
      50             : 
      51             : #define ATK_TYPE(x)             (((x) >> 16) & 0xff)
      52             : #define ATK_TYPE_VOLT           2
      53             : #define ATK_TYPE_TEMP           3
      54             : #define ATK_TYPE_FAN            4
      55             : 
      56             : #define AIBS_MORE_SENSORS
      57             : /* #define AIBS_VERBOSE */
      58             : 
      59             : struct aibs_sensor {
      60             :         struct ksensor  s;
      61             :         int64_t         i;
      62             :         int64_t         l;
      63             :         int64_t         h;
      64             :         SIMPLEQ_ENTRY(aibs_sensor)      entry;
      65             : };
      66             : 
      67             : struct aibs_softc {
      68             :         struct device           sc_dev;
      69             : 
      70             :         struct acpi_softc       *sc_acpi;
      71             :         struct aml_node         *sc_devnode;
      72             : 
      73             :         struct aml_node         *sc_ggrpnode;
      74             :         struct aml_node         *sc_gitmnode;
      75             :         struct aml_node         *sc_sitmnode;
      76             :         struct aml_node         *sc_rtmpnode;
      77             :         struct aml_node         *sc_rvltnode;
      78             :         struct aml_node         *sc_rfannode;
      79             : 
      80             :         SIMPLEQ_HEAD(, aibs_sensor)     sc_sensorlist;
      81             :         struct ksensordev       sc_sensordev;
      82             : 
      83             :         int                     sc_mode;        /* 1 = new, 0 = old */
      84             : };
      85             : 
      86             : /* Command buffer used for GITM and SITM methods */
      87             : struct aibs_cmd_buffer {
      88             :         uint32_t        id;
      89             :         uint32_t        param1;
      90             :         uint32_t        param2;
      91             : };
      92             : 
      93             : /* Return buffer used by the GITM and SITM mehtods */
      94             : struct aibs_ret_buffer {
      95             :         uint32_t        flags;
      96             :         uint32_t        value;
      97             :         /* there is more stuff that is unknown */
      98             : };
      99             : 
     100             : int     aibs_match(struct device *, void *, void *);
     101             : void    aibs_attach(struct device *, struct device *, void *);
     102             : int     aibs_notify(struct aml_node *, int, void *);
     103             : void    aibs_refresh(void *);
     104             : 
     105             : void    aibs_attach_sif(struct aibs_softc *, enum sensor_type);
     106             : void    aibs_attach_new(struct aibs_softc *);
     107             : void    aibs_add_sensor(struct aibs_softc *, char *);
     108             : void    aibs_refresh_r(struct aibs_softc *, struct aibs_sensor *);
     109             : int     aibs_getvalue(struct aibs_softc *, int64_t, int64_t *);
     110             : int     aibs_getpack(struct aibs_softc *, struct aml_node *, int64_t,
     111             :             struct aml_value *);
     112             : void    aibs_probe(struct aibs_softc *);
     113             : int     aibs_find_cb(struct aml_node *, void *);
     114             : 
     115             : 
     116             : struct cfattach aibs_ca = {
     117             :         sizeof(struct aibs_softc), aibs_match, aibs_attach
     118             : };
     119             : 
     120             : struct cfdriver aibs_cd = {
     121             :         NULL, "aibs", DV_DULL
     122             : };
     123             : 
     124             : static const char* aibs_hids[] = {
     125             :         "ATK0110",
     126             :         NULL
     127             : };
     128             : 
     129             : int
     130           0 : aibs_match(struct device *parent, void *match, void *aux)
     131             : {
     132           0 :         struct acpi_attach_args *aa = aux;
     133           0 :         struct cfdata           *cf = match;
     134             : 
     135           0 :         return acpi_matchhids(aa, aibs_hids, cf->cf_driver->cd_name);
     136             : }
     137             : 
     138             : void
     139           0 : aibs_attach(struct device *parent, struct device *self, void *aux)
     140             : {
     141           0 :         struct aibs_softc       *sc = (struct aibs_softc *)self;
     142           0 :         struct acpi_attach_args *aa = aux;
     143             : 
     144           0 :         sc->sc_acpi = (struct acpi_softc *)parent;
     145           0 :         sc->sc_devnode = aa->aaa_node;
     146             : 
     147           0 :         strlcpy(sc->sc_sensordev.xname, sc->sc_dev.dv_xname,
     148             :             sizeof(sc->sc_sensordev.xname));
     149           0 :         SIMPLEQ_INIT(&sc->sc_sensorlist);
     150             : 
     151           0 :         aibs_probe(sc);
     152           0 :         printf("\n");
     153             : 
     154           0 :         if (sc->sc_mode)
     155           0 :                 aibs_attach_new(sc);
     156             :         else {
     157           0 :                 aibs_attach_sif(sc, SENSOR_TEMP);
     158           0 :                 aibs_attach_sif(sc, SENSOR_FANRPM);
     159           0 :                 aibs_attach_sif(sc, SENSOR_VOLTS_DC);
     160             :         }
     161             : 
     162           0 :         if (sc->sc_sensordev.sensors_count == 0) {
     163           0 :                 printf("%s: no sensors found\n", DEVNAME(sc));
     164           0 :                 return;
     165             :         }
     166             : 
     167           0 :         sensordev_install(&sc->sc_sensordev);
     168             : 
     169           0 :         aml_register_notify(sc->sc_devnode, aa->aaa_dev,
     170           0 :             aibs_notify, sc, ACPIDEV_POLL);
     171           0 : }
     172             : 
     173             : void
     174           0 : aibs_attach_sif(struct aibs_softc *sc, enum sensor_type st)
     175             : {
     176           0 :         struct aml_value        res;
     177             :         struct aml_value        **v;
     178             :         int                     i, n;
     179           0 :         char                    name[] = "?SIF";
     180             : 
     181           0 :         switch (st) {
     182             :         case SENSOR_TEMP:
     183           0 :                 name[0] = 'T';
     184           0 :                 break;
     185             :         case SENSOR_FANRPM:
     186           0 :                 name[0] = 'F';
     187           0 :                 break;
     188             :         case SENSOR_VOLTS_DC:
     189           0 :                 name[0] = 'V';
     190           0 :                 break;
     191             :         default:
     192           0 :                 return;
     193             :         }
     194             : 
     195           0 :         if (aml_evalname(sc->sc_acpi, sc->sc_devnode, name, 0, NULL, &res)) {
     196           0 :                 printf("%s: %s not found\n", DEVNAME(sc), name);
     197           0 :                 aml_freevalue(&res);
     198           0 :                 return;
     199             :         }
     200           0 :         if (res.type != AML_OBJTYPE_PACKAGE) {
     201           0 :                 printf("%s: %s: not a package\n", DEVNAME(sc), name);
     202           0 :                 aml_freevalue(&res);
     203           0 :                 return;
     204             :         }
     205           0 :         v = res.v_package;
     206           0 :         if (v[0]->type != AML_OBJTYPE_INTEGER) {
     207           0 :                 printf("%s: %s[0]: invalid type\n", DEVNAME(sc), name);
     208           0 :                 aml_freevalue(&res);
     209           0 :                 return;
     210             :         }
     211             : 
     212           0 :         n = v[0]->v_integer;
     213           0 :         if (res.length - 1 < n) {
     214           0 :                 printf("%s: %s: invalid package\n", DEVNAME(sc), name);
     215           0 :                 aml_freevalue(&res);
     216           0 :                 return;
     217           0 :         } else if (res.length - 1 > n) {
     218           0 :                 printf("%s: %s: misformed package: %i/%i",
     219           0 :                     DEVNAME(sc), name, n, res.length - 1);
     220             : #ifdef AIBS_MORE_SENSORS
     221           0 :                 n = res.length - 1;
     222             : #endif
     223           0 :                 printf(", assume %i\n", n);
     224           0 :         }
     225           0 :         if (n < 1) {
     226           0 :                 printf("%s: %s: no members in the package\n",
     227           0 :                     DEVNAME(sc), name);
     228           0 :                 aml_freevalue(&res);
     229           0 :                 return;
     230             :         }
     231             : 
     232           0 :         for (i = 0, v++; i < n; i++, v++) {
     233           0 :                 if(v[0]->type != AML_OBJTYPE_STRING) {
     234           0 :                         printf("%s: %s: %i: not a string: %i type\n",
     235           0 :                             DEVNAME(sc), name, i, v[0]->type);
     236           0 :                         continue;
     237             :                 }
     238           0 :                 aibs_add_sensor(sc, v[0]->v_string);
     239           0 :         }
     240             : 
     241           0 :         aml_freevalue(&res);
     242           0 : }
     243             : 
     244             : void
     245           0 : aibs_attach_new(struct aibs_softc *sc)
     246             : {
     247           0 :         struct aml_value        res;
     248             :         int                     i;
     249             : 
     250           0 :         if (aibs_getpack(sc, sc->sc_ggrpnode, ATK_ID_MUX_HWMON, &res)) {
     251           0 :                 printf("%s: GGRP: sensor enumeration failed\n", DEVNAME(sc));
     252           0 :                 return;
     253             :         }
     254             : 
     255           0 :         for (i = 0; i < res.length; i++) {
     256             :                 struct aml_value        *r;
     257           0 :                 r = res.v_package[i];
     258           0 :                 if (r->type != AML_OBJTYPE_STRING) {
     259           0 :                         printf("%s: %s: %i: not a string (type %i)\n",
     260           0 :                             DEVNAME(sc), "GGRP", i, r->type);
     261           0 :                         continue;
     262             :                 }
     263           0 :                 aibs_add_sensor(sc, r->v_string);
     264           0 :         }
     265           0 :         aml_freevalue(&res);
     266           0 : }
     267             : 
     268             : void
     269           0 : aibs_add_sensor(struct aibs_softc *sc, char *name)
     270             : {
     271           0 :         struct aml_value         ri;
     272             :         struct aibs_sensor      *as;
     273             :         int                      len, lim1, lim2, ena;
     274             : 
     275           0 :         if (aml_evalname(sc->sc_acpi, sc->sc_devnode, name,
     276             :             0, NULL, &ri)) {
     277           0 :                 printf("%s: aibs_add_sensor: %s not found\n",
     278           0 :                     DEVNAME(sc), name);
     279           0 :                 aml_freevalue(&ri);
     280           0 :                 return;
     281             :         }
     282           0 :         if (ri.type != AML_OBJTYPE_PACKAGE) {
     283           0 :                 printf("%s: aibs_add_sensor: %s: not a package\n",
     284           0 :                     DEVNAME(sc), name);
     285           0 :                 aml_freevalue(&ri);
     286           0 :                 return;
     287             :         }
     288           0 :         if (sc->sc_mode) {
     289             :                 len = 7;
     290             :                 lim1 = 4;
     291             :                 lim2 = 5;
     292             :                 ena = 6;
     293           0 :         } else {
     294             :                 len = 5;
     295             :                 lim1 = 2;
     296             :                 lim2 = 3;
     297             :                 ena = 4;
     298             :         }
     299             : 
     300           0 :         if (ri.length != len ||
     301           0 :             ri.v_package[0]->type != AML_OBJTYPE_INTEGER ||
     302           0 :             ri.v_package[1]->type != AML_OBJTYPE_STRING ||
     303           0 :             ri.v_package[lim1]->type != AML_OBJTYPE_INTEGER ||
     304           0 :             ri.v_package[lim2]->type != AML_OBJTYPE_INTEGER ||
     305           0 :             ri.v_package[ena]->type != AML_OBJTYPE_INTEGER) {
     306           0 :                 printf("%s: aibs_add_sensor: %s: invalid package\n",
     307           0 :                     DEVNAME(sc), name);
     308           0 :                 aml_freevalue(&ri);
     309           0 :                 return;
     310             :         }
     311           0 :         as = malloc(sizeof(*as), M_DEVBUF, M_NOWAIT | M_ZERO);
     312           0 :         if (!as) {
     313           0 :                 printf("%s: aibs_add_sensor: %s: failed to allocate sensor\n",
     314           0 :                     DEVNAME(sc), name);
     315           0 :                 aml_freevalue(&ri);
     316           0 :                 return;
     317             :         }
     318           0 :         as->i = ri.v_package[0]->v_integer;
     319           0 :         switch (ATK_TYPE(as->i)) {
     320             :         case ATK_TYPE_VOLT:
     321           0 :                 as->s.type = SENSOR_VOLTS_DC;
     322           0 :                 break;
     323             :         case ATK_TYPE_TEMP:
     324           0 :                 as->s.type = SENSOR_TEMP;
     325           0 :                 break;
     326             :         case ATK_TYPE_FAN:
     327           0 :                 as->s.type = SENSOR_FANRPM;
     328           0 :                 break;
     329             :         default:
     330           0 :                 printf("%s: aibs_add_sensor: %s: unknown sensor type %llx\n",
     331           0 :                     DEVNAME(sc), name, ri.v_package[0]->v_integer);
     332           0 :                 aml_freevalue(&ri);
     333           0 :                 free(as, M_DEVBUF, sizeof(*as));
     334           0 :                 return;
     335             :         }
     336           0 :         strlcpy(as->s.desc, ri.v_package[1]->v_string,
     337             :             sizeof(as->s.desc));
     338           0 :         as->l = ri.v_package[lim1]->v_integer;
     339           0 :         if (sc->sc_mode)
     340             :                 /* the second limit is a actually a range */
     341           0 :                 as->h = as->l + ri.v_package[lim2]->v_integer;
     342             :         else
     343           0 :                 as->h = ri.v_package[lim2]->v_integer;
     344             : #ifdef AIBS_VERBOSE
     345             :         printf("%s: %4s: %s 0x%08llx %5lli / %5lli  0x%llx\n",
     346             :             DEVNAME(sc), name, as->s.desc, as->i, as->l, as->h,
     347             :             ri.v_package[ena]->v_integer);
     348             : #endif
     349           0 :         SIMPLEQ_INSERT_TAIL(&sc->sc_sensorlist, as, entry);
     350           0 :         sensor_attach(&sc->sc_sensordev, &as->s);
     351           0 :         aml_freevalue(&ri);
     352           0 :         return;
     353           0 : }
     354             : 
     355             : void
     356           0 : aibs_refresh(void *arg)
     357             : {
     358           0 :         struct aibs_softc       *sc = arg;
     359             :         struct aibs_sensor      *as;
     360             : 
     361           0 :         SIMPLEQ_FOREACH(as, &sc->sc_sensorlist, entry)
     362           0 :                 aibs_refresh_r(sc, as);
     363           0 : }
     364             : 
     365             : void
     366           0 : aibs_refresh_r(struct aibs_softc *sc, struct aibs_sensor *as)
     367             : {
     368           0 :         struct ksensor          *s = &as->s;
     369           0 :         int64_t                 v;
     370           0 :         const int64_t           l = as->l, h = as->h;
     371             : 
     372           0 :         if (aibs_getvalue(sc, as->i, &v)) {
     373           0 :                 s->flags |= SENSOR_FINVALID;
     374           0 :                 return;
     375             :         }
     376           0 :         switch (s->type) {
     377             :         case SENSOR_TEMP:
     378           0 :                 s->value = v * 100 * 1000 + 273150000;
     379           0 :                 if (v == 0) {
     380           0 :                         s->status = SENSOR_S_UNKNOWN;
     381           0 :                         s->flags |= SENSOR_FINVALID;
     382           0 :                 } else {
     383           0 :                         if (v > h)
     384           0 :                                 s->status = SENSOR_S_CRIT;
     385           0 :                         else if (v > l)
     386           0 :                                 s->status = SENSOR_S_WARN;
     387             :                         else
     388           0 :                                 s->status = SENSOR_S_OK;
     389           0 :                         s->flags &= ~SENSOR_FINVALID;
     390             :                 }
     391             :                 break;
     392             :         case SENSOR_FANRPM:
     393           0 :                 s->value = v;
     394             :                 /* some boards have strange limits for fans */
     395           0 :                 if ((l != 0 && l < v && v < h) ||
     396           0 :                     (l == 0 && v > h))
     397           0 :                         s->status = SENSOR_S_OK;
     398             :                 else
     399           0 :                         s->status = SENSOR_S_WARN;
     400           0 :                 s->flags &= ~SENSOR_FINVALID;
     401           0 :                 break;
     402             :         case SENSOR_VOLTS_DC:
     403           0 :                 s->value = v * 1000;
     404           0 :                 if (l < v && v < h)
     405           0 :                         s->status = SENSOR_S_OK;
     406             :                 else
     407           0 :                         s->status = SENSOR_S_WARN;
     408           0 :                 s->flags &= ~SENSOR_FINVALID;
     409           0 :                 break;
     410             :         default:
     411             :                 /* NOTREACHED */
     412             :                 break;
     413             :         }
     414           0 : }
     415             : 
     416             : int
     417           0 : aibs_getvalue(struct aibs_softc *sc, int64_t i, int64_t *v)
     418             : {
     419           0 :         struct aml_node         *n = sc->sc_gitmnode;
     420           0 :         struct aml_value        req, res;
     421           0 :         struct aibs_cmd_buffer  cmd;
     422             :         struct aibs_ret_buffer  ret;
     423             :         enum aml_objecttype     type;
     424             : 
     425           0 :         if (sc->sc_mode) {
     426           0 :                 cmd.id = i;
     427           0 :                 cmd.param1 = 0;
     428           0 :                 cmd.param2 = 0;
     429           0 :                 type = req.type = AML_OBJTYPE_BUFFER;
     430           0 :                 req.v_buffer = (uint8_t *)&cmd;
     431           0 :                 req.length = sizeof(cmd);
     432           0 :         } else {
     433           0 :                 switch (ATK_TYPE(i)) {
     434             :                 case ATK_TYPE_TEMP:
     435           0 :                         n = sc->sc_rtmpnode;
     436           0 :                         break;
     437             :                 case ATK_TYPE_FAN:
     438           0 :                         n = sc->sc_rfannode;
     439           0 :                         break;
     440             :                 case ATK_TYPE_VOLT:
     441           0 :                         n = sc->sc_rvltnode;
     442           0 :                         break;
     443             :                 default:
     444           0 :                         return (-1);
     445             :                 }
     446           0 :                 type = req.type = AML_OBJTYPE_INTEGER;
     447           0 :                 req.v_integer = i;
     448             :         }
     449             : 
     450           0 :         if (aml_evalnode(sc->sc_acpi, n, 1, &req, &res)) {
     451             :                 dprintf("%s: %s: %lld: evaluation failed\n",
     452             :                     DEVNAME(sc), n->name, i);
     453           0 :                 aml_freevalue(&res);
     454           0 :                 return (-1);
     455             :         }
     456           0 :         if (res.type != type) {
     457             :                 dprintf("%s: %s: %lld: not an integer: type %i\n",
     458             :                     DEVNAME(sc), n->name, i, res.type);
     459           0 :                 aml_freevalue(&res);
     460           0 :                 return (-1);
     461             :         }
     462             : 
     463           0 :         if (sc->sc_mode) {
     464           0 :                 if (res.length < sizeof(ret)) {
     465             :                         dprintf("%s: %s: %lld: result buffer too small\n",
     466             :                             DEVNAME(sc), n->name, i);
     467           0 :                         aml_freevalue(&res);
     468           0 :                         return (-1);
     469             :                 }
     470           0 :                 memcpy(&ret, res.v_buffer, sizeof(ret));
     471           0 :                 if (ret.flags == 0) {
     472             :                         dprintf("%s: %s: %lld: bad flags in result\n",
     473             :                             DEVNAME(sc), n->name, i);
     474           0 :                         aml_freevalue(&res);
     475           0 :                         return (-1);
     476             :                 }
     477           0 :                 *v = ret.value;
     478           0 :         } else {
     479           0 :                 *v = res.v_integer;
     480             :         }
     481           0 :         aml_freevalue(&res);
     482             : 
     483           0 :         return (0);
     484           0 : }
     485             : 
     486             : int
     487           0 : aibs_getpack(struct aibs_softc *sc, struct aml_node *n, int64_t i,
     488             :     struct aml_value *res)
     489             : {
     490           0 :         struct aml_value        req;
     491             : 
     492           0 :         req.type = AML_OBJTYPE_INTEGER;
     493           0 :         req.v_integer = i;
     494             : 
     495           0 :         if (aml_evalnode(sc->sc_acpi, n, 1, &req, res)) {
     496             :                 dprintf("%s: %s: %lld: evaluation failed\n",
     497             :                     DEVNAME(sc), n->name, i);
     498           0 :                 aml_freevalue(res);
     499           0 :                 return (-1);
     500             :         }
     501           0 :         if (res->type != AML_OBJTYPE_PACKAGE) {
     502             :                 dprintf("%s: %s: %lld: not a package: type %i\n",
     503             :                     DEVNAME(sc), n->name, i, res->type);
     504           0 :                 aml_freevalue(res);
     505           0 :                 return (-1);
     506             :         }
     507             : 
     508           0 :         return (0);
     509           0 : }
     510             : 
     511             : void
     512           0 : aibs_probe(struct aibs_softc *sc)
     513             : {
     514             :         /*
     515             :          * Old mode uses TSIF, VSIF, and FSIF to enumerate sensors and
     516             :          * RTMP, RVLT, and RFAN are used to get the values.
     517             :          * New mode uses GGRP for enumeration and GITM and SITM as accessor.
     518             :          * If the new methods are available use them else default to old mode.
     519             :          */
     520           0 :         aml_find_node(sc->sc_devnode, "RTMP", aibs_find_cb, &sc->sc_rtmpnode);
     521           0 :         aml_find_node(sc->sc_devnode, "RVLT", aibs_find_cb, &sc->sc_rvltnode);
     522           0 :         aml_find_node(sc->sc_devnode, "RFAN", aibs_find_cb, &sc->sc_rfannode);
     523             : 
     524           0 :         aml_find_node(sc->sc_devnode, "GGRP", aibs_find_cb, &sc->sc_ggrpnode);
     525           0 :         aml_find_node(sc->sc_devnode, "GITM", aibs_find_cb, &sc->sc_gitmnode);
     526           0 :         aml_find_node(sc->sc_devnode, "SITM", aibs_find_cb, &sc->sc_sitmnode);
     527             : 
     528           0 :         if (sc->sc_ggrpnode && sc->sc_gitmnode && sc->sc_sitmnode &&
     529           0 :             !sc->sc_rtmpnode && !sc->sc_rvltnode && !sc->sc_rfannode)
     530           0 :                 sc->sc_mode = 1;
     531           0 : }
     532             : 
     533             : int
     534           0 : aibs_find_cb(struct aml_node *node, void *arg)
     535             : {
     536           0 :         struct aml_node **np = arg;
     537             : 
     538           0 :         printf(" %s", node->name);
     539           0 :         *np = node;
     540           0 :         return (1);
     541             : }
     542             : 
     543             : int
     544           0 : aibs_notify(struct aml_node *node, int notify_type, void *arg)
     545             : {
     546           0 :         struct aibs_softc *sc = arg;
     547             : 
     548           0 :         if (notify_type == 0x00) {
     549             :                 /* Poll sensors */
     550           0 :                 aibs_refresh(sc);
     551           0 :         }
     552           0 :         return (0);
     553             : }

Generated by: LCOV version 1.13