[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     ! 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