Annotation of sys/arch/luna88k/dev/siotty.c, Revision 1.1
1.1 ! nbrk 1: /* $OpenBSD: siotty.c,v 1.5 2007/02/14 01:12:16 jsg Exp $ */
! 2: /* $NetBSD: siotty.c,v 1.9 2002/03/17 19:40:43 atatat Exp $ */
! 3:
! 4: /*-
! 5: * Copyright (c) 2000 The NetBSD Foundation, Inc.
! 6: * All rights reserved.
! 7: *
! 8: * This code is derived from software contributed to The NetBSD Foundation
! 9: * by Tohru Nishimura.
! 10: *
! 11: * Redistribution and use in source and binary forms, with or without
! 12: * modification, are permitted provided that the following conditions
! 13: * are met:
! 14: * 1. Redistributions of source code must retain the above copyright
! 15: * notice, this list of conditions and the following disclaimer.
! 16: * 2. Redistributions in binary form must reproduce the above copyright
! 17: * notice, this list of conditions and the following disclaimer in the
! 18: * documentation and/or other materials provided with the distribution.
! 19: * 3. All advertising materials mentioning features or use of this software
! 20: * must display the following acknowledgement:
! 21: * This product includes software developed by the NetBSD
! 22: * Foundation, Inc. and its contributors.
! 23: * 4. Neither the name of The NetBSD Foundation nor the names of its
! 24: * contributors may be used to endorse or promote products derived
! 25: * from this software without specific prior written permission.
! 26: *
! 27: * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
! 28: * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
! 29: * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
! 30: * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
! 31: * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
! 32: * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
! 33: * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
! 34: * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
! 35: * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
! 36: * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
! 37: * POSSIBILITY OF SUCH DAMAGE.
! 38: */
! 39:
! 40: #include <sys/param.h>
! 41: #include <sys/systm.h>
! 42: #include <sys/device.h>
! 43: #include <sys/conf.h>
! 44: #include <sys/ioctl.h>
! 45: #include <sys/proc.h>
! 46: #include <sys/user.h>
! 47: #include <sys/tty.h>
! 48: #include <sys/uio.h>
! 49: #include <sys/fcntl.h>
! 50: #include <dev/cons.h>
! 51:
! 52: #include <machine/cpu.h>
! 53:
! 54: #include <luna88k/dev/sioreg.h>
! 55: #include <luna88k/dev/siovar.h>
! 56:
! 57: #define TIOCM_BREAK 01000 /* non standard use */
! 58:
! 59: static const u_int8_t ch0_regs[6] = {
! 60: WR0_RSTINT, /* reset E/S interrupt */
! 61: WR1_RXALLS | WR1_TXENBL, /* Rx per char, Tx */
! 62: 0, /* */
! 63: WR3_RX8BIT | WR3_RXENBL, /* Rx */
! 64: WR4_BAUD96 | WR4_STOP1, /* Tx/Rx */
! 65: WR5_TX8BIT | WR5_TXENBL | WR5_DTR | WR5_RTS, /* Tx */
! 66: };
! 67:
! 68: static const struct speedtab siospeedtab[] = {
! 69: { 2400, WR4_BAUD24, },
! 70: { 4800, WR4_BAUD48, },
! 71: { 9600, WR4_BAUD96, },
! 72: { -1, 0, },
! 73: };
! 74:
! 75: struct siotty_softc {
! 76: struct device sc_dev;
! 77: struct tty *sc_tty;
! 78: struct sioreg *sc_ctl;
! 79: u_int sc_flags;
! 80: u_int8_t sc_wr[6];
! 81: };
! 82:
! 83: cdev_decl(sio);
! 84: void siostart(struct tty *);
! 85: int sioparam(struct tty *, struct termios *);
! 86: void siottyintr(int);
! 87: int siomctl(struct siotty_softc *, int, int);
! 88:
! 89: int siotty_match(struct device *, void *, void *);
! 90: void siotty_attach(struct device *, struct device *, void *);
! 91:
! 92: const struct cfattach siotty_ca = {
! 93: sizeof(struct siotty_softc), siotty_match, siotty_attach
! 94: };
! 95:
! 96: struct cfdriver siotty_cd = {
! 97: NULL, "siotty", DV_TTY
! 98: };
! 99:
! 100: int
! 101: siotty_match(parent, cf, aux)
! 102: struct device *parent;
! 103: void *cf, *aux;
! 104: {
! 105: struct sio_attach_args *args = aux;
! 106:
! 107: if (args->channel != 0) /* XXX allow tty on Ch.B XXX */
! 108: return 0;
! 109: return 1;
! 110: }
! 111:
! 112: void
! 113: siotty_attach(parent, self, aux)
! 114: struct device *parent, *self;
! 115: void *aux;
! 116: {
! 117: struct sio_softc *scp = (void *)parent;
! 118: struct siotty_softc *sc = (void *)self;
! 119: struct sio_attach_args *args = aux;
! 120:
! 121: sc->sc_ctl = (struct sioreg *)scp->scp_ctl + args->channel;
! 122: bcopy(ch0_regs, sc->sc_wr, sizeof(ch0_regs));
! 123: scp->scp_intr[args->channel] = siottyintr;
! 124:
! 125: if (args->hwflags == 1) {
! 126: printf(" (console)");
! 127: sc->sc_flags = TIOCFLAG_SOFTCAR;
! 128: }
! 129: else {
! 130: setsioreg(sc->sc_ctl, WR0, WR0_CHANRST);
! 131: setsioreg(sc->sc_ctl, WR2A, WR2_VEC86 | WR2_INTR_1);
! 132: setsioreg(sc->sc_ctl, WR2B, 0);
! 133: setsioreg(sc->sc_ctl, WR0, sc->sc_wr[WR0]);
! 134: setsioreg(sc->sc_ctl, WR4, sc->sc_wr[WR4]);
! 135: setsioreg(sc->sc_ctl, WR3, sc->sc_wr[WR3]);
! 136: setsioreg(sc->sc_ctl, WR5, sc->sc_wr[WR5]);
! 137: setsioreg(sc->sc_ctl, WR0, sc->sc_wr[WR0]);
! 138: }
! 139: setsioreg(sc->sc_ctl, WR1, sc->sc_wr[WR1]); /* now interrupt driven */
! 140:
! 141: printf("\n");
! 142: }
! 143:
! 144: /*-------------------- low level routine --------------------*/
! 145:
! 146: void
! 147: siottyintr(chan)
! 148: int chan;
! 149: {
! 150: struct siotty_softc *sc;
! 151: struct sioreg *sio;
! 152: struct tty *tp;
! 153: unsigned int code;
! 154: int rr;
! 155:
! 156: if (chan >= siotty_cd.cd_ndevs)
! 157: return;
! 158: sc = siotty_cd.cd_devs[chan];
! 159: tp = sc->sc_tty;
! 160: sio = sc->sc_ctl;
! 161: rr = getsiocsr(sio);
! 162: if (rr & RR_RXRDY) {
! 163: do {
! 164: code = sio->sio_data;
! 165: if (rr & (RR_FRAMING | RR_OVERRUN | RR_PARITY)) {
! 166: sio->sio_cmd = WR0_ERRRST;
! 167: if (sio->sio_stat & RR_FRAMING)
! 168: code |= TTY_FE;
! 169: else if (sio->sio_stat & RR_PARITY)
! 170: code |= TTY_PE;
! 171: }
! 172: if (tp == NULL || (tp->t_state & TS_ISOPEN) == 0)
! 173: continue;
! 174: #if 0 && defined(DDB) /* ?!?! fails to resume ?!?! */
! 175: if ((rr & RR_BREAK) && tp->t_dev == cn_tab->cn_dev) {
! 176: if (db_console)
! 177: Debugger();
! 178: return;
! 179: }
! 180: #endif
! 181: /*
! 182: (*tp->t_linesw->l_rint)(code, tp);
! 183: */
! 184: (*linesw[tp->t_line].l_rint)(code, tp);
! 185: } while ((rr = getsiocsr(sio)) & RR_RXRDY);
! 186: }
! 187: if (rr & RR_TXRDY) {
! 188: sio->sio_cmd = WR0_RSTPEND;
! 189: if (tp != NULL) {
! 190: tp->t_state &= ~(TS_BUSY|TS_FLUSH);
! 191: /*
! 192: (*tp->t_linesw->l_start)(tp);
! 193: */
! 194: (*linesw[tp->t_line].l_start)(tp);
! 195: }
! 196: }
! 197: }
! 198:
! 199: void
! 200: siostart(tp)
! 201: struct tty *tp;
! 202: {
! 203: struct siotty_softc *sc = siotty_cd.cd_devs[minor(tp->t_dev)];
! 204: int s, c;
! 205:
! 206: s = spltty();
! 207: if (tp->t_state & (TS_BUSY|TS_TIMEOUT|TS_TTSTOP))
! 208: goto out;
! 209: if (tp->t_outq.c_cc <= tp->t_lowat) {
! 210: if (tp->t_state & TS_ASLEEP) {
! 211: tp->t_state &= ~TS_ASLEEP;
! 212: wakeup((caddr_t)&tp->t_outq);
! 213: }
! 214: selwakeup(&tp->t_wsel);
! 215: }
! 216: if (tp->t_outq.c_cc == 0)
! 217: goto out;
! 218:
! 219: tp->t_state |= TS_BUSY;
! 220: while (getsiocsr(sc->sc_ctl) & RR_TXRDY) {
! 221: if ((c = getc(&tp->t_outq)) == -1)
! 222: break;
! 223: sc->sc_ctl->sio_data = c;
! 224: }
! 225: out:
! 226: splx(s);
! 227: }
! 228:
! 229: int
! 230: siostop(tp, flag)
! 231: struct tty *tp;
! 232: int flag;
! 233: {
! 234: int s;
! 235:
! 236: s = spltty();
! 237: if (TS_BUSY == (tp->t_state & (TS_BUSY|TS_TTSTOP))) {
! 238: /*
! 239: * Device is transmitting; must stop it.
! 240: */
! 241: tp->t_state |= TS_FLUSH;
! 242: }
! 243: splx(s);
! 244: return (0);
! 245: }
! 246:
! 247: int
! 248: sioparam(tp, t)
! 249: struct tty *tp;
! 250: struct termios *t;
! 251: {
! 252: struct siotty_softc *sc = siotty_cd.cd_devs[minor(tp->t_dev)];
! 253: int wr4, s;
! 254:
! 255: if (t->c_ispeed && t->c_ispeed != t->c_ospeed)
! 256: return EINVAL;
! 257: wr4 = ttspeedtab(t->c_ospeed, siospeedtab);
! 258: if (wr4 < 0)
! 259: return EINVAL;
! 260:
! 261: if (sc->sc_flags & TIOCFLAG_SOFTCAR) {
! 262: t->c_cflag |= CLOCAL;
! 263: t->c_cflag &= ~HUPCL;
! 264: }
! 265: if (sc->sc_flags & TIOCFLAG_CLOCAL)
! 266: t->c_cflag |= CLOCAL;
! 267:
! 268: /*
! 269: * If there were no changes, don't do anything. This avoids dropping
! 270: * input and improves performance when all we did was frob things like
! 271: * VMIN and VTIME.
! 272: */
! 273: if (tp->t_ospeed == t->c_ospeed && tp->t_cflag == t->c_cflag)
! 274: return 0;
! 275:
! 276: tp->t_ispeed = t->c_ispeed;
! 277: tp->t_ospeed = t->c_ospeed;
! 278: tp->t_cflag = t->c_cflag;
! 279:
! 280: sc->sc_wr[WR3] &= 0x3f;
! 281: sc->sc_wr[WR5] &= 0x9f;
! 282: switch (tp->t_cflag & CSIZE) {
! 283: case CS7:
! 284: sc->sc_wr[WR3] |= WR3_RX7BIT; sc->sc_wr[WR5] |= WR5_TX7BIT;
! 285: break;
! 286: case CS8:
! 287: sc->sc_wr[WR3] |= WR3_RX8BIT; sc->sc_wr[WR5] |= WR5_TX8BIT;
! 288: break;
! 289: }
! 290: if (tp->t_cflag & PARENB) {
! 291: wr4 |= WR4_PARENAB;
! 292: if ((tp->t_cflag & PARODD) == 0)
! 293: wr4 |= WR4_EPARITY;
! 294: }
! 295: wr4 |= (tp->t_cflag & CSTOPB) ? WR4_STOP2 : WR4_STOP1;
! 296: sc->sc_wr[WR4] = wr4;
! 297:
! 298: s = spltty();
! 299: setsioreg(sc->sc_ctl, WR4, sc->sc_wr[WR4]);
! 300: setsioreg(sc->sc_ctl, WR3, sc->sc_wr[WR3]);
! 301: setsioreg(sc->sc_ctl, WR5, sc->sc_wr[WR5]);
! 302: splx(s);
! 303:
! 304: return 0;
! 305: }
! 306:
! 307: int
! 308: siomctl(sc, control, op)
! 309: struct siotty_softc *sc;
! 310: int control, op;
! 311: {
! 312: int val, s, wr5, rr;
! 313:
! 314: val = 0;
! 315: if (control & TIOCM_BREAK)
! 316: val |= WR5_BREAK;
! 317: if (control & TIOCM_DTR)
! 318: val |= WR5_DTR;
! 319: if (control & TIOCM_RTS)
! 320: val |= WR5_RTS;
! 321: s = spltty();
! 322: wr5 = sc->sc_wr[WR5];
! 323: switch (op) {
! 324: case DMSET:
! 325: wr5 &= ~(WR5_BREAK|WR5_DTR|WR5_RTS);
! 326: /* FALLTHROUGH */
! 327: case DMBIS:
! 328: wr5 |= val;
! 329: break;
! 330: case DMBIC:
! 331: wr5 &= ~val;
! 332: break;
! 333: case DMGET:
! 334: val = 0;
! 335: rr = getsiocsr(sc->sc_ctl);
! 336: if (wr5 & WR5_DTR)
! 337: val |= TIOCM_DTR;
! 338: if (wr5 & WR5_RTS)
! 339: val |= TIOCM_RTS;
! 340: if (rr & RR_CTS)
! 341: val |= TIOCM_CTS;
! 342: if (rr & RR_DCD)
! 343: val |= TIOCM_CD;
! 344: goto done;
! 345: }
! 346: sc->sc_wr[WR5] = wr5;
! 347: setsioreg(sc->sc_ctl, WR5, wr5);
! 348: val = 0;
! 349: done:
! 350: splx(s);
! 351: return val;
! 352: }
! 353:
! 354: /*-------------------- cdevsw[] interface --------------------*/
! 355:
! 356: int
! 357: sioopen(dev, flag, mode, p)
! 358: dev_t dev;
! 359: int flag, mode;
! 360: struct proc *p;
! 361: {
! 362: struct siotty_softc *sc;
! 363: struct tty *tp;
! 364: int error;
! 365:
! 366: if ((sc = siotty_cd.cd_devs[minor(dev)]) == NULL)
! 367: return ENXIO;
! 368: if ((tp = sc->sc_tty) == NULL) {
! 369: tp = sc->sc_tty = ttymalloc();
! 370: }
! 371: else if ((tp->t_state & TS_ISOPEN) && (tp->t_state & TS_XCLUDE)
! 372: && p->p_ucred->cr_uid != 0)
! 373: return EBUSY;
! 374:
! 375: tp->t_oproc = siostart;
! 376: tp->t_param = sioparam;
! 377: tp->t_hwiflow = NULL /* XXX siohwiflow XXX */;
! 378: tp->t_dev = dev;
! 379: if ((tp->t_state & TS_ISOPEN) == 0) {
! 380: struct termios t;
! 381:
! 382: t.c_ispeed = t.c_ospeed = TTYDEF_SPEED;
! 383: t.c_cflag = TTYDEF_CFLAG;
! 384: tp->t_ospeed = 0; /* force register update */
! 385: (void)sioparam(tp, &t);
! 386: tp->t_iflag = TTYDEF_IFLAG;
! 387: tp->t_oflag = TTYDEF_OFLAG;
! 388: tp->t_lflag = TTYDEF_LFLAG;
! 389: ttychars(tp);
! 390: ttsetwater(tp);
! 391: /* raise RTS and DTR here; but, DTR lead is not wired */
! 392: /* then check DCD condition; but, DCD lead is not wired */
! 393: tp->t_state |= TS_CARR_ON; /* assume detected all the time */
! 394: #if 0
! 395: if ((sc->sc_flags & TIOCFLAG_SOFTCAR)
! 396: || (tp->t_cflag & MDMBUF)
! 397: || (getsiocsr(sc->sc_ctl) & RR_DCD))
! 398: tp->t_state |= TS_CARR_ON;
! 399: else
! 400: tp->t_state &= ~TS_CARR_ON;
! 401: #endif
! 402: }
! 403:
! 404: error = ttyopen(dev, tp);
! 405: if (error > 0)
! 406: return error;
! 407: /*
! 408: return (*tp->t_linesw->l_open)(dev, tp);
! 409: */
! 410: return (*linesw[tp->t_line].l_open)(dev, tp);
! 411: }
! 412:
! 413: int
! 414: sioclose(dev, flag, mode, p)
! 415: dev_t dev;
! 416: int flag, mode;
! 417: struct proc *p;
! 418: {
! 419: struct siotty_softc *sc = siotty_cd.cd_devs[minor(dev)];
! 420: struct tty *tp = sc->sc_tty;
! 421: int s;
! 422:
! 423: /*
! 424: (*tp->t_linesw->l_close)(tp, flag);
! 425: */
! 426: (*linesw[tp->t_line].l_close)(tp, flag);
! 427:
! 428: s = spltty();
! 429: siomctl(sc, TIOCM_BREAK, DMBIC);
! 430: #if 0 /* because unable to feed DTR signal */
! 431: if ((tp->t_cflag & HUPCL)
! 432: || tp->t_wopen || (tp->t_state & TS_ISOPEN) == 0) {
! 433: siomctl(sc, TIOCM_DTR, DMBIC);
! 434: /* Yield CPU time to others for 1 second, then ... */
! 435: siomctl(sc, TIOCM_DTR, DMBIS);
! 436: }
! 437: #endif
! 438: splx(s);
! 439: return ttyclose(tp);
! 440: }
! 441:
! 442: int
! 443: sioread(dev, uio, flag)
! 444: dev_t dev;
! 445: struct uio *uio;
! 446: int flag;
! 447: {
! 448: struct siotty_softc *sc = siotty_cd.cd_devs[minor(dev)];
! 449: struct tty *tp = sc->sc_tty;
! 450:
! 451: /*
! 452: return (*tp->t_linesw->l_read)(tp, uio, flag);
! 453: */
! 454: return (*linesw[tp->t_line].l_read)(tp, uio, flag);
! 455: }
! 456:
! 457: int
! 458: siowrite(dev, uio, flag)
! 459: dev_t dev;
! 460: struct uio *uio;
! 461: int flag;
! 462: {
! 463: struct siotty_softc *sc = siotty_cd.cd_devs[minor(dev)];
! 464: struct tty *tp = sc->sc_tty;
! 465:
! 466: /*
! 467: return (*tp->t_linesw->l_write)(tp, uio, flag);
! 468: */
! 469: return (*linesw[tp->t_line].l_write)(tp, uio, flag);
! 470: }
! 471:
! 472: #if 0
! 473: int
! 474: sioselect(dev, events, p)
! 475: dev_t dev;
! 476: int events;
! 477: struct proc *p;
! 478: {
! 479: struct siotty_softc *sc = siotty_cd.cd_devs[minor(dev)];
! 480: struct tty *tp = sc->sc_tty;
! 481:
! 482: /*
! 483: return ((*tp->t_linesw->l_poll)(tp, events, p));
! 484: */
! 485: return ((*linesw[tp->t_line].l_select)(tp, events, p));
! 486:
! 487: }
! 488: #endif
! 489:
! 490: int
! 491: sioioctl(dev, cmd, data, flag, p)
! 492: dev_t dev;
! 493: u_long cmd;
! 494: caddr_t data;
! 495: int flag;
! 496: struct proc *p;
! 497: {
! 498: struct siotty_softc *sc = siotty_cd.cd_devs[minor(dev)];
! 499: struct tty *tp = sc->sc_tty;
! 500: int error;
! 501:
! 502: /*
! 503: error = (*tp->t_linesw->l_ioctl)(tp, cmd, data, flag, p);
! 504: */
! 505: error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag, p);
! 506: if (error >= 0)
! 507: return error;
! 508:
! 509: error = ttioctl(tp, cmd, data, flag, p);
! 510: if (error >= 0)
! 511: return error;
! 512:
! 513: /* the last resort for TIOC ioctl tranversing */
! 514: switch (cmd) {
! 515: case TIOCSBRK: /* Set the hardware into BREAK condition */
! 516: siomctl(sc, TIOCM_BREAK, DMBIS);
! 517: break;
! 518: case TIOCCBRK: /* Clear the hardware BREAK condition */
! 519: siomctl(sc, TIOCM_BREAK, DMBIC);
! 520: break;
! 521: case TIOCSDTR: /* Assert DTR signal */
! 522: siomctl(sc, TIOCM_DTR|TIOCM_RTS, DMBIS);
! 523: break;
! 524: case TIOCCDTR: /* Clear DTR signal */
! 525: siomctl(sc, TIOCM_DTR|TIOCM_RTS, DMBIC);
! 526: break;
! 527: case TIOCMSET: /* Set modem state replacing current one */
! 528: siomctl(sc, *(int *)data, DMSET);
! 529: break;
! 530: case TIOCMGET: /* Return current modem state */
! 531: *(int *)data = siomctl(sc, 0, DMGET);
! 532: break;
! 533: case TIOCMBIS: /* Set individual bits of modem state */
! 534: siomctl(sc, *(int *)data, DMBIS);
! 535: break;
! 536: case TIOCMBIC: /* Clear individual bits of modem state */
! 537: siomctl(sc, *(int *)data, DMBIC);
! 538: break;
! 539: case TIOCSFLAGS: /* Instruct how serial port behaves */
! 540: error = suser(p, 0);
! 541: if (error != 0)
! 542: return EPERM;
! 543: sc->sc_flags = *(int *)data;
! 544: break;
! 545: case TIOCGFLAGS: /* Return current serial port state */
! 546: *(int *)data = sc->sc_flags;
! 547: break;
! 548: default:
! 549: /*
! 550: return EPASSTHROUGH;
! 551: */
! 552: return ENOTTY;
! 553: }
! 554: return 0;
! 555: }
! 556:
! 557: /* ARSGUSED */
! 558: struct tty *
! 559: siotty(dev)
! 560: dev_t dev;
! 561: {
! 562: struct siotty_softc *sc = siotty_cd.cd_devs[minor(dev)];
! 563:
! 564: return sc->sc_tty;
! 565: }
! 566:
! 567: /*-------------------- miscellaneous routines --------------------*/
! 568:
! 569: /* EXPORT */ void
! 570: setsioreg(sio, regno, val)
! 571: struct sioreg *sio;
! 572: int regno, val;
! 573: {
! 574: if (regno != 0)
! 575: sio->sio_cmd = regno; /* DELAY(); */
! 576: sio->sio_cmd = val; /* DELAY(); */
! 577: }
! 578:
! 579: /* EXPORT */ int
! 580: getsiocsr(sio)
! 581: struct sioreg *sio;
! 582: {
! 583: int val;
! 584:
! 585: val = sio->sio_stat << 8; /* DELAY(); */
! 586: sio->sio_cmd = 1; /* DELAY(); */
! 587: val |= sio->sio_stat; /* DELAY(); */
! 588: return val;
! 589: }
! 590:
! 591: /*--------------------- console interface ----------------------*/
! 592:
! 593: void syscnattach(int);
! 594: int syscngetc(dev_t);
! 595: void syscnputc(dev_t, int);
! 596:
! 597: struct consdev syscons = {
! 598: NULL,
! 599: NULL,
! 600: syscngetc,
! 601: syscnputc,
! 602: nullcnpollc,
! 603: NULL,
! 604: NODEV,
! 605: CN_REMOTE,
! 606: };
! 607:
! 608: /* EXPORT */ void
! 609: syscnattach(channel)
! 610: int channel;
! 611: {
! 612: /*
! 613: * Channel A is immediately initialized with 9600N1 right after cold
! 614: * boot/reset/poweron. ROM monitor emits one line message on CH.A.
! 615: */
! 616: struct sioreg *sio;
! 617: sio = (struct sioreg *)0x51000000 + channel;
! 618:
! 619: /* syscons.cn_dev = makedev(7, channel); */
! 620: syscons.cn_dev = makedev(12, channel);
! 621: cn_tab = &syscons;
! 622:
! 623: #if 0
! 624: setsioreg(sio, WR0, WR0_CHANRST);
! 625: setsioreg(sio, WR2A, WR2_VEC86 | WR2_INTR_1);
! 626: setsioreg(sio, WR2B, 0);
! 627: setsioreg(sio, WR0, ch0_regs[WR0]);
! 628: setsioreg(sio, WR4, ch0_regs[WR4]);
! 629: setsioreg(sio, WR3, ch0_regs[WR3]);
! 630: setsioreg(sio, WR5, ch0_regs[WR5]);
! 631: setsioreg(sio, WR0, ch0_regs[WR0]);
! 632: #endif
! 633: }
! 634:
! 635: /* EXPORT */ int
! 636: syscngetc(dev)
! 637: dev_t dev;
! 638: {
! 639: struct sioreg *sio;
! 640: int s, c;
! 641:
! 642: sio = (struct sioreg *)0x51000000 + ((int)dev & 0x1);
! 643: s = splhigh();
! 644: while ((getsiocsr(sio) & RR_RXRDY) == 0)
! 645: ;
! 646: c = sio->sio_data;
! 647: splx(s);
! 648:
! 649: return c;
! 650: }
! 651:
! 652: /* EXPORT */ void
! 653: syscnputc(dev, c)
! 654: dev_t dev;
! 655: int c;
! 656: {
! 657: struct sioreg *sio;
! 658: int s;
! 659:
! 660: sio = (struct sioreg *)0x51000000 + ((int)dev & 0x1);
! 661: s = splhigh();
! 662: while ((getsiocsr(sio) & RR_TXRDY) == 0)
! 663: ;
! 664: sio->sio_cmd = WR0_RSTPEND;
! 665: sio->sio_data = c;
! 666: splx(s);
! 667: }
CVSweb