[BACK]Return to acpi.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / sys / dev / acpi

Annotation of src/sys/dev/acpi/acpi.c, Revision 1.10

1.10    ! tshiozak    1: /*     $NetBSD: acpi.c,v 1.9 2002/06/17 08:18:51 kanaoka Exp $ */
1.1       thorpej     2:
                      3: /*
                      4:  * Copyright 2001 Wasabi Systems, Inc.
                      5:  * All rights reserved.
                      6:  *
                      7:  * Written by Jason R. Thorpe for Wasabi Systems, Inc.
                      8:  *
                      9:  * Redistribution and use in source and binary forms, with or without
                     10:  * modification, are permitted provided that the following conditions
                     11:  * are met:
                     12:  * 1. Redistributions of source code must retain the above copyright
                     13:  *    notice, this list of conditions and the following disclaimer.
                     14:  * 2. Redistributions in binary form must reproduce the above copyright
                     15:  *    notice, this list of conditions and the following disclaimer in the
                     16:  *    documentation and/or other materials provided with the distribution.
                     17:  * 3. All advertising materials mentioning features or use of this software
                     18:  *    must display the following acknowledgement:
                     19:  *     This product includes software developed for the NetBSD Project by
                     20:  *     Wasabi Systems, Inc.
                     21:  * 4. The name of Wasabi Systems, Inc. may not be used to endorse
                     22:  *    or promote products derived from this software without specific prior
                     23:  *    written permission.
                     24:  *
                     25:  * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND
                     26:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
                     27:  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
                     28:  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL WASABI SYSTEMS, INC
                     29:  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
                     30:  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
                     31:  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
                     32:  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
                     33:  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
                     34:  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
                     35:  * POSSIBILITY OF SUCH DAMAGE.
                     36:  */
                     37:
                     38: /*
                     39:  * Autoconfiguration support for the Intel ACPI Component Architecture
                     40:  * ACPI reference implementation.
                     41:  */
1.5       lukem      42:
                     43: #include <sys/cdefs.h>
1.10    ! tshiozak   44: __KERNEL_RCSID(0, "$NetBSD: acpi.c,v 1.9 2002/06/17 08:18:51 kanaoka Exp $");
1.1       thorpej    45:
                     46: #include <sys/param.h>
                     47: #include <sys/systm.h>
                     48: #include <sys/device.h>
                     49: #include <sys/malloc.h>
                     50:
                     51: #include <dev/acpi/acpica.h>
                     52: #include <dev/acpi/acpireg.h>
                     53: #include <dev/acpi/acpivar.h>
                     54: #include <dev/acpi/acpi_osd.h>
                     55:
1.10    ! tshiozak   56: #include <machine/acpi_machdep.h>
        !            57:
1.1       thorpej    58: #ifdef ENABLE_DEBUGGER
                     59: #define        ACPI_DBGR_INIT          0x01
                     60: #define        ACPI_DBGR_TABLES        0x02
                     61: #define        ACPI_DBGR_ENABLE        0x04
                     62: #define        ACPI_DBGR_PROBE         0x08
                     63: #define        ACPI_DBGR_RUNNING       0x10
                     64:
                     65: int    acpi_dbgr = 0x00;
                     66: #endif
                     67:
                     68: int    acpi_match(struct device *, struct cfdata *, void *);
                     69: void   acpi_attach(struct device *, struct device *, void *);
                     70:
                     71: int    acpi_print(void *aux, const char *);
                     72:
                     73: extern struct cfdriver acpi_cd;
                     74:
                     75: struct cfattach acpi_ca = {
                     76:        sizeof(struct acpi_softc), acpi_match, acpi_attach,
                     77: };
                     78:
                     79: /*
                     80:  * This is a flag we set when the ACPI subsystem is active.  Machine
                     81:  * dependent code may wish to skip other steps (such as attaching
                     82:  * subsystems that ACPI supercedes) when ACPI is active.
                     83:  */
                     84: int    acpi_active;
                     85:
                     86: /*
                     87:  * Pointer to the ACPI subsystem's state.  There can be only
                     88:  * one ACPI instance.
                     89:  */
                     90: struct acpi_softc *acpi_softc;
                     91:
                     92: void           acpi_shutdown(void *);
                     93: ACPI_STATUS    acpi_disable(struct acpi_softc *sc);
                     94: void           acpi_build_tree(struct acpi_softc *);
                     95: ACPI_STATUS    acpi_make_devnode(ACPI_HANDLE, UINT32, void *, void **);
                     96:
                     97: void           acpi_enable_fixed_events(struct acpi_softc *);
                     98:
                     99: /*
                    100:  * acpi_probe:
                    101:  *
                    102:  *     Probe for ACPI support.  This is called by the
                    103:  *     machine-dependent ACPI front-end.  All of the
                    104:  *     actual work is done by ACPICA.
                    105:  *
                    106:  *     NOTE: This is not an autoconfiguration interface function.
                    107:  */
                    108: int
                    109: acpi_probe(void)
                    110: {
                    111:        static int beenhere;
                    112:        ACPI_STATUS rv;
                    113:
                    114:        if (beenhere != 0)
                    115:                panic("acpi_probe: ACPI has already been probed");
                    116:        beenhere = 1;
                    117:
                    118:        /*
                    119:         * Start up ACPICA.
                    120:         */
                    121: #ifdef ENABLE_DEBUGGER
                    122:        if (acpi_dbgr & ACPI_DBGR_INIT)
                    123:                acpi_osd_debugger();
                    124: #endif
                    125:
                    126:        rv = AcpiInitializeSubsystem();
                    127:        if (rv != AE_OK) {
                    128:                printf("ACPI: unable to initialize ACPICA: %d\n", rv);
                    129:                return (0);
                    130:        }
                    131:
                    132: #ifdef ENABLE_DEBUGGER
                    133:        if (acpi_dbgr & ACPI_DBGR_TABLES)
                    134:                acpi_osd_debugger();
                    135: #endif
                    136:
                    137:        rv = AcpiLoadTables();
                    138:        if (rv != AE_OK) {
                    139:                printf("ACPI: unable to load tables: %d\n", rv);
                    140:                return (0);
                    141:        }
                    142:
                    143:        /*
                    144:         * Looks like we have ACPI!
                    145:         */
                    146:
                    147:        return (1);
                    148: }
                    149:
                    150: /*
                    151:  * acpi_match:
                    152:  *
                    153:  *     Autoconfiguration `match' routine.
                    154:  */
                    155: int
                    156: acpi_match(struct device *parent, struct cfdata *match, void *aux)
                    157: {
                    158:        struct acpibus_attach_args *aa = aux;
                    159:
                    160:        if (strcmp(aa->aa_busname, acpi_cd.cd_name) != 0)
                    161:                return (0);
                    162:
                    163:        /*
                    164:         * XXX Check other locators?  Hard to know -- machine
                    165:         * dependent code has already checked for the presence
                    166:         * of ACPI by calling acpi_probe(), so I suppose we
                    167:         * don't really have to do anything else.
                    168:         */
                    169:        return (1);
                    170: }
                    171:
                    172: /*
                    173:  * acpi_attach:
                    174:  *
                    175:  *     Autoconfiguration `attach' routine.  Finish initializing
                    176:  *     ACPICA (some initialization was done in acpi_probe(),
                    177:  *     which was required to check for the presence of ACPI),
                    178:  *     and enable the ACPI subsystem.
                    179:  */
                    180: void
                    181: acpi_attach(struct device *parent, struct device *self, void *aux)
                    182: {
                    183:        struct acpi_softc *sc = (void *) self;
                    184:        struct acpibus_attach_args *aa = aux;
                    185:        ACPI_STATUS rv;
                    186:
                    187:        printf("\n");
                    188:
                    189:        if (acpi_softc != NULL)
                    190:                panic("acpi_attach: ACPI has already been attached");
                    191:
                    192:        sc->sc_iot = aa->aa_iot;
                    193:        sc->sc_memt = aa->aa_memt;
                    194:        sc->sc_pc = aa->aa_pc;
                    195:        sc->sc_pciflags = aa->aa_pciflags;
                    196:
                    197:        acpi_softc = sc;
                    198:
                    199:        /*
                    200:         * Install the default address space handlers.
                    201:         */
                    202:
                    203:        rv = AcpiInstallAddressSpaceHandler(ACPI_ROOT_OBJECT,
                    204:            ACPI_ADR_SPACE_SYSTEM_MEMORY, ACPI_DEFAULT_HANDLER, NULL, NULL);
                    205:        if (rv != AE_OK) {
                    206:                printf("%s: unable to install SYSTEM MEMORY handler: %d\n",
                    207:                    sc->sc_dev.dv_xname, rv);
                    208:                return;
                    209:        }
                    210:
                    211:        rv = AcpiInstallAddressSpaceHandler(ACPI_ROOT_OBJECT,
                    212:            ACPI_ADR_SPACE_SYSTEM_IO, ACPI_DEFAULT_HANDLER, NULL, NULL);
                    213:        if (rv != AE_OK) {
                    214:                printf("%s: unable to install SYSTEM IO handler: %d\n",
                    215:                    sc->sc_dev.dv_xname, rv);
                    216:                return;
                    217:        }
                    218:
                    219:        rv = AcpiInstallAddressSpaceHandler(ACPI_ROOT_OBJECT,
                    220:            ACPI_ADR_SPACE_PCI_CONFIG, ACPI_DEFAULT_HANDLER, NULL, NULL);
                    221:        if (rv != AE_OK) {
                    222:                printf("%s: unable to install PCI CONFIG handler: %d\n",
                    223:                    sc->sc_dev.dv_xname, rv);
                    224:                return;
                    225:        }
                    226:
                    227:        /*
                    228:         * Bring ACPI on-line.
                    229:         *
                    230:         * Note that we request that _STA (device init) and _INI (object init)
                    231:         * methods not be run.
                    232:         *
                    233:         * XXX We need to arrange for the object init pass after we have
                    234:         * XXX attached all of our children.
                    235:         */
                    236: #ifdef ENABLE_DEBUGGER
                    237:        if (acpi_dbgr & ACPI_DBGR_ENABLE)
                    238:                acpi_osd_debugger();
                    239: #endif
                    240:        rv = AcpiEnableSubsystem(ACPI_NO_DEVICE_INIT | ACPI_NO_OBJECT_INIT);
                    241:        if (rv != AE_OK) {
                    242:                printf("%s: unable to enable ACPI: %d\n",
                    243:                    sc->sc_dev.dv_xname, rv);
                    244:                return;
                    245:        }
                    246:        acpi_active = 1;
                    247:
                    248:        /*
                    249:         * Set up the default sleep state to enter when various
                    250:         * switches are activated.
                    251:         */
                    252:        sc->sc_switch_sleep[ACPI_SWITCH_POWERBUTTON] = ACPI_STATE_S5;
                    253:        sc->sc_switch_sleep[ACPI_SWITCH_SLEEPBUTTON] = ACPI_STATE_S1;
                    254:        sc->sc_switch_sleep[ACPI_SWITCH_LID]         = ACPI_STATE_S1;
                    255:
                    256:        /* Our current state is "awake". */
                    257:        sc->sc_sleepstate = ACPI_STATE_S0;
                    258:
1.9       kanaoka   259:        /* Show SCI interrupt. */
                    260:        if (AcpiGbl_FADT != NULL)
                    261:                printf("%s: SCI interrupting at irq %d\n",
                    262:                        sc->sc_dev.dv_xname, AcpiGbl_FADT->SciInt);
1.1       thorpej   263:        /*
                    264:         * Check for fixed-hardware features.
                    265:         */
                    266:        acpi_enable_fixed_events(sc);
                    267:
                    268:        /*
                    269:         * Scan the namespace and build our device tree.
                    270:         */
                    271: #ifdef ENABLE_DEBUGGER
                    272:        if (acpi_dbgr & ACPI_DBGR_PROBE)
                    273:                acpi_osd_debugger();
                    274: #endif
                    275:        acpi_build_tree(sc);
                    276:
                    277:        /*
                    278:         * Register a shutdown hook that disables certain ACPI
                    279:         * events that might happen and confuse us while we're
                    280:         * trying to shut down.
                    281:         */
                    282:        sc->sc_sdhook = shutdownhook_establish(acpi_shutdown, sc);
                    283:        if (sc->sc_sdhook == NULL)
                    284:                printf("%s: WARNING: unable to register shutdown hook\n",
                    285:                    sc->sc_dev.dv_xname);
                    286:
                    287: #ifdef ENABLE_DEBUGGER
                    288:        if (acpi_dbgr & ACPI_DBGR_RUNNING)
                    289:                acpi_osd_debugger();
                    290: #endif
                    291: }
                    292:
                    293: /*
                    294:  * acpi_shutdown:
                    295:  *
                    296:  *     Shutdown hook for ACPI -- disable some events that
                    297:  *     might confuse us.
                    298:  */
                    299: void
                    300: acpi_shutdown(void *arg)
                    301: {
                    302:        struct acpi_softc *sc = arg;
                    303:
                    304:        if (acpi_disable(sc) != AE_OK)
                    305:                printf("%s: WARNING: unable to disable ACPI\n",
                    306:                    sc->sc_dev.dv_xname);
                    307: }
                    308:
                    309: /*
                    310:  * acpi_disable:
                    311:  *
                    312:  *     Disable ACPI.
                    313:  */
                    314: ACPI_STATUS
                    315: acpi_disable(struct acpi_softc *sc)
                    316: {
                    317:        ACPI_STATUS rv = AE_OK;
                    318:
                    319:        if (acpi_active) {
                    320:                rv = AcpiDisable();
                    321:                if (rv == AE_OK)
                    322:                        acpi_active = 0;
                    323:        }
                    324:        return (rv);
                    325: }
                    326:
                    327: struct acpi_make_devnode_state {
                    328:        struct acpi_softc *softc;
                    329:        struct acpi_scope *scope;
                    330: };
                    331:
                    332: /*
                    333:  * acpi_build_tree:
                    334:  *
                    335:  *     Scan relevant portions of the ACPI namespace and attach
                    336:  *     child devices.
                    337:  */
                    338: void
                    339: acpi_build_tree(struct acpi_softc *sc)
                    340: {
                    341:        static const char *scopes[] = {
                    342:                "\\_PR_",       /* ACPI 1.0 processor namespace */
                    343:                "\\_SB_",       /* system bus namespace */
                    344:                "\\_SI_",       /* system idicator namespace */
                    345:                "\\_TZ_",       /* ACPI 1.0 thermal zone namespace */
                    346:                NULL,
                    347:        };
                    348:        struct acpi_attach_args aa;
                    349:        struct acpi_make_devnode_state state;
                    350:        struct acpi_scope *as;
                    351:        struct acpi_devnode *ad;
                    352:        ACPI_HANDLE parent;
                    353:        int i;
                    354:
                    355:        TAILQ_INIT(&sc->sc_scopes);
                    356:
                    357:        state.softc = sc;
                    358:
                    359:        /*
                    360:         * Scan the namespace and build our tree.
                    361:         */
                    362:        for (i = 0; scopes[i] != NULL; i++) {
                    363:                as = malloc(sizeof(*as), M_DEVBUF, M_WAITOK);
                    364:                as->as_name = scopes[i];
                    365:                TAILQ_INIT(&as->as_devnodes);
                    366:
                    367:                TAILQ_INSERT_TAIL(&sc->sc_scopes, as, as_list);
                    368:
                    369:                state.scope = as;
                    370:
                    371:                if (AcpiGetHandle(ACPI_ROOT_OBJECT, (char *) scopes[i],
                    372:                    &parent) == AE_OK) {
                    373:                        AcpiWalkNamespace(ACPI_TYPE_ANY, parent, 100,
                    374:                            acpi_make_devnode, &state, NULL);
                    375:                }
                    376:
                    377:                /* Now, for this namespace, try and attach the devices. */
                    378:                TAILQ_FOREACH(ad, &as->as_devnodes, ad_list) {
                    379:                        aa.aa_node = ad;
                    380:                        aa.aa_iot = sc->sc_iot;
                    381:                        aa.aa_memt = sc->sc_memt;
                    382:                        aa.aa_pc = sc->sc_pc;
                    383:                        aa.aa_pciflags = sc->sc_pciflags;
                    384:
                    385:                        /*
                    386:                         * XXX We only attach devices which are:
                    387:                         *
                    388:                         *      - present
                    389:                         *      - enabled
                    390:                         *      - functioning properly
                    391:                         *
                    392:                         * However, if enabled, it's decoding resources,
                    393:                         * so we should claim them, if possible.  Requires
                    394:                         * changes to bus_space(9).
                    395:                         */
                    396:                        if ((ad->ad_devinfo.CurrentStatus &
                    397:                             (ACPI_STA_DEV_PRESENT|ACPI_STA_DEV_ENABLED|
1.9       kanaoka   398:                              ACPI_STA_DEV_OK)) !=
1.1       thorpej   399:                            (ACPI_STA_DEV_PRESENT|ACPI_STA_DEV_ENABLED|
1.9       kanaoka   400:                             ACPI_STA_DEV_OK))
1.1       thorpej   401:                                continue;
                    402:
                    403:                        /*
                    404:                         * XXX Same problem as above...
                    405:                         */
                    406:                        if ((ad->ad_devinfo.Valid & ACPI_VALID_HID) == 0)
                    407:                                continue;
                    408:
                    409:                        ad->ad_device = config_found(&sc->sc_dev,
                    410:                            &aa, acpi_print);
                    411:                }
                    412:        }
                    413: }
                    414:
                    415: /*
                    416:  * acpi_make_devnode:
                    417:  *
                    418:  *     Make an ACPI devnode.
                    419:  */
                    420: ACPI_STATUS
                    421: acpi_make_devnode(ACPI_HANDLE handle, UINT32 level, void *context,
                    422:     void **status)
                    423: {
                    424:        struct acpi_make_devnode_state *state = context;
1.4       thorpej   425: #ifdef ACPI_DEBUG
1.1       thorpej   426:        struct acpi_softc *sc = state->softc;
1.4       thorpej   427: #endif
1.1       thorpej   428:        struct acpi_scope *as = state->scope;
                    429:        struct acpi_devnode *ad;
                    430:        ACPI_OBJECT_TYPE type;
                    431:        ACPI_STATUS rv;
                    432:
                    433:        if (AcpiGetType(handle, &type) == AE_OK) {
                    434:                switch (type) {
                    435:                case ACPI_TYPE_DEVICE:
                    436:                case ACPI_TYPE_PROCESSOR:
                    437:                case ACPI_TYPE_THERMAL:
                    438:                case ACPI_TYPE_POWER:
1.6       tsutsui   439:                        ad = malloc(sizeof(*ad), M_DEVBUF, M_NOWAIT|M_ZERO);
1.1       thorpej   440:                        if (ad == NULL)
                    441:                                return (AE_NO_MEMORY);
                    442:
                    443:                        ad->ad_handle = handle;
                    444:                        ad->ad_level = level;
                    445:                        ad->ad_scope = as;
                    446:                        ad->ad_type = type;
                    447:
                    448:                        TAILQ_INSERT_TAIL(&as->as_devnodes, ad, ad_list);
                    449:
                    450:                        rv = AcpiGetObjectInfo(handle, &ad->ad_devinfo);
                    451:                        if (rv != AE_OK)
                    452:                                goto out;
                    453:
                    454:                        if ((ad->ad_devinfo.Valid & ACPI_VALID_HID) == 0)
                    455:                                goto out;
                    456:
                    457: #ifdef ACPI_DEBUG
                    458:                        printf("%s: HID %s found in scope %s level %d\n",
                    459:                            sc->sc_dev.dv_xname, ad->ad_devinfo.HardwareId,
                    460:                            as->as_name, ad->ad_level);
                    461:                        if (ad->ad_devinfo.Valid & ACPI_VALID_UID)
                    462:                                printf("       UID %s\n",
                    463:                                    ad->ad_devinfo.UniqueId);
                    464:                        if (ad->ad_devinfo.Valid & ACPI_VALID_ADR)
                    465:                                printf("       ADR 0x%016qx\n",
                    466:                                    ad->ad_devinfo.Address);
                    467:                        if (ad->ad_devinfo.Valid & ACPI_VALID_STA)
                    468:                                printf("       STA 0x%08x\n",
                    469:                                    ad->ad_devinfo.CurrentStatus);
                    470: #endif
                    471:                }
                    472:        }
                    473:  out:
                    474:        return (AE_OK);
                    475: }
                    476:
                    477: /*
                    478:  * acpi_print:
                    479:  *
                    480:  *     Autoconfiguration print routine.
                    481:  */
                    482: int
                    483: acpi_print(void *aux, const char *pnp)
                    484: {
                    485:        struct acpi_attach_args *aa = aux;
1.7       sommerfe  486: #if 0
1.4       thorpej   487:        char *str;
1.7       sommerfe  488: #endif
1.1       thorpej   489:
1.4       thorpej   490:        if (pnp) {
                    491:                printf("%s ", aa->aa_node->ad_devinfo.HardwareId);
1.7       sommerfe  492: #if 0 /* Not until we fix acpi_eval_string */
1.4       thorpej   493:                if (acpi_eval_string(aa->aa_node->ad_handle,
                    494:                    "_STR", &str) == AE_OK) {
                    495:                        printf("[%s] ", str);
                    496:                        AcpiOsFree(str);
                    497:                }
1.7       sommerfe  498: #endif
1.4       thorpej   499:                printf("at %s", pnp);
                    500:        }
1.1       thorpej   501:
                    502:        return (UNCONF);
                    503: }
                    504:
                    505: /*****************************************************************************
                    506:  * ACPI fixed-hardware feature handlers
                    507:  *****************************************************************************/
                    508:
                    509: UINT32         acpi_fixed_power_button_handler(void *);
                    510: UINT32         acpi_fixed_sleep_button_handler(void *);
                    511:
                    512: /*
                    513:  * acpi_enable_fixed_events:
                    514:  *
                    515:  *     Enable any fixed-hardware feature handlers.
                    516:  */
                    517: void
                    518: acpi_enable_fixed_events(struct acpi_softc *sc)
                    519: {
                    520:        static int beenhere;
                    521:        ACPI_STATUS rv;
                    522:
                    523:        /*
                    524:         * Check for fixed-hardware buttons.
                    525:         */
                    526:
                    527:        if (AcpiGbl_FADT != NULL && AcpiGbl_FADT->PwrButton == 0) {
                    528:                if (beenhere == 0)
                    529:                        printf("%s: fixed-feature power button present\n",
                    530:                            sc->sc_dev.dv_xname);
                    531:                rv = AcpiInstallFixedEventHandler(ACPI_EVENT_POWER_BUTTON,
                    532:                    acpi_fixed_power_button_handler, sc);
                    533:                if (rv != AE_OK)
                    534:                        printf("%s: unable to install handler for fixed "
                    535:                            "power button: %d\n", sc->sc_dev.dv_xname, rv);
                    536:        }
                    537:
                    538:        if (AcpiGbl_FADT != NULL && AcpiGbl_FADT->SleepButton == 0) {
                    539:                if (beenhere == 0)
                    540:                        printf("%s: fixed-feature sleep button present\n",
                    541:                            sc->sc_dev.dv_xname);
                    542:                rv = AcpiInstallFixedEventHandler(ACPI_EVENT_SLEEP_BUTTON,
                    543:                    acpi_fixed_sleep_button_handler, sc);
                    544:                if (rv != AE_OK)
                    545:                        printf("%s: unable to install handler for fixed "
                    546:                            "power button: %d\n", sc->sc_dev.dv_xname, rv);
                    547:        }
                    548:
                    549:        beenhere = 1;
                    550: }
                    551:
                    552: /*
                    553:  * acpi_fixed_power_button_handler:
                    554:  *
                    555:  *     Fixed event handler for the power button.
                    556:  */
                    557: UINT32
                    558: acpi_fixed_power_button_handler(void *context)
                    559: {
                    560:        struct acpi_softc *sc = context;
                    561:
                    562:        /* XXX XXX XXX */
                    563:
                    564:        printf("%s: fixed power button pressed\n", sc->sc_dev.dv_xname);
                    565:
1.8       thorpej   566:        return (ACPI_INTERRUPT_HANDLED);
1.1       thorpej   567: }
                    568:
                    569: /*
                    570:  * acpi_fixed_sleep_button_handler:
                    571:  *
                    572:  *     Fixed event handler for the sleep button.
                    573:  */
                    574: UINT32
                    575: acpi_fixed_sleep_button_handler(void *context)
                    576: {
                    577:        struct acpi_softc *sc = context;
                    578:
                    579:        /* XXX XXX XXX */
                    580:
                    581:        printf("%s: fixed sleep button pressed\n", sc->sc_dev.dv_xname);
                    582:
1.8       thorpej   583:        return (ACPI_INTERRUPT_HANDLED);
1.1       thorpej   584: }
                    585:
                    586: /*****************************************************************************
                    587:  * ACPI utility routines.
                    588:  *****************************************************************************/
                    589:
1.2       thorpej   590: /*
                    591:  * acpi_eval_integer:
                    592:  *
                    593:  *     Evaluate an integer object.
                    594:  */
1.1       thorpej   595: ACPI_STATUS
                    596: acpi_eval_integer(ACPI_HANDLE handle, char *path, int *valp)
                    597: {
                    598:        ACPI_STATUS rv;
                    599:        ACPI_BUFFER buf;
                    600:        ACPI_OBJECT param;
                    601:
                    602:        if (handle == NULL)
                    603:                handle = ACPI_ROOT_OBJECT;
                    604:
                    605:        buf.Pointer = &param;
                    606:        buf.Length = sizeof(param);
                    607:
                    608:        rv = AcpiEvaluateObject(handle, path, NULL, &buf);
                    609:        if (rv == AE_OK) {
                    610:                if (param.Type == ACPI_TYPE_INTEGER)
                    611:                        *valp = param.Integer.Value;
                    612:                else
                    613:                        rv = AE_TYPE;
                    614:        }
                    615:
1.4       thorpej   616:        return (rv);
                    617: }
                    618:
1.7       sommerfe  619: #if 0
1.4       thorpej   620: /*
                    621:  * acpi_eval_string:
                    622:  *
1.7       sommerfe  623:  *     Evaluate a (Unicode) string object.
                    624:  * XXX current API may leak memory, so don't use this.
1.4       thorpej   625:  */
                    626: ACPI_STATUS
                    627: acpi_eval_string(ACPI_HANDLE handle, char *path, char **stringp)
                    628: {
                    629:        ACPI_STATUS rv;
                    630:        ACPI_BUFFER buf;
1.7       sommerfe  631:        ACPI_OBJECT *param;
1.4       thorpej   632:
                    633:        if (handle == NULL)
                    634:                handle = ACPI_ROOT_OBJECT;
                    635:
                    636:        buf.Pointer = NULL;
                    637:        buf.Length = 0;
                    638:
                    639:        rv = AcpiEvaluateObject(handle, path, NULL, &buf);
                    640:        if (rv != AE_BUFFER_OVERFLOW)
                    641:                return (rv);
                    642:
                    643:        buf.Pointer = AcpiOsAllocate(buf.Length);
                    644:        if (buf.Pointer == NULL)
                    645:                return (AE_NO_MEMORY);
                    646:
                    647:        rv = AcpiEvaluateObject(handle, path, NULL, &buf);
1.7       sommerfe  648:        param = (ACPI_OBJECT *)buf.Pointer;
1.4       thorpej   649:        if (rv == AE_OK) {
1.7       sommerfe  650:                if (param->Type == ACPI_TYPE_STRING) {
                    651:                        /* XXX may leak buf.Pointer!! */
                    652:                        *stringp = param->String.Pointer;
1.4       thorpej   653:                        return (AE_OK);
                    654:                }
                    655:                rv = AE_TYPE;
                    656:        }
                    657:
                    658:        AcpiOsFree(buf.Pointer);
1.7       sommerfe  659:        return (rv);
                    660: }
                    661: #endif
                    662:
                    663:
                    664: /*
                    665:  * acpi_eval_struct:
                    666:  *
                    667:  *     Evaluate a more complex structure.  Caller must free buf.Pointer.
                    668:  */
                    669: ACPI_STATUS
                    670: acpi_eval_struct(ACPI_HANDLE handle, char *path, ACPI_BUFFER *bufp)
                    671: {
                    672:        ACPI_STATUS rv;
                    673:
                    674:        if (handle == NULL)
                    675:                handle = ACPI_ROOT_OBJECT;
                    676:
                    677:        bufp->Pointer = NULL;
                    678:        bufp->Length = 0;
                    679:
                    680:        rv = AcpiEvaluateObject(handle, path, NULL, bufp);
                    681:        if (rv != AE_BUFFER_OVERFLOW)
                    682:                return (rv);
                    683:
                    684:        bufp->Pointer = AcpiOsAllocate(bufp->Length);
                    685:        if (bufp->Pointer == NULL)
                    686:                return (AE_NO_MEMORY);
                    687:
                    688:        rv = AcpiEvaluateObject(handle, path, NULL, bufp);
                    689:
1.1       thorpej   690:        return (rv);
1.2       thorpej   691: }
                    692:
                    693: /*
                    694:  * acpi_get:
                    695:  *
                    696:  *     Fetch data info the specified (empty) ACPI buffer.
                    697:  */
                    698: ACPI_STATUS
                    699: acpi_get(ACPI_HANDLE handle, ACPI_BUFFER *buf,
                    700:     ACPI_STATUS (*getit)(ACPI_HANDLE, ACPI_BUFFER *))
                    701: {
                    702:        ACPI_STATUS rv;
                    703:
                    704:        buf->Pointer = NULL;
                    705:        buf->Length = 0;
                    706:
                    707:        rv = (*getit)(handle, buf);
                    708:        if (rv != AE_BUFFER_OVERFLOW)
                    709:                return (rv);
                    710:
1.8       thorpej   711:        buf->Pointer = AcpiOsAllocate(buf->Length);
1.2       thorpej   712:        if (buf->Pointer == NULL)
                    713:                return (AE_NO_MEMORY);
1.8       thorpej   714:        memset(buf->Pointer, 0, buf->Length);
1.2       thorpej   715:
                    716:        return ((*getit)(handle, buf));
1.10    ! tshiozak  717: }
        !           718:
        !           719:
        !           720: /*****************************************************************************
        !           721:  * ACPI sleep support.
        !           722:  *****************************************************************************/
        !           723:
        !           724: static int
        !           725: is_available_state(struct acpi_softc *sc, int state)
        !           726: {
        !           727:        UINT8 type_a, type_b;
        !           728:
        !           729:        return (ACPI_SUCCESS(AcpiGetSleepTypeData((UINT8)state,
        !           730:                                                  &type_a, &type_b)));
        !           731: }
        !           732:
        !           733: /*
        !           734:  * acpi_enter_sleep_state:
        !           735:  *
        !           736:  *     enter to the specified sleep state.
        !           737:  */
        !           738:
        !           739: ACPI_STATUS
        !           740: acpi_enter_sleep_state(struct acpi_softc *sc, int state)
        !           741: {
        !           742:        int s;
        !           743:        ACPI_STATUS ret = AE_OK;
        !           744:
        !           745:        switch (state) {
        !           746:        case ACPI_STATE_S0:
        !           747:                break;
        !           748:        case ACPI_STATE_S1:
        !           749:        case ACPI_STATE_S2:
        !           750:        case ACPI_STATE_S3:
        !           751:        case ACPI_STATE_S4:
        !           752:                if (!is_available_state(sc, state)) {
        !           753:                        printf("acpi: cannot enter the sleep state (%d).\n",
        !           754:                               state);
        !           755:                        break;
        !           756:                }
        !           757:                ret = AcpiEnterSleepStatePrep(state);
        !           758:                if (ACPI_FAILURE(ret)) {
        !           759:                        printf("acpi: failed preparing to sleep (%s)\n",
        !           760:                               AcpiFormatException(ret));
        !           761:                        break;
        !           762:                }
        !           763:                if (state==ACPI_STATE_S1) {
        !           764:                        /* just enter the state */
        !           765:                        AcpiEnterSleepState((UINT8)state);
        !           766:                        AcpiUtReleaseMutex(ACPI_MTX_HARDWARE);
        !           767:                } else {
        !           768:                        /* XXX: powerhooks(9) framework is too poor to
        !           769:                         * support ACPI sleep state...
        !           770:                         */
        !           771:                        dopowerhooks(PWR_SOFTSUSPEND);
        !           772:                        s = splhigh();
        !           773:                        dopowerhooks(PWR_SUSPEND);
        !           774:                        acpi_md_sleep(state);
        !           775:                        dopowerhooks(PWR_RESUME);
        !           776:                        splx(s);
        !           777:                        dopowerhooks(PWR_SOFTRESUME);
        !           778:                        if (state==ACPI_STATE_S4)
        !           779:                                AcpiEnable();
        !           780:                }
        !           781:                AcpiLeaveSleepState((UINT8)state);
        !           782:                break;
        !           783:        case ACPI_STATE_S5:
        !           784:                AcpiEnterSleepStatePrep(ACPI_STATE_S5);
        !           785:                AcpiEnterSleepState(ACPI_STATE_S5);
        !           786:                printf("WARNING: powerdown failed!\n");
        !           787:                break;
        !           788:        }
        !           789:
        !           790:        return_ACPI_STATUS(ret);
1.1       thorpej   791: }

CVSweb <webmaster@jp.NetBSD.org>