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

          Line data    Source code
       1             : /* $OpenBSD: acpiec.c,v 1.59 2018/07/01 19:40:49 mlarkin Exp $ */
       2             : /*
       3             :  * Copyright (c) 2006 Can Erkin Acar <canacar@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/signalvar.h>
      20             : #include <sys/systm.h>
      21             : #include <sys/device.h>
      22             : 
      23             : #include <machine/bus.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             : #include <sys/sensors.h>
      32             : 
      33             : int             acpiec_match(struct device *, void *, void *);
      34             : void            acpiec_attach(struct device *, struct device *, void *);
      35             : 
      36             : uint8_t         acpiec_status(struct acpiec_softc *);
      37             : uint8_t         acpiec_read_data(struct acpiec_softc *);
      38             : void            acpiec_write_cmd(struct acpiec_softc *, uint8_t);
      39             : void            acpiec_write_data(struct acpiec_softc *, uint8_t);
      40             : void            acpiec_burst_enable(struct acpiec_softc *sc);
      41             : void            acpiec_burst_disable(struct acpiec_softc *sc);
      42             : 
      43             : uint8_t         acpiec_read_1(struct acpiec_softc *, uint8_t);
      44             : void            acpiec_write_1(struct acpiec_softc *, uint8_t, uint8_t);
      45             : 
      46             : void            acpiec_read(struct acpiec_softc *, uint8_t, int, uint8_t *);
      47             : void            acpiec_write(struct acpiec_softc *, uint8_t, int, uint8_t *);
      48             : 
      49             : int             acpiec_getcrs(struct acpiec_softc *,
      50             :                     struct acpi_attach_args *);
      51             : int             acpiec_parse_resources(int, union acpi_resource *, void *);
      52             : 
      53             : void            acpiec_wait(struct acpiec_softc *, uint8_t, uint8_t);
      54             : void            acpiec_sci_event(struct acpiec_softc *);
      55             : 
      56             : void            acpiec_get_events(struct acpiec_softc *);
      57             : 
      58             : int             acpiec_gpehandler(struct acpi_softc *, int, void *);
      59             : 
      60             : void            acpiec_lock(struct acpiec_softc *);
      61             : void            acpiec_unlock(struct acpiec_softc *);
      62             : 
      63             : /* EC Status bits */
      64             : #define         EC_STAT_SMI_EVT 0x40    /* SMI event pending */
      65             : #define         EC_STAT_SCI_EVT 0x20    /* SCI event pending */
      66             : #define         EC_STAT_BURST   0x10    /* Controller in burst mode */
      67             : #define         EC_STAT_CMD     0x08    /* data is command */
      68             : #define         EC_STAT_IBF     0x02    /* input buffer full */
      69             : #define         EC_STAT_OBF     0x01    /* output buffer full */
      70             : 
      71             : /* EC Commands */
      72             : #define         EC_CMD_RD       0x80    /* Read */
      73             : #define         EC_CMD_WR       0x81    /* Write */
      74             : #define         EC_CMD_BE       0x82    /* Burst Enable */
      75             : #define         EC_CMD_BD       0x83    /* Burst Disable */
      76             : #define         EC_CMD_QR       0x84    /* Query */
      77             : 
      78             : int     acpiec_reg(struct acpiec_softc *);
      79             : 
      80             : extern char     *hw_vendor, *hw_prod;
      81             : 
      82             : struct cfattach acpiec_ca = {
      83             :         sizeof(struct acpiec_softc), acpiec_match, acpiec_attach
      84             : };
      85             : 
      86             : struct cfdriver acpiec_cd = {
      87             :         NULL, "acpiec", DV_DULL
      88             : };
      89             : 
      90             : const char *acpiec_hids[] = {
      91             :         ACPI_DEV_ECD,
      92             :         NULL
      93             : };
      94             : 
      95             : void
      96           0 : acpiec_wait(struct acpiec_softc *sc, uint8_t mask, uint8_t val)
      97             : {
      98             :         static int acpiecnowait;
      99             :         uint8_t         stat;
     100             : 
     101             :         dnprintf(40, "%s: EC wait_ns for: %b == %02x\n",
     102             :             DEVNAME(sc), (int)mask,
     103             :             "\20\x8IGN\x7SMI\x6SCI\05BURST\04CMD\03IGN\02IBF\01OBF", (int)val);
     104             : 
     105           0 :         while (((stat = acpiec_status(sc)) & mask) != val) {
     106           0 :                 if (stat & EC_STAT_SCI_EVT)
     107           0 :                         sc->sc_gotsci = 1;
     108           0 :                 if (cold || (stat & EC_STAT_BURST))
     109           0 :                         delay(1);
     110             :                 else
     111           0 :                         tsleep(&acpiecnowait, PWAIT, "acpiec", 1);
     112             :         }
     113             : 
     114             :         dnprintf(40, "%s: EC wait_ns, stat: %b\n", DEVNAME(sc), (int)stat,
     115             :             "\20\x8IGN\x7SMI\x6SCI\05BURST\04CMD\03IGN\02IBF\01OBF");
     116           0 : }
     117             : 
     118             : uint8_t
     119           0 : acpiec_status(struct acpiec_softc *sc)
     120             : {
     121           0 :         return (bus_space_read_1(sc->sc_cmd_bt, sc->sc_cmd_bh, 0));
     122             : }
     123             : 
     124             : void
     125           0 : acpiec_write_data(struct acpiec_softc *sc, uint8_t val)
     126             : {
     127           0 :         acpiec_wait(sc, EC_STAT_IBF, 0);
     128             :         dnprintf(40, "acpiec: write_data -- %d\n", (int)val);
     129           0 :         bus_space_write_1(sc->sc_data_bt, sc->sc_data_bh, 0, val);
     130           0 : }
     131             : 
     132             : void
     133           0 : acpiec_write_cmd(struct acpiec_softc *sc, uint8_t val)
     134             : {
     135           0 :         acpiec_wait(sc, EC_STAT_IBF, 0);
     136             :         dnprintf(40, "acpiec: write_cmd -- %d\n", (int)val);
     137           0 :         bus_space_write_1(sc->sc_cmd_bt, sc->sc_cmd_bh, 0, val);
     138           0 : }
     139             : 
     140             : uint8_t
     141           0 : acpiec_read_data(struct acpiec_softc *sc)
     142             : {
     143             :         uint8_t         val;
     144             : 
     145           0 :         acpiec_wait(sc, EC_STAT_OBF, EC_STAT_OBF);
     146           0 :         val = bus_space_read_1(sc->sc_data_bt, sc->sc_data_bh, 0);
     147             : 
     148             :         dnprintf(40, "acpiec: read_data %d\n", (int)val);
     149             : 
     150           0 :         return (val);
     151             : }
     152             : 
     153             : void
     154           0 : acpiec_sci_event(struct acpiec_softc *sc)
     155             : {
     156             :         uint8_t         evt;
     157             : 
     158           0 :         sc->sc_gotsci = 0;
     159             : 
     160           0 :         acpiec_wait(sc, EC_STAT_IBF, 0);
     161           0 :         bus_space_write_1(sc->sc_cmd_bt, sc->sc_cmd_bh, 0, EC_CMD_QR);
     162             : 
     163           0 :         acpiec_wait(sc, EC_STAT_OBF, EC_STAT_OBF);
     164           0 :         evt = bus_space_read_1(sc->sc_data_bt, sc->sc_data_bh, 0);
     165             : 
     166           0 :         if (evt) {
     167             :                 dnprintf(10, "%s: sci_event: 0x%02x\n", DEVNAME(sc), (int)evt);
     168           0 :                 aml_evalnode(sc->sc_acpi, sc->sc_events[evt].event, 0, NULL,
     169             :                     NULL);
     170           0 :         }
     171           0 : }
     172             : 
     173             : uint8_t
     174           0 : acpiec_read_1(struct acpiec_softc *sc, uint8_t addr)
     175             : {
     176             :         uint8_t         val;
     177             : 
     178           0 :         if ((acpiec_status(sc) & EC_STAT_SCI_EVT) == EC_STAT_SCI_EVT)
     179           0 :                 sc->sc_gotsci = 1;
     180             : 
     181           0 :         acpiec_write_cmd(sc, EC_CMD_RD);
     182           0 :         acpiec_write_data(sc, addr);
     183             : 
     184           0 :         val = acpiec_read_data(sc);
     185             : 
     186           0 :         return (val);
     187             : }
     188             : 
     189             : void
     190           0 : acpiec_write_1(struct acpiec_softc *sc, uint8_t addr, uint8_t data)
     191             : {
     192           0 :         if ((acpiec_status(sc) & EC_STAT_SCI_EVT) == EC_STAT_SCI_EVT)
     193           0 :                 sc->sc_gotsci = 1;
     194             : 
     195           0 :         acpiec_write_cmd(sc, EC_CMD_WR);
     196           0 :         acpiec_write_data(sc, addr);
     197           0 :         acpiec_write_data(sc, data);
     198           0 : }
     199             : 
     200             : void
     201           0 : acpiec_burst_enable(struct acpiec_softc *sc)
     202             : {
     203           0 :         if (sc->sc_cantburst)
     204             :                 return;
     205             : 
     206           0 :         acpiec_write_cmd(sc, EC_CMD_BE);
     207           0 :         acpiec_read_data(sc);
     208           0 : }
     209             : 
     210             : void
     211           0 : acpiec_burst_disable(struct acpiec_softc *sc)
     212             : {
     213           0 :         if (sc->sc_cantburst)
     214             :                 return;
     215             : 
     216           0 :         if ((acpiec_status(sc) & EC_STAT_BURST) == EC_STAT_BURST)
     217           0 :                 acpiec_write_cmd(sc, EC_CMD_BD);
     218           0 : }
     219             : 
     220             : void
     221           0 : acpiec_read(struct acpiec_softc *sc, uint8_t addr, int len, uint8_t *buffer)
     222             : {
     223             :         int                     reg;
     224             : 
     225             :         /*
     226             :          * this works because everything runs in the acpi thread context.
     227             :          * at some point add a lock to deal with concurrency so that a
     228             :          * transaction does not get interrupted.
     229             :          */
     230             :         dnprintf(20, "%s: read %d, %d\n", DEVNAME(sc), (int)addr, len);
     231           0 :         sc->sc_ecbusy = 1;
     232           0 :         acpiec_burst_enable(sc);
     233           0 :         for (reg = 0; reg < len; reg++)
     234           0 :                 buffer[reg] = acpiec_read_1(sc, addr + reg);
     235           0 :         acpiec_burst_disable(sc);
     236           0 :         sc->sc_ecbusy = 0;
     237           0 : }
     238             : 
     239             : void
     240           0 : acpiec_write(struct acpiec_softc *sc, uint8_t addr, int len, uint8_t *buffer)
     241             : {
     242             :         int                     reg;
     243             : 
     244             :         /*
     245             :          * this works because everything runs in the acpi thread context.
     246             :          * at some point add a lock to deal with concurrency so that a
     247             :          * transaction does not get interrupted.
     248             :          */
     249             :         dnprintf(20, "%s: write %d, %d\n", DEVNAME(sc), (int)addr, len);
     250           0 :         sc->sc_ecbusy = 1;
     251           0 :         acpiec_burst_enable(sc);
     252           0 :         for (reg = 0; reg < len; reg++)
     253           0 :                 acpiec_write_1(sc, addr + reg, buffer[reg]);
     254           0 :         acpiec_burst_disable(sc);
     255           0 :         sc->sc_ecbusy = 0;
     256           0 : }
     257             : 
     258             : int
     259           0 : acpiec_match(struct device *parent, void *match, void *aux)
     260             : {
     261           0 :         struct acpi_attach_args *aa = aux;
     262           0 :         struct cfdata           *cf = match;
     263           0 :         struct acpi_ecdt        *ecdt = aa->aaa_table;
     264           0 :         struct acpi_softc       *acpisc = (struct acpi_softc *)parent;
     265             : 
     266             :         /* Check for early ECDT table attach */
     267           0 :         if (ecdt && 
     268           0 :             !memcmp(ecdt->hdr.signature, ECDT_SIG, sizeof(ECDT_SIG) - 1))
     269           0 :                 return (1);
     270           0 :         if (acpisc->sc_ec)
     271           0 :                 return (0);
     272             : 
     273             :         /* sanity */
     274           0 :         return (acpi_matchhids(aa, acpiec_hids, cf->cf_driver->cd_name));
     275           0 : }
     276             : 
     277             : void
     278           0 : acpiec_attach(struct device *parent, struct device *self, void *aux)
     279             : {
     280           0 :         struct acpiec_softc     *sc = (struct acpiec_softc *)self;
     281           0 :         struct acpi_attach_args *aa = aux;
     282           0 :         struct aml_value res;
     283           0 :         int64_t st;
     284             : 
     285           0 :         sc->sc_acpi = (struct acpi_softc *)parent;
     286           0 :         sc->sc_devnode = aa->aaa_node;
     287           0 :         sc->sc_cantburst = 0;
     288             : 
     289           0 :         if (aml_evalinteger(sc->sc_acpi, sc->sc_devnode, "_STA", 0, NULL, &st))
     290           0 :                 st = STA_PRESENT | STA_ENABLED | STA_DEV_OK;
     291           0 :         if ((st & STA_PRESENT) == 0) {
     292           0 :                 printf(": not present\n");
     293           0 :                 return;
     294             :         }
     295             : 
     296           0 :         printf("\n");
     297           0 :         if (acpiec_getcrs(sc, aa)) {
     298           0 :                 printf("%s: Failed to read resource settings\n", DEVNAME(sc));
     299           0 :                 return;
     300             :         }
     301             : 
     302           0 :         sc->sc_acpi->sc_ec = sc;
     303             : 
     304           0 :         if (acpiec_reg(sc)) {
     305           0 :                 printf("%s: Failed to register address space\n", DEVNAME(sc));
     306           0 :                 return;
     307             :         }
     308             : 
     309             :         /*
     310             :          * Some Chromebooks using the Google EC do not support burst mode and
     311             :          * cause us to spin forever waiting for the acknowledgment.  Don't use
     312             :          * burst mode at all on these machines.
     313             :          */
     314           0 :         if (hw_vendor != NULL && hw_prod != NULL &&
     315           0 :             strcmp(hw_vendor, "GOOGLE") == 0 &&
     316           0 :             strcmp(hw_prod, "Samus") == 0)
     317           0 :                 sc->sc_cantburst = 1;
     318             : 
     319           0 :         acpiec_get_events(sc);
     320             : 
     321             :         dnprintf(10, "%s: GPE: %d\n", DEVNAME(sc), sc->sc_gpe);
     322             : 
     323             : #ifndef SMALL_KERNEL
     324           0 :         acpi_set_gpehandler(sc->sc_acpi, sc->sc_gpe, acpiec_gpehandler,
     325           0 :             sc, 1);
     326             : #endif
     327             : 
     328           0 :         if (aml_evalname(sc->sc_acpi, sc->sc_devnode, "_GLK", 0, NULL, &res))
     329           0 :                 sc->sc_glk = 0;
     330           0 :         else if (res.type != AML_OBJTYPE_INTEGER)
     331           0 :                 sc->sc_glk = 0;
     332             :         else
     333           0 :                 sc->sc_glk = res.v_integer ? 1 : 0;
     334           0 : }
     335             : 
     336             : void
     337           0 : acpiec_get_events(struct acpiec_softc *sc)
     338             : {
     339             :         int                     idx;
     340           0 :         char                    name[16];
     341             : 
     342           0 :         memset(sc->sc_events, 0, sizeof(sc->sc_events));
     343           0 :         for (idx = 0; idx < ACPIEC_MAX_EVENTS; idx++) {
     344           0 :                 snprintf(name, sizeof(name), "_Q%02X", idx);
     345           0 :                 sc->sc_events[idx].event = aml_searchname(sc->sc_devnode, name);
     346             :                 if (sc->sc_events[idx].event != NULL)
     347             :                         dnprintf(10, "%s: Found event %s\n", DEVNAME(sc), name);
     348             :         }
     349           0 : }
     350             : 
     351             : int
     352           0 : acpiec_gpehandler(struct acpi_softc *acpi_sc, int gpe, void *arg)
     353             : {
     354           0 :         struct acpiec_softc     *sc = arg;
     355             :         uint8_t                 mask, stat, en;
     356             :         int                     s;
     357             : 
     358           0 :         KASSERT(sc->sc_ecbusy == 0);
     359             :         dnprintf(10, "ACPIEC: got gpe\n");
     360             : 
     361           0 :         do {
     362           0 :                 if (sc->sc_gotsci)
     363           0 :                         acpiec_sci_event(sc);
     364             : 
     365           0 :                 stat = acpiec_status(sc);
     366             :                 dnprintf(40, "%s: EC interrupt, stat: %b\n",
     367             :                     DEVNAME(sc), (int)stat,
     368             :                     "\20\x8IGN\x7SMI\x6SCI\05BURST\04CMD\03IGN\02IBF\01OBF");
     369             : 
     370           0 :                 if (stat & EC_STAT_SCI_EVT)
     371           0 :                         sc->sc_gotsci = 1;
     372             :                 else
     373           0 :                         sc->sc_gotsci = 0;
     374           0 :         } while (sc->sc_gotsci);
     375             : 
     376             :         /* Unmask the GPE which was blocked at interrupt time */
     377           0 :         s = spltty();
     378           0 :         mask = (1L << (gpe & 7));
     379           0 :         en = acpi_read_pmreg(acpi_sc, ACPIREG_GPE_EN, gpe>>3);
     380           0 :         acpi_write_pmreg(acpi_sc, ACPIREG_GPE_EN, gpe>>3, en | mask);
     381           0 :         splx(s);
     382             : 
     383           0 :         return (0);
     384             : }
     385             : 
     386             : int
     387           0 : acpiec_parse_resources(int crsidx, union acpi_resource *crs, void *arg)
     388             : {
     389           0 :         struct acpiec_softc *sc = arg;
     390           0 :         int type = AML_CRSTYPE(crs);
     391             : 
     392           0 :         switch (crsidx) {
     393             :         case 0:
     394           0 :                 if (type != SR_IOPORT) {
     395           0 :                         printf("%s: Unexpected resource #%d type %d\n",
     396           0 :                             DEVNAME(sc), crsidx, type);
     397           0 :                         break;
     398             :                 }
     399           0 :                 sc->sc_data_bt = sc->sc_acpi->sc_iot;
     400           0 :                 sc->sc_ec_data = crs->sr_ioport._max;
     401           0 :                 break;
     402             :         case 1:
     403           0 :                 if (type != SR_IOPORT) {
     404           0 :                         printf("%s: Unexpected resource #%d type %d\n",
     405           0 :                             DEVNAME(sc), crsidx, type);
     406           0 :                         break;
     407             :                 }
     408           0 :                 sc->sc_cmd_bt = sc->sc_acpi->sc_iot;
     409           0 :                 sc->sc_ec_sc = crs->sr_ioport._max;
     410           0 :                 break;
     411             :         case 2:
     412           0 :                 if (!sc->sc_acpi->sc_hw_reduced) {
     413           0 :                         printf("%s: Not running on HW-Reduced ACPI type %d\n",
     414           0 :                             DEVNAME(sc), type);
     415           0 :                         break;
     416             :                 }
     417             :                 /* XXX: handle SCI GPIO  */
     418             :                 break;
     419             :         default:
     420           0 :                 printf("%s: invalid resource #%d type %d\n",
     421           0 :                     DEVNAME(sc), crsidx, type);
     422           0 :         }
     423             : 
     424           0 :         return 0;
     425             : }
     426             : 
     427             : int
     428           0 : acpiec_getcrs(struct acpiec_softc *sc, struct acpi_attach_args *aa)
     429             : {
     430           0 :         struct aml_value        res;
     431           0 :         int64_t                 gpe;
     432           0 :         struct acpi_ecdt        *ecdt = aa->aaa_table;
     433             :         extern struct aml_node  aml_root;
     434             :         int                     rc;
     435             : 
     436             :         /* Check if this is ECDT initialization */
     437           0 :         if (ecdt) {
     438             :                 /* Get GPE, Data and Control segments */
     439           0 :                 sc->sc_gpe = ecdt->gpe_bit;
     440             : 
     441           0 :                 if (ecdt->ec_control.address_space_id == GAS_SYSTEM_IOSPACE)
     442           0 :                         sc->sc_cmd_bt = sc->sc_acpi->sc_iot;
     443             :                 else
     444           0 :                         sc->sc_cmd_bt = sc->sc_acpi->sc_memt;
     445           0 :                 sc->sc_ec_sc = ecdt->ec_control.address;
     446             : 
     447           0 :                 if (ecdt->ec_data.address_space_id == GAS_SYSTEM_IOSPACE)
     448           0 :                         sc->sc_data_bt = sc->sc_acpi->sc_iot;
     449             :                 else
     450           0 :                         sc->sc_data_bt = sc->sc_acpi->sc_memt;
     451           0 :                 sc->sc_ec_data = ecdt->ec_data.address;
     452             : 
     453             :                 /* Get devnode from header */
     454           0 :                 sc->sc_devnode = aml_searchname(&aml_root, ecdt->ec_id);
     455             : 
     456           0 :                 goto ecdtdone;
     457             :         }
     458             : 
     459           0 :         rc = aml_evalinteger(sc->sc_acpi, sc->sc_devnode,
     460             :             "_GPE", 0, NULL, &gpe);
     461           0 :         if (rc) {
     462             :                 dnprintf(10, "%s: no _GPE\n", DEVNAME(sc));
     463           0 :                 return (1);
     464             :         }
     465             : 
     466           0 :         sc->sc_gpe = gpe;
     467             : 
     468           0 :         if (aml_evalname(sc->sc_acpi, sc->sc_devnode, "_CRS", 0, NULL, &res)) {
     469             :                 dnprintf(10, "%s: no _CRS\n", DEVNAME(sc));
     470           0 :                 return (1);
     471             :         }
     472             : 
     473             :         /* Parse CRS to get control and data registers */
     474             : 
     475           0 :         if (res.type != AML_OBJTYPE_BUFFER) {
     476             :                 dnprintf(10, "%s: unknown _CRS type %d\n",
     477             :                     DEVNAME(sc), res.type);
     478           0 :                 aml_freevalue(&res);
     479           0 :                 return (1);
     480             :         }
     481             : 
     482           0 :         aml_parse_resource(&res, acpiec_parse_resources, sc);
     483           0 :         aml_freevalue(&res);
     484           0 :         if (sc->sc_ec_data == 0 || sc->sc_ec_sc == 0) {
     485           0 :                 printf("%s: failed to read from _CRS\n", DEVNAME(sc));
     486           0 :                 return (1);
     487             :         }
     488             : 
     489             : ecdtdone:
     490             : 
     491             :         dnprintf(10, "%s: Data: 0x%lx, S/C: 0x%lx\n",
     492             :             DEVNAME(sc), sc->sc_ec_data, sc->sc_ec_sc);
     493             : 
     494           0 :         if (bus_space_map(sc->sc_cmd_bt, sc->sc_ec_sc, 1, 0, &sc->sc_cmd_bh)) {
     495             :                 dnprintf(10, "%s: failed to map S/C reg.\n", DEVNAME(sc));
     496           0 :                 return (1);
     497             :         }
     498             : 
     499           0 :         rc = bus_space_map(sc->sc_data_bt, sc->sc_ec_data, 1, 0,
     500           0 :             &sc->sc_data_bh);
     501           0 :         if (rc) {
     502             :                 dnprintf(10, "%s: failed to map DATA reg.\n", DEVNAME(sc));
     503           0 :                 bus_space_unmap(sc->sc_cmd_bt, sc->sc_cmd_bh, 1);
     504           0 :                 return (1);
     505             :         }
     506             : 
     507           0 :         return (0);
     508           0 : }
     509             : 
     510             : int
     511           0 : acpiec_reg(struct acpiec_softc *sc)
     512             : {
     513           0 :         struct aml_value arg[2];
     514             :         struct aml_node *node;
     515             : 
     516           0 :         memset(&arg, 0, sizeof(arg));
     517           0 :         arg[0].type = AML_OBJTYPE_INTEGER;
     518           0 :         arg[0].v_integer = ACPI_OPREG_EC;
     519           0 :         arg[1].type = AML_OBJTYPE_INTEGER;
     520           0 :         arg[1].v_integer = 1;
     521             : 
     522           0 :         node = aml_searchname(sc->sc_devnode, "_REG");
     523           0 :         if (node && aml_evalnode(sc->sc_acpi, node, 2, arg, NULL)) {
     524             :                 dnprintf(10, "%s: eval method _REG failed\n", DEVNAME(sc));
     525           0 :                 printf("acpiec _REG failed, broken BIOS\n");
     526           0 :         }
     527             : 
     528           0 :         return (0);
     529           0 : }
     530             : 
     531             : void
     532           0 : acpiec_lock(struct acpiec_softc *sc)
     533             : {
     534           0 :         KASSERT(sc->sc_ecbusy == 0);
     535             : 
     536           0 :         sc->sc_ecbusy = 1;
     537             : 
     538           0 :         if (sc->sc_glk) {
     539           0 :                 acpi_glk_enter();
     540           0 :         }
     541           0 : }
     542             : 
     543             : void
     544           0 : acpiec_unlock(struct acpiec_softc *sc)
     545             : {
     546           0 :         KASSERT(sc->sc_ecbusy == 1);
     547             : 
     548           0 :         if (sc->sc_glk) {
     549           0 :                 acpi_glk_leave();
     550           0 :         }
     551             : 
     552           0 :         sc->sc_ecbusy = 0;
     553           0 : }

Generated by: LCOV version 1.13