1 /* $OpenBSD: sab.c,v 1.37 2019/10/12 15:55:31 cheloha Exp $ */ 2 3 /* 4 * Copyright (c) 2001 Jason L. Wright (jason@thought.net) 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 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, 20 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 22 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 24 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 25 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 26 * POSSIBILITY OF SUCH DAMAGE. 27 * 28 * Effort sponsored in part by the Defense Advanced Research Projects 29 * Agency (DARPA) and Air Force Research Laboratory, Air Force 30 * Materiel Command, USAF, under agreement number F30602-01-2-0537. 31 * 32 */ 33 34 /* 35 * SAB82532 Dual UART driver 36 */ 37 38 #include <sys/param.h> 39 #include <sys/systm.h> 40 #include <sys/device.h> 41 #include <sys/conf.h> 42 #include <sys/fcntl.h> 43 #include <sys/ioctl.h> 44 #include <sys/kernel.h> 45 #include <sys/proc.h> 46 #include <sys/tty.h> 47 #include <sys/time.h> 48 #include <sys/syslog.h> 49 50 #include <machine/autoconf.h> 51 #include <machine/openfirm.h> 52 #include <machine/conf.h> 53 #include <machine/cpu.h> 54 #include <machine/psl.h> 55 56 #include <dev/cons.h> 57 #include <ddb/db_output.h> 58 59 #include <sparc64/dev/ebusreg.h> 60 #include <sparc64/dev/ebusvar.h> 61 #include <sparc64/dev/cons.h> 62 #include <sparc64/dev/sab82532reg.h> 63 64 #define SAB_CARD(x) ((minor(x) >> 6) & 3) 65 #define SAB_PORT(x) (minor(x) & 7) 66 #define SAB_DIALOUT(x) (minor(x) & 0x10) 67 #define SABTTY_RBUF_SIZE 1024 /* must be divisible by 2 */ 68 69 struct sab_softc { 70 struct device sc_dv; 71 struct intrhand * sc_ih; 72 bus_space_tag_t sc_bt; 73 bus_space_handle_t sc_bh; 74 struct sabtty_softc * sc_child[SAB_NCHAN]; 75 u_int sc_nchild; 76 void * sc_softintr; 77 int sc_node; 78 }; 79 80 struct sabtty_attach_args { 81 u_int sbt_portno; 82 }; 83 84 struct sabtty_softc { 85 struct device sc_dv; 86 struct sab_softc * sc_parent; 87 bus_space_tag_t sc_bt; 88 bus_space_handle_t sc_bh; 89 struct tty * sc_tty; 90 u_int sc_portno; 91 u_int8_t sc_pvr_dtr, sc_pvr_dsr; 92 u_int8_t sc_imr0, sc_imr1; 93 int sc_openflags; 94 u_char * sc_txp; 95 int sc_txc; 96 int sc_flags; 97 #define SABTTYF_STOP 0x01 98 #define SABTTYF_DONE 0x02 99 #define SABTTYF_RINGOVERFLOW 0x04 100 #define SABTTYF_CDCHG 0x08 101 #define SABTTYF_CONS_IN 0x10 102 #define SABTTYF_CONS_OUT 0x20 103 #define SABTTYF_TXDRAIN 0x40 104 #define SABTTYF_DONTDDB 0x80 105 int sc_speed; 106 u_int8_t sc_rbuf[SABTTY_RBUF_SIZE]; 107 u_int8_t *sc_rend, *sc_rput, *sc_rget; 108 u_int8_t sc_polling, sc_pollrfc; 109 }; 110 111 struct sabtty_softc *sabtty_cons_input; 112 struct sabtty_softc *sabtty_cons_output; 113 114 #define SAB_READ(sc,r) \ 115 bus_space_read_1((sc)->sc_bt, (sc)->sc_bh, (r)) 116 #define SAB_WRITE(sc,r,v) \ 117 bus_space_write_1((sc)->sc_bt, (sc)->sc_bh, (r), (v)) 118 #define SAB_WRITE_BLOCK(sc,r,p,c) \ 119 bus_space_write_region_1((sc)->sc_bt, (sc)->sc_bh, (r), (p), (c)) 120 121 int sab_match(struct device *, void *, void *); 122 void sab_attach(struct device *, struct device *, void *); 123 124 int sab_print(void *, const char *); 125 int sab_intr(void *); 126 void sab_softintr(void *); 127 void sab_cnputc(dev_t, int); 128 int sab_cngetc(dev_t); 129 void sab_cnpollc(dev_t, int); 130 131 int sabtty_match(struct device *, void *, void *); 132 void sabtty_attach(struct device *, struct device *, void *); 133 int sabtty_activate(struct device *, int); 134 135 void sabtty_start(struct tty *); 136 int sabtty_param(struct tty *, struct termios *); 137 int sabtty_intr(struct sabtty_softc *, int *); 138 void sabtty_softintr(struct sabtty_softc *); 139 int sabtty_mdmctrl(struct sabtty_softc *, int, int); 140 int sabtty_cec_wait(struct sabtty_softc *); 141 int sabtty_tec_wait(struct sabtty_softc *); 142 void sabtty_reset(struct sabtty_softc *); 143 void sabtty_flush(struct sabtty_softc *); 144 int sabtty_speed(int); 145 void sabtty_console_flags(struct sabtty_softc *); 146 void sabtty_console_speed(struct sabtty_softc *); 147 void sabtty_cnpollc(struct sabtty_softc *, int); 148 void sabtty_shutdown(struct sabtty_softc *); 149 int sabttyparam(struct sabtty_softc *, struct tty *, struct termios *); 150 151 int sabttyopen(dev_t, int, int, struct proc *); 152 int sabttyclose(dev_t, int, int, struct proc *); 153 int sabttyread(dev_t, struct uio *, int); 154 int sabttywrite(dev_t, struct uio *, int); 155 int sabttyioctl(dev_t, u_long, caddr_t, int, struct proc *); 156 int sabttystop(struct tty *, int); 157 struct tty *sabttytty(dev_t); 158 void sabtty_cnputc(struct sabtty_softc *, int); 159 int sabtty_cngetc(struct sabtty_softc *); 160 void sabtty_abort(struct sabtty_softc *); 161 162 struct cfattach sab_ca = { 163 sizeof(struct sab_softc), sab_match, sab_attach 164 }; 165 166 struct cfdriver sab_cd = { 167 NULL, "sab", DV_DULL 168 }; 169 170 struct cfattach sabtty_ca = { 171 sizeof(struct sabtty_softc), sabtty_match, sabtty_attach, 172 NULL, sabtty_activate 173 }; 174 175 struct cfdriver sabtty_cd = { 176 NULL, "sabtty", DV_TTY 177 }; 178 179 struct sabtty_rate { 180 int baud; 181 int n, m; 182 }; 183 184 struct sabtty_rate sabtty_baudtable[] = { 185 { 50, 35, 10 }, 186 { 75, 47, 9 }, 187 { 110, 32, 9 }, 188 { 134, 53, 8 }, 189 { 150, 47, 8 }, 190 { 200, 35, 8 }, 191 { 300, 47, 7 }, 192 { 600, 47, 6 }, 193 { 1200, 47, 5 }, 194 { 1800, 31, 5 }, 195 { 2400, 47, 4 }, 196 { 4800, 47, 3 }, 197 { 9600, 47, 2 }, 198 { 19200, 47, 1 }, 199 { 38400, 23, 1 }, 200 { 57600, 15, 1 }, 201 { 115200, 7, 1 }, 202 { 230400, 3, 1 }, 203 { 460800, 1, 1 }, 204 { 76800, 11, 1 }, 205 { 153600, 5, 1 }, 206 { 307200, 3, 1 }, 207 { 614400, 3, 0 }, 208 { 921600, 0, 1 }, 209 }; 210 211 int 212 sab_match(parent, match, aux) 213 struct device *parent; 214 void *match, *aux; 215 { 216 struct ebus_attach_args *ea = aux; 217 char *compat; 218 219 if (strcmp(ea->ea_name, "se") == 0 || 220 strcmp(ea->ea_name, "FJSV,se") == 0) 221 return (1); 222 compat = getpropstring(ea->ea_node, "compatible"); 223 if (compat != NULL && !strcmp(compat, "sab82532")) 224 return (1); 225 return (0); 226 } 227 228 void 229 sab_attach(parent, self, aux) 230 struct device *parent; 231 struct device *self; 232 void *aux; 233 { 234 struct sab_softc *sc = (struct sab_softc *)self; 235 struct ebus_attach_args *ea = aux; 236 u_int8_t r; 237 u_int i; 238 239 sc->sc_bt = ea->ea_memtag; 240 sc->sc_node = ea->ea_node; 241 242 /* Use prom mapping, if available. */ 243 if (ea->ea_nvaddrs) { 244 if (bus_space_map(sc->sc_bt, ea->ea_vaddrs[0], 245 0, BUS_SPACE_MAP_PROMADDRESS, &sc->sc_bh) != 0) { 246 printf(": can't map register space\n"); 247 return; 248 } 249 } else if (ebus_bus_map(sc->sc_bt, 0, 250 EBUS_PADDR_FROM_REG(&ea->ea_regs[0]), ea->ea_regs[0].size, 0, 0, 251 &sc->sc_bh) != 0) { 252 printf(": can't map register space\n"); 253 return; 254 } 255 256 BUS_SPACE_SET_FLAGS(sc->sc_bt, sc->sc_bh, BSHDB_NO_ACCESS); 257 258 sc->sc_ih = bus_intr_establish(sc->sc_bt, ea->ea_intrs[0], 259 IPL_TTY, 0, sab_intr, sc, self->dv_xname); 260 if (sc->sc_ih == NULL) { 261 printf(": can't map interrupt\n"); 262 return; 263 } 264 265 sc->sc_softintr = softintr_establish(IPL_TTY, sab_softintr, sc); 266 if (sc->sc_softintr == NULL) { 267 printf(": can't get soft intr\n"); 268 return; 269 } 270 271 printf(": rev "); 272 r = SAB_READ(sc, SAB_VSTR) & SAB_VSTR_VMASK; 273 switch (r) { 274 case SAB_VSTR_V_1: 275 printf("1"); 276 break; 277 case SAB_VSTR_V_2: 278 printf("2"); 279 break; 280 case SAB_VSTR_V_32: 281 printf("3.2"); 282 break; 283 default: 284 printf("unknown(0x%x)", r); 285 break; 286 } 287 printf("\n"); 288 289 /* Let current output drain */ 290 DELAY(100000); 291 292 /* Set all pins, except DTR pins to be inputs */ 293 SAB_WRITE(sc, SAB_PCR, ~(SAB_PVR_DTR_A | SAB_PVR_DTR_B)); 294 /* Disable port interrupts */ 295 SAB_WRITE(sc, SAB_PIM, 0xff); 296 SAB_WRITE(sc, SAB_PVR, SAB_PVR_DTR_A | SAB_PVR_DTR_B | SAB_PVR_MAGIC); 297 SAB_WRITE(sc, SAB_IPC, SAB_IPC_ICPL); 298 299 for (i = 0; i < SAB_NCHAN; i++) { 300 struct sabtty_attach_args sta; 301 302 sta.sbt_portno = i; 303 sc->sc_child[i] = (struct sabtty_softc *)config_found_sm(self, 304 &sta, sab_print, sabtty_match); 305 if (sc->sc_child[i] != NULL) 306 sc->sc_nchild++; 307 } 308 } 309 310 int 311 sabtty_activate(struct device *self, int act) 312 { 313 struct sabtty_softc *sc = (struct sabtty_softc *)self; 314 int ret = 0; 315 316 switch (act) { 317 case DVACT_POWERDOWN: 318 if (sc->sc_flags & SABTTYF_CONS_IN) 319 sabtty_shutdown(sc); 320 break; 321 } 322 323 return (ret); 324 } 325 326 int 327 sab_print(args, name) 328 void *args; 329 const char *name; 330 { 331 struct sabtty_attach_args *sa = args; 332 333 if (name) 334 printf("sabtty at %s", name); 335 printf(" port %d", sa->sbt_portno); 336 return (UNCONF); 337 } 338 339 int 340 sab_intr(vsc) 341 void *vsc; 342 { 343 struct sab_softc *sc = vsc; 344 int r = 0, needsoft = 0; 345 u_int8_t gis; 346 347 gis = SAB_READ(sc, SAB_GIS); 348 349 /* channel A */ 350 if ((gis & (SAB_GIS_ISA1 | SAB_GIS_ISA0)) && sc->sc_child[0] && 351 sc->sc_child[0]->sc_tty) 352 r |= sabtty_intr(sc->sc_child[0], &needsoft); 353 354 /* channel B */ 355 if ((gis & (SAB_GIS_ISB1 | SAB_GIS_ISB0)) && sc->sc_child[1] && 356 sc->sc_child[1]->sc_tty) 357 r |= sabtty_intr(sc->sc_child[1], &needsoft); 358 359 if (needsoft) 360 softintr_schedule(sc->sc_softintr); 361 362 return (r); 363 } 364 365 void 366 sab_softintr(vsc) 367 void *vsc; 368 { 369 struct sab_softc *sc = vsc; 370 371 if (sc->sc_child[0] && sc->sc_child[0]->sc_tty) 372 sabtty_softintr(sc->sc_child[0]); 373 if (sc->sc_child[1] && sc->sc_child[1]->sc_tty) 374 sabtty_softintr(sc->sc_child[1]); 375 } 376 377 int 378 sabtty_match(parent, match, aux) 379 struct device *parent; 380 void *match, *aux; 381 { 382 struct sabtty_attach_args *sa = aux; 383 384 if (sa->sbt_portno < SAB_NCHAN) 385 return (1); 386 return (0); 387 } 388 389 void 390 sabtty_attach(parent, self, aux) 391 struct device *parent; 392 struct device *self; 393 void *aux; 394 { 395 struct sabtty_softc *sc = (struct sabtty_softc *)self; 396 struct sabtty_attach_args *sa = aux; 397 int r; 398 399 sc->sc_tty = ttymalloc(0); 400 sc->sc_tty->t_oproc = sabtty_start; 401 sc->sc_tty->t_param = sabtty_param; 402 403 sc->sc_parent = (struct sab_softc *)parent; 404 sc->sc_bt = sc->sc_parent->sc_bt; 405 sc->sc_portno = sa->sbt_portno; 406 sc->sc_rend = sc->sc_rbuf + SABTTY_RBUF_SIZE; 407 408 switch (sa->sbt_portno) { 409 case 0: /* port A */ 410 sc->sc_pvr_dtr = SAB_PVR_DTR_A; 411 sc->sc_pvr_dsr = SAB_PVR_DSR_A; 412 r = bus_space_subregion(sc->sc_bt, sc->sc_parent->sc_bh, 413 SAB_CHAN_A, SAB_CHANLEN, &sc->sc_bh); 414 break; 415 case 1: /* port B */ 416 sc->sc_pvr_dtr = SAB_PVR_DTR_B; 417 sc->sc_pvr_dsr = SAB_PVR_DSR_B; 418 r = bus_space_subregion(sc->sc_bt, sc->sc_parent->sc_bh, 419 SAB_CHAN_B, SAB_CHANLEN, &sc->sc_bh); 420 break; 421 default: 422 printf(": invalid channel: %u\n", sa->sbt_portno); 423 return; 424 } 425 if (r != 0) { 426 printf(": failed to allocate register subregion\n"); 427 return; 428 } 429 430 sabtty_console_flags(sc); 431 sabtty_console_speed(sc); 432 433 if (sc->sc_flags & (SABTTYF_CONS_IN | SABTTYF_CONS_OUT)) { 434 struct termios t; 435 char *acc; 436 437 switch (sc->sc_flags & (SABTTYF_CONS_IN | SABTTYF_CONS_OUT)) { 438 case SABTTYF_CONS_IN: 439 acc = " input"; 440 break; 441 case SABTTYF_CONS_OUT: 442 acc = " output"; 443 break; 444 case SABTTYF_CONS_IN|SABTTYF_CONS_OUT: 445 default: 446 acc = ""; 447 break; 448 } 449 450 if (sc->sc_flags & SABTTYF_CONS_OUT) { 451 /* Let current output drain */ 452 DELAY(100000); 453 } 454 455 t.c_ispeed = 0; 456 t.c_ospeed = sc->sc_speed; 457 t.c_cflag = CREAD | CS8 | HUPCL; 458 sc->sc_tty->t_ospeed = 0; 459 sabttyparam(sc, sc->sc_tty, &t); 460 461 if (sc->sc_flags & SABTTYF_CONS_IN) { 462 sabtty_cons_input = sc; 463 cn_tab->cn_pollc = sab_cnpollc; 464 cn_tab->cn_getc = sab_cngetc; 465 cn_tab->cn_dev = makedev(77/*XXX*/, self->dv_unit); 466 } 467 468 if (sc->sc_flags & SABTTYF_CONS_OUT) { 469 sabtty_cons_output = sc; 470 cn_tab->cn_putc = sab_cnputc; 471 cn_tab->cn_dev = makedev(77/*XXX*/, self->dv_unit); 472 } 473 printf(": console%s", acc); 474 } else { 475 /* Not a console... */ 476 sabtty_reset(sc); 477 } 478 479 printf("\n"); 480 } 481 482 int 483 sabtty_intr(sc, needsoftp) 484 struct sabtty_softc *sc; 485 int *needsoftp; 486 { 487 u_int8_t isr0, isr1; 488 int i, len = 0, needsoft = 0, r = 0, clearfifo = 0; 489 490 isr0 = SAB_READ(sc, SAB_ISR0); 491 isr1 = SAB_READ(sc, SAB_ISR1); 492 493 if (isr0 || isr1) 494 r = 1; 495 496 if (isr0 & SAB_ISR0_RPF) { 497 len = 32; 498 clearfifo = 1; 499 } 500 if (isr0 & SAB_ISR0_TCD) { 501 len = (32 - 1) & SAB_READ(sc, SAB_RBCL); 502 clearfifo = 1; 503 } 504 if (isr0 & SAB_ISR0_TIME) { 505 sabtty_cec_wait(sc); 506 SAB_WRITE(sc, SAB_CMDR, SAB_CMDR_RFRD); 507 } 508 if (isr0 & SAB_ISR0_RFO) { 509 sc->sc_flags |= SABTTYF_RINGOVERFLOW; 510 clearfifo = 1; 511 } 512 if (len != 0) { 513 u_int8_t *ptr; 514 515 ptr = sc->sc_rput; 516 for (i = 0; i < len; i++) { 517 *ptr++ = SAB_READ(sc, SAB_RFIFO); 518 if (ptr == sc->sc_rend) 519 ptr = sc->sc_rbuf; 520 if (ptr == sc->sc_rget) { 521 if (ptr == sc->sc_rbuf) 522 ptr = sc->sc_rend; 523 ptr--; 524 sc->sc_flags |= SABTTYF_RINGOVERFLOW; 525 } 526 } 527 sc->sc_rput = ptr; 528 needsoft = 1; 529 } 530 531 if (clearfifo) { 532 sabtty_cec_wait(sc); 533 SAB_WRITE(sc, SAB_CMDR, SAB_CMDR_RMC); 534 } 535 536 if (isr0 & SAB_ISR0_CDSC) { 537 sc->sc_flags |= SABTTYF_CDCHG; 538 needsoft = 1; 539 } 540 541 if (isr1 & SAB_ISR1_BRKT) 542 sabtty_abort(sc); 543 544 if (isr1 & (SAB_ISR1_XPR | SAB_ISR1_ALLS)) { 545 if ((SAB_READ(sc, SAB_STAR) & SAB_STAR_XFW) && 546 (sc->sc_flags & SABTTYF_STOP) == 0) { 547 if (sc->sc_txc < 32) 548 len = sc->sc_txc; 549 else 550 len = 32; 551 552 if (len > 0) { 553 SAB_WRITE_BLOCK(sc, SAB_XFIFO, sc->sc_txp, len); 554 sc->sc_txp += len; 555 sc->sc_txc -= len; 556 557 sabtty_cec_wait(sc); 558 SAB_WRITE(sc, SAB_CMDR, SAB_CMDR_XF); 559 560 /* 561 * Prevent the false end of xmit from 562 * confusing things below. 563 */ 564 isr1 &= ~SAB_ISR1_ALLS; 565 } 566 } 567 568 if ((sc->sc_txc == 0) || (sc->sc_flags & SABTTYF_STOP)) { 569 if ((sc->sc_imr1 & SAB_IMR1_XPR) == 0) { 570 sc->sc_imr1 |= SAB_IMR1_XPR; 571 sc->sc_imr1 &= ~SAB_IMR1_ALLS; 572 SAB_WRITE(sc, SAB_IMR1, sc->sc_imr1); 573 } 574 } 575 } 576 577 if ((isr1 & SAB_ISR1_ALLS) && ((sc->sc_txc == 0) || 578 (sc->sc_flags & SABTTYF_STOP))) { 579 if (sc->sc_flags & SABTTYF_TXDRAIN) 580 wakeup(sc); 581 sc->sc_flags &= ~SABTTYF_STOP; 582 sc->sc_flags |= SABTTYF_DONE; 583 sc->sc_imr1 |= SAB_IMR1_ALLS; 584 SAB_WRITE(sc, SAB_IMR1, sc->sc_imr1); 585 needsoft = 1; 586 } 587 588 if (needsoft) 589 *needsoftp = needsoft; 590 return (r); 591 } 592 593 void 594 sabtty_softintr(sc) 595 struct sabtty_softc *sc; 596 { 597 struct tty *tp = sc->sc_tty; 598 int s, flags; 599 u_int8_t r; 600 601 if (tp == NULL) 602 return; 603 604 if ((tp->t_state & TS_ISOPEN) == 0) 605 return; 606 607 while (sc->sc_rget != sc->sc_rput) { 608 int data; 609 u_int8_t stat; 610 611 data = sc->sc_rget[0]; 612 stat = sc->sc_rget[1]; 613 sc->sc_rget += 2; 614 if (stat & SAB_RSTAT_PE) 615 data |= TTY_PE; 616 if (stat & SAB_RSTAT_FE) 617 data |= TTY_FE; 618 if (sc->sc_rget == sc->sc_rend) 619 sc->sc_rget = sc->sc_rbuf; 620 621 (*linesw[tp->t_line].l_rint)(data, tp); 622 } 623 624 s = splhigh(); 625 flags = sc->sc_flags; 626 sc->sc_flags &= ~(SABTTYF_DONE|SABTTYF_CDCHG|SABTTYF_RINGOVERFLOW); 627 splx(s); 628 629 if (flags & SABTTYF_CDCHG) { 630 s = spltty(); 631 r = SAB_READ(sc, SAB_VSTR) & SAB_VSTR_CD; 632 splx(s); 633 634 (*linesw[tp->t_line].l_modem)(tp, r); 635 } 636 637 if (flags & SABTTYF_RINGOVERFLOW) 638 log(LOG_WARNING, "%s: ring overflow\n", sc->sc_dv.dv_xname); 639 640 if (flags & SABTTYF_DONE) { 641 ndflush(&tp->t_outq, sc->sc_txp - tp->t_outq.c_cf); 642 tp->t_state &= ~TS_BUSY; 643 (*linesw[tp->t_line].l_start)(tp); 644 } 645 } 646 647 int 648 sabttyopen(dev, flags, mode, p) 649 dev_t dev; 650 int flags, mode; 651 struct proc *p; 652 { 653 struct sab_softc *bc; 654 struct sabtty_softc *sc; 655 struct tty *tp; 656 int card = SAB_CARD(dev), port = SAB_PORT(dev), s, s1; 657 658 if (card >= sab_cd.cd_ndevs) 659 return (ENXIO); 660 bc = sab_cd.cd_devs[card]; 661 if (bc == NULL) 662 return (ENXIO); 663 664 if (port >= bc->sc_nchild) 665 return (ENXIO); 666 sc = bc->sc_child[port]; 667 if (sc == NULL) 668 return (ENXIO); 669 670 tp = sc->sc_tty; 671 tp->t_dev = dev; 672 673 if ((tp->t_state & TS_ISOPEN) == 0) { 674 tp->t_state |= TS_WOPEN; 675 676 ttychars(tp); 677 tp->t_iflag = TTYDEF_IFLAG; 678 tp->t_oflag = TTYDEF_OFLAG; 679 tp->t_cflag = TTYDEF_CFLAG; 680 if (sc->sc_openflags & TIOCFLAG_CLOCAL) 681 tp->t_cflag |= CLOCAL; 682 if (sc->sc_openflags & TIOCFLAG_CRTSCTS) 683 tp->t_cflag |= CRTSCTS; 684 if (sc->sc_openflags & TIOCFLAG_MDMBUF) 685 tp->t_cflag |= MDMBUF; 686 tp->t_lflag = TTYDEF_LFLAG; 687 if (sc->sc_flags & (SABTTYF_CONS_IN | SABTTYF_CONS_OUT)) 688 tp->t_ispeed = tp->t_ospeed = sc->sc_speed; 689 else 690 tp->t_ispeed = tp->t_ospeed = TTYDEF_SPEED; 691 692 sc->sc_rput = sc->sc_rget = sc->sc_rbuf; 693 694 s = spltty(); 695 696 ttsetwater(tp); 697 698 s1 = splhigh(); 699 sabtty_reset(sc); 700 sabtty_param(tp, &tp->t_termios); 701 sc->sc_imr0 = SAB_IMR0_PERR | SAB_IMR0_FERR | SAB_IMR0_PLLA; 702 SAB_WRITE(sc, SAB_IMR0, sc->sc_imr0); 703 sc->sc_imr1 = SAB_IMR1_BRK | SAB_IMR1_ALLS | SAB_IMR1_XDU | 704 SAB_IMR1_TIN | SAB_IMR1_CSC | SAB_IMR1_XMR | SAB_IMR1_XPR; 705 SAB_WRITE(sc, SAB_IMR1, sc->sc_imr1); 706 SAB_WRITE(sc, SAB_CCR0, SAB_READ(sc, SAB_CCR0) | SAB_CCR0_PU); 707 sabtty_cec_wait(sc); 708 SAB_WRITE(sc, SAB_CMDR, SAB_CMDR_XRES); 709 sabtty_cec_wait(sc); 710 SAB_WRITE(sc, SAB_CMDR, SAB_CMDR_RRES); 711 sabtty_cec_wait(sc); 712 splx(s1); 713 714 sabtty_flush(sc); 715 716 if ((sc->sc_openflags & TIOCFLAG_SOFTCAR) || 717 (SAB_READ(sc, SAB_VSTR) & SAB_VSTR_CD)) 718 tp->t_state |= TS_CARR_ON; 719 else 720 tp->t_state &= ~TS_CARR_ON; 721 } else if ((tp->t_state & TS_XCLUDE) && 722 (!suser(p))) { 723 return (EBUSY); 724 } else { 725 s = spltty(); 726 } 727 728 if ((flags & O_NONBLOCK) == 0) { 729 while ((tp->t_cflag & CLOCAL) == 0 && 730 (tp->t_state & TS_CARR_ON) == 0) { 731 int error; 732 733 tp->t_state |= TS_WOPEN; 734 error = ttysleep(tp, &tp->t_rawq, TTIPRI | PCATCH, 735 "sabttycd"); 736 if (error != 0) { 737 splx(s); 738 tp->t_state &= ~TS_WOPEN; 739 return (error); 740 } 741 } 742 } 743 744 splx(s); 745 746 s = (*linesw[tp->t_line].l_open)(dev, tp, p); 747 if (s != 0) { 748 if (tp->t_state & TS_ISOPEN) 749 return (s); 750 751 if (tp->t_cflag & HUPCL) { 752 sabtty_mdmctrl(sc, 0, DMSET); 753 tsleep_nsec(sc, TTIPRI, ttclos, SEC_TO_NSEC(1)); 754 } 755 756 if ((sc->sc_flags & (SABTTYF_CONS_IN | SABTTYF_CONS_OUT)) == 0) { 757 /* Flush and power down if we're not the console */ 758 sabtty_flush(sc); 759 sabtty_reset(sc); 760 } 761 } 762 return (s); 763 } 764 765 int 766 sabttyclose(dev, flags, mode, p) 767 dev_t dev; 768 int flags, mode; 769 struct proc *p; 770 { 771 struct sab_softc *bc = sab_cd.cd_devs[SAB_CARD(dev)]; 772 struct sabtty_softc *sc = bc->sc_child[SAB_PORT(dev)]; 773 struct tty *tp = sc->sc_tty; 774 int s; 775 776 (*linesw[tp->t_line].l_close)(tp, flags, p); 777 778 s = spltty(); 779 780 if ((tp->t_state & TS_ISOPEN) == 0) { 781 /* Wait for output drain */ 782 sc->sc_imr1 &= ~SAB_IMR1_ALLS; 783 SAB_WRITE(sc, SAB_IMR1, sc->sc_imr1); 784 sc->sc_flags |= SABTTYF_TXDRAIN; 785 tsleep_nsec(sc, TTIPRI, ttclos, SEC_TO_NSEC(5)); 786 sc->sc_imr1 |= SAB_IMR1_ALLS; 787 SAB_WRITE(sc, SAB_IMR1, sc->sc_imr1); 788 sc->sc_flags &= ~SABTTYF_TXDRAIN; 789 790 if (tp->t_cflag & HUPCL) { 791 sabtty_mdmctrl(sc, 0, DMSET); 792 tsleep_nsec(bc, TTIPRI, ttclos, SEC_TO_NSEC(1)); 793 } 794 795 if ((sc->sc_flags & (SABTTYF_CONS_IN | SABTTYF_CONS_OUT)) == 0) { 796 /* Flush and power down if we're not the console */ 797 sabtty_flush(sc); 798 sabtty_reset(sc); 799 } 800 } 801 802 ttyclose(tp); 803 splx(s); 804 805 return (0); 806 } 807 808 int 809 sabttyread(dev, uio, flags) 810 dev_t dev; 811 struct uio *uio; 812 int flags; 813 { 814 struct sab_softc *bc = sab_cd.cd_devs[SAB_CARD(dev)]; 815 struct sabtty_softc *sc = bc->sc_child[SAB_PORT(dev)]; 816 struct tty *tp = sc->sc_tty; 817 818 return ((*linesw[tp->t_line].l_read)(tp, uio, flags)); 819 } 820 821 int 822 sabttywrite(dev, uio, flags) 823 dev_t dev; 824 struct uio *uio; 825 int flags; 826 { 827 struct sab_softc *bc = sab_cd.cd_devs[SAB_CARD(dev)]; 828 struct sabtty_softc *sc = bc->sc_child[SAB_PORT(dev)]; 829 struct tty *tp = sc->sc_tty; 830 831 return ((*linesw[tp->t_line].l_write)(tp, uio, flags)); 832 } 833 834 int 835 sabttyioctl(dev, cmd, data, flags, p) 836 dev_t dev; 837 u_long cmd; 838 caddr_t data; 839 int flags; 840 struct proc *p; 841 { 842 struct sab_softc *bc = sab_cd.cd_devs[SAB_CARD(dev)]; 843 struct sabtty_softc *sc = bc->sc_child[SAB_PORT(dev)]; 844 struct tty *tp = sc->sc_tty; 845 int error; 846 847 error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flags, p); 848 if (error >= 0) 849 return (error); 850 851 error = ttioctl(tp, cmd, data, flags, p); 852 if (error >= 0) 853 return (error); 854 855 error = 0; 856 857 switch (cmd) { 858 case TIOCSBRK: 859 SAB_WRITE(sc, SAB_DAFO, 860 SAB_READ(sc, SAB_DAFO) | SAB_DAFO_XBRK); 861 break; 862 case TIOCCBRK: 863 SAB_WRITE(sc, SAB_DAFO, 864 SAB_READ(sc, SAB_DAFO) & ~SAB_DAFO_XBRK); 865 break; 866 case TIOCSDTR: 867 sabtty_mdmctrl(sc, TIOCM_DTR, DMBIS); 868 break; 869 case TIOCCDTR: 870 sabtty_mdmctrl(sc, TIOCM_DTR, DMBIC); 871 break; 872 case TIOCMBIS: 873 sabtty_mdmctrl(sc, *((int *)data), DMBIS); 874 break; 875 case TIOCMBIC: 876 sabtty_mdmctrl(sc, *((int *)data), DMBIC); 877 break; 878 case TIOCMGET: 879 *((int *)data) = sabtty_mdmctrl(sc, 0, DMGET); 880 break; 881 case TIOCMSET: 882 sabtty_mdmctrl(sc, *((int *)data), DMSET); 883 break; 884 case TIOCGFLAGS: 885 *((int *)data) = sc->sc_openflags; 886 break; 887 case TIOCSFLAGS: 888 if (suser(p)) 889 error = EPERM; 890 else 891 sc->sc_openflags = *((int *)data) & 892 (TIOCFLAG_SOFTCAR | TIOCFLAG_CLOCAL | 893 TIOCFLAG_CRTSCTS | TIOCFLAG_MDMBUF); 894 break; 895 default: 896 error = ENOTTY; 897 } 898 899 return (error); 900 } 901 902 struct tty * 903 sabttytty(dev) 904 dev_t dev; 905 { 906 struct sab_softc *bc = sab_cd.cd_devs[SAB_CARD(dev)]; 907 struct sabtty_softc *sc = bc->sc_child[SAB_PORT(dev)]; 908 909 return (sc->sc_tty); 910 } 911 912 int 913 sabttystop(tp, flags) 914 struct tty *tp; 915 int flags; 916 { 917 struct sab_softc *bc = sab_cd.cd_devs[SAB_CARD(tp->t_dev)]; 918 struct sabtty_softc *sc = bc->sc_child[SAB_PORT(tp->t_dev)]; 919 int s; 920 921 s = spltty(); 922 if (tp->t_state & TS_BUSY) { 923 if ((tp->t_state & TS_TTSTOP) == 0) 924 tp->t_state |= TS_FLUSH; 925 sc->sc_flags |= SABTTYF_STOP; 926 sc->sc_imr1 &= ~SAB_IMR1_ALLS; 927 SAB_WRITE(sc, SAB_IMR1, sc->sc_imr1); 928 } 929 splx(s); 930 return (0); 931 } 932 933 int 934 sabtty_mdmctrl(sc, bits, how) 935 struct sabtty_softc *sc; 936 int bits, how; 937 { 938 u_int8_t r; 939 int s; 940 941 s = spltty(); 942 switch (how) { 943 case DMGET: 944 bits = 0; 945 if (SAB_READ(sc, SAB_STAR) & SAB_STAR_CTS) 946 bits |= TIOCM_CTS; 947 if ((SAB_READ(sc, SAB_VSTR) & SAB_VSTR_CD) == 0) 948 bits |= TIOCM_CD; 949 950 r = SAB_READ(sc, SAB_PVR); 951 if ((r & sc->sc_pvr_dtr) == 0) 952 bits |= TIOCM_DTR; 953 if ((r & sc->sc_pvr_dsr) == 0) 954 bits |= TIOCM_DSR; 955 956 r = SAB_READ(sc, SAB_MODE); 957 if ((r & (SAB_MODE_RTS|SAB_MODE_FRTS)) == SAB_MODE_RTS) 958 bits |= TIOCM_RTS; 959 break; 960 case DMSET: 961 r = SAB_READ(sc, SAB_MODE); 962 if (bits & TIOCM_RTS) { 963 r &= ~SAB_MODE_FRTS; 964 r |= SAB_MODE_RTS; 965 } else 966 r |= SAB_MODE_FRTS | SAB_MODE_RTS; 967 SAB_WRITE(sc, SAB_MODE, r); 968 969 r = SAB_READ(sc, SAB_PVR); 970 if (bits & TIOCM_DTR) 971 r &= ~sc->sc_pvr_dtr; 972 else 973 r |= sc->sc_pvr_dtr; 974 SAB_WRITE(sc, SAB_PVR, r); 975 break; 976 case DMBIS: 977 if (bits & TIOCM_RTS) { 978 r = SAB_READ(sc, SAB_MODE); 979 r &= ~SAB_MODE_FRTS; 980 r |= SAB_MODE_RTS; 981 SAB_WRITE(sc, SAB_MODE, r); 982 } 983 if (bits & TIOCM_DTR) { 984 r = SAB_READ(sc, SAB_PVR); 985 r &= ~sc->sc_pvr_dtr; 986 SAB_WRITE(sc, SAB_PVR, r); 987 } 988 break; 989 case DMBIC: 990 if (bits & TIOCM_RTS) { 991 r = SAB_READ(sc, SAB_MODE); 992 r |= SAB_MODE_FRTS | SAB_MODE_RTS; 993 SAB_WRITE(sc, SAB_MODE, r); 994 } 995 if (bits & TIOCM_DTR) { 996 r = SAB_READ(sc, SAB_PVR); 997 r |= sc->sc_pvr_dtr; 998 SAB_WRITE(sc, SAB_PVR, r); 999 } 1000 break; 1001 } 1002 splx(s); 1003 return (bits); 1004 } 1005 1006 int 1007 sabttyparam(sc, tp, t) 1008 struct sabtty_softc *sc; 1009 struct tty *tp; 1010 struct termios *t; 1011 { 1012 int s, ospeed; 1013 tcflag_t cflag; 1014 u_int8_t dafo, r; 1015 1016 ospeed = sabtty_speed(t->c_ospeed); 1017 if (ospeed < 0 || (t->c_ispeed && t->c_ispeed != t->c_ospeed)) 1018 return (EINVAL); 1019 1020 s = spltty(); 1021 1022 /* hang up line if ospeed is zero, otherwise raise dtr */ 1023 sabtty_mdmctrl(sc, TIOCM_DTR, 1024 (t->c_ospeed == 0) ? DMBIC : DMBIS); 1025 1026 dafo = SAB_READ(sc, SAB_DAFO); 1027 1028 cflag = t->c_cflag; 1029 1030 if (sc->sc_flags & (SABTTYF_CONS_IN | SABTTYF_CONS_OUT)) { 1031 cflag |= CLOCAL; 1032 cflag &= ~HUPCL; 1033 } 1034 1035 if (cflag & CSTOPB) 1036 dafo |= SAB_DAFO_STOP; 1037 else 1038 dafo &= ~SAB_DAFO_STOP; 1039 1040 dafo &= ~SAB_DAFO_CHL_CSIZE; 1041 switch (cflag & CSIZE) { 1042 case CS5: 1043 dafo |= SAB_DAFO_CHL_CS5; 1044 break; 1045 case CS6: 1046 dafo |= SAB_DAFO_CHL_CS6; 1047 break; 1048 case CS7: 1049 dafo |= SAB_DAFO_CHL_CS7; 1050 break; 1051 default: 1052 dafo |= SAB_DAFO_CHL_CS8; 1053 break; 1054 } 1055 1056 dafo &= ~SAB_DAFO_PARMASK; 1057 if (cflag & PARENB) { 1058 if (cflag & PARODD) 1059 dafo |= SAB_DAFO_PAR_ODD; 1060 else 1061 dafo |= SAB_DAFO_PAR_EVEN; 1062 } else 1063 dafo |= SAB_DAFO_PAR_NONE; 1064 1065 if (ospeed != 0) { 1066 SAB_WRITE(sc, SAB_BGR, ospeed & 0xff); 1067 r = SAB_READ(sc, SAB_CCR2); 1068 r &= ~(SAB_CCR2_BR9 | SAB_CCR2_BR8); 1069 r |= (ospeed >> 2) & (SAB_CCR2_BR9 | SAB_CCR2_BR8); 1070 SAB_WRITE(sc, SAB_CCR2, r); 1071 } 1072 1073 r = SAB_READ(sc, SAB_MODE); 1074 r |= SAB_MODE_RAC; 1075 if (cflag & CRTSCTS) { 1076 r &= ~(SAB_MODE_RTS | SAB_MODE_FCTS); 1077 r |= SAB_MODE_FRTS; 1078 sc->sc_imr1 &= ~SAB_IMR1_CSC; 1079 } else { 1080 r |= SAB_MODE_RTS | SAB_MODE_FCTS; 1081 r &= ~SAB_MODE_FRTS; 1082 sc->sc_imr1 |= SAB_IMR1_CSC; 1083 } 1084 SAB_WRITE(sc, SAB_MODE, r); 1085 SAB_WRITE(sc, SAB_IMR1, sc->sc_imr1); 1086 1087 tp->t_cflag = cflag; 1088 1089 splx(s); 1090 return (0); 1091 } 1092 1093 int 1094 sabtty_param(tp, t) 1095 struct tty *tp; 1096 struct termios *t; 1097 { 1098 struct sab_softc *bc = sab_cd.cd_devs[SAB_CARD(tp->t_dev)]; 1099 struct sabtty_softc *sc = bc->sc_child[SAB_PORT(tp->t_dev)]; 1100 1101 return (sabttyparam(sc, tp, t)); 1102 } 1103 1104 void 1105 sabtty_start(tp) 1106 struct tty *tp; 1107 { 1108 struct sab_softc *bc = sab_cd.cd_devs[SAB_CARD(tp->t_dev)]; 1109 struct sabtty_softc *sc = bc->sc_child[SAB_PORT(tp->t_dev)]; 1110 int s; 1111 1112 s = spltty(); 1113 if ((tp->t_state & (TS_TTSTOP | TS_TIMEOUT | TS_BUSY)) == 0) { 1114 ttwakeupwr(tp); 1115 if (tp->t_outq.c_cc) { 1116 sc->sc_txc = ndqb(&tp->t_outq, 0); 1117 sc->sc_txp = tp->t_outq.c_cf; 1118 tp->t_state |= TS_BUSY; 1119 sc->sc_imr1 &= ~(SAB_ISR1_XPR | SAB_ISR1_ALLS); 1120 SAB_WRITE(sc, SAB_IMR1, sc->sc_imr1); 1121 } 1122 } 1123 splx(s); 1124 } 1125 1126 int 1127 sabtty_cec_wait(struct sabtty_softc *sc) 1128 { 1129 int i = 50000; 1130 1131 for (;;) { 1132 if ((SAB_READ(sc, SAB_STAR) & SAB_STAR_CEC) == 0) 1133 return (0); 1134 if (--i == 0) 1135 return (1); 1136 DELAY(1); 1137 } 1138 } 1139 1140 int 1141 sabtty_tec_wait(struct sabtty_softc *sc) 1142 { 1143 int i = 200000; 1144 1145 for (;;) { 1146 if ((SAB_READ(sc, SAB_STAR) & SAB_STAR_TEC) == 0) 1147 return (0); 1148 if (--i == 0) 1149 return (1); 1150 DELAY(1); 1151 } 1152 } 1153 1154 void 1155 sabtty_reset(sc) 1156 struct sabtty_softc *sc; 1157 { 1158 /* power down */ 1159 SAB_WRITE(sc, SAB_CCR0, 0); 1160 1161 /* set basic configuration */ 1162 SAB_WRITE(sc, SAB_CCR0, 1163 SAB_CCR0_MCE | SAB_CCR0_SC_NRZ | SAB_CCR0_SM_ASYNC); 1164 SAB_WRITE(sc, SAB_CCR1, SAB_CCR1_ODS | SAB_CCR1_BCR | SAB_CCR1_CM_7); 1165 SAB_WRITE(sc, SAB_CCR2, SAB_CCR2_BDF | SAB_CCR2_SSEL | SAB_CCR2_TOE); 1166 SAB_WRITE(sc, SAB_CCR3, 0); 1167 SAB_WRITE(sc, SAB_CCR4, SAB_CCR4_MCK4 | SAB_CCR4_EBRG); 1168 SAB_WRITE(sc, SAB_MODE, SAB_MODE_RTS | SAB_MODE_FCTS | SAB_MODE_RAC); 1169 SAB_WRITE(sc, SAB_RFC, 1170 SAB_RFC_DPS | SAB_RFC_RFDF | SAB_RFC_RFTH_32CHAR); 1171 1172 /* clear interrupts */ 1173 sc->sc_imr0 = sc->sc_imr1 = 0xff; 1174 SAB_WRITE(sc, SAB_IMR0, sc->sc_imr0); 1175 SAB_WRITE(sc, SAB_IMR1, sc->sc_imr1); 1176 SAB_READ(sc, SAB_ISR0); 1177 SAB_READ(sc, SAB_ISR1); 1178 } 1179 1180 void 1181 sabtty_flush(sc) 1182 struct sabtty_softc *sc; 1183 { 1184 /* clear rx fifo */ 1185 sabtty_cec_wait(sc); 1186 SAB_WRITE(sc, SAB_CMDR, SAB_CMDR_RRES); 1187 1188 /* clear tx fifo */ 1189 sabtty_cec_wait(sc); 1190 SAB_WRITE(sc, SAB_CMDR, SAB_CMDR_XRES); 1191 } 1192 1193 int 1194 sabtty_speed(rate) 1195 int rate; 1196 { 1197 int i, len, r; 1198 1199 if (rate == 0) 1200 return (0); 1201 len = sizeof(sabtty_baudtable)/sizeof(sabtty_baudtable[0]); 1202 for (i = 0; i < len; i++) { 1203 if (rate == sabtty_baudtable[i].baud) { 1204 r = sabtty_baudtable[i].n | 1205 (sabtty_baudtable[i].m << 6); 1206 return (r); 1207 } 1208 } 1209 return (-1); 1210 } 1211 1212 void 1213 sabtty_cnputc(sc, c) 1214 struct sabtty_softc *sc; 1215 int c; 1216 { 1217 sabtty_tec_wait(sc); 1218 SAB_WRITE(sc, SAB_TIC, c); 1219 sabtty_tec_wait(sc); 1220 } 1221 1222 int 1223 sabtty_cngetc(sc) 1224 struct sabtty_softc *sc; 1225 { 1226 u_int8_t r, len, ipc; 1227 1228 ipc = SAB_READ(sc, SAB_IPC); 1229 SAB_WRITE(sc, SAB_IPC, ipc | SAB_IPC_VIS); 1230 1231 again: 1232 do { 1233 r = SAB_READ(sc, SAB_STAR); 1234 } while ((r & SAB_STAR_RFNE) == 0); 1235 1236 /* 1237 * Ok, at least one byte in RFIFO, ask for permission to access RFIFO 1238 * (I hate this chip... hate hate hate). 1239 */ 1240 sabtty_cec_wait(sc); 1241 SAB_WRITE(sc, SAB_CMDR, SAB_CMDR_RFRD); 1242 1243 /* Wait for RFIFO to come ready */ 1244 do { 1245 r = SAB_READ(sc, SAB_ISR0); 1246 } while ((r & SAB_ISR0_TCD) == 0); 1247 1248 len = SAB_READ(sc, SAB_RBCL) & (32 - 1); 1249 if (len == 0) 1250 goto again; /* Shouldn't happen... */ 1251 1252 r = SAB_READ(sc, SAB_RFIFO); 1253 1254 /* 1255 * Blow away everything left in the FIFO... 1256 */ 1257 sabtty_cec_wait(sc); 1258 SAB_WRITE(sc, SAB_CMDR, SAB_CMDR_RMC); 1259 SAB_WRITE(sc, SAB_IPC, ipc); 1260 return (r); 1261 } 1262 1263 void 1264 sabtty_cnpollc(sc, on) 1265 struct sabtty_softc *sc; 1266 int on; 1267 { 1268 u_int8_t r; 1269 1270 if (on) { 1271 if (sc->sc_polling) 1272 return; 1273 SAB_WRITE(sc, SAB_IPC, SAB_READ(sc, SAB_IPC) | SAB_IPC_VIS); 1274 r = sc->sc_pollrfc = SAB_READ(sc, SAB_RFC); 1275 r &= ~(SAB_RFC_RFDF); 1276 SAB_WRITE(sc, SAB_RFC, r); 1277 sabtty_cec_wait(sc); 1278 SAB_WRITE(sc, SAB_CMDR, SAB_CMDR_RRES); 1279 sc->sc_polling = 1; 1280 } else { 1281 if (!sc->sc_polling) 1282 return; 1283 SAB_WRITE(sc, SAB_IPC, SAB_READ(sc, SAB_IPC) & ~SAB_IPC_VIS); 1284 SAB_WRITE(sc, SAB_RFC, sc->sc_pollrfc); 1285 sabtty_cec_wait(sc); 1286 SAB_WRITE(sc, SAB_CMDR, SAB_CMDR_RRES); 1287 sc->sc_polling = 0; 1288 } 1289 } 1290 1291 void 1292 sab_cnputc(dev, c) 1293 dev_t dev; 1294 int c; 1295 { 1296 struct sabtty_softc *sc = sabtty_cons_output; 1297 1298 if (sc == NULL) 1299 return; 1300 sabtty_cnputc(sc, c); 1301 } 1302 1303 void 1304 sab_cnpollc(dev, on) 1305 dev_t dev; 1306 int on; 1307 { 1308 struct sabtty_softc *sc = sabtty_cons_input; 1309 1310 sabtty_cnpollc(sc, on); 1311 } 1312 1313 int 1314 sab_cngetc(dev) 1315 dev_t dev; 1316 { 1317 struct sabtty_softc *sc = sabtty_cons_input; 1318 1319 if (sc == NULL) 1320 return (-1); 1321 return (sabtty_cngetc(sc)); 1322 } 1323 1324 void 1325 sabtty_console_flags(sc) 1326 struct sabtty_softc *sc; 1327 { 1328 int node, channel, options, cookie; 1329 char buf[255]; 1330 1331 node = sc->sc_parent->sc_node; 1332 channel = sc->sc_portno; 1333 1334 options = OF_finddevice("/options"); 1335 1336 /* Default to channel 0 if there are no explicit prom args */ 1337 cookie = 0; 1338 1339 if (node == OF_instance_to_package(OF_stdin())) { 1340 if (OF_getprop(options, "input-device", buf, 1341 sizeof(buf)) != -1) { 1342 if (strncmp("ttyb", buf, strlen("ttyb")) == 0) 1343 cookie = 1; 1344 } 1345 1346 if (channel == cookie) 1347 sc->sc_flags |= SABTTYF_CONS_IN; 1348 } 1349 1350 /* Default to same channel if there are no explicit prom args */ 1351 1352 if (node == OF_instance_to_package(OF_stdout())) { 1353 if (OF_getprop(options, "output-device", buf, 1354 sizeof(buf)) != -1) { 1355 if (strncmp("ttyb", buf, strlen("ttyb")) == 0) 1356 cookie = 1; 1357 } 1358 1359 if (channel == cookie) 1360 sc->sc_flags |= SABTTYF_CONS_OUT; 1361 } 1362 } 1363 1364 void 1365 sabtty_console_speed(sc) 1366 struct sabtty_softc *sc; 1367 { 1368 char *name; 1369 int node, channel, options; 1370 1371 node = sc->sc_parent->sc_node; 1372 channel = sc->sc_portno; 1373 1374 if (getpropint(node, "ssp-console", -1) == channel) { 1375 sc->sc_speed = getpropspeed(node, "ssp-console-modes"); 1376 return; 1377 } 1378 if (getpropint(node, "ssp-control", -1) == channel) { 1379 sc->sc_speed = getpropspeed(node, "ssp-control-modes"); 1380 return; 1381 } 1382 1383 options = OF_finddevice("/options"); 1384 name = sc->sc_portno ? "ttyb-mode" : "ttya-mode"; 1385 sc->sc_speed = getpropspeed(options, name); 1386 } 1387 1388 void 1389 sabtty_abort(sc) 1390 struct sabtty_softc *sc; 1391 { 1392 1393 if (sc->sc_flags & SABTTYF_CONS_IN) { 1394 #ifdef DDB 1395 extern int db_active, db_console; 1396 1397 if (db_console == 0) 1398 return; 1399 if (db_active == 0) 1400 db_enter(); 1401 else 1402 callrom(); 1403 #else 1404 callrom(); 1405 #endif 1406 } 1407 } 1408 1409 void 1410 sabtty_shutdown(struct sabtty_softc *sc) 1411 { 1412 /* Have to put the chip back into single char mode */ 1413 sc->sc_flags |= SABTTYF_DONTDDB; 1414 SAB_WRITE(sc, SAB_RFC, SAB_READ(sc, SAB_RFC) & ~SAB_RFC_RFDF); 1415 sabtty_cec_wait(sc); 1416 SAB_WRITE(sc, SAB_CMDR, SAB_CMDR_RRES); 1417 sabtty_cec_wait(sc); 1418 SAB_WRITE(sc, SAB_IPC, SAB_READ(sc, SAB_IPC) | SAB_IPC_VIS); 1419 } 1420