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