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

          Line data    Source code
       1             : /* $OpenBSD: acpidock.c,v 1.44 2015/03/14 03:38:46 jsg Exp $ */
       2             : /*
       3             :  * Copyright (c) 2006,2007 Michael Knudsen <mk@openbsd.org>
       4             :  *
       5             :  * Permission to use, copy, modify, and distribute this software for any
       6             :  * purpose with or without fee is hereby granted, provided that the above
       7             :  * copyright notice and this permission notice appear in all copies.
       8             :  *
       9             :  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
      10             :  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
      11             :  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
      12             :  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
      13             :  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
      14             :  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
      15             :  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
      16             :  */
      17             : 
      18             : #include <sys/param.h>
      19             : #include <sys/systm.h>
      20             : #include <sys/device.h>
      21             : #include <sys/malloc.h>
      22             : #include <sys/sensors.h>
      23             : 
      24             : #include <machine/bus.h>
      25             : 
      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             : struct aml_nodelist {
      32             :         struct aml_node *node;
      33             :         TAILQ_ENTRY(aml_nodelist) entries;
      34             : };
      35             : 
      36             : int     acpidock_match(struct device *, void *, void *);
      37             : void    acpidock_attach(struct device *, struct device *, void *);
      38             : 
      39             : struct cfattach acpidock_ca = {
      40             :         sizeof(struct acpidock_softc), acpidock_match, acpidock_attach
      41             : };
      42             : 
      43             : struct cfdriver acpidock_cd = {
      44             :         NULL, "acpidock", DV_DULL
      45             : };
      46             : 
      47             : int     acpidock_docklock(struct acpidock_softc *, int);
      48             : int     acpidock_dockctl(struct acpidock_softc *, int);
      49             : int     acpidock_eject(struct acpidock_softc *, struct aml_node *);
      50             : int     acpidock_notify(struct aml_node *, int, void *);
      51             : int     acpidock_status(struct acpidock_softc *);
      52             : int     acpidock_walkchildren(struct aml_node *, void *);
      53             : 
      54             : int     acpidock_foundejd(struct aml_node *, void *);
      55             : 
      56             : int
      57           0 : acpidock_match(struct device *parent, void *match, void *aux)
      58             : {
      59           0 :         struct acpi_attach_args  *aaa = aux;
      60           0 :         struct cfdata            *cf = match;
      61             : 
      62             :         /* sanity */
      63           0 :         if (aaa->aaa_name == NULL ||
      64           0 :             strcmp(aaa->aaa_name, cf->cf_driver->cd_name) != 0 ||
      65           0 :             aaa->aaa_table != NULL)
      66           0 :                 return (0);
      67             : 
      68           0 :         return (1);
      69           0 : }
      70             : 
      71             : void
      72           0 : acpidock_attach(struct device *parent, struct device *self, void *aux)
      73             : {
      74           0 :         struct acpidock_softc   *sc = (struct acpidock_softc *)self;
      75           0 :         struct acpi_attach_args *aa = aux;
      76             :         extern struct aml_node  aml_root;
      77             : 
      78           0 :         sc->sc_acpi = (struct acpi_softc *)parent;
      79           0 :         sc->sc_devnode = aa->aaa_node;
      80             : 
      81           0 :         printf(": %s", sc->sc_devnode->name);
      82             : 
      83           0 :         acpidock_status(sc);
      84           0 :         if (sc->sc_docked == ACPIDOCK_STATUS_DOCKED) {
      85           0 :                 acpidock_docklock(sc, 1);
      86           0 :                 acpidock_dockctl(sc, 1);
      87           0 :         }
      88             : 
      89           0 :         acpidock_status(sc);
      90           0 :         printf("%s docked (%d)\n",
      91           0 :             sc->sc_docked == ACPIDOCK_STATUS_DOCKED ? "" : " not",
      92           0 :             sc->sc_sta);
      93             : 
      94           0 :         strlcpy(sc->sc_sensdev.xname, DEVNAME(sc),
      95             :             sizeof(sc->sc_sensdev.xname));
      96           0 :         if (sc->sc_docked)
      97           0 :                 strlcpy(sc->sc_sens.desc, "docked",
      98             :                     sizeof(sc->sc_sens.desc));
      99             :         else
     100           0 :                 strlcpy(sc->sc_sens.desc, "not docked",
     101             :                     sizeof(sc->sc_sens.desc));
     102             : 
     103           0 :         sc->sc_sens.type = SENSOR_INDICATOR;
     104           0 :         sc->sc_sens.value = sc->sc_docked == ACPIDOCK_STATUS_DOCKED;
     105           0 :         sc->sc_sens.status = sc->sc_docked ? SENSOR_S_OK : SENSOR_S_UNKNOWN;
     106           0 :         sensor_attach(&sc->sc_sensdev, &sc->sc_sens);
     107           0 :         sensordev_install(&sc->sc_sensdev);
     108             : 
     109           0 :         TAILQ_INIT(&sc->sc_deps_h);
     110           0 :         aml_find_node(&aml_root, "_EJD", acpidock_foundejd, sc);
     111             : 
     112           0 :         aml_register_notify(sc->sc_devnode, aa->aaa_dev,
     113             :             acpidock_notify, sc, ACPIDEV_NOPOLL);
     114           0 : }
     115             : 
     116             : int
     117           0 : acpidock_status(struct acpidock_softc *sc)
     118             : {
     119           0 :         int64_t                 sta;
     120             :         int                     rv;
     121             : 
     122           0 :         if (aml_evalinteger(sc->sc_acpi, sc->sc_devnode, "_STA", 0, NULL,
     123           0 :             &sta) != 0) {
     124           0 :                 sta = 0;
     125             :                 rv = 0;
     126           0 :         } else
     127             :                 rv = 1;
     128             : 
     129           0 :         sc->sc_sta = sta;
     130           0 :         sc->sc_docked = sc->sc_sta & STA_PRESENT;
     131             : 
     132           0 :         return (rv);
     133           0 : }
     134             : 
     135             : int
     136           0 : acpidock_docklock(struct acpidock_softc *sc, int lock)
     137             : {
     138           0 :         struct aml_value        cmd;
     139           0 :         struct aml_value        res;
     140             :         int                     rv;
     141             : 
     142           0 :         memset(&cmd, 0, sizeof cmd);
     143           0 :         cmd.v_integer = lock;
     144           0 :         cmd.type = AML_OBJTYPE_INTEGER;
     145           0 :         if (aml_evalname(sc->sc_acpi, sc->sc_devnode, "_LCK", 1, &cmd,
     146           0 :             &res) != 0) {
     147             :                 dnprintf(20, "%s: _LCK %d failed\n", DEVNAME(sc), lock);
     148             :                 rv = 0;
     149           0 :         } else {
     150             :                 dnprintf(20, "%s: _LCK %d successful\n", DEVNAME(sc), lock);
     151             :                 rv = 1;
     152             :         }
     153             : 
     154           0 :         aml_freevalue(&res);
     155             : 
     156           0 :         return (rv);
     157           0 : }
     158             : 
     159             : int
     160           0 : acpidock_dockctl(struct acpidock_softc *sc, int dock)
     161             : {
     162           0 :         struct aml_value        cmd;
     163           0 :         struct aml_value        res;
     164             :         int                     rv;
     165             : 
     166           0 :         memset(&cmd, 0, sizeof cmd);
     167           0 :         cmd.v_integer = dock;
     168           0 :         cmd.type = AML_OBJTYPE_INTEGER;
     169           0 :         if (aml_evalname(sc->sc_acpi, sc->sc_devnode, "_DCK", 1, &cmd,
     170           0 :             &res) != 0) {
     171             :                 dnprintf(15, "%s: _DCK %d failed\n", DEVNAME(sc), dock);
     172             :                 rv = 0;
     173           0 :         } else {
     174             :                 dnprintf(15, "%s: _DCK %d successful\n", DEVNAME(sc), dock);
     175             :                 rv = 1;
     176             :         }
     177             : 
     178           0 :         aml_freevalue(&res);
     179             : 
     180           0 :         return (rv);
     181           0 : }
     182             : 
     183             : int
     184           0 : acpidock_eject(struct acpidock_softc *sc, struct aml_node *node)
     185             : {
     186           0 :         struct aml_value        cmd;
     187           0 :         struct aml_value        res;
     188             :         int                     rv;
     189             : 
     190           0 :         if (node != sc->sc_devnode)
     191           0 :                 aml_notify(node, 3);
     192             : 
     193           0 :         memset(&cmd, 0, sizeof cmd);
     194           0 :         cmd.v_integer = 1;
     195           0 :         cmd.type = AML_OBJTYPE_INTEGER;
     196           0 :         if (aml_evalname(sc->sc_acpi, node, "_EJ0", 1, &cmd,
     197           0 :             &res) != 0) {
     198             :                 dnprintf(15, "%s: _EJ0 failed\n", DEVNAME(sc));
     199             :                 rv = 0;
     200           0 :         } else {
     201             :                 dnprintf(15, "%s: _EJ0 successful\n", DEVNAME(sc));
     202             :                 rv = 1;
     203             :         }
     204             : 
     205           0 :         aml_freevalue(&res);
     206             : 
     207           0 :         return (rv);
     208           0 : }
     209             : 
     210             : int
     211           0 : acpidock_notify(struct aml_node *node, int notify_type, void *arg)
     212             : {
     213           0 :         struct acpidock_softc   *sc = arg;
     214             :         struct aml_nodelist     *n;
     215             : 
     216             :         dnprintf(5, "%s: acpidock_notify: notify %d\n", DEVNAME(sc),
     217             :             notify_type);
     218             : 
     219           0 :         switch (notify_type) {
     220             :         case ACPIDOCK_EVENT_INSERT:
     221           0 :                 acpidock_docklock(sc, 1);
     222           0 :                 acpidock_dockctl(sc, 1);
     223             : 
     224           0 :                 TAILQ_FOREACH_REVERSE(n, &sc->sc_deps_h, aml_nodelisth, entries)
     225           0 :                         aml_notify(n->node, 0x00);
     226             :                 break;
     227             : 
     228             :         case ACPIDOCK_EVENT_EJECT:
     229             :         case ACPIDOCK_EVENT_DEVCHECK:
     230             :                 /* ACPI Spec says eject button press generates
     231             :                  * a Notify(Device, 1); */
     232           0 :                 TAILQ_FOREACH(n, &sc->sc_deps_h, entries)
     233           0 :                         acpidock_eject(sc, n->node);
     234           0 :                 acpidock_dockctl(sc, 0);
     235           0 :                 acpidock_docklock(sc, 0);
     236             : 
     237             :                 /* now actually undock */
     238           0 :                 acpidock_eject(sc, sc->sc_devnode);
     239           0 :                 break;
     240             :         }
     241             : 
     242           0 :         acpidock_status(sc);
     243           0 :         sc->sc_sens.value = sc->sc_docked == ACPIDOCK_STATUS_DOCKED;
     244           0 :         sc->sc_sens.status = sc->sc_docked ? SENSOR_S_OK : SENSOR_S_UNKNOWN;
     245           0 :         if (sc->sc_docked)
     246           0 :                 strlcpy(sc->sc_sens.desc, "docked",
     247             :                     sizeof(sc->sc_sens.desc));
     248             :         else
     249           0 :                 strlcpy(sc->sc_sens.desc, "not docked",
     250             :                     sizeof(sc->sc_sens.desc));
     251             : 
     252           0 :         printf("%s: %s\n",
     253           0 :             DEVNAME(sc), sc->sc_docked == ACPIDOCK_STATUS_DOCKED ?
     254             :             "docked" : "undocked");
     255             : 
     256           0 :         return (0);
     257             : }
     258             : 
     259             : int
     260           0 : acpidock_walkchildren(struct aml_node *node, void *arg)
     261             : {
     262           0 :         struct acpidock_softc   *sc = arg;
     263             :         struct aml_nodelist     *n;
     264             : 
     265           0 :         if (node && node->value && node->value->type == AML_OBJTYPE_DEVICE) {
     266           0 :                 n = malloc(sizeof *n, M_DEVBUF, M_WAITOK | M_ZERO);
     267           0 :                 n->node = node;
     268             :                 dnprintf(10,"%s depends on", aml_nodename(node));
     269             :                 dnprintf(10,"%s\n", aml_nodename(sc->sc_devnode));
     270           0 :                 TAILQ_INSERT_TAIL(&sc->sc_deps_h, n, entries);
     271           0 :         }
     272             : 
     273           0 :         return (0);
     274             : }
     275             : 
     276             : int
     277           0 : acpidock_foundejd(struct aml_node *node, void *arg)
     278             : {
     279           0 :         struct acpidock_softc   *sc = (struct acpidock_softc *)arg;
     280           0 :         struct aml_value        res;
     281             :         struct aml_node         *dock;
     282             :         extern struct aml_node  aml_root;
     283             : 
     284             :         dnprintf(15, "%s: %s", DEVNAME(sc), node->name);
     285             : 
     286           0 :         if (aml_evalnode(sc->sc_acpi, node, 0, NULL, &res) == -1)
     287           0 :                 printf(": error\n");
     288             :         else {
     289           0 :                 dock = aml_searchname(&aml_root, res.v_string);
     290             : 
     291           0 :                 if (dock == sc->sc_devnode)
     292             :                         /* Add all children devices of Device containing _EJD */
     293           0 :                         aml_walknodes(node->parent, AML_WALK_POST,
     294             :                             acpidock_walkchildren, sc);
     295           0 :                 aml_freevalue(&res);
     296             :         }
     297             : 
     298           0 :         return (0);
     299           0 : }

Generated by: LCOV version 1.13