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