[BACK]Return to pckbc_ebus.c CVS log [TXT][DIR] Up to [local] / sys / arch / sparc64 / dev

Annotation of sys/arch/sparc64/dev/pckbc_ebus.c, Revision 1.1

1.1     ! nbrk        1: /*     $OpenBSD: pckbc_ebus.c,v 1.7 2004/11/02 21:17:39 miod Exp $     */
        !             2:
        !             3: /*
        !             4:  * Copyright (c) 2002 Jason L. Wright (jason@thought.net)
        !             5:  * All rights reserved.
        !             6:  *
        !             7:  * Redistribution and use in source and binary forms, with or without
        !             8:  * modification, are permitted provided that the following conditions
        !             9:  * are met:
        !            10:  * 1. Redistributions of source code must retain the above copyright
        !            11:  *    notice, this list of conditions and the following disclaimer.
        !            12:  * 2. Redistributions in binary form must reproduce the above copyright
        !            13:  *    notice, this list of conditions and the following disclaimer in the
        !            14:  *    documentation and/or other materials provided with the distribution.
        !            15:  *
        !            16:  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
        !            17:  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
        !            18:  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
        !            19:  * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
        !            20:  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
        !            21:  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
        !            22:  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        !            23:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
        !            24:  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
        !            25:  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
        !            26:  * POSSIBILITY OF SUCH DAMAGE.
        !            27:  */
        !            28:
        !            29: /*
        !            30:  * Driver for i8042 keyboard controller found on some PCI based
        !            31:  * UltraSPARCs
        !            32:  *
        !            33:  * Effort sponsored in part by the Defense Advanced Research Projects
        !            34:  * Agency (DARPA) and Air Force Research Laboratory, Air Force
        !            35:  * Materiel Command, USAF, under agreement number F30602-01-2-0537.
        !            36:  *
        !            37:  */
        !            38:
        !            39: #include <sys/types.h>
        !            40: #include <sys/param.h>
        !            41: #include <sys/systm.h>
        !            42: #include <sys/device.h>
        !            43: #include <sys/conf.h>
        !            44: #include <sys/malloc.h>
        !            45:
        !            46: #include <machine/bus.h>
        !            47: #include <machine/autoconf.h>
        !            48: #include <machine/openfirm.h>
        !            49:
        !            50: #include <sparc64/dev/ebusreg.h>
        !            51: #include <sparc64/dev/ebusvar.h>
        !            52:
        !            53: #include <dev/ic/i8042reg.h>
        !            54: #include <dev/ic/pckbcvar.h>
        !            55:
        !            56: struct pckbc_ebus_softc {
        !            57:        struct pckbc_softc sc_pckbc;
        !            58:        bus_space_tag_t sc_iot;
        !            59:        bus_space_handle_t sc_ioh;
        !            60:        bus_space_handle_t sc_ioh_c;
        !            61:        bus_space_handle_t sc_ioh_d;
        !            62:        void *sc_irq[2];
        !            63:        int sc_node;
        !            64: };
        !            65:
        !            66: int pckbc_ebus_match(struct device *, void *, void *);
        !            67: void pckbc_ebus_attach(struct device *, struct device *, void *);
        !            68:
        !            69: struct cfattach pckbc_ebus_ca = {
        !            70:        sizeof(struct pckbc_ebus_softc), pckbc_ebus_match, pckbc_ebus_attach
        !            71: };
        !            72:
        !            73: void pckbc_ebus_intr_establish(struct pckbc_softc *, pckbc_slot_t);
        !            74: int pckbc_ebus_is_console(struct pckbc_ebus_softc *);
        !            75:
        !            76: int
        !            77: pckbc_ebus_match(parent, match, aux)
        !            78:        struct device *parent;
        !            79:        void *match;
        !            80:        void *aux;
        !            81: {
        !            82:        struct ebus_attach_args *ea = aux;
        !            83:
        !            84:        if (strcmp(ea->ea_name, "8042") == 0)
        !            85:                return (1);
        !            86:        return (0);
        !            87: }
        !            88:
        !            89: void
        !            90: pckbc_ebus_attach(parent, self, aux)
        !            91:        struct device *parent, *self;
        !            92:        void *aux;
        !            93: {
        !            94:        struct pckbc_ebus_softc *sc = (void *)self;
        !            95:        struct pckbc_softc *psc = &sc->sc_pckbc;
        !            96:        struct ebus_attach_args *ea = aux;
        !            97:        struct pckbc_internal *t = NULL;
        !            98:        int console;
        !            99:
        !           100:        sc->sc_node = ea->ea_node;
        !           101:        console = pckbc_ebus_is_console(sc);
        !           102:
        !           103:        /* Use prom address if available, otherwise map it. */
        !           104:        if (ea->ea_nvaddrs && bus_space_map(ea->ea_iotag, ea->ea_vaddrs[0], 0,
        !           105:            0, &sc->sc_ioh) == 0) {
        !           106:                sc->sc_iot = ea->ea_iotag;
        !           107:        } else if (ebus_bus_map(ea->ea_iotag, 0,
        !           108:            EBUS_PADDR_FROM_REG(&ea->ea_regs[0]), ea->ea_regs[0].size,
        !           109:            0, 0, &sc->sc_ioh) == 0) {
        !           110:                sc->sc_iot = ea->ea_iotag;
        !           111:        } else if (ebus_bus_map(ea->ea_memtag, 0,
        !           112:            EBUS_PADDR_FROM_REG(&ea->ea_regs[0]), ea->ea_regs[0].size,
        !           113:            0, 0, &sc->sc_ioh) == 0) {
        !           114:                sc->sc_iot = ea->ea_memtag;
        !           115:        } else {
        !           116:                printf(": can't map register space\n");
        !           117:                return;
        !           118:        }
        !           119:
        !           120:        if (console) {
        !           121:                if (pckbc_cnattach(sc->sc_iot,
        !           122:                    EBUS_PADDR_FROM_REG(&ea->ea_regs[0]), KBCMDP,
        !           123:                    PCKBC_KBD_SLOT) == 0) {
        !           124:                        t = &pckbc_consdata;
        !           125:                        pckbc_console_attached = 1;
        !           126:                        sc->sc_ioh_c = t->t_ioh_c;
        !           127:                        sc->sc_ioh_d = t->t_ioh_d;
        !           128:                } else
        !           129:                        console = 0;
        !           130:        }
        !           131:
        !           132:        if (console == 0) {
        !           133:                if (bus_space_subregion(sc->sc_iot, sc->sc_ioh,
        !           134:                    KBCMDP, sizeof(u_int32_t), &sc->sc_ioh_c) != 0) {
        !           135:                        printf(": couldn't get cmd subregion\n");
        !           136:                        return;
        !           137:                }
        !           138:                if (bus_space_subregion(sc->sc_iot, sc->sc_ioh,
        !           139:                    KBDATAP, sizeof(u_int32_t), &sc->sc_ioh_d) != 0) {
        !           140:                        printf(": couldn't get data subregion\n");
        !           141:                        return;
        !           142:                }
        !           143:
        !           144:                t = malloc(sizeof(struct pckbc_internal), M_DEVBUF, M_NOWAIT);
        !           145:                bzero(t, sizeof(struct pckbc_internal));
        !           146:        }
        !           147:
        !           148:        psc->intr_establish = pckbc_ebus_intr_establish;
        !           149:
        !           150:        sc->sc_irq[0] = bus_intr_establish(sc->sc_iot, ea->ea_intrs[0],
        !           151:            IPL_TTY, 0, pckbcintr, psc, self->dv_xname);
        !           152:        if (sc->sc_irq[0] == NULL) {
        !           153:                printf(": couldn't get intr0\n");
        !           154:                return;
        !           155:        }
        !           156:
        !           157:        sc->sc_irq[1] = bus_intr_establish(sc->sc_iot, ea->ea_intrs[1],
        !           158:            IPL_TTY, 0, pckbcintr, psc, self->dv_xname);
        !           159:        if (sc->sc_irq[1] == NULL) {
        !           160:                printf(": couldn't get intr1\n");
        !           161:                return;
        !           162:        }
        !           163:
        !           164:        t->t_iot = sc->sc_iot;
        !           165:        t->t_ioh_c = sc->sc_ioh_c;
        !           166:        t->t_ioh_d = sc->sc_ioh_d;
        !           167:        t->t_cmdbyte = KC8_CPU;
        !           168:        t->t_sc = psc;
        !           169:        psc->id = t;
        !           170:
        !           171:        printf("\n");
        !           172:        pckbc_attach(psc);
        !           173:
        !           174: }
        !           175:
        !           176: int
        !           177: pckbc_ebus_is_console(sc)
        !           178:        struct pckbc_ebus_softc *sc;
        !           179: {
        !           180:        char *name;
        !           181:        int node;
        !           182:
        !           183:        /*
        !           184:         * Loop through the children of 8042 and see if the keyboard
        !           185:         * exists, and further, whether it is the console input device.
        !           186:         * This is almost redundant because 8042 doesn't show up in
        !           187:         * device tree unless a keyboard is in fact attached.
        !           188:         */
        !           189:        for (node = OF_child(sc->sc_node); node; node = OF_peer(node)) {
        !           190:                name = getpropstring(node, "name");
        !           191:                if (name == NULL)
        !           192:                        continue;
        !           193:                if (strcmp("kb_ps2", name) == 0 ||
        !           194:                    strcmp("keyboard", name) == 0) {
        !           195:                        if (node == OF_instance_to_package(OF_stdin()))
        !           196:                                return (1);
        !           197:                }
        !           198:        }
        !           199:        return (0);
        !           200: }
        !           201:
        !           202: void
        !           203: pckbc_ebus_intr_establish(psc, slot)
        !           204:        struct pckbc_softc *psc;
        !           205:        pckbc_slot_t slot;
        !           206: {
        !           207:        /* Nothing to do, interrupts were mapped in attach. */
        !           208: }

CVSweb