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