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