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

Annotation of sys/dev/isa/pckbc_isa.c, Revision 1.1

1.1     ! nbrk        1: /*     $OpenBSD: pckbc_isa.c,v 1.4 2004/04/02 04:39:51 deraadt Exp $   */
        !             2: /*     $NetBSD: pckbc_isa.c,v 1.2 2000/03/23 07:01:35 thorpej Exp $    */
        !             3:
        !             4: /*
        !             5:  * Copyright (c) 1998
        !             6:  *     Matthias Drochner.  All rights reserved.
        !             7:  *
        !             8:  * Redistribution and use in source and binary forms, with or without
        !             9:  * modification, are permitted provided that the following conditions
        !            10:  * are met:
        !            11:  * 1. Redistributions of source code must retain the above copyright
        !            12:  *    notice, this list of conditions and the following disclaimer.
        !            13:  * 2. Redistributions in binary form must reproduce the above copyright
        !            14:  *    notice, this list of conditions and the following disclaimer in the
        !            15:  *    documentation and/or other materials provided with the distribution.
        !            16:  *
        !            17:  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
        !            18:  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
        !            19:  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
        !            20:  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
        !            21:  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
        !            22:  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
        !            23:  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
        !            24:  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
        !            25:  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
        !            26:  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
        !            27:  */
        !            28:
        !            29: #include <sys/param.h>
        !            30: #include <sys/systm.h>
        !            31: #include <sys/kernel.h>
        !            32: #include <sys/proc.h>
        !            33: #include <sys/device.h>
        !            34: #include <sys/malloc.h>
        !            35: #include <sys/errno.h>
        !            36: #include <sys/queue.h>
        !            37: #include <sys/lock.h>
        !            38:
        !            39: #include <machine/bus.h>
        !            40:
        !            41: #include <dev/isa/isareg.h>
        !            42: #include <dev/isa/isavar.h>
        !            43:
        !            44: #include <dev/ic/i8042reg.h>
        !            45: #include <dev/ic/pckbcvar.h>
        !            46:
        !            47: int    pckbc_isa_match(struct device *, void *, void *);
        !            48: void   pckbc_isa_attach(struct device *, struct device *, void *);
        !            49:
        !            50: struct pckbc_isa_softc {
        !            51:        struct pckbc_softc sc_pckbc;
        !            52:
        !            53:        isa_chipset_tag_t sc_ic;
        !            54:        int sc_irq[PCKBC_NSLOTS];
        !            55: };
        !            56:
        !            57: struct cfattach pckbc_isa_ca = {
        !            58:        sizeof(struct pckbc_isa_softc), pckbc_isa_match, pckbc_isa_attach,
        !            59: };
        !            60:
        !            61: void   pckbc_isa_intr_establish(struct pckbc_softc *, pckbc_slot_t);
        !            62:
        !            63: int
        !            64: pckbc_isa_match(parent, match, aux)
        !            65:        struct device *parent;
        !            66:        void *match;
        !            67:        void *aux;
        !            68: {
        !            69:        struct isa_attach_args *ia = aux;
        !            70:        bus_space_tag_t iot = ia->ia_iot;
        !            71:        bus_space_handle_t ioh_d, ioh_c;
        !            72:        int res, ok = 1;
        !            73:
        !            74:        /* If values are hardwired to something that they can't be, punt. */
        !            75:        if ((ia->ia_iobase != IOBASEUNK && ia->ia_iobase != IO_KBD) ||
        !            76:            ia->ia_maddr != MADDRUNK ||
        !            77:            (ia->ia_irq != IRQUNK && ia->ia_irq != 1 /* XXX */) ||
        !            78:            ia->ia_drq != DRQUNK)
        !            79:                return (0);
        !            80:
        !            81:        if (pckbc_is_console(iot, IO_KBD) == 0) {
        !            82:                if (bus_space_map(iot, IO_KBD + KBDATAP, 1, 0, &ioh_d))
        !            83:                        return (0);
        !            84:                if (bus_space_map(iot, IO_KBD + KBCMDP, 1, 0, &ioh_c)) {
        !            85:                        bus_space_unmap(iot, ioh_d, 1);
        !            86:                        return (0);
        !            87:                }
        !            88:
        !            89:                /* flush KBC */
        !            90:                (void) pckbc_poll_data1(iot, ioh_d, ioh_c, PCKBC_KBD_SLOT, 0);
        !            91:
        !            92:                /* KBC selftest */
        !            93:                if (pckbc_send_cmd(iot, ioh_c, KBC_SELFTEST) == 0) {
        !            94:                        ok = 0;
        !            95:                        goto out;
        !            96:                }
        !            97:                res = pckbc_poll_data1(iot, ioh_d, ioh_c, PCKBC_KBD_SLOT, 0);
        !            98:                if (res != 0x55) {
        !            99:                        printf("kbc selftest: %x\n", res);
        !           100:                        ok = 0;
        !           101:                }
        !           102:  out:
        !           103:                bus_space_unmap(iot, ioh_d, 1);
        !           104:                bus_space_unmap(iot, ioh_c, 1);
        !           105:        }
        !           106:
        !           107:        if (ok) {
        !           108:                ia->ia_iobase = IO_KBD;
        !           109:                ia->ia_iosize = 5;
        !           110:                ia->ia_msize = 0x0;
        !           111:        }
        !           112:        return (ok);
        !           113: }
        !           114:
        !           115: void
        !           116: pckbc_isa_attach(parent, self, aux)
        !           117:        struct device *parent, *self;
        !           118:        void *aux;
        !           119: {
        !           120:        struct pckbc_isa_softc *isc = (void *)self;
        !           121:        struct pckbc_softc *sc = &isc->sc_pckbc;
        !           122:        struct isa_attach_args *ia = aux;
        !           123:        struct pckbc_internal *t;
        !           124:        bus_space_tag_t iot;
        !           125:        bus_space_handle_t ioh_d, ioh_c;
        !           126:
        !           127:        isc->sc_ic = ia->ia_ic;
        !           128:        iot = ia->ia_iot;
        !           129:
        !           130:        /*
        !           131:         * Set up IRQs for "normal" ISA.
        !           132:         *
        !           133:         * XXX The "aux" slot is different (9) on the Alpha AXP150 Jensen.
        !           134:         */
        !           135:        isc->sc_irq[PCKBC_KBD_SLOT] = 1;
        !           136:        isc->sc_irq[PCKBC_AUX_SLOT] = 12;
        !           137:
        !           138:        sc->intr_establish = pckbc_isa_intr_establish;
        !           139:
        !           140:        if (pckbc_is_console(iot, IO_KBD)) {
        !           141:                t = &pckbc_consdata;
        !           142:                ioh_d = t->t_ioh_d;
        !           143:                ioh_c = t->t_ioh_c;
        !           144:                pckbc_console_attached = 1;
        !           145:                /* t->t_cmdbyte was initialized by cnattach */
        !           146:        } else {
        !           147:                if (bus_space_map(iot, IO_KBD + KBDATAP, 1, 0, &ioh_d) ||
        !           148:                    bus_space_map(iot, IO_KBD + KBCMDP, 1, 0, &ioh_c))
        !           149:                        panic("pckbc_attach: couldn't map");
        !           150:
        !           151:                t = malloc(sizeof(struct pckbc_internal), M_DEVBUF, M_WAITOK);
        !           152:                bzero(t, sizeof(struct pckbc_internal));
        !           153:                t->t_iot = iot;
        !           154:                t->t_ioh_d = ioh_d;
        !           155:                t->t_ioh_c = ioh_c;
        !           156:                t->t_addr = IO_KBD;
        !           157:                t->t_cmdbyte = KC8_CPU; /* Enable ports */
        !           158:        }
        !           159:
        !           160:        t->t_sc = sc;
        !           161:        sc->id = t;
        !           162:
        !           163:        printf("\n");
        !           164:
        !           165:        /* Finish off the attach. */
        !           166:        pckbc_attach(sc);
        !           167: }
        !           168:
        !           169: void
        !           170: pckbc_isa_intr_establish(sc, slot)
        !           171:        struct pckbc_softc *sc;
        !           172:        pckbc_slot_t slot;
        !           173: {
        !           174:        struct pckbc_isa_softc *isc = (void *) sc;
        !           175:        void *rv;
        !           176:
        !           177:        rv = isa_intr_establish(isc->sc_ic, isc->sc_irq[slot], IST_EDGE,
        !           178:            IPL_TTY, pckbcintr, sc, sc->sc_dv.dv_xname);
        !           179:        if (rv == NULL) {
        !           180:                printf("%s: unable to establish interrupt for %s slot\n",
        !           181:                    sc->sc_dv.dv_xname, pckbc_slot_names[slot]);
        !           182:        } else {
        !           183:                printf("%s: using irq %d for %s slot\n", sc->sc_dv.dv_xname,
        !           184:                    isc->sc_irq[slot], pckbc_slot_names[slot]);
        !           185:        }
        !           186: }

CVSweb