1*54008Sfujita /* 2*54008Sfujita * Copyright (c) 1992 OMRON Corporation. 3*54008Sfujita * Copyright (c) 1992 The Regents of the University of California. 4*54008Sfujita * All rights reserved. 5*54008Sfujita * 6*54008Sfujita * This code is derived from software contributed to Berkeley by 7*54008Sfujita * OMRON Corporation. 8*54008Sfujita * 9*54008Sfujita * %sccs.include.redist.c% 10*54008Sfujita * 11*54008Sfujita * @(#)sio.c 7.1 (Berkeley) 06/15/92 12*54008Sfujita */ 13*54008Sfujita 14*54008Sfujita /* 15*54008Sfujita * sio.c -- NEC uPD7201A UART Device Driver 16*54008Sfujita * by A.Fujita, NOV-25-1991 17*54008Sfujita */ 18*54008Sfujita 19*54008Sfujita #include "sio.h" 20*54008Sfujita #if NSIO > 0 21*54008Sfujita 22*54008Sfujita #undef LOCAL_CONSOLE 23*54008Sfujita 24*54008Sfujita /* 25*54008Sfujita * OMRON LUNA internal serial interface 26*54008Sfujita * uese NEC uPD7201A SIO 27*54008Sfujita */ 28*54008Sfujita 29*54008Sfujita #include "sys/param.h" 30*54008Sfujita #include "sys/systm.h" 31*54008Sfujita #include "sys/ioctl.h" 32*54008Sfujita #include "sys/proc.h" 33*54008Sfujita #include "sys/tty.h" 34*54008Sfujita #include "sys/conf.h" 35*54008Sfujita #include "sys/file.h" 36*54008Sfujita #include "sys/uio.h" 37*54008Sfujita #include "sys/kernel.h" 38*54008Sfujita #include "sys/syslog.h" 39*54008Sfujita 40*54008Sfujita #include "device.h" 41*54008Sfujita #include "sioreg.h" 42*54008Sfujita 43*54008Sfujita #define SIO_IPL 6 44*54008Sfujita 45*54008Sfujita int sioprobe(); 46*54008Sfujita struct driver siodriver = { 47*54008Sfujita sioprobe, "sio", 48*54008Sfujita }; 49*54008Sfujita 50*54008Sfujita void siostart(); 51*54008Sfujita int sioparam(), siointr(); 52*54008Sfujita int sio_active; 53*54008Sfujita int sioconsole = -1; 54*54008Sfujita int sioconsinit; 55*54008Sfujita int siodefaultrate = TTYDEF_SPEED; 56*54008Sfujita int siomajor; 57*54008Sfujita struct siodevice *sio_addr[2]; 58*54008Sfujita struct tty sio_tty[NSIO]; 59*54008Sfujita 60*54008Sfujita #define siounit(x) minor(x) 61*54008Sfujita 62*54008Sfujita 63*54008Sfujita #ifndef LOCAL_CONSOLE 64*54008Sfujita 65*54008Sfujita /* 66*54008Sfujita * local buffering 67*54008Sfujita */ 68*54008Sfujita 69*54008Sfujita #define LOCAL_BUFSIZ 128 70*54008Sfujita 71*54008Sfujita struct local_buf { 72*54008Sfujita u_char *push; 73*54008Sfujita u_char *pop; 74*54008Sfujita u_char buf[LOCAL_BUFSIZ+4]; 75*54008Sfujita }; 76*54008Sfujita 77*54008Sfujita struct local_buf rbuf, *rbp = &rbuf; 78*54008Sfujita 79*54008Sfujita 80*54008Sfujita siolbufinit(bp) 81*54008Sfujita register struct local_buf *bp; 82*54008Sfujita { 83*54008Sfujita bp->push = bp->pop = &(bp->buf[LOCAL_BUFSIZ]); 84*54008Sfujita } 85*54008Sfujita 86*54008Sfujita siolbufpush(bp, c) 87*54008Sfujita register struct local_buf *bp; 88*54008Sfujita register int c; 89*54008Sfujita { 90*54008Sfujita 91*54008Sfujita *(--bp->push) = c; 92*54008Sfujita 93*54008Sfujita if (bp->push == &(bp->buf[0])) 94*54008Sfujita bp->push = &(bp->buf[LOCAL_BUFSIZ]); 95*54008Sfujita 96*54008Sfujita if (bp->push == bp->pop) 97*54008Sfujita bp->pop == (u_char *) 0; 98*54008Sfujita } 99*54008Sfujita 100*54008Sfujita int 101*54008Sfujita siolbufpop(bp) 102*54008Sfujita register struct local_buf *bp; 103*54008Sfujita { 104*54008Sfujita register int c; 105*54008Sfujita 106*54008Sfujita if (bp->pop == (u_char *) 0) 107*54008Sfujita bp->pop = bp->push; 108*54008Sfujita 109*54008Sfujita c = *(--bp->pop); 110*54008Sfujita 111*54008Sfujita if (bp->pop == &(bp->buf[0])) 112*54008Sfujita bp->pop = &(bp->buf[LOCAL_BUFSIZ]); 113*54008Sfujita 114*54008Sfujita return(c); 115*54008Sfujita } 116*54008Sfujita 117*54008Sfujita int 118*54008Sfujita siolbufempty(bp) 119*54008Sfujita register struct local_buf *bp; 120*54008Sfujita { 121*54008Sfujita if (bp->push == bp->pop) 122*54008Sfujita return(1); 123*54008Sfujita else 124*54008Sfujita return(0); 125*54008Sfujita } 126*54008Sfujita #endif 127*54008Sfujita 128*54008Sfujita /* 129*54008Sfujita * probing 130*54008Sfujita */ 131*54008Sfujita 132*54008Sfujita sioprobe(hd) 133*54008Sfujita register struct hp_device *hd; 134*54008Sfujita { 135*54008Sfujita register struct siodevice *sio; 136*54008Sfujita register int unit; 137*54008Sfujita 138*54008Sfujita sio = (struct siodevice *)hd->hp_addr; 139*54008Sfujita unit = hd->hp_unit; 140*54008Sfujita 141*54008Sfujita hd->hp_ipl = SIO_IPL; 142*54008Sfujita 143*54008Sfujita /* 144*54008Sfujita * We must set hardware address here. 145*54008Sfujita * but now already it's done. 146*54008Sfujita 147*54008Sfujita sio_addr[unit] = sio; 148*54008Sfujita 149*54008Sfujita */ 150*54008Sfujita 151*54008Sfujita sio_active |= 1 << unit; 152*54008Sfujita 153*54008Sfujita /* 154*54008Sfujita * We must pick up information from hd->hp_flags here. 155*54008Sfujita * It should be used instead of TTYDEF_CFLAG or like something. 156*54008Sfujita * 157*54008Sfujita */ 158*54008Sfujita 159*54008Sfujita #ifdef LOCAL_CONSOLE 160*54008Sfujita 161*54008Sfujita /* 162*54008Sfujita * Enable Interrupt 163*54008Sfujita * I must rewirte basic handlers of console support, 164*54008Sfujita * Because it does not work, if interrupt occar. 165*54008Sfujita * Now using LOCAL_CONSOLE, so the problem isn't happend. 166*54008Sfujita * 167*54008Sfujita */ 168*54008Sfujita 169*54008Sfujita sioreg(REG(unit, WR1), WR1_RXALLS | WR1_TXENBL); 170*54008Sfujita 171*54008Sfujita #endif 172*54008Sfujita if (unit == sioconsole) { 173*54008Sfujita sioconsinit = 0; 174*54008Sfujita } 175*54008Sfujita 176*54008Sfujita return (1); 177*54008Sfujita } 178*54008Sfujita 179*54008Sfujita int 180*54008Sfujita /* ARGSUSED */ 181*54008Sfujita #ifdef __STDC__ 182*54008Sfujita sioopen(dev_t dev, int flag, int mode, struct proc *p) 183*54008Sfujita #else 184*54008Sfujita sioopen(dev, flag, mode, p) 185*54008Sfujita dev_t dev; 186*54008Sfujita int flag, mode; 187*54008Sfujita struct proc *p; 188*54008Sfujita #endif 189*54008Sfujita { 190*54008Sfujita register struct tty *tp; 191*54008Sfujita register int unit; 192*54008Sfujita int error = 0; 193*54008Sfujita 194*54008Sfujita unit = siounit(dev); 195*54008Sfujita if (unit >= NSIO || (sio_active & (1 << unit)) == 0) 196*54008Sfujita return (ENXIO); 197*54008Sfujita 198*54008Sfujita tp = &sio_tty[unit]; 199*54008Sfujita tp->t_oproc = siostart; 200*54008Sfujita tp->t_param = sioparam; 201*54008Sfujita tp->t_dev = dev; 202*54008Sfujita 203*54008Sfujita if ((tp->t_state & TS_ISOPEN) == 0) { 204*54008Sfujita tp->t_state |= TS_WOPEN; 205*54008Sfujita ttychars(tp); 206*54008Sfujita if (tp->t_ispeed == 0) { 207*54008Sfujita tp->t_iflag = TTYDEF_IFLAG; 208*54008Sfujita tp->t_oflag = TTYDEF_OFLAG; 209*54008Sfujita tp->t_cflag = (CREAD | CS8 | HUPCL); 210*54008Sfujita tp->t_lflag = TTYDEF_LFLAG; 211*54008Sfujita tp->t_ispeed = tp->t_ospeed = siodefaultrate; 212*54008Sfujita } 213*54008Sfujita sioparam(tp, &tp->t_termios); 214*54008Sfujita ttsetwater(tp); 215*54008Sfujita } else if (tp->t_state&TS_XCLUDE && p->p_ucred->cr_uid != 0) 216*54008Sfujita return (EBUSY); 217*54008Sfujita 218*54008Sfujita /* 219*54008Sfujita * We must set DTR & RTS here. 220*54008Sfujita * Need a routine like XXXmctl(). 221*54008Sfujita * 222*54008Sfujita */ 223*54008Sfujita 224*54008Sfujita /* 225*54008Sfujita * The next statment should be executed, when Carrier Detected 226*54008Sfujita * or using special serial line which ignore carrier. 227*54008Sfujita * 228*54008Sfujita * Should be checked out RR0, I think. Omit this time. 229*54008Sfujita */ 230*54008Sfujita 231*54008Sfujita tp->t_state |= TS_CARR_ON; 232*54008Sfujita 233*54008Sfujita (void) spltty(); 234*54008Sfujita 235*54008Sfujita while ((flag&O_NONBLOCK) == 0 && (tp->t_cflag&CLOCAL) == 0 && 236*54008Sfujita (tp->t_state & TS_CARR_ON) == 0) { 237*54008Sfujita tp->t_state |= TS_WOPEN; 238*54008Sfujita if (error = ttysleep(tp, (caddr_t)&tp->t_rawq, TTIPRI | PCATCH, 239*54008Sfujita ttopen, 0)) 240*54008Sfujita break; 241*54008Sfujita } 242*54008Sfujita 243*54008Sfujita (void) spl0(); 244*54008Sfujita 245*54008Sfujita if (error == 0) 246*54008Sfujita error = (*linesw[tp->t_line].l_open)(dev, tp); 247*54008Sfujita 248*54008Sfujita return (error); 249*54008Sfujita } 250*54008Sfujita 251*54008Sfujita /*ARGSUSED*/ 252*54008Sfujita sioclose(dev, flag, mode, p) 253*54008Sfujita dev_t dev; 254*54008Sfujita int flag, mode; 255*54008Sfujita struct proc *p; 256*54008Sfujita { 257*54008Sfujita register struct tty *tp; 258*54008Sfujita register struct siodevice *sio; 259*54008Sfujita register int unit; 260*54008Sfujita 261*54008Sfujita unit = siounit(dev); 262*54008Sfujita sio = sio_addr[unit]; 263*54008Sfujita tp = &sio_tty[unit]; 264*54008Sfujita 265*54008Sfujita (*linesw[tp->t_line].l_close)(tp, flag); 266*54008Sfujita 267*54008Sfujita /* 268*54008Sfujita * We must send BREAK to current line here. 269*54008Sfujita * Not supported yet. 270*54008Sfujita */ 271*54008Sfujita 272*54008Sfujita /* 273*54008Sfujita * We must reset DTR & RTS here. 274*54008Sfujita * Need a routine like XXXmctl(). 275*54008Sfujita * 276*54008Sfujita */ 277*54008Sfujita 278*54008Sfujita ttyclose(tp); 279*54008Sfujita return (0); 280*54008Sfujita } 281*54008Sfujita 282*54008Sfujita sioread(dev, uio, flag) 283*54008Sfujita dev_t dev; 284*54008Sfujita struct uio *uio; 285*54008Sfujita int flag; 286*54008Sfujita { 287*54008Sfujita register struct tty *tp = &sio_tty[siounit(dev)]; 288*54008Sfujita 289*54008Sfujita return ((*linesw[tp->t_line].l_read)(tp, uio, flag)); 290*54008Sfujita } 291*54008Sfujita 292*54008Sfujita siowrite(dev, uio, flag) 293*54008Sfujita dev_t dev; 294*54008Sfujita struct uio *uio; 295*54008Sfujita int flag; 296*54008Sfujita { 297*54008Sfujita register struct tty *tp = &sio_tty[siounit(dev)]; 298*54008Sfujita 299*54008Sfujita return ((*linesw[tp->t_line].l_write)(tp, uio, flag)); 300*54008Sfujita } 301*54008Sfujita 302*54008Sfujita siointr() 303*54008Sfujita { 304*54008Sfujita register int unit = 0; 305*54008Sfujita register struct siodevice *sio = sio_addr[unit]; 306*54008Sfujita register u_char code; 307*54008Sfujita register struct tty *tp; 308*54008Sfujita int s, rr; 309*54008Sfujita 310*54008Sfujita rr = siogetreg(unit); 311*54008Sfujita tp = &sio_tty[unit]; 312*54008Sfujita if (rr & RR_RXRDY) { 313*54008Sfujita code = sio->sio_data; 314*54008Sfujita if ((tp->t_state & TS_ISOPEN) != 0) 315*54008Sfujita (*linesw[tp->t_line].l_rint)(code, tp); 316*54008Sfujita #ifndef LOCAL_CONSOLE 317*54008Sfujita else 318*54008Sfujita siolbufpush(rbp, code); 319*54008Sfujita #endif 320*54008Sfujita } 321*54008Sfujita 322*54008Sfujita if (rr & RR_TXRDY) { 323*54008Sfujita sio->sio_cmd = WR0_RSTPEND; 324*54008Sfujita tp->t_state &= ~(TS_BUSY|TS_FLUSH); 325*54008Sfujita if (tp->t_line) 326*54008Sfujita (*linesw[tp->t_line].l_start)(tp); 327*54008Sfujita else 328*54008Sfujita siostart(tp); 329*54008Sfujita } 330*54008Sfujita } 331*54008Sfujita 332*54008Sfujita sioioctl(dev, cmd, data, flag, p) 333*54008Sfujita dev_t dev; 334*54008Sfujita int cmd; 335*54008Sfujita caddr_t data; 336*54008Sfujita int flag; 337*54008Sfujita struct proc *p; 338*54008Sfujita { 339*54008Sfujita register struct tty *tp; 340*54008Sfujita register int unit = siounit(dev); 341*54008Sfujita register struct siodevice *sio; 342*54008Sfujita register int error; 343*54008Sfujita 344*54008Sfujita tp = &sio_tty[unit]; 345*54008Sfujita error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag, p); 346*54008Sfujita if (error >= 0) 347*54008Sfujita return (error); 348*54008Sfujita error = ttioctl(tp, cmd, data, flag); 349*54008Sfujita if (error >= 0) 350*54008Sfujita return (error); 351*54008Sfujita 352*54008Sfujita /* 353*54008Sfujita * We must support flow control of serial lines. 354*54008Sfujita * Not yet. 355*54008Sfujita */ 356*54008Sfujita 357*54008Sfujita sio = sio_addr[unit]; 358*54008Sfujita switch (cmd) { 359*54008Sfujita 360*54008Sfujita case TIOCSBRK: 361*54008Sfujita case TIOCCBRK: 362*54008Sfujita case TIOCSDTR: 363*54008Sfujita case TIOCCDTR: 364*54008Sfujita case TIOCMSET: 365*54008Sfujita case TIOCMBIS: 366*54008Sfujita case TIOCMBIC: 367*54008Sfujita case TIOCMGET: 368*54008Sfujita default: 369*54008Sfujita return (ENOTTY); 370*54008Sfujita } 371*54008Sfujita 372*54008Sfujita return (0); 373*54008Sfujita } 374*54008Sfujita 375*54008Sfujita sioparam(tp, t) 376*54008Sfujita register struct tty *tp; 377*54008Sfujita register struct termios *t; 378*54008Sfujita { 379*54008Sfujita return (0); 380*54008Sfujita } 381*54008Sfujita 382*54008Sfujita void 383*54008Sfujita siostart(tp) 384*54008Sfujita register struct tty *tp; 385*54008Sfujita { 386*54008Sfujita register struct siodevice *sio; 387*54008Sfujita int s, unit, c, rr; 388*54008Sfujita 389*54008Sfujita unit = siounit(tp->t_dev); 390*54008Sfujita sio = sio_addr[unit]; 391*54008Sfujita 392*54008Sfujita s = spltty(); 393*54008Sfujita 394*54008Sfujita if (tp->t_state & (TS_TIMEOUT|TS_TTSTOP)) 395*54008Sfujita goto out; 396*54008Sfujita 397*54008Sfujita if (tp->t_outq.c_cc <= tp->t_lowat) { 398*54008Sfujita if (tp->t_state&TS_ASLEEP) { 399*54008Sfujita tp->t_state &= ~TS_ASLEEP; 400*54008Sfujita wakeup((caddr_t)&tp->t_outq); 401*54008Sfujita } 402*54008Sfujita selwakeup(&tp->t_wsel); 403*54008Sfujita } 404*54008Sfujita 405*54008Sfujita if (tp->t_outq.c_cc == 0) 406*54008Sfujita goto out; 407*54008Sfujita 408*54008Sfujita rr = siogetreg(unit); 409*54008Sfujita if (rr & RR_TXRDY) { 410*54008Sfujita c = getc(&tp->t_outq); 411*54008Sfujita tp->t_state |= TS_BUSY; 412*54008Sfujita sio->sio_data = c; 413*54008Sfujita } 414*54008Sfujita 415*54008Sfujita out: 416*54008Sfujita splx(s); 417*54008Sfujita } 418*54008Sfujita 419*54008Sfujita /* 420*54008Sfujita * Stop output on a line. 421*54008Sfujita */ 422*54008Sfujita /*ARGSUSED*/ 423*54008Sfujita siostop(tp, flag) 424*54008Sfujita register struct tty *tp; 425*54008Sfujita int flag; 426*54008Sfujita { 427*54008Sfujita register int s; 428*54008Sfujita 429*54008Sfujita s = spltty(); 430*54008Sfujita if (tp->t_state & TS_BUSY) { 431*54008Sfujita if ((tp->t_state&TS_TTSTOP)==0) 432*54008Sfujita tp->t_state |= TS_FLUSH; 433*54008Sfujita } 434*54008Sfujita splx(s); 435*54008Sfujita } 436*54008Sfujita 437*54008Sfujita /* 438*54008Sfujita * Following are all routines needed for SIO to act as console 439*54008Sfujita */ 440*54008Sfujita #include "../luna68k/cons.h" 441*54008Sfujita 442*54008Sfujita siocnprobe(cp) 443*54008Sfujita struct consdev *cp; 444*54008Sfujita { 445*54008Sfujita int unit; 446*54008Sfujita 447*54008Sfujita /* Line Selection: 0: Channel-A (ttya), 1: Channel-B (keyboard) */ 448*54008Sfujita unit = 0; 449*54008Sfujita 450*54008Sfujita /* locate the major number */ 451*54008Sfujita for (siomajor = 0; siomajor < nchrdev; siomajor++) 452*54008Sfujita if (cdevsw[siomajor].d_open == sioopen) 453*54008Sfujita break; 454*54008Sfujita 455*54008Sfujita sio_addr[0] = (struct siodevice *) 0x51000000; 456*54008Sfujita sio_addr[1] = (struct siodevice *) 0x51000004; 457*54008Sfujita 458*54008Sfujita /* make sure hardware exists */ 459*54008Sfujita if (badaddr((short *)sio_addr[0])) { 460*54008Sfujita cp->cn_pri = CN_DEAD; 461*54008Sfujita return; 462*54008Sfujita } 463*54008Sfujita 464*54008Sfujita /* locate the major number */ 465*54008Sfujita 466*54008Sfujita /* initialize required fields */ 467*54008Sfujita cp->cn_dev = makedev(siomajor, unit); 468*54008Sfujita cp->cn_tp = 0; 469*54008Sfujita cp->cn_pri = CN_NORMAL; 470*54008Sfujita } 471*54008Sfujita 472*54008Sfujita siocninit(cp) 473*54008Sfujita struct consdev *cp; 474*54008Sfujita { 475*54008Sfujita int unit = siounit(cp->cn_dev); 476*54008Sfujita 477*54008Sfujita sioinit(unit); 478*54008Sfujita sioconsole = unit; 479*54008Sfujita } 480*54008Sfujita 481*54008Sfujita /* 482*54008Sfujita * Routines for Console Support 483*54008Sfujita */ 484*54008Sfujita 485*54008Sfujita 486*54008Sfujita #ifdef LOCAL_CONSOLE 487*54008Sfujita 488*54008Sfujita int local_console; 489*54008Sfujita 490*54008Sfujita siocngetc(dev) 491*54008Sfujita dev_t dev; 492*54008Sfujita { 493*54008Sfujita int c, rr0, rr1; 494*54008Sfujita int unit; 495*54008Sfujita int s; 496*54008Sfujita 497*54008Sfujita unit = local_console; 498*54008Sfujita 499*54008Sfujita s = splhigh(); 500*54008Sfujita loop: 501*54008Sfujita while (((rr0 = sioreg(REG(unit, RR0), 0)) & RR0_RXAVAIL) == 0); 502*54008Sfujita rr1 = sioreg(REG(unit, RR1), 0); 503*54008Sfujita c = sio_addr[unit]->sio_data; 504*54008Sfujita 505*54008Sfujita if ((rr0 & RR0_BREAK) == RR0_BREAK) /* Break Detected */ 506*54008Sfujita goto loop; 507*54008Sfujita 508*54008Sfujita if ((rr1 & RR1_OVERRUN) == RR1_OVERRUN) { /* Data Over Run */ 509*54008Sfujita sioreg(REG(unit, WR0), WR0_ERRRST); 510*54008Sfujita goto loop; 511*54008Sfujita } 512*54008Sfujita 513*54008Sfujita if ((rr1 & RR1_PARITY) == RR1_PARITY) { /* Parity Error */ 514*54008Sfujita sioreg(REG(unit, WR0), WR0_ERRRST); 515*54008Sfujita goto loop; 516*54008Sfujita } 517*54008Sfujita 518*54008Sfujita if ((rr1 & RR1_FRAMING) == RR1_FRAMING) { /* Framing Error */ 519*54008Sfujita sioreg(REG(unit, WR0), WR0_ERRRST); 520*54008Sfujita goto loop; 521*54008Sfujita } 522*54008Sfujita 523*54008Sfujita sioreg(REG(unit, WR0), WR0_RSTPEND); 524*54008Sfujita splx(s); 525*54008Sfujita return(c); 526*54008Sfujita } 527*54008Sfujita 528*54008Sfujita siocnputc(dev, c) 529*54008Sfujita dev_t dev; 530*54008Sfujita int c; 531*54008Sfujita { 532*54008Sfujita int unit; 533*54008Sfujita int s; 534*54008Sfujita 535*54008Sfujita unit = local_console; 536*54008Sfujita 537*54008Sfujita if (sioconsole == -1) { 538*54008Sfujita (void) sioinit(unit); 539*54008Sfujita sioconsole = unit; 540*54008Sfujita } 541*54008Sfujita 542*54008Sfujita s = splhigh(); 543*54008Sfujita 544*54008Sfujita /* wait for any pending transmission to finish */ 545*54008Sfujita while ((sioreg(REG(unit, RR0), 0) & RR0_TXEMPTY) == 0); 546*54008Sfujita 547*54008Sfujita sio_addr[unit]->sio_data = (c & 0xFF); 548*54008Sfujita 549*54008Sfujita /* wait for any pending transmission to finish */ 550*54008Sfujita while ((sioreg(REG(unit, RR0), 0) & RR0_TXEMPTY) == 0); 551*54008Sfujita 552*54008Sfujita splx(s); 553*54008Sfujita } 554*54008Sfujita 555*54008Sfujita sioinit(unit) 556*54008Sfujita int unit; 557*54008Sfujita { 558*54008Sfujita int s; 559*54008Sfujita 560*54008Sfujita s = splhigh(); 561*54008Sfujita 562*54008Sfujita sioreg(REG(unit, WR0), WR0_CHANRST); /* Channel-A Reset */ 563*54008Sfujita sioreg(WR2A, WR2_VEC86 | WR2_INTR_1); /* Set CPU BUS Interface Mode */ 564*54008Sfujita sioreg(WR2B, 0); /* Set Interrupt Vector */ 565*54008Sfujita sioreg(REG(unit, WR0), WR0_RSTINT); /* Reset E/S Interrupt */ 566*54008Sfujita sioreg(REG(unit, WR4), WR4_BAUD96 | WR4_STOP1 | WR4_NPARITY); /* Tx/Rx */ 567*54008Sfujita sioreg(REG(unit, WR3), WR3_RX8BIT | WR3_RXENBL); /* Rx */ 568*54008Sfujita sioreg(REG(unit, WR5), WR5_TX8BIT | WR5_TXENBL); /* Tx */ 569*54008Sfujita sioreg(REG(unit, WR0), WR0_RSTINT); /* Reset E/S Interrupt */ 570*54008Sfujita 571*54008Sfujita unit = local_console = 1 - unit; 572*54008Sfujita 573*54008Sfujita sioreg(REG(unit, WR0), WR0_CHANRST); /* Channel-B Reset */ 574*54008Sfujita 575*54008Sfujita sioreg(REG(unit, WR0), WR0_RSTINT); /* Reset E/S Interrupt */ 576*54008Sfujita sioreg(REG(unit, WR4), WR4_BAUD96 | WR4_STOP1 | WR4_NPARITY); /* Tx/Rx */ 577*54008Sfujita sioreg(REG(unit, WR3), WR3_RX8BIT | WR3_RXENBL); /* Rx */ 578*54008Sfujita sioreg(REG(unit, WR5), WR5_TX8BIT | WR5_TXENBL); /* Tx */ 579*54008Sfujita sioreg(REG(unit, WR0), WR0_RSTINT); /* Reset E/S Interrupt */ 580*54008Sfujita 581*54008Sfujita splx(s); 582*54008Sfujita } 583*54008Sfujita #else 584*54008Sfujita 585*54008Sfujita /* 586*54008Sfujita * console put & get 587*54008Sfujita */ 588*54008Sfujita 589*54008Sfujita siocngetc(dev) 590*54008Sfujita dev_t dev; 591*54008Sfujita { 592*54008Sfujita while (siolbufempty(rbp)) 593*54008Sfujita DELAY(10); 594*54008Sfujita 595*54008Sfujita return(siolbufpop(rbp)); 596*54008Sfujita } 597*54008Sfujita 598*54008Sfujita siocnputc(dev, c) 599*54008Sfujita dev_t dev; 600*54008Sfujita int c; 601*54008Sfujita { 602*54008Sfujita register int unit = siounit(dev); 603*54008Sfujita register struct siodevice *sio = sio_addr[unit]; 604*54008Sfujita register u_char code; 605*54008Sfujita int s, rr; 606*54008Sfujita 607*54008Sfujita s = splhigh(); 608*54008Sfujita sioreg(REG(unit, WR1), WR1_RXALLS); 609*54008Sfujita 610*54008Sfujita do { 611*54008Sfujita DELAY(1); 612*54008Sfujita rr = siogetreg(unit); 613*54008Sfujita } while (!(rr & RR_TXRDY)); 614*54008Sfujita 615*54008Sfujita code = (c & 0xff); 616*54008Sfujita sio->sio_data = code; 617*54008Sfujita 618*54008Sfujita do { 619*54008Sfujita DELAY(1); 620*54008Sfujita rr = siogetreg(unit); 621*54008Sfujita } while (!(rr & RR_TXRDY)); 622*54008Sfujita 623*54008Sfujita sioreg(REG(unit, WR1), WR1_RXALLS | WR1_TXENBL); 624*54008Sfujita splx(s); 625*54008Sfujita } 626*54008Sfujita 627*54008Sfujita sioinit(unit) 628*54008Sfujita int unit; 629*54008Sfujita { 630*54008Sfujita int s; 631*54008Sfujita 632*54008Sfujita siolbufinit(rbp); 633*54008Sfujita 634*54008Sfujita s = splhigh(); 635*54008Sfujita 636*54008Sfujita unit = 0; 637*54008Sfujita 638*54008Sfujita sioreg(REG(unit, WR0), WR0_CHANRST); /* Channel-A Reset */ 639*54008Sfujita sioreg(WR2A, WR2_VEC86 | WR2_INTR_1); /* Set CPU BUS Interface Mode */ 640*54008Sfujita sioreg(WR2B, 0); /* Set Interrupt Vector */ 641*54008Sfujita sioreg(REG(unit, WR0), WR0_RSTINT); /* Reset E/S Interrupt */ 642*54008Sfujita sioreg(REG(unit, WR4), WR4_BAUD96 | WR4_STOP1 | WR4_NPARITY); /* Tx/Rx */ 643*54008Sfujita sioreg(REG(unit, WR3), WR3_RX8BIT | WR3_RXENBL); /* Rx */ 644*54008Sfujita sioreg(REG(unit, WR5), WR5_TX8BIT | WR5_TXENBL); /* Tx */ 645*54008Sfujita sioreg(REG(unit, WR0), WR0_RSTINT); /* Reset E/S Interrupt */ 646*54008Sfujita sioreg(REG(unit, WR1), WR1_RXALLS | WR1_TXENBL); 647*54008Sfujita 648*54008Sfujita unit = 1; 649*54008Sfujita 650*54008Sfujita sioreg(REG(unit, WR0), WR0_CHANRST); /* Channel-A Reset */ 651*54008Sfujita 652*54008Sfujita sioreg(REG(unit, WR0), WR0_RSTINT); /* Reset E/S Interrupt */ 653*54008Sfujita sioreg(REG(unit, WR4), WR4_BAUD96 | WR4_STOP1 | WR4_NPARITY); /* Tx/Rx */ 654*54008Sfujita sioreg(REG(unit, WR3), WR3_RX8BIT | WR3_RXENBL); /* Rx */ 655*54008Sfujita sioreg(REG(unit, WR5), WR5_TX8BIT | WR5_TXENBL); /* Tx */ 656*54008Sfujita sioreg(REG(unit, WR0), WR0_RSTINT); /* Reset E/S Interrupt */ 657*54008Sfujita sioreg(REG(unit, WR1), WR1_RXALLS | WR1_TXENBL); 658*54008Sfujita 659*54008Sfujita splx(s); 660*54008Sfujita } 661*54008Sfujita #endif 662*54008Sfujita 663*54008Sfujita int 664*54008Sfujita siogetreg(unit) 665*54008Sfujita register int unit; 666*54008Sfujita { 667*54008Sfujita register struct siodevice *sio = sio_addr[unit]; 668*54008Sfujita register int rr = 0; 669*54008Sfujita 670*54008Sfujita rr = sio->sio_stat; 671*54008Sfujita rr <<= 8; 672*54008Sfujita sio->sio_cmd = 1; /* Select RR1 */ 673*54008Sfujita rr |= sio->sio_stat; 674*54008Sfujita 675*54008Sfujita return(rr); 676*54008Sfujita } 677*54008Sfujita 678*54008Sfujita int 679*54008Sfujita sioreg(reg, val) 680*54008Sfujita register int reg, val; 681*54008Sfujita { 682*54008Sfujita register int chan; 683*54008Sfujita 684*54008Sfujita chan = CHANNEL(reg); 685*54008Sfujita 686*54008Sfujita if (isStatusReg(reg)) { 687*54008Sfujita if (REGNO(reg) != 0) 688*54008Sfujita sio_addr[chan]->sio_cmd = REGNO(reg); 689*54008Sfujita return(sio_addr[chan]->sio_stat); 690*54008Sfujita } else { 691*54008Sfujita if (REGNO(reg) != 0) 692*54008Sfujita sio_addr[chan]->sio_cmd = REGNO(reg); 693*54008Sfujita sio_addr[chan]->sio_cmd = val; 694*54008Sfujita return(val); 695*54008Sfujita } 696*54008Sfujita } 697*54008Sfujita #endif 698