[BACK]Return to acpidock.c CVS log [TXT][DIR] Up to [local] / sys / dev / acpi

Annotation of sys/dev/acpi/acpidock.c, Revision 1.1.1.1

1.1       nbrk        1: /* $OpenBSD: acpidock.c,v 1.25 2007/04/23 19:29:03 mk 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/acpireg.h>
                     27: #include <dev/acpi/acpivar.h>
                     28: #include <dev/acpi/acpidev.h>
                     29: #include <dev/acpi/amltypes.h>
                     30: #include <dev/acpi/dsdt.h>
                     31:
                     32: struct aml_nodelist {
                     33:        struct aml_node *node;
                     34:        TAILQ_ENTRY(aml_nodelist) entries;
                     35: };
                     36:
                     37: int    acpidock_match(struct device *, void *, void *);
                     38: void   acpidock_attach(struct device *, struct device *, void *);
                     39:
                     40: struct cfattach acpidock_ca = {
                     41:        sizeof(struct acpidock_softc), acpidock_match, acpidock_attach
                     42: };
                     43:
                     44: struct cfdriver acpidock_cd = {
                     45:        NULL, "acpidock", DV_DULL
                     46: };
                     47:
                     48:
                     49: int    acpidock_docklock(struct acpidock_softc *, int);
                     50: int    acpidock_dockctl(struct acpidock_softc *, int);
                     51: int    acpidock_eject(struct acpidock_softc *, struct aml_node *);
                     52: int    acpidock_notify(struct aml_node *, int, void *);
                     53: int    acpidock_status(struct acpidock_softc *);
                     54:
                     55: void   acpidock_foundejd(struct aml_node *, void *);
                     56:
                     57: int
                     58: acpidock_match(struct device *parent, void *match, void *aux)
                     59: {
                     60:        struct acpi_attach_args  *aaa = aux;
                     61:        struct cfdata            *cf = match;
                     62:
                     63:        /* sanity */
                     64:        if (aaa->aaa_name == NULL ||
                     65:            strcmp(aaa->aaa_name, cf->cf_driver->cd_name) != 0 ||
                     66:            aaa->aaa_table != NULL)
                     67:                return (0);
                     68:
                     69:        return (1);
                     70: }
                     71:
                     72: void
                     73: acpidock_attach(struct device *parent, struct device *self, void *aux)
                     74: {
                     75:        struct acpidock_softc   *sc = (struct acpidock_softc *)self;
                     76:        struct acpi_attach_args *aa = aux;
                     77:        extern struct aml_node  aml_root;
                     78:
                     79:        sc->sc_acpi = (struct acpi_softc *)parent;
                     80:        sc->sc_devnode = aa->aaa_node->child;
                     81:
                     82:        printf(": %s", sc->sc_devnode->parent->name);
                     83:
                     84:        acpidock_status(sc);
                     85:        if (sc->sc_docked == ACPIDOCK_STATUS_DOCKED) {
                     86:                acpidock_docklock(sc, 1);
                     87:                acpidock_dockctl(sc, 1);
                     88:        } else {
                     89:                acpidock_dockctl(sc, 0);
                     90:                acpidock_docklock(sc, 0);
                     91:        }
                     92:
                     93:        acpidock_status(sc);
                     94:        printf(":%s docked (%d)\n",
                     95:            sc->sc_docked == ACPIDOCK_STATUS_DOCKED ? "" : " not",
                     96:            sc->sc_sta);
                     97:
                     98:        strlcpy(sc->sc_sensdev.xname, DEVNAME(sc),
                     99:            sizeof(sc->sc_sensdev.xname));
                    100:        if (sc->sc_docked)
                    101:                strlcpy(sc->sc_sens.desc, "docked",
                    102:                    sizeof(sc->sc_sens.desc));
                    103:        else
                    104:                strlcpy(sc->sc_sens.desc, "not docked",
                    105:                    sizeof(sc->sc_sens.desc));
                    106:
                    107:        sc->sc_sens.type = SENSOR_INDICATOR;
                    108:        sc->sc_sens.value = sc->sc_docked == ACPIDOCK_STATUS_DOCKED;
                    109:        sensor_attach(&sc->sc_sensdev, &sc->sc_sens);
                    110:        sensordev_install(&sc->sc_sensdev);
                    111:
                    112:        TAILQ_INIT(&sc->sc_deps_h);
                    113:        aml_find_node(aml_root.child, "_EJD", acpidock_foundejd, sc);
                    114:
                    115:        aml_register_notify(sc->sc_devnode->parent, aa->aaa_dev,
                    116:            acpidock_notify, sc, ACPIDEV_NOPOLL);
                    117:
                    118: }
                    119:
                    120: int
                    121: acpidock_status(struct acpidock_softc *sc)
                    122: {
                    123:        struct aml_value        res;
                    124:        int                     rv;
                    125:
                    126:        if (aml_evalname(sc->sc_acpi, sc->sc_devnode, "_STA", 0, NULL,
                    127:            &res) != 0)
                    128:                rv = 0;
                    129:        else
                    130:                rv = 1;
                    131:
                    132:        sc->sc_sta = aml_val2int(&res);
                    133:
                    134:        sc->sc_docked = sc->sc_sta & STA_PRESENT;
                    135:
                    136:        aml_freevalue(&res);
                    137:
                    138:        return (rv);
                    139: }
                    140:
                    141: int
                    142: acpidock_docklock(struct acpidock_softc *sc, int lock)
                    143: {
                    144:        struct aml_value        cmd;
                    145:        struct aml_value        res;
                    146:        int rv;
                    147:
                    148:        memset(&cmd, 0, sizeof cmd);
                    149:        cmd.v_integer = lock;
                    150:        cmd.type = AML_OBJTYPE_INTEGER;
                    151:        if (aml_evalname(sc->sc_acpi, sc->sc_devnode, "_LCK", 1, &cmd,
                    152:            &res) != 0) {
                    153:                dnprintf(20, "%s: _LCK %d failed\n", DEVNAME(sc), lock);
                    154:
                    155:                rv = 0;
                    156:        } else {
                    157:                dnprintf(20, "%s: _LCK %d successful\n", DEVNAME(sc), lock);
                    158:
                    159:                rv = 1;
                    160:        }
                    161:
                    162:        aml_freevalue(&res);
                    163:
                    164:        return rv;
                    165: }
                    166:
                    167: int
                    168: acpidock_dockctl(struct acpidock_softc *sc, int dock)
                    169: {
                    170:        struct aml_value        cmd;
                    171:        struct aml_value        res;
                    172:        int rv;
                    173:
                    174:        memset(&cmd, 0, sizeof cmd);
                    175:        cmd.v_integer = dock;
                    176:        cmd.type = AML_OBJTYPE_INTEGER;
                    177:        if (aml_evalname(sc->sc_acpi, sc->sc_devnode, "_DCK", 1, &cmd,
                    178:            &res) != 0) {
                    179:                /* XXX */
                    180:                dnprintf(15, "%s: _DCK %d failed\n", DEVNAME(sc), dock);
                    181:
                    182:                rv = 0;
                    183:        } else {
                    184:                dnprintf(15, "%s: _DCK %d successful\n", DEVNAME(sc), dock);
                    185:
                    186:                rv = 1;
                    187:        }
                    188:
                    189:        aml_freevalue(&res);
                    190:
                    191:        return rv;
                    192: }
                    193:
                    194: int
                    195: acpidock_eject(struct acpidock_softc *sc, struct aml_node *node)
                    196: {
                    197:        struct aml_value        cmd;
                    198:        struct aml_value        res;
                    199:        int rv;
                    200:
                    201:        memset(&cmd, 0, sizeof cmd);
                    202:        cmd.v_integer = 1;
                    203:        cmd.type = AML_OBJTYPE_INTEGER;
                    204:        if (aml_evalname(sc->sc_acpi, node, "_EJ0", 1, &cmd,
                    205:            &res) != 0) {
                    206:                /* XXX */
                    207:                dnprintf(15, "%s: _EJ0 failed\n", DEVNAME(sc));
                    208:
                    209:                rv = 0;
                    210:        } else {
                    211:                dnprintf(15, "%s: _EJ0 successful\n", DEVNAME(sc));
                    212:
                    213:                rv = 1;
                    214:        }
                    215:
                    216:        aml_freevalue(&res);
                    217:
                    218:        return rv;
                    219: }
                    220:
                    221: int
                    222: acpidock_notify(struct aml_node *node, int notify_type, void *arg)
                    223: {
                    224:        struct acpidock_softc   *sc = arg;
                    225:
                    226:        dnprintf(5, "%s: acpidock_notify: notify %d\n", DEVNAME(sc),
                    227:            notify_type);
                    228:
                    229:        switch (notify_type) {
                    230:        case ACPIDOCK_EVENT_INSERT:
                    231:                printf("%s: dock", DEVNAME(sc));
                    232:                acpidock_docklock(sc, 1);
                    233:                acpidock_dockctl(sc, 1);
                    234:
                    235:                break;
                    236:        case ACPIDOCK_EVENT_EJECT: {
                    237:                struct aml_nodelist *n;
                    238:
                    239:                TAILQ_FOREACH(n, &sc->sc_deps_h, entries)
                    240:                        acpidock_eject(sc, n->node);
                    241:
                    242:                acpidock_dockctl(sc, 0);
                    243:                acpidock_docklock(sc, 0);
                    244:
                    245:                /* now actually undock */
                    246:                acpidock_eject(sc, sc->sc_devnode);
                    247:
                    248:                printf("%s: undock", DEVNAME(sc));
                    249:
                    250:                break;
                    251:                }
                    252:        }
                    253:
                    254:        acpidock_status(sc);
                    255:        sc->sc_sens.value = sc->sc_docked == ACPIDOCK_STATUS_DOCKED;
                    256:        if (sc->sc_docked)
                    257:                strlcpy(sc->sc_sens.desc, "docked",
                    258:                    sizeof(sc->sc_sens.desc));
                    259:        else
                    260:                strlcpy(sc->sc_sens.desc, "not docked",
                    261:                    sizeof(sc->sc_sens.desc));
                    262:
                    263:        printf(": status %s\n",
                    264:            sc->sc_docked == ACPIDOCK_STATUS_DOCKED ? "docked" : "undocked");
                    265:
                    266:        return (0);
                    267: }
                    268:
                    269: void
                    270: acpidock_foundejd(struct aml_node *node, void *arg)
                    271: {
                    272:        struct acpidock_softc *sc = (struct acpidock_softc *)arg;
                    273:        struct aml_value res;
                    274:
                    275:        dnprintf(15, "%s: %s", DEVNAME(sc), node->parent->name);
                    276:
                    277:        if (aml_evalnode(sc->sc_acpi, node, 0, NULL, &res) == -1) {
                    278:                printf(": error\n");
                    279:        } else {
                    280:                struct aml_nodelist *n;
                    281:
                    282:                /* XXX debug */
                    283:                dnprintf(10, "%s: %s depends on %s\n", DEVNAME(sc),
                    284:                    node->parent->name, res.v_string);
                    285:
                    286:                /* XXX more than one dock? */
                    287:
                    288:                n = malloc(sizeof(struct aml_nodelist), M_DEVBUF, M_WAITOK);
                    289:                n->node = node->parent;
                    290:
                    291:                TAILQ_INSERT_TAIL(&sc->sc_deps_h, n, entries);
                    292:        }
                    293:
                    294:        aml_freevalue(&res);
                    295: }

CVSweb