1*56876Sakito /* 2*56876Sakito * Copyright (c) 1992 OMRON Corporation. 3*56876Sakito * Copyright (c) 1992 The Regents of the University of California. 4*56876Sakito * All rights reserved. 5*56876Sakito * 6*56876Sakito * This code is derived from software contributed to Berkeley by 7*56876Sakito * OMRON Corporation. 8*56876Sakito * 9*56876Sakito * %sccs.include.redist.c% 10*56876Sakito * 11*56876Sakito * @(#)bmc.c 7.1 (Berkeley) 11/17/92 12*56876Sakito */ 13*56876Sakito 14*56876Sakito #define BMC_NOCONSOLE 15*56876Sakito #define BMD 16*56876Sakito 17*56876Sakito #ifdef BMD 18*56876Sakito #define BMC_CNPORT 1 19*56876Sakito #else 20*56876Sakito #define BMC_CNPORT 0 21*56876Sakito #endif 22*56876Sakito 23*56876Sakito #include "bmc.h" 24*56876Sakito #if NBMC > 0 25*56876Sakito 26*56876Sakito #include "sys/param.h" 27*56876Sakito #include "sys/systm.h" 28*56876Sakito #include "sys/ioctl.h" 29*56876Sakito #include "sys/proc.h" 30*56876Sakito #include "sys/tty.h" 31*56876Sakito #include "sys/conf.h" 32*56876Sakito #include "sys/file.h" 33*56876Sakito #include "sys/uio.h" 34*56876Sakito #include "sys/kernel.h" 35*56876Sakito #include "sys/syslog.h" 36*56876Sakito 37*56876Sakito #include "device.h" 38*56876Sakito #include "sioreg.h" 39*56876Sakito #include "siovar.h" 40*56876Sakito 41*56876Sakito #ifdef BMD 42*56876Sakito #include "kbdreg.h" 43*56876Sakito #endif 44*56876Sakito 45*56876Sakito extern struct sio_portc *sio_port_assign(); 46*56876Sakito 47*56876Sakito int bmcprobe(); 48*56876Sakito int bmcopen(); 49*56876Sakito void bmcstart(); 50*56876Sakito int bmcparam(); 51*56876Sakito int bmcintr(); 52*56876Sakito 53*56876Sakito struct driver bmcdriver = { 54*56876Sakito bmcprobe, "bmc", 55*56876Sakito }; 56*56876Sakito 57*56876Sakito struct bmc_softc { 58*56876Sakito struct sio_portc *sc_pc; 59*56876Sakito int sc_mask; 60*56876Sakito }; 61*56876Sakito 62*56876Sakito struct bmc_softc bmc_softc[NBMC]; 63*56876Sakito 64*56876Sakito struct tty bmc_tty[NBMC]; 65*56876Sakito 66*56876Sakito int bmc_config_done = 0; 67*56876Sakito 68*56876Sakito int bmcconsole; 69*56876Sakito int bmcdefaultrate = B9600; /* speed of console line is fixed */ 70*56876Sakito int bmcmajor = 0; 71*56876Sakito 72*56876Sakito #define bmcunit(x) minor(x) 73*56876Sakito 74*56876Sakito 75*56876Sakito /* 76*56876Sakito * probe routine 77*56876Sakito */ 78*56876Sakito 79*56876Sakito bmcprobe(hd) 80*56876Sakito register struct hp_device *hd; 81*56876Sakito { 82*56876Sakito } 83*56876Sakito 84*56876Sakito bmcinit(port) 85*56876Sakito register int port; 86*56876Sakito { 87*56876Sakito register struct bmc_softc *sc = &bmc_softc[0]; 88*56876Sakito 89*56876Sakito /* 90*56876Sakito * if BMC is already configured, should be skipped. 91*56876Sakito */ 92*56876Sakito if (bmc_config_done) 93*56876Sakito return(0); 94*56876Sakito 95*56876Sakito /* 96*56876Sakito * Check out bitmap Interface board 97*56876Sakito */ 98*56876Sakito 99*56876Sakito /* port checking (for keyboard) */ 100*56876Sakito if (port != 1) 101*56876Sakito return(0); 102*56876Sakito 103*56876Sakito /* locate the major number */ 104*56876Sakito for (bmcmajor = 0; bmcmajor < nchrdev; bmcmajor++) 105*56876Sakito if (cdevsw[bmcmajor].d_open == bmcopen) 106*56876Sakito break; 107*56876Sakito 108*56876Sakito sc->sc_pc = sio_port_assign(port, bmcmajor, 0, bmcintr); 109*56876Sakito 110*56876Sakito printf("bmc%d: port %d, address 0x%x\n", sc->sc_pc->pc_unit, port, sc->sc_pc->pc_addr); 111*56876Sakito 112*56876Sakito #ifdef BMD 113*56876Sakito bmdinit(); 114*56876Sakito #endif 115*56876Sakito 116*56876Sakito bmc_config_done = 1; 117*56876Sakito return(1); 118*56876Sakito } 119*56876Sakito 120*56876Sakito 121*56876Sakito /* 122*56876Sakito * entry routines 123*56876Sakito */ 124*56876Sakito 125*56876Sakito /* ARGSUSED */ 126*56876Sakito #ifdef __STDC__ 127*56876Sakito bmcopen(dev_t dev, int flag, int mode, struct proc *p) 128*56876Sakito #else 129*56876Sakito bmcopen(dev, flag, mode, p) 130*56876Sakito dev_t dev; 131*56876Sakito int flag, mode; 132*56876Sakito struct proc *p; 133*56876Sakito #endif 134*56876Sakito { 135*56876Sakito register struct tty *tp; 136*56876Sakito register int unit; 137*56876Sakito int error = 0; 138*56876Sakito 139*56876Sakito unit = bmcunit(dev); 140*56876Sakito if (unit >= NBMC) 141*56876Sakito return (ENXIO); 142*56876Sakito tp = &bmc_tty[unit]; 143*56876Sakito tp->t_oproc = bmcstart; 144*56876Sakito tp->t_param = bmcparam; 145*56876Sakito tp->t_dev = dev; 146*56876Sakito if ((tp->t_state & TS_ISOPEN) == 0) { 147*56876Sakito tp->t_state |= TS_WOPEN; 148*56876Sakito ttychars(tp); 149*56876Sakito if (tp->t_ispeed == 0) { 150*56876Sakito tp->t_iflag = TTYDEF_IFLAG; 151*56876Sakito tp->t_oflag = TTYDEF_OFLAG; 152*56876Sakito tp->t_cflag = TTYDEF_CFLAG; 153*56876Sakito /* tp->t_cflag = (CREAD | CS8 | HUPCL); */ 154*56876Sakito tp->t_lflag = TTYDEF_LFLAG; 155*56876Sakito tp->t_ispeed = tp->t_ospeed = bmcdefaultrate; 156*56876Sakito } 157*56876Sakito bmcparam(tp, &tp->t_termios); 158*56876Sakito ttsetwater(tp); 159*56876Sakito } else if (tp->t_state&TS_XCLUDE && p->p_ucred->cr_uid != 0) 160*56876Sakito return (EBUSY); 161*56876Sakito tp->t_state |= TS_CARR_ON; 162*56876Sakito (void) spltty(); 163*56876Sakito while ((flag&O_NONBLOCK) == 0 && (tp->t_cflag&CLOCAL) == 0 && 164*56876Sakito (tp->t_state & TS_CARR_ON) == 0) { 165*56876Sakito tp->t_state |= TS_WOPEN; 166*56876Sakito if (error = ttysleep(tp, (caddr_t)&tp->t_rawq, TTIPRI | PCATCH, 167*56876Sakito ttopen, 0)) 168*56876Sakito break; 169*56876Sakito } 170*56876Sakito (void) spl0(); 171*56876Sakito if (error == 0) 172*56876Sakito error = (*linesw[tp->t_line].l_open)(dev, tp); 173*56876Sakito 174*56876Sakito return (error); 175*56876Sakito } 176*56876Sakito 177*56876Sakito /*ARGSUSED*/ 178*56876Sakito bmcclose(dev, flag, mode, p) 179*56876Sakito dev_t dev; 180*56876Sakito int flag, mode; 181*56876Sakito struct proc *p; 182*56876Sakito { 183*56876Sakito register struct tty *tp; 184*56876Sakito register int unit; 185*56876Sakito 186*56876Sakito unit = bmcunit(dev); 187*56876Sakito tp = &bmc_tty[unit]; 188*56876Sakito (*linesw[tp->t_line].l_close)(tp, flag); 189*56876Sakito ttyclose(tp); 190*56876Sakito return (0); 191*56876Sakito } 192*56876Sakito 193*56876Sakito bmcread(dev, uio, flag) 194*56876Sakito dev_t dev; 195*56876Sakito struct uio *uio; 196*56876Sakito { 197*56876Sakito register struct tty *tp = &bmc_tty[bmcunit(dev)]; 198*56876Sakito 199*56876Sakito return ((*linesw[tp->t_line].l_read)(tp, uio, flag)); 200*56876Sakito } 201*56876Sakito 202*56876Sakito bmcwrite(dev, uio, flag) 203*56876Sakito dev_t dev; 204*56876Sakito struct uio *uio; 205*56876Sakito { 206*56876Sakito register struct tty *tp = &bmc_tty[bmcunit(dev)]; 207*56876Sakito 208*56876Sakito return ((*linesw[tp->t_line].l_write)(tp, uio, flag)); 209*56876Sakito } 210*56876Sakito 211*56876Sakito /* 212*56876Sakito * Stop output on a line. 213*56876Sakito */ 214*56876Sakito /*ARGSUSED*/ 215*56876Sakito bmcstop(tp, flag) 216*56876Sakito register struct tty *tp; 217*56876Sakito { 218*56876Sakito register int s; 219*56876Sakito 220*56876Sakito s = spltty(); 221*56876Sakito if (tp->t_state & TS_BUSY) { 222*56876Sakito if ((tp->t_state&TS_TTSTOP)==0) 223*56876Sakito tp->t_state |= TS_FLUSH; 224*56876Sakito } 225*56876Sakito splx(s); 226*56876Sakito } 227*56876Sakito 228*56876Sakito bmcioctl(dev, cmd, data, flag, p) 229*56876Sakito dev_t dev; 230*56876Sakito int cmd; 231*56876Sakito caddr_t data; 232*56876Sakito int flag; 233*56876Sakito struct proc *p; 234*56876Sakito { 235*56876Sakito register struct tty *tp; 236*56876Sakito register int unit = bmcunit(dev); 237*56876Sakito register int error; 238*56876Sakito 239*56876Sakito tp = &bmc_tty[unit]; 240*56876Sakito error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag, p); 241*56876Sakito if (error >= 0) 242*56876Sakito return (error); 243*56876Sakito error = ttioctl(tp, cmd, data, flag); 244*56876Sakito if (error >= 0) 245*56876Sakito return (error); 246*56876Sakito 247*56876Sakito switch (cmd) { 248*56876Sakito default: 249*56876Sakito return (ENOTTY); 250*56876Sakito } 251*56876Sakito return (0); 252*56876Sakito } 253*56876Sakito 254*56876Sakito /* 255*56876Sakito * 256*56876Sakito */ 257*56876Sakito #ifdef BMD 258*56876Sakito void 259*56876Sakito bmcstart(tp) 260*56876Sakito register struct tty *tp; 261*56876Sakito { 262*56876Sakito int unit = bmcunit(tp->t_dev); 263*56876Sakito register struct bmc_softc *sc = &bmc_softc[unit]; 264*56876Sakito register int cc, s; 265*56876Sakito int hiwat = 0; 266*56876Sakito 267*56876Sakito s = spltty(); 268*56876Sakito if (tp->t_state & (TS_TIMEOUT|TS_BUSY|TS_TTSTOP)) { 269*56876Sakito splx(s); 270*56876Sakito return; 271*56876Sakito } 272*56876Sakito tp->t_state |= TS_BUSY; 273*56876Sakito cc = tp->t_outq.c_cc; 274*56876Sakito if (cc <= tp->t_lowat) { 275*56876Sakito if (tp->t_state & TS_ASLEEP) { 276*56876Sakito tp->t_state &= ~TS_ASLEEP; 277*56876Sakito wakeup((caddr_t)&tp->t_outq); 278*56876Sakito } 279*56876Sakito selwakeup(&tp->t_wsel); 280*56876Sakito } 281*56876Sakito /* 282*56876Sakito * Limit the amount of output we do in one burst 283*56876Sakito * to prevent hogging the CPU. 284*56876Sakito */ 285*56876Sakito /* 286*56876Sakito if (cc > iteburst) { 287*56876Sakito hiwat++; 288*56876Sakito cc = iteburst; 289*56876Sakito } 290*56876Sakito */ 291*56876Sakito while (--cc >= 0) { 292*56876Sakito register int c; 293*56876Sakito 294*56876Sakito c = getc(&tp->t_outq); 295*56876Sakito /* 296*56876Sakito * iteputchar() may take a long time and we don't want to 297*56876Sakito * block all interrupts for long periods of time. Since 298*56876Sakito * there is no need to stay at high priority while outputing 299*56876Sakito * the character (since we don't have to worry about 300*56876Sakito * interrupts), we don't. We just need to make sure that 301*56876Sakito * we don't reenter iteputchar, which is guarenteed by the 302*56876Sakito * earlier setting of TS_BUSY. 303*56876Sakito */ 304*56876Sakito splx(s); 305*56876Sakito bmdputc(c & sc->sc_mask); 306*56876Sakito spltty(); 307*56876Sakito } 308*56876Sakito /* 309*56876Sakito if (hiwat) { 310*56876Sakito tp->t_state |= TS_TIMEOUT; 311*56876Sakito timeout(ttrstrt, tp, 1); 312*56876Sakito } 313*56876Sakito */ 314*56876Sakito tp->t_state &= ~TS_BUSY; 315*56876Sakito splx(s); 316*56876Sakito } 317*56876Sakito #else 318*56876Sakito void 319*56876Sakito bmcstart(tp) 320*56876Sakito register struct tty *tp; 321*56876Sakito { 322*56876Sakito register struct siodevice *sio; 323*56876Sakito register int rr; 324*56876Sakito int s, unit, c; 325*56876Sakito 326*56876Sakito unit = bmcunit(tp->t_dev); 327*56876Sakito sio = bmc_softc[unit].sc_pc->pc_addr; 328*56876Sakito s = spltty(); 329*56876Sakito if (tp->t_state & (TS_TIMEOUT|TS_TTSTOP)) 330*56876Sakito goto out; 331*56876Sakito if (tp->t_outq.c_cc <= tp->t_lowat) { 332*56876Sakito if (tp->t_state&TS_ASLEEP) { 333*56876Sakito tp->t_state &= ~TS_ASLEEP; 334*56876Sakito wakeup((caddr_t)&tp->t_outq); 335*56876Sakito } 336*56876Sakito selwakeup(&tp->t_wsel); 337*56876Sakito } 338*56876Sakito if (tp->t_outq.c_cc == 0) 339*56876Sakito goto out; 340*56876Sakito rr = siogetreg(sio); 341*56876Sakito if (rr & RR_TXRDY) { 342*56876Sakito c = getc(&tp->t_outq); 343*56876Sakito tp->t_state |= TS_BUSY; 344*56876Sakito sio->sio_data = c; 345*56876Sakito } 346*56876Sakito out: 347*56876Sakito splx(s); 348*56876Sakito } 349*56876Sakito #endif 350*56876Sakito 351*56876Sakito bmcparam(tp, t) 352*56876Sakito register struct tty *tp; 353*56876Sakito register struct termios *t; 354*56876Sakito { 355*56876Sakito int unit = bmcunit(tp->t_dev); 356*56876Sakito register struct bmc_softc *sc = &bmc_softc[unit]; 357*56876Sakito register int cflag = t->c_cflag; 358*56876Sakito 359*56876Sakito /* and copy to tty */ 360*56876Sakito tp->t_ispeed = t->c_ispeed; 361*56876Sakito tp->t_ospeed = t->c_ospeed; 362*56876Sakito tp->t_cflag = cflag; 363*56876Sakito 364*56876Sakito /* 365*56876Sakito * change line speed 366*56876Sakito */ 367*56876Sakito 368*56876Sakito switch (cflag&CSIZE) { 369*56876Sakito case CS5: 370*56876Sakito sc->sc_mask = 0x1F ; break; 371*56876Sakito case CS6: 372*56876Sakito sc->sc_mask = 0x3F ; break; 373*56876Sakito case CS7: 374*56876Sakito sc->sc_mask = 0x7F ; break; 375*56876Sakito case CS8: 376*56876Sakito sc->sc_mask = 0xFF ; break; 377*56876Sakito } 378*56876Sakito 379*56876Sakito /* 380*56876Sakito * parity 381*56876Sakito */ 382*56876Sakito 383*56876Sakito /* 384*56876Sakito * stop bit 385*56876Sakito */ 386*56876Sakito 387*56876Sakito return (0); 388*56876Sakito } 389*56876Sakito 390*56876Sakito 391*56876Sakito /* 392*56876Sakito * interrupt handling 393*56876Sakito */ 394*56876Sakito 395*56876Sakito #ifdef BMD 396*56876Sakito bmcintr(unit) 397*56876Sakito register int unit; 398*56876Sakito { 399*56876Sakito register struct siodevice *sio = bmc_softc[unit].sc_pc->pc_addr; 400*56876Sakito register struct tty *tp; 401*56876Sakito register u_char code; 402*56876Sakito register int c; 403*56876Sakito int s, rr; 404*56876Sakito 405*56876Sakito tp = &bmc_tty[unit]; 406*56876Sakito rr = siogetreg(sio); 407*56876Sakito 408*56876Sakito if (rr & RR_RXRDY) { 409*56876Sakito code = sio->sio_data; 410*56876Sakito c = kbd_decode(code); 411*56876Sakito if (c & KC_TYPE) /* skip special codes */ 412*56876Sakito return; 413*56876Sakito code = (c & KC_CHAR); 414*56876Sakito if ((tp->t_state & TS_ISOPEN) != 0) 415*56876Sakito (*linesw[tp->t_line].l_rint)(code, tp); 416*56876Sakito } 417*56876Sakito } 418*56876Sakito #else 419*56876Sakito bmcintr(unit) 420*56876Sakito register int unit; 421*56876Sakito { 422*56876Sakito register struct siodevice *sio = bmc_softc[unit].sc_pc->pc_addr; 423*56876Sakito register u_char code; 424*56876Sakito register struct tty *tp; 425*56876Sakito int s, rr; 426*56876Sakito 427*56876Sakito tp = &bmc_tty[unit]; 428*56876Sakito rr = siogetreg(sio); 429*56876Sakito 430*56876Sakito if (rr & RR_RXRDY) { 431*56876Sakito code = sio->sio_data; 432*56876Sakito if ((tp->t_state & TS_ISOPEN) != 0) 433*56876Sakito (*linesw[tp->t_line].l_rint)(code, tp); 434*56876Sakito } 435*56876Sakito 436*56876Sakito if (rr & RR_TXRDY) { 437*56876Sakito sio->sio_cmd = WR0_RSTPEND; 438*56876Sakito tp->t_state &= ~(TS_BUSY|TS_FLUSH); 439*56876Sakito if (tp->t_line) 440*56876Sakito (*linesw[tp->t_line].l_start)(tp); 441*56876Sakito else 442*56876Sakito bmcstart(tp); 443*56876Sakito } 444*56876Sakito 445*56876Sakito } 446*56876Sakito #endif 447*56876Sakito 448*56876Sakito /* 449*56876Sakito * Following are all routines needed for SIO to act as console 450*56876Sakito */ 451*56876Sakito #include "../luna68k/cons.h" 452*56876Sakito 453*56876Sakito bmccnprobe(cp) 454*56876Sakito register struct consdev *cp; 455*56876Sakito { 456*56876Sakito #ifdef BMC_NOCONSOLE 457*56876Sakito cp->cn_pri = CN_DEAD; 458*56876Sakito return; 459*56876Sakito #else 460*56876Sakito /* check DIP-SW setup */ 461*56876Sakito /* check bitmap interface board */ 462*56876Sakito 463*56876Sakito /* locate the major number */ 464*56876Sakito for (bmcmajor = 0; bmcmajor < nchrdev; bmcmajor++) 465*56876Sakito if (cdevsw[bmcmajor].d_open == bmcopen) 466*56876Sakito break; 467*56876Sakito 468*56876Sakito /* initialize required fields */ 469*56876Sakito cp->cn_dev = makedev(bmcmajor, 0); 470*56876Sakito cp->cn_tp = &bmc_tty[0]; 471*56876Sakito cp->cn_pri = CN_INTERNAL; 472*56876Sakito 473*56876Sakito bmc_config_done = 1; 474*56876Sakito #endif 475*56876Sakito } 476*56876Sakito 477*56876Sakito bmccninit(cp) 478*56876Sakito struct consdev *cp; 479*56876Sakito { 480*56876Sakito int unit = bmcunit(cp->cn_dev); 481*56876Sakito register struct bmc_softc *sc = &bmc_softc[0]; 482*56876Sakito 483*56876Sakito sioinit((struct siodevice *) SIO_HARDADDR, bmcdefaultrate); 484*56876Sakito #ifdef BMD 485*56876Sakito bmdinit(); 486*56876Sakito #endif 487*56876Sakito 488*56876Sakito /* port assign */ 489*56876Sakito sc->sc_pc = sio_port_assign(BMC_CNPORT, bmcmajor, 0, bmcintr); 490*56876Sakito 491*56876Sakito bmcconsole = unit; 492*56876Sakito } 493*56876Sakito 494*56876Sakito bmccngetc(dev) 495*56876Sakito dev_t dev; 496*56876Sakito { 497*56876Sakito struct bmc_softc *sc = &bmc_softc[bmcunit(dev)]; 498*56876Sakito struct sio_portc *pc = sc->sc_pc; 499*56876Sakito #ifdef BMD 500*56876Sakito register int c; 501*56876Sakito register u_char code; 502*56876Sakito 503*56876Sakito do { 504*56876Sakito code = sio_imgetc(pc->pc_addr); 505*56876Sakito } while ((c = kbd_decode(code)) & KC_TYPE); 506*56876Sakito 507*56876Sakito return(c); 508*56876Sakito #else 509*56876Sakito return(sio_imgetc(pc->pc_addr)); 510*56876Sakito #endif 511*56876Sakito } 512*56876Sakito 513*56876Sakito bmccnputc(dev, c) 514*56876Sakito dev_t dev; 515*56876Sakito int c; 516*56876Sakito { 517*56876Sakito struct bmc_softc *sc = &bmc_softc[bmcunit(dev)]; 518*56876Sakito struct sio_portc *pc = sc->sc_pc; 519*56876Sakito 520*56876Sakito #ifdef BMD 521*56876Sakito bmdputc(c); 522*56876Sakito #else 523*56876Sakito sio_imputc(pc->pc_addr, c); 524*56876Sakito #endif 525*56876Sakito } 526*56876Sakito #endif 527