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