Annotation of sys/arch/vax/vsa/dz_ibus.c, Revision 1.1
1.1 ! nbrk 1: /* $OpenBSD: dz_ibus.c,v 1.22 2006/08/03 18:45:40 miod Exp $ */
! 2: /* $NetBSD: dz_ibus.c,v 1.15 1999/08/27 17:50:42 ragge Exp $ */
! 3: /*
! 4: * Copyright (c) 1998 Ludd, University of Lule}, Sweden.
! 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: * 3. All advertising materials mentioning features or use of this software
! 16: * must display the following acknowledgement:
! 17: * This product includes software developed at Ludd, University of
! 18: * Lule}, Sweden and its contributors.
! 19: * 4. The name of the author may not be used to endorse or promote products
! 20: * derived from this software without specific prior written permission
! 21: *
! 22: * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
! 23: * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
! 24: * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
! 25: * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
! 26: * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
! 27: * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
! 28: * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
! 29: * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
! 30: * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
! 31: * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
! 32: */
! 33:
! 34:
! 35:
! 36: #include <sys/param.h>
! 37: #include <sys/proc.h>
! 38: #include <sys/systm.h>
! 39: #include <sys/ioctl.h>
! 40: #include <sys/tty.h>
! 41: #include <sys/file.h>
! 42: #include <sys/conf.h>
! 43: #include <sys/device.h>
! 44: #include <sys/reboot.h>
! 45:
! 46: #include <dev/cons.h>
! 47:
! 48: #include <machine/mtpr.h>
! 49: #include <machine/sid.h>
! 50: #include <machine/uvax.h>
! 51: #include <machine/vsbus.h>
! 52: #include <machine/cpu.h>
! 53: #include <machine/scb.h>
! 54: #include <machine/nexus.h>
! 55: #include <machine/ka420.h>
! 56:
! 57: #include <vax/vax/gencons.h>
! 58:
! 59: #include <vax/qbus/dzreg.h>
! 60: #include <vax/qbus/dzvar.h>
! 61:
! 62: #include <vax/dec/dzkbdvar.h>
! 63:
! 64: #include "dzkbd.h"
! 65: #include "dzms.h"
! 66:
! 67: static int dz_vsbus_match(struct device *, struct cfdata *, void *);
! 68: static void dz_vsbus_attach(struct device *, struct device *, void *);
! 69:
! 70: static vaddr_t dz_regs; /* Used for console */
! 71:
! 72: struct cfattach dz_vsbus_ca = {
! 73: sizeof(struct dz_softc), (cfmatch_t)dz_vsbus_match, dz_vsbus_attach
! 74: };
! 75:
! 76: #define REG(name) short name; short X##name##X;
! 77: static volatile struct ss_dz {/* base address of DZ-controller: 0x200a0000 */
! 78: REG(csr); /* 00 Csr: control/status register */
! 79: REG(rbuf); /* 04 Rbuf/Lpr: receive buffer/line param reg. */
! 80: REG(tcr); /* 08 Tcr: transmit console register */
! 81: REG(tdr); /* 0C Msr/Tdr: modem status reg/transmit data reg */
! 82: REG(lpr0); /* 10 Lpr0: */
! 83: REG(lpr1); /* 14 Lpr0: */
! 84: REG(lpr2); /* 18 Lpr0: */
! 85: REG(lpr3); /* 1C Lpr0: */
! 86: } *dz;
! 87: #undef REG
! 88:
! 89: cons_decl(dz);
! 90: cdev_decl(dz);
! 91:
! 92: int dz_can_have_kbd(void);
! 93:
! 94: extern int getmajor(void *); /* conf.c */
! 95:
! 96: #if NDZKBD > 0 || NDZMS > 0
! 97: static int
! 98: dz_print(void *aux, const char *name)
! 99: {
! 100: struct dzkm_attach_args *dz_args = aux;
! 101:
! 102: if (name != NULL)
! 103: printf(dz_args->daa_line == 0 ? "lkkbd at %s" : "lkms at %s",
! 104: name);
! 105: else
! 106: printf(" line %d", dz_args->daa_line);
! 107:
! 108: return (UNCONF);
! 109: }
! 110: #endif
! 111:
! 112: static int
! 113: dz_vsbus_match(parent, cf, aux)
! 114: struct device *parent;
! 115: struct cfdata *cf;
! 116: void *aux;
! 117: {
! 118: struct vsbus_attach_args *va = aux;
! 119: struct ss_dz *dzP;
! 120: short i;
! 121:
! 122: #if VAX53 || VAX49
! 123: if (vax_boardtype == VAX_BTYP_49 ||
! 124: vax_boardtype == VAX_BTYP_1303)
! 125: if (cf->cf_loc[0] != 0x25000000)
! 126: return 0; /* don't probe unnecessarily */
! 127: #endif
! 128:
! 129: dzP = (struct ss_dz *)va->va_addr;
! 130: i = dzP->tcr;
! 131: dzP->csr = DZ_CSR_MSE|DZ_CSR_TXIE;
! 132: dzP->tcr = 0;
! 133: DELAY(1000);
! 134: dzP->tcr = 1;
! 135: DELAY(100000);
! 136: dzP->tcr = i;
! 137:
! 138: /* If the device doesn't exist, no interrupt has been generated */
! 139:
! 140: return 1;
! 141: }
! 142:
! 143: static void
! 144: dz_vsbus_attach(parent, self, aux)
! 145: struct device *parent, *self;
! 146: void *aux;
! 147: {
! 148: struct dz_softc *sc = (void *)self;
! 149: struct vsbus_attach_args *va = aux;
! 150: #if NDZKBD > 0 || NDZMS > 0
! 151: struct dzkm_attach_args daa;
! 152: #endif
! 153:
! 154: /*
! 155: * XXX - This is evil and ugly, but...
! 156: * due to the nature of how bus_space_* works on VAX, this will
! 157: * be perfectly good until everything is converted.
! 158: */
! 159:
! 160: if (dz_regs == 0) /* This isn't console */
! 161: dz_regs = vax_map_physmem(va->va_paddr, 1);
! 162:
! 163: sc->sc_ioh = dz_regs;
! 164: sc->sc_dr.dr_csr = 0;
! 165: sc->sc_dr.dr_rbuf = 4;
! 166: sc->sc_dr.dr_dtr = 9;
! 167: sc->sc_dr.dr_break = 13;
! 168: sc->sc_dr.dr_tbuf = 12;
! 169: sc->sc_dr.dr_tcr = 8;
! 170: sc->sc_dr.dr_dcd = 13;
! 171: sc->sc_dr.dr_ring = 13;
! 172:
! 173: sc->sc_type = DZ_DZV;
! 174:
! 175: sc->sc_dsr = 0x0f; /* XXX check if VS has modem ctrl bits */
! 176:
! 177: sc->sc_rcvec = va->va_cvec;
! 178: scb_vecalloc(sc->sc_rcvec, dzxint, sc, SCB_ISTACK,
! 179: &sc->sc_tintrcnt);
! 180: sc->sc_tcvec = va->va_cvec - 4;
! 181: scb_vecalloc(sc->sc_tcvec, dzrint, sc, SCB_ISTACK,
! 182: &sc->sc_rintrcnt);
! 183: evcount_attach(&sc->sc_rintrcnt, sc->sc_dev.dv_xname,
! 184: (void *)&sc->sc_rcvec, &evcount_intr);
! 185: evcount_attach(&sc->sc_tintrcnt, sc->sc_dev.dv_xname,
! 186: (void *)&sc->sc_tcvec, &evcount_intr);
! 187:
! 188: printf(": 4 lines");
! 189:
! 190: dzattach(sc);
! 191:
! 192: if (dz_can_have_kbd()) {
! 193: #if NDZKBD > 0
! 194: extern struct consdev wsdisplay_cons;
! 195:
! 196: dz->rbuf = DZ_LPR_RX_ENABLE | (DZ_LPR_B4800 << 8)
! 197: | DZ_LPR_8_BIT_CHAR;
! 198: daa.daa_line = 0;
! 199: daa.daa_flags =
! 200: (cn_tab == &wsdisplay_cons ? DZKBD_CONSOLE : 0);
! 201: config_found(self, &daa, dz_print);
! 202: #endif
! 203: #if NDZMS > 0
! 204: dz->rbuf = DZ_LPR_RX_ENABLE | (DZ_LPR_B4800 << 8) |
! 205: DZ_LPR_8_BIT_CHAR | DZ_LPR_PARENB | DZ_LPR_OPAR |
! 206: 1 /* line */;
! 207: daa.daa_line = 1;
! 208: daa.daa_flags = 0;
! 209: config_found(self, &daa, dz_print);
! 210: #endif
! 211: }
! 212:
! 213: #if 0
! 214: s = spltty();
! 215: dzrint(sc);
! 216: dzxint(sc);
! 217: splx(s);
! 218: #endif
! 219: }
! 220:
! 221: int
! 222: dzcngetc(dev)
! 223: dev_t dev;
! 224: {
! 225: int c = 0, s;
! 226: int mino = minor(dev);
! 227: u_short rbuf;
! 228:
! 229: s = spltty();
! 230: do {
! 231: while ((dz->csr & DZ_CSR_RX_DONE) == 0)
! 232: ; /* Wait for char */
! 233: rbuf = dz->rbuf;
! 234: if (((rbuf >> 8) & 3) != mino)
! 235: continue;
! 236: c = rbuf & 0x7f;
! 237: } while (c == 17 || c == 19); /* ignore XON/XOFF */
! 238: splx(s);
! 239:
! 240: if (c == 13)
! 241: c = 10;
! 242:
! 243: return (c);
! 244: }
! 245:
! 246: int
! 247: dz_can_have_kbd()
! 248: {
! 249: switch (vax_boardtype) {
! 250: case VAX_BTYP_410:
! 251: case VAX_BTYP_420:
! 252: case VAX_BTYP_43:
! 253: if ((vax_confdata & KA420_CFG_MULTU) == 0)
! 254: return (1);
! 255: break;
! 256:
! 257: case VAX_BTYP_46:
! 258: if ((vax_siedata & 0xff) == VAX_VTYP_46)
! 259: return (1);
! 260: break;
! 261: case VAX_BTYP_48:
! 262: if (((vax_siedata >> 8) & 0xff) == VAX_STYP_48)
! 263: return (1);
! 264: break;
! 265:
! 266: case VAX_BTYP_49:
! 267: return (1);
! 268:
! 269: default:
! 270: break;
! 271: }
! 272:
! 273: return (0);
! 274: }
! 275:
! 276: void
! 277: dzcnprobe(cndev)
! 278: struct consdev *cndev;
! 279: {
! 280: extern vaddr_t iospace;
! 281: int diagcons, major;
! 282: paddr_t ioaddr = 0x200a0000;
! 283:
! 284: if ((major = getmajor(dzopen)) < 0)
! 285: return;
! 286:
! 287: switch (vax_boardtype) {
! 288: case VAX_BTYP_410:
! 289: case VAX_BTYP_420:
! 290: case VAX_BTYP_43:
! 291: diagcons = (vax_confdata & KA420_CFG_L3CON ? 3 : 0);
! 292: break;
! 293:
! 294: case VAX_BTYP_46:
! 295: case VAX_BTYP_48:
! 296: diagcons = (vax_confdata & 0x100 ? 3 : 0);
! 297: break;
! 298:
! 299: case VAX_BTYP_49:
! 300: ioaddr = 0x25000000;
! 301: diagcons = (vax_confdata & 8 ? 3 : 0);
! 302: break;
! 303:
! 304: case VAX_BTYP_1303:
! 305: ioaddr = 0x25000000;
! 306: diagcons = 3;
! 307: break;
! 308:
! 309: default:
! 310: return;
! 311: }
! 312: cndev->cn_pri = diagcons != 0 ? CN_REMOTE : CN_NORMAL;
! 313: cndev->cn_dev = makedev(major, dz_can_have_kbd() ? 3 : diagcons);
! 314: dz_regs = iospace;
! 315: dz = (void *)dz_regs;
! 316: ioaccess(iospace, ioaddr, 1);
! 317: }
! 318:
! 319: void
! 320: dzcninit(cndev)
! 321: struct consdev *cndev;
! 322: {
! 323: dz = (void *)dz_regs;
! 324:
! 325: dz->csr = 0; /* Disable scanning until initting is done */
! 326: dz->tcr = (1 << minor(cndev->cn_dev)); /* Turn on xmitter */
! 327: dz->csr = DZ_CSR_MSE; /* Turn scanning back on */
! 328: }
! 329:
! 330: void
! 331: dzcnputc(dev,ch)
! 332: dev_t dev;
! 333: int ch;
! 334: {
! 335: int timeout = 1<<15; /* don't hang the machine! */
! 336: int s;
! 337: int mino = minor(dev);
! 338: u_short tcr;
! 339:
! 340: if (mfpr(PR_MAPEN) == 0)
! 341: return;
! 342:
! 343: /*
! 344: * If we are past boot stage, dz* will interrupt,
! 345: * therefore we block.
! 346: */
! 347: s = spltty();
! 348: tcr = dz->tcr; /* remember which lines to scan */
! 349: dz->tcr = (1 << mino);
! 350:
! 351: while ((dz->csr & DZ_CSR_TX_READY) == 0) /* Wait until ready */
! 352: if (--timeout < 0)
! 353: break;
! 354: dz->tdr = ch; /* Put the character */
! 355: timeout = 1<<15;
! 356: while ((dz->csr & DZ_CSR_TX_READY) == 0) /* Wait until ready */
! 357: if (--timeout < 0)
! 358: break;
! 359:
! 360: dz->tcr = tcr;
! 361: splx(s);
! 362: }
! 363:
! 364: void
! 365: dzcnpollc(dev, pollflag)
! 366: dev_t dev;
! 367: int pollflag;
! 368: {
! 369: static u_char mask;
! 370:
! 371: if (pollflag)
! 372: mask = vsbus_setmask(0);
! 373: else
! 374: vsbus_setmask(mask);
! 375: }
! 376:
! 377: #if NDZKBD > 0 || NDZMS > 0
! 378: int
! 379: dzgetc(struct dz_linestate *ls)
! 380: {
! 381: int line;
! 382: int s;
! 383: u_short rbuf;
! 384:
! 385: if (ls != NULL)
! 386: line = ls->dz_line;
! 387: else
! 388: line = 0; /* keyboard */
! 389:
! 390: s = spltty();
! 391: for (;;) {
! 392: for(; (dz->csr & DZ_CSR_RX_DONE) == 0;)
! 393: ;
! 394: rbuf = dz->rbuf;
! 395: if (((rbuf >> 8) & 3) == line) {
! 396: splx(s);
! 397: return (rbuf & 0xff);
! 398: }
! 399: }
! 400: }
! 401:
! 402: void
! 403: dzputc(struct dz_linestate *ls, int ch)
! 404: {
! 405: int line;
! 406: u_short tcr;
! 407: int s;
! 408:
! 409: /* if the dz has already been attached, the MI
! 410: driver will do the transmitting: */
! 411: if (ls && ls->dz_sc) {
! 412: s = spltty();
! 413: line = ls->dz_line;
! 414: putc(ch, &ls->dz_tty->t_outq);
! 415: tcr = dz->tcr;
! 416: if (!(tcr & (1 << line)))
! 417: dz->tcr = tcr | (1 << line);
! 418: dzxint(ls->dz_sc);
! 419: splx(s);
! 420: return;
! 421: }
! 422: /* use dzcnputc to do the transmitting: */
! 423: dzcnputc(makedev(getmajor(dzopen), 0), ch);
! 424: }
! 425: #endif /* NDZKBD > 0 || NDZMS > 0 */
CVSweb