1 /* $OpenBSD: sab.c,v 1.15 2003/10/03 16:44:50 miod 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 sc->sc_tty->t_oproc = sabtty_start; 381 sc->sc_tty->t_param = sabtty_param; 382 383 sc->sc_parent = (struct sab_softc *)parent; 384 sc->sc_bt = sc->sc_parent->sc_bt; 385 sc->sc_portno = sa->sbt_portno; 386 sc->sc_rend = sc->sc_rbuf + SABTTY_RBUF_SIZE; 387 388 switch (sa->sbt_portno) { 389 case 0: /* port A */ 390 sc->sc_pvr_dtr = SAB_PVR_DTR_A; 391 sc->sc_pvr_dsr = SAB_PVR_DSR_A; 392 r = bus_space_subregion(sc->sc_bt, sc->sc_parent->sc_bh, 393 SAB_CHAN_A, SAB_CHANLEN, &sc->sc_bh); 394 break; 395 case 1: /* port B */ 396 sc->sc_pvr_dtr = SAB_PVR_DTR_B; 397 sc->sc_pvr_dsr = SAB_PVR_DSR_B; 398 r = bus_space_subregion(sc->sc_bt, sc->sc_parent->sc_bh, 399 SAB_CHAN_B, SAB_CHANLEN, &sc->sc_bh); 400 break; 401 default: 402 printf(": invalid channel: %u\n", sa->sbt_portno); 403 return; 404 } 405 if (r != 0) { 406 printf(": failed to allocate register subregion\n"); 407 return; 408 } 409 410 sabtty_console_flags(sc); 411 412 if (sc->sc_flags & (SABTTYF_CONS_IN | SABTTYF_CONS_OUT)) { 413 struct termios t; 414 char *acc; 415 416 switch (sc->sc_flags & (SABTTYF_CONS_IN | SABTTYF_CONS_OUT)) { 417 case SABTTYF_CONS_IN: 418 acc = "input"; 419 break; 420 case SABTTYF_CONS_OUT: 421 acc = "output"; 422 break; 423 case SABTTYF_CONS_IN|SABTTYF_CONS_OUT: 424 default: 425 acc = "i/o"; 426 break; 427 } 428 429 t.c_ispeed= 0; 430 t.c_ospeed = 9600; 431 t.c_cflag = CREAD | CS8 | HUPCL; 432 sc->sc_tty->t_ospeed = 0; 433 sabttyparam(sc, sc->sc_tty, &t); 434 435 if (sc->sc_flags & SABTTYF_CONS_IN) { 436 sabtty_cons_input = sc; 437 cn_tab->cn_pollc = sab_cnpollc; 438 cn_tab->cn_getc = sab_cngetc; 439 cn_tab->cn_dev = makedev(77/*XXX*/, self->dv_unit); 440 shutdownhook_establish(sabtty_shutdown, sc); 441 } 442 443 if (sc->sc_flags & SABTTYF_CONS_OUT) { 444 sabtty_cons_output = sc; 445 cn_tab->cn_putc = sab_cnputc; 446 cn_tab->cn_dev = makedev(77/*XXX*/, self->dv_unit); 447 } 448 printf(": console %s", acc); 449 } else { 450 /* Not a console... */ 451 sabtty_reset(sc); 452 } 453 454 printf("\n"); 455 } 456 457 int 458 sabtty_intr(sc, needsoftp) 459 struct sabtty_softc *sc; 460 int *needsoftp; 461 { 462 u_int8_t isr0, isr1; 463 int i, len = 0, needsoft = 0, r = 0, clearfifo = 0; 464 465 isr0 = SAB_READ(sc, SAB_ISR0); 466 isr1 = SAB_READ(sc, SAB_ISR1); 467 468 if (isr0 || isr1) 469 r = 1; 470 471 if (isr0 & SAB_ISR0_RPF) { 472 len = 32; 473 clearfifo = 1; 474 } 475 if (isr0 & SAB_ISR0_TCD) { 476 len = (32 - 1) & SAB_READ(sc, SAB_RBCL); 477 clearfifo = 1; 478 } 479 if (isr0 & SAB_ISR0_TIME) { 480 sabtty_cec_wait(sc); 481 SAB_WRITE(sc, SAB_CMDR, SAB_CMDR_RFRD); 482 } 483 if (isr0 & SAB_ISR0_RFO) { 484 sc->sc_flags |= SABTTYF_RINGOVERFLOW; 485 clearfifo = 1; 486 } 487 if (len != 0) { 488 u_int8_t *ptr; 489 490 ptr = sc->sc_rput; 491 for (i = 0; i < len; i++) { 492 *ptr++ = SAB_READ(sc, SAB_RFIFO); 493 if (ptr == sc->sc_rend) 494 ptr = sc->sc_rbuf; 495 if (ptr == sc->sc_rget) { 496 if (ptr == sc->sc_rbuf) 497 ptr = sc->sc_rend; 498 ptr--; 499 sc->sc_flags |= SABTTYF_RINGOVERFLOW; 500 } 501 } 502 sc->sc_rput = ptr; 503 needsoft = 1; 504 } 505 506 if (clearfifo) { 507 sabtty_cec_wait(sc); 508 SAB_WRITE(sc, SAB_CMDR, SAB_CMDR_RMC); 509 } 510 511 if (isr0 & SAB_ISR0_CDSC) { 512 sc->sc_flags |= SABTTYF_CDCHG; 513 needsoft = 1; 514 } 515 516 if (isr1 & SAB_ISR1_BRKT) 517 sabtty_abort(sc); 518 519 if (isr1 & (SAB_ISR1_XPR | SAB_ISR1_ALLS)) { 520 if ((SAB_READ(sc, SAB_STAR) & SAB_STAR_XFW) && 521 (sc->sc_flags & SABTTYF_STOP) == 0) { 522 if (sc->sc_txc < 32) 523 len = sc->sc_txc; 524 else 525 len = 32; 526 527 if (len > 0) { 528 SAB_WRITE_BLOCK(sc, SAB_XFIFO, sc->sc_txp, len); 529 sc->sc_txp += len; 530 sc->sc_txc -= len; 531 532 sabtty_cec_wait(sc); 533 SAB_WRITE(sc, SAB_CMDR, SAB_CMDR_XF); 534 535 /* 536 * Prevent the false end of xmit from 537 * confusing things below. 538 */ 539 isr1 &= ~SAB_ISR1_ALLS; 540 } 541 } 542 543 if ((sc->sc_txc == 0) || (sc->sc_flags & SABTTYF_STOP)) { 544 if ((sc->sc_imr1 & SAB_IMR1_XPR) == 0) { 545 sc->sc_imr1 |= SAB_IMR1_XPR; 546 sc->sc_imr1 &= ~SAB_IMR1_ALLS; 547 SAB_WRITE(sc, SAB_IMR1, sc->sc_imr1); 548 } 549 } 550 } 551 552 if ((isr1 & SAB_ISR1_ALLS) && ((sc->sc_txc == 0) || 553 (sc->sc_flags & SABTTYF_STOP))) { 554 if (sc->sc_flags & SABTTYF_TXDRAIN) 555 wakeup(sc); 556 sc->sc_flags &= ~SABTTYF_STOP; 557 sc->sc_flags |= SABTTYF_DONE; 558 sc->sc_imr1 |= SAB_IMR1_ALLS; 559 SAB_WRITE(sc, SAB_IMR1, sc->sc_imr1); 560 needsoft = 1; 561 } 562 563 if (needsoft) 564 *needsoftp = needsoft; 565 return (r); 566 } 567 568 void 569 sabtty_softintr(sc) 570 struct sabtty_softc *sc; 571 { 572 struct tty *tp = sc->sc_tty; 573 int s, flags; 574 u_int8_t r; 575 576 if (tp == NULL) 577 return; 578 579 if ((tp->t_state & TS_ISOPEN) == 0) 580 return; 581 582 while (sc->sc_rget != sc->sc_rput) { 583 int data; 584 u_int8_t stat; 585 586 data = sc->sc_rget[0]; 587 stat = sc->sc_rget[1]; 588 sc->sc_rget += 2; 589 if (stat & SAB_RSTAT_PE) 590 data |= TTY_PE; 591 if (stat & SAB_RSTAT_FE) 592 data |= TTY_FE; 593 if (sc->sc_rget == sc->sc_rend) 594 sc->sc_rget = sc->sc_rbuf; 595 596 (*linesw[tp->t_line].l_rint)(data, tp); 597 } 598 599 s = splhigh(); 600 flags = sc->sc_flags; 601 sc->sc_flags &= ~(SABTTYF_DONE|SABTTYF_CDCHG|SABTTYF_RINGOVERFLOW); 602 splx(s); 603 604 if (flags & SABTTYF_CDCHG) { 605 s = spltty(); 606 r = SAB_READ(sc, SAB_VSTR) & SAB_VSTR_CD; 607 splx(s); 608 609 (*linesw[tp->t_line].l_modem)(tp, r); 610 } 611 612 if (flags & SABTTYF_RINGOVERFLOW) 613 log(LOG_WARNING, "%s: ring overflow\n", sc->sc_dv.dv_xname); 614 615 if (flags & SABTTYF_DONE) { 616 ndflush(&tp->t_outq, sc->sc_txp - tp->t_outq.c_cf); 617 tp->t_state &= ~TS_BUSY; 618 (*linesw[tp->t_line].l_start)(tp); 619 } 620 } 621 622 int 623 sabttyopen(dev, flags, mode, p) 624 dev_t dev; 625 int flags, mode; 626 struct proc *p; 627 { 628 struct sab_softc *bc; 629 struct sabtty_softc *sc; 630 struct tty *tp; 631 int card = SAB_CARD(dev), port = SAB_PORT(dev), s, s1; 632 633 if (card >= sab_cd.cd_ndevs) 634 return (ENXIO); 635 bc = sab_cd.cd_devs[card]; 636 if (bc == NULL) 637 return (ENXIO); 638 639 if (port >= bc->sc_nchild) 640 return (ENXIO); 641 sc = bc->sc_child[port]; 642 if (sc == NULL) 643 return (ENXIO); 644 645 tp = sc->sc_tty; 646 tp->t_dev = dev; 647 648 if ((tp->t_state & TS_ISOPEN) == 0) { 649 tp->t_state |= TS_WOPEN; 650 651 ttychars(tp); 652 tp->t_iflag = TTYDEF_IFLAG; 653 tp->t_oflag = TTYDEF_OFLAG; 654 tp->t_cflag = TTYDEF_CFLAG; 655 if (sc->sc_openflags & TIOCFLAG_CLOCAL) 656 tp->t_cflag |= CLOCAL; 657 if (sc->sc_openflags & TIOCFLAG_CRTSCTS) 658 tp->t_cflag |= CRTSCTS; 659 if (sc->sc_openflags & TIOCFLAG_MDMBUF) 660 tp->t_cflag |= MDMBUF; 661 tp->t_lflag = TTYDEF_LFLAG; 662 tp->t_ispeed = tp->t_ospeed = TTYDEF_SPEED; 663 664 sc->sc_rput = sc->sc_rget = sc->sc_rbuf; 665 666 s = spltty(); 667 668 ttsetwater(tp); 669 670 s1 = splhigh(); 671 sabtty_reset(sc); 672 sabtty_param(tp, &tp->t_termios); 673 sc->sc_imr0 = SAB_IMR0_PERR | SAB_IMR0_FERR | SAB_IMR0_PLLA; 674 SAB_WRITE(sc, SAB_IMR0, sc->sc_imr0); 675 sc->sc_imr1 = SAB_IMR1_BRK | SAB_IMR1_ALLS | SAB_IMR1_XDU | 676 SAB_IMR1_TIN | SAB_IMR1_CSC | SAB_IMR1_XMR | SAB_IMR1_XPR; 677 SAB_WRITE(sc, SAB_IMR1, sc->sc_imr1); 678 SAB_WRITE(sc, SAB_CCR0, SAB_READ(sc, SAB_CCR0) | SAB_CCR0_PU); 679 sabtty_cec_wait(sc); 680 SAB_WRITE(sc, SAB_CMDR, SAB_CMDR_XRES); 681 sabtty_cec_wait(sc); 682 SAB_WRITE(sc, SAB_CMDR, SAB_CMDR_RRES); 683 sabtty_cec_wait(sc); 684 splx(s1); 685 686 sabtty_flush(sc); 687 688 if ((sc->sc_openflags & TIOCFLAG_SOFTCAR) || 689 (SAB_READ(sc, SAB_VSTR) & SAB_VSTR_CD)) 690 tp->t_state |= TS_CARR_ON; 691 else 692 tp->t_state &= ~TS_CARR_ON; 693 } else if ((tp->t_state & TS_XCLUDE) && 694 (!suser(p, 0))) { 695 return (EBUSY); 696 } else { 697 s = spltty(); 698 } 699 700 if ((flags & O_NONBLOCK) == 0) { 701 while ((tp->t_cflag & CLOCAL) == 0 && 702 (tp->t_state & TS_CARR_ON) == 0) { 703 int error; 704 705 tp->t_state |= TS_WOPEN; 706 error = ttysleep(tp, &tp->t_rawq, TTIPRI | PCATCH, 707 "sabttycd", 0); 708 if (error != 0) { 709 splx(s); 710 tp->t_state &= ~TS_WOPEN; 711 return (error); 712 } 713 } 714 } 715 716 splx(s); 717 718 s = (*linesw[tp->t_line].l_open)(dev, tp); 719 if (s != 0) { 720 if (tp->t_state & TS_ISOPEN) 721 return (s); 722 723 if (tp->t_cflag & HUPCL) { 724 sabtty_mdmctrl(sc, 0, DMSET); 725 (void)tsleep(sc, TTIPRI, ttclos, hz); 726 } 727 728 if ((sc->sc_flags & (SABTTYF_CONS_IN | SABTTYF_CONS_OUT)) == 0) { 729 /* Flush and power down if we're not the console */ 730 sabtty_flush(sc); 731 sabtty_reset(sc); 732 } 733 } 734 return (s); 735 } 736 737 int 738 sabttyclose(dev, flags, mode, p) 739 dev_t dev; 740 int flags, mode; 741 struct proc *p; 742 { 743 struct sab_softc *bc = sab_cd.cd_devs[SAB_CARD(dev)]; 744 struct sabtty_softc *sc = bc->sc_child[SAB_PORT(dev)]; 745 struct tty *tp = sc->sc_tty; 746 int s; 747 748 (*linesw[tp->t_line].l_close)(tp, flags); 749 750 s = spltty(); 751 752 if ((tp->t_state & TS_ISOPEN) == 0) { 753 /* Wait for output drain */ 754 sc->sc_imr1 &= ~SAB_IMR1_ALLS; 755 SAB_WRITE(sc, SAB_IMR1, sc->sc_imr1); 756 sc->sc_flags |= SABTTYF_TXDRAIN; 757 (void)tsleep(sc, TTIPRI, ttclos, 5 * hz); 758 sc->sc_imr1 |= SAB_IMR1_ALLS; 759 SAB_WRITE(sc, SAB_IMR1, sc->sc_imr1); 760 sc->sc_flags &= ~SABTTYF_TXDRAIN; 761 762 if (tp->t_cflag & HUPCL) { 763 sabtty_mdmctrl(sc, 0, DMSET); 764 (void)tsleep(bc, TTIPRI, ttclos, hz); 765 } 766 767 if ((sc->sc_flags & (SABTTYF_CONS_IN | SABTTYF_CONS_OUT)) == 0) { 768 /* Flush and power down if we're not the console */ 769 sabtty_flush(sc); 770 sabtty_reset(sc); 771 } 772 } 773 774 ttyclose(tp); 775 splx(s); 776 777 return (0); 778 } 779 780 int 781 sabttyread(dev, uio, flags) 782 dev_t dev; 783 struct uio *uio; 784 int flags; 785 { 786 struct sab_softc *bc = sab_cd.cd_devs[SAB_CARD(dev)]; 787 struct sabtty_softc *sc = bc->sc_child[SAB_PORT(dev)]; 788 struct tty *tp = sc->sc_tty; 789 790 return ((*linesw[tp->t_line].l_read)(tp, uio, flags)); 791 } 792 793 int 794 sabttywrite(dev, uio, flags) 795 dev_t dev; 796 struct uio *uio; 797 int flags; 798 { 799 struct sab_softc *bc = sab_cd.cd_devs[SAB_CARD(dev)]; 800 struct sabtty_softc *sc = bc->sc_child[SAB_PORT(dev)]; 801 struct tty *tp = sc->sc_tty; 802 803 return ((*linesw[tp->t_line].l_write)(tp, uio, flags)); 804 } 805 806 int 807 sabttyioctl(dev, cmd, data, flags, p) 808 dev_t dev; 809 u_long cmd; 810 caddr_t data; 811 int flags; 812 struct proc *p; 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 int error; 818 819 error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flags, p); 820 if (error >= 0) 821 return (error); 822 823 error = ttioctl(tp, cmd, data, flags, p); 824 if (error >= 0) 825 return (error); 826 827 error = 0; 828 829 switch (cmd) { 830 case TIOCSBRK: 831 SAB_WRITE(sc, SAB_DAFO, 832 SAB_READ(sc, SAB_DAFO) | SAB_DAFO_XBRK); 833 break; 834 case TIOCCBRK: 835 SAB_WRITE(sc, SAB_DAFO, 836 SAB_READ(sc, SAB_DAFO) & ~SAB_DAFO_XBRK); 837 break; 838 case TIOCSDTR: 839 sabtty_mdmctrl(sc, TIOCM_DTR, DMBIS); 840 break; 841 case TIOCCDTR: 842 sabtty_mdmctrl(sc, TIOCM_DTR, DMBIC); 843 break; 844 case TIOCMBIS: 845 sabtty_mdmctrl(sc, *((int *)data), DMBIS); 846 break; 847 case TIOCMBIC: 848 sabtty_mdmctrl(sc, *((int *)data), DMBIC); 849 break; 850 case TIOCMGET: 851 *((int *)data) = sabtty_mdmctrl(sc, 0, DMGET); 852 break; 853 case TIOCMSET: 854 sabtty_mdmctrl(sc, *((int *)data), DMSET); 855 break; 856 case TIOCGFLAGS: 857 *((int *)data) = sc->sc_openflags; 858 break; 859 case TIOCSFLAGS: 860 if (suser(p, 0)) 861 error = EPERM; 862 else 863 sc->sc_openflags = *((int *)data) & 864 (TIOCFLAG_SOFTCAR | TIOCFLAG_CLOCAL | 865 TIOCFLAG_CRTSCTS | TIOCFLAG_MDMBUF); 866 break; 867 default: 868 error = ENOTTY; 869 } 870 871 return (error); 872 } 873 874 struct tty * 875 sabttytty(dev) 876 dev_t dev; 877 { 878 struct sab_softc *bc = sab_cd.cd_devs[SAB_CARD(dev)]; 879 struct sabtty_softc *sc = bc->sc_child[SAB_PORT(dev)]; 880 881 return (sc->sc_tty); 882 } 883 884 int 885 sabttystop(tp, flags) 886 struct tty *tp; 887 int flags; 888 { 889 struct sab_softc *bc = sab_cd.cd_devs[SAB_CARD(tp->t_dev)]; 890 struct sabtty_softc *sc = bc->sc_child[SAB_PORT(tp->t_dev)]; 891 int s; 892 893 s = spltty(); 894 if (tp->t_state & TS_BUSY) { 895 if ((tp->t_state & TS_TTSTOP) == 0) 896 tp->t_state |= TS_FLUSH; 897 sc->sc_flags |= SABTTYF_STOP; 898 sc->sc_imr1 &= ~SAB_IMR1_ALLS; 899 SAB_WRITE(sc, SAB_IMR1, sc->sc_imr1); 900 } 901 splx(s); 902 return (0); 903 } 904 905 int 906 sabtty_mdmctrl(sc, bits, how) 907 struct sabtty_softc *sc; 908 int bits, how; 909 { 910 u_int8_t r; 911 int s; 912 913 s = spltty(); 914 switch (how) { 915 case DMGET: 916 bits = 0; 917 if (SAB_READ(sc, SAB_STAR) & SAB_STAR_CTS) 918 bits |= TIOCM_CTS; 919 if ((SAB_READ(sc, SAB_VSTR) & SAB_VSTR_CD) == 0) 920 bits |= TIOCM_CD; 921 922 r = SAB_READ(sc, SAB_PVR); 923 if ((r & sc->sc_pvr_dtr) == 0) 924 bits |= TIOCM_DTR; 925 if ((r & sc->sc_pvr_dsr) == 0) 926 bits |= TIOCM_DSR; 927 928 r = SAB_READ(sc, SAB_MODE); 929 if ((r & (SAB_MODE_RTS|SAB_MODE_FRTS)) == SAB_MODE_RTS) 930 bits |= TIOCM_RTS; 931 break; 932 case DMSET: 933 r = SAB_READ(sc, SAB_MODE); 934 if (bits & TIOCM_RTS) { 935 r &= ~SAB_MODE_FRTS; 936 r |= SAB_MODE_RTS; 937 } else 938 r |= SAB_MODE_FRTS | SAB_MODE_RTS; 939 SAB_WRITE(sc, SAB_MODE, r); 940 941 r = SAB_READ(sc, SAB_PVR); 942 if (bits & TIOCM_DTR) 943 r &= ~sc->sc_pvr_dtr; 944 else 945 r |= sc->sc_pvr_dtr; 946 SAB_WRITE(sc, SAB_PVR, r); 947 break; 948 case DMBIS: 949 if (bits & TIOCM_RTS) { 950 r = SAB_READ(sc, SAB_MODE); 951 r &= ~SAB_MODE_FRTS; 952 r |= SAB_MODE_RTS; 953 SAB_WRITE(sc, SAB_MODE, r); 954 } 955 if (bits & TIOCM_DTR) { 956 r = SAB_READ(sc, SAB_PVR); 957 r &= ~sc->sc_pvr_dtr; 958 SAB_WRITE(sc, SAB_PVR, r); 959 } 960 break; 961 case DMBIC: 962 if (bits & TIOCM_RTS) { 963 r = SAB_READ(sc, SAB_MODE); 964 r |= SAB_MODE_FRTS | SAB_MODE_RTS; 965 SAB_WRITE(sc, SAB_MODE, r); 966 } 967 if (bits & TIOCM_DTR) { 968 r = SAB_READ(sc, SAB_PVR); 969 r |= sc->sc_pvr_dtr; 970 SAB_WRITE(sc, SAB_PVR, r); 971 } 972 break; 973 } 974 splx(s); 975 return (bits); 976 } 977 978 int 979 sabttyparam(sc, tp, t) 980 struct sabtty_softc *sc; 981 struct tty *tp; 982 struct termios *t; 983 { 984 int s, ospeed; 985 tcflag_t cflag; 986 u_int8_t dafo, r; 987 988 ospeed = sabtty_speed(t->c_ospeed); 989 if (ospeed < 0 || (t->c_ispeed && t->c_ispeed != t->c_ospeed)) 990 return (EINVAL); 991 992 s = spltty(); 993 994 /* hang up line if ospeed is zero, otherwise raise dtr */ 995 sabtty_mdmctrl(sc, TIOCM_DTR, 996 (t->c_ospeed == 0) ? DMBIC : DMBIS); 997 998 dafo = SAB_READ(sc, SAB_DAFO); 999 1000 cflag = t->c_cflag; 1001 1002 if (sc->sc_flags & (SABTTYF_CONS_IN | SABTTYF_CONS_OUT)) { 1003 cflag |= CLOCAL; 1004 cflag &= ~HUPCL; 1005 } 1006 1007 if (cflag & CSTOPB) 1008 dafo |= SAB_DAFO_STOP; 1009 else 1010 dafo &= ~SAB_DAFO_STOP; 1011 1012 dafo &= ~SAB_DAFO_CHL_CSIZE; 1013 switch (cflag & CSIZE) { 1014 case CS5: 1015 dafo |= SAB_DAFO_CHL_CS5; 1016 break; 1017 case CS6: 1018 dafo |= SAB_DAFO_CHL_CS6; 1019 break; 1020 case CS7: 1021 dafo |= SAB_DAFO_CHL_CS7; 1022 break; 1023 default: 1024 dafo |= SAB_DAFO_CHL_CS8; 1025 break; 1026 } 1027 1028 dafo &= ~SAB_DAFO_PARMASK; 1029 if (cflag & PARENB) { 1030 if (cflag & PARODD) 1031 dafo |= SAB_DAFO_PAR_ODD; 1032 else 1033 dafo |= SAB_DAFO_PAR_EVEN; 1034 } else 1035 dafo |= SAB_DAFO_PAR_NONE; 1036 1037 if (ospeed != 0) { 1038 SAB_WRITE(sc, SAB_BGR, ospeed & 0xff); 1039 r = SAB_READ(sc, SAB_CCR2); 1040 r &= ~(SAB_CCR2_BR9 | SAB_CCR2_BR8); 1041 r |= (ospeed >> 2) & (SAB_CCR2_BR9 | SAB_CCR2_BR8); 1042 SAB_WRITE(sc, SAB_CCR2, r); 1043 } 1044 1045 r = SAB_READ(sc, SAB_MODE); 1046 r |= SAB_MODE_RAC; 1047 if (cflag & CRTSCTS) { 1048 r &= ~(SAB_MODE_RTS | SAB_MODE_FCTS); 1049 r |= SAB_MODE_FRTS; 1050 sc->sc_imr1 &= ~SAB_IMR1_CSC; 1051 } else { 1052 r |= SAB_MODE_RTS | SAB_MODE_FCTS; 1053 r &= ~SAB_MODE_FRTS; 1054 sc->sc_imr1 |= SAB_IMR1_CSC; 1055 } 1056 SAB_WRITE(sc, SAB_MODE, r); 1057 SAB_WRITE(sc, SAB_IMR1, sc->sc_imr1); 1058 1059 tp->t_cflag = cflag; 1060 1061 splx(s); 1062 return (0); 1063 } 1064 1065 int 1066 sabtty_param(tp, t) 1067 struct tty *tp; 1068 struct termios *t; 1069 { 1070 struct sab_softc *bc = sab_cd.cd_devs[SAB_CARD(tp->t_dev)]; 1071 struct sabtty_softc *sc = bc->sc_child[SAB_PORT(tp->t_dev)]; 1072 1073 return (sabttyparam(sc, tp, t)); 1074 } 1075 1076 void 1077 sabtty_start(tp) 1078 struct tty *tp; 1079 { 1080 struct sab_softc *bc = sab_cd.cd_devs[SAB_CARD(tp->t_dev)]; 1081 struct sabtty_softc *sc = bc->sc_child[SAB_PORT(tp->t_dev)]; 1082 int s; 1083 1084 s = spltty(); 1085 if ((tp->t_state & (TS_TTSTOP | TS_TIMEOUT | TS_BUSY)) == 0) { 1086 if (tp->t_outq.c_cc <= tp->t_lowat) { 1087 if (tp->t_state & TS_ASLEEP) { 1088 tp->t_state &= ~TS_ASLEEP; 1089 wakeup(&tp->t_outq); 1090 } 1091 selwakeup(&tp->t_wsel); 1092 } 1093 if (tp->t_outq.c_cc) { 1094 sc->sc_txc = ndqb(&tp->t_outq, 0); 1095 sc->sc_txp = tp->t_outq.c_cf; 1096 tp->t_state |= TS_BUSY; 1097 sc->sc_imr1 &= ~(SAB_ISR1_XPR | SAB_ISR1_ALLS); 1098 SAB_WRITE(sc, SAB_IMR1, sc->sc_imr1); 1099 } 1100 } 1101 splx(s); 1102 } 1103 1104 int 1105 sabtty_cec_wait(sc) 1106 struct sabtty_softc *sc; 1107 { 1108 int i = 50000; 1109 1110 for (;;) { 1111 if ((SAB_READ(sc, SAB_STAR) & SAB_STAR_CEC) == 0) 1112 return (0); 1113 if (--i == 0) 1114 return (1); 1115 DELAY(1); 1116 } 1117 } 1118 1119 int 1120 sabtty_tec_wait(sc) 1121 struct sabtty_softc *sc; 1122 { 1123 int i = 200000; 1124 1125 for (;;) { 1126 if ((SAB_READ(sc, SAB_STAR) & SAB_STAR_TEC) == 0) 1127 return (0); 1128 if (--i == 0) 1129 return (1); 1130 DELAY(1); 1131 } 1132 } 1133 1134 void 1135 sabtty_reset(sc) 1136 struct sabtty_softc *sc; 1137 { 1138 /* power down */ 1139 SAB_WRITE(sc, SAB_CCR0, 0); 1140 1141 /* set basic configuration */ 1142 SAB_WRITE(sc, SAB_CCR0, 1143 SAB_CCR0_MCE | SAB_CCR0_SC_NRZ | SAB_CCR0_SM_ASYNC); 1144 SAB_WRITE(sc, SAB_CCR1, SAB_CCR1_ODS | SAB_CCR1_BCR | SAB_CCR1_CM_7); 1145 SAB_WRITE(sc, SAB_CCR2, SAB_CCR2_BDF | SAB_CCR2_SSEL | SAB_CCR2_TOE); 1146 SAB_WRITE(sc, SAB_CCR3, 0); 1147 SAB_WRITE(sc, SAB_CCR4, SAB_CCR4_MCK4 | SAB_CCR4_EBRG); 1148 SAB_WRITE(sc, SAB_MODE, SAB_MODE_RTS | SAB_MODE_FCTS | SAB_MODE_RAC); 1149 SAB_WRITE(sc, SAB_RFC, 1150 SAB_RFC_DPS | SAB_RFC_RFDF | SAB_RFC_RFTH_32CHAR); 1151 1152 /* clear interrupts */ 1153 sc->sc_imr0 = sc->sc_imr1 = 0xff; 1154 SAB_WRITE(sc, SAB_IMR0, sc->sc_imr0); 1155 SAB_WRITE(sc, SAB_IMR1, sc->sc_imr1); 1156 SAB_READ(sc, SAB_ISR0); 1157 SAB_READ(sc, SAB_ISR1); 1158 } 1159 1160 void 1161 sabtty_flush(sc) 1162 struct sabtty_softc *sc; 1163 { 1164 /* clear rx fifo */ 1165 sabtty_cec_wait(sc); 1166 SAB_WRITE(sc, SAB_CMDR, SAB_CMDR_RRES); 1167 1168 /* clear tx fifo */ 1169 sabtty_cec_wait(sc); 1170 SAB_WRITE(sc, SAB_CMDR, SAB_CMDR_XRES); 1171 } 1172 1173 int 1174 sabtty_speed(rate) 1175 int rate; 1176 { 1177 int i, len, r; 1178 1179 if (rate == 0) 1180 return (0); 1181 len = sizeof(sabtty_baudtable)/sizeof(sabtty_baudtable[0]); 1182 for (i = 0; i < len; i++) { 1183 if (rate == sabtty_baudtable[i].baud) { 1184 r = sabtty_baudtable[i].n | 1185 (sabtty_baudtable[i].m << 6); 1186 return (r); 1187 } 1188 } 1189 return (-1); 1190 } 1191 1192 void 1193 sabtty_cnputc(sc, c) 1194 struct sabtty_softc *sc; 1195 int c; 1196 { 1197 sabtty_tec_wait(sc); 1198 SAB_WRITE(sc, SAB_TIC, c); 1199 sabtty_tec_wait(sc); 1200 } 1201 1202 int 1203 sabtty_cngetc(sc) 1204 struct sabtty_softc *sc; 1205 { 1206 u_int8_t r, len; 1207 1208 again: 1209 do { 1210 r = SAB_READ(sc, SAB_STAR); 1211 } while ((r & SAB_STAR_RFNE) == 0); 1212 1213 /* 1214 * Ok, at least one byte in RFIFO, ask for permission to access RFIFO 1215 * (I hate this chip... hate hate hate). 1216 */ 1217 sabtty_cec_wait(sc); 1218 SAB_WRITE(sc, SAB_CMDR, SAB_CMDR_RFRD); 1219 1220 /* Wait for RFIFO to come ready */ 1221 do { 1222 r = SAB_READ(sc, SAB_ISR0); 1223 } while ((r & SAB_ISR0_TCD) == 0); 1224 1225 len = SAB_READ(sc, SAB_RBCL) & (32 - 1); 1226 if (len == 0) 1227 goto again; /* Shouldn't happen... */ 1228 1229 r = SAB_READ(sc, SAB_RFIFO); 1230 1231 /* 1232 * Blow away everything left in the FIFO... 1233 */ 1234 sabtty_cec_wait(sc); 1235 SAB_WRITE(sc, SAB_CMDR, SAB_CMDR_RMC); 1236 return (r); 1237 } 1238 1239 void 1240 sabtty_cnpollc(sc, on) 1241 struct sabtty_softc *sc; 1242 int on; 1243 { 1244 u_int8_t r; 1245 1246 if (on) { 1247 if (sc->sc_polling) 1248 return; 1249 SAB_WRITE(sc, SAB_IPC, SAB_READ(sc, SAB_IPC) | SAB_IPC_VIS); 1250 r = sc->sc_pollrfc = SAB_READ(sc, SAB_RFC); 1251 r &= ~(SAB_RFC_RFDF); 1252 SAB_WRITE(sc, SAB_RFC, r); 1253 sabtty_cec_wait(sc); 1254 SAB_WRITE(sc, SAB_CMDR, SAB_CMDR_RRES); 1255 sc->sc_polling = 1; 1256 } else { 1257 if (!sc->sc_polling) 1258 return; 1259 SAB_WRITE(sc, SAB_IPC, SAB_READ(sc, SAB_IPC) & ~SAB_IPC_VIS); 1260 SAB_WRITE(sc, SAB_RFC, sc->sc_pollrfc); 1261 sabtty_cec_wait(sc); 1262 SAB_WRITE(sc, SAB_CMDR, SAB_CMDR_RRES); 1263 sc->sc_polling = 0; 1264 } 1265 } 1266 1267 void 1268 sab_cnputc(dev, c) 1269 dev_t dev; 1270 int c; 1271 { 1272 struct sabtty_softc *sc = sabtty_cons_output; 1273 1274 if (sc == NULL) 1275 return; 1276 sabtty_cnputc(sc, c); 1277 } 1278 1279 void 1280 sab_cnpollc(dev, on) 1281 dev_t dev; 1282 int on; 1283 { 1284 struct sabtty_softc *sc = sabtty_cons_input; 1285 1286 sabtty_cnpollc(sc, on); 1287 } 1288 1289 int 1290 sab_cngetc(dev) 1291 dev_t dev; 1292 { 1293 struct sabtty_softc *sc = sabtty_cons_input; 1294 1295 if (sc == NULL) 1296 return (-1); 1297 return (sabtty_cngetc(sc)); 1298 } 1299 1300 void 1301 sabtty_console_flags(sc) 1302 struct sabtty_softc *sc; 1303 { 1304 int node, channel, cookie; 1305 u_int options; 1306 char buf[255]; 1307 1308 node = sc->sc_parent->sc_node; 1309 channel = sc->sc_portno; 1310 1311 options = OF_finddevice("/options"); 1312 1313 /* Default to channel 0 if there are no explicit prom args */ 1314 cookie = 0; 1315 1316 if (node == OF_instance_to_package(OF_stdin())) { 1317 if (OF_getprop(options, "input-device", buf, 1318 sizeof(buf)) != -1) { 1319 if (strncmp("ttyb", buf, strlen("ttyb")) == 0) 1320 cookie = 1; 1321 } 1322 1323 if (channel == cookie) 1324 sc->sc_flags |= SABTTYF_CONS_IN; 1325 } 1326 1327 /* Default to same channel if there are no explicit prom args */ 1328 1329 if (node == OF_instance_to_package(OF_stdout())) { 1330 if (OF_getprop(options, "output-device", buf, 1331 sizeof(buf)) != -1) { 1332 if (strncmp("ttyb", buf, strlen("ttyb")) == 0) 1333 cookie = 1; 1334 } 1335 1336 if (channel == cookie) 1337 sc->sc_flags |= SABTTYF_CONS_OUT; 1338 } 1339 } 1340 1341 void 1342 sabtty_abort(sc) 1343 struct sabtty_softc *sc; 1344 { 1345 1346 if (sc->sc_flags & SABTTYF_CONS_IN) { 1347 #ifdef DDB 1348 extern int db_active, db_console; 1349 1350 if (db_console == 0) 1351 return; 1352 if (db_active == 0) 1353 Debugger(); 1354 else 1355 callrom(); 1356 #else 1357 callrom(); 1358 #endif 1359 } 1360 } 1361 1362 void 1363 sabtty_shutdown(vsc) 1364 void *vsc; 1365 { 1366 struct sabtty_softc *sc = vsc; 1367 1368 /* Have to put the chip back into single char mode */ 1369 sc->sc_flags |= SABTTYF_DONTDDB; 1370 SAB_WRITE(sc, SAB_RFC, SAB_READ(sc, SAB_RFC) & ~SAB_RFC_RFDF); 1371 sabtty_cec_wait(sc); 1372 SAB_WRITE(sc, SAB_CMDR, SAB_CMDR_RRES); 1373 sabtty_cec_wait(sc); 1374 } 1375