1 /* $NetBSD: sci.c,v 1.8 2000/03/27 16:24:08 msaitoh Exp $ */ 2 3 /*- 4 * Copyright (C) 1999 T.Horiuchi and SAITOH Masanobu. All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 3. The name of the author may not be used to endorse or promote products 15 * derived from this software without specific prior written permission. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 */ 28 29 /*- 30 * Copyright (c) 1998, 1999 The NetBSD Foundation, Inc. 31 * All rights reserved. 32 * 33 * This code is derived from software contributed to The NetBSD Foundation 34 * by Charles M. Hannum. 35 * 36 * Redistribution and use in source and binary forms, with or without 37 * modification, are permitted provided that the following conditions 38 * are met: 39 * 1. Redistributions of source code must retain the above copyright 40 * notice, this list of conditions and the following disclaimer. 41 * 2. Redistributions in binary form must reproduce the above copyright 42 * notice, this list of conditions and the following disclaimer in the 43 * documentation and/or other materials provided with the distribution. 44 * 3. All advertising materials mentioning features or use of this software 45 * must display the following acknowledgement: 46 * This product includes software developed by the NetBSD 47 * Foundation, Inc. and its contributors. 48 * 4. Neither the name of The NetBSD Foundation nor the names of its 49 * contributors may be used to endorse or promote products derived 50 * from this software without specific prior written permission. 51 * 52 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 53 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 54 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 55 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 56 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 57 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 58 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 59 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 60 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 61 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 62 * POSSIBILITY OF SUCH DAMAGE. 63 */ 64 65 /* 66 * Copyright (c) 1991 The Regents of the University of California. 67 * All rights reserved. 68 * 69 * Redistribution and use in source and binary forms, with or without 70 * modification, are permitted provided that the following conditions 71 * are met: 72 * 1. Redistributions of source code must retain the above copyright 73 * notice, this list of conditions and the following disclaimer. 74 * 2. Redistributions in binary form must reproduce the above copyright 75 * notice, this list of conditions and the following disclaimer in the 76 * documentation and/or other materials provided with the distribution. 77 * 3. All advertising materials mentioning features or use of this software 78 * must display the following acknowledgement: 79 * This product includes software developed by the University of 80 * California, Berkeley and its contributors. 81 * 4. Neither the name of the University nor the names of its contributors 82 * may be used to endorse or promote products derived from this software 83 * without specific prior written permission. 84 * 85 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 86 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 87 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 88 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 89 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 90 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 91 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 92 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 93 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 94 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 95 * SUCH DAMAGE. 96 * 97 * @(#)com.c 7.5 (Berkeley) 5/16/91 98 */ 99 100 /* 101 * SH internal serial driver 102 * 103 * This code is derived from both z8530tty.c and com.c 104 */ 105 106 #include "opt_pclock.h" 107 #include "opt_sci.h" 108 109 #include <sys/param.h> 110 #include <sys/systm.h> 111 #include <sys/tty.h> 112 #include <sys/proc.h> 113 #include <sys/conf.h> 114 #include <sys/file.h> 115 #include <sys/syslog.h> 116 #include <sys/kernel.h> 117 #include <sys/device.h> 118 #include <sys/malloc.h> 119 120 #include <dev/cons.h> 121 122 #include <machine/cpu.h> 123 #include <sh3/scireg.h> 124 #include <sh3/tmureg.h> 125 126 #include <machine/shbvar.h> 127 128 static void scistart __P((struct tty *)); 129 static int sciparam __P((struct tty *, struct termios *)); 130 131 void scicnprobe __P((struct consdev *)); 132 void scicninit __P((struct consdev *)); 133 void scicnputc __P((dev_t, int)); 134 int scicngetc __P((dev_t)); 135 void scicnpoolc __P((dev_t, int)); 136 int sciintr __P((void *)); 137 138 struct sci_softc { 139 struct device sc_dev; /* boilerplate */ 140 struct tty *sc_tty; 141 void *sc_ih; 142 143 struct callout sc_diag_ch; 144 145 #if 0 146 bus_space_tag_t sc_iot; /* ISA i/o space identifier */ 147 bus_space_handle_t sc_ioh; /* ISA io handle */ 148 149 int sc_drq; 150 151 int sc_frequency; 152 #endif 153 154 u_int sc_overflows, 155 sc_floods, 156 sc_errors; /* number of retries so far */ 157 u_char sc_status[7]; /* copy of registers */ 158 159 int sc_hwflags; 160 int sc_swflags; 161 u_int sc_fifolen; /* XXX always 0? */ 162 163 u_int sc_r_hiwat, 164 sc_r_lowat; 165 u_char *volatile sc_rbget, 166 *volatile sc_rbput; 167 volatile u_int sc_rbavail; 168 u_char *sc_rbuf, 169 *sc_ebuf; 170 171 u_char *sc_tba; /* transmit buffer address */ 172 u_int sc_tbc, /* transmit byte count */ 173 sc_heldtbc; 174 175 volatile u_char sc_rx_flags, /* receiver blocked */ 176 #define RX_TTY_BLOCKED 0x01 177 #define RX_TTY_OVERFLOWED 0x02 178 #define RX_IBUF_BLOCKED 0x04 179 #define RX_IBUF_OVERFLOWED 0x08 180 #define RX_ANY_BLOCK 0x0f 181 sc_tx_busy, /* working on an output chunk */ 182 sc_tx_done, /* done with one output chunk */ 183 sc_tx_stopped, /* H/W level stop (lost CTS) */ 184 sc_st_check, /* got a status interrupt */ 185 sc_rx_ready; 186 187 volatile u_char sc_heldchange; 188 }; 189 190 /* controller driver configuration */ 191 static int sci_match __P((struct device *, struct cfdata *, void *)); 192 static void sci_attach __P((struct device *, struct device *, void *)); 193 194 void sci_break __P((struct sci_softc *, int)); 195 void sci_iflush __P((struct sci_softc *)); 196 197 #define integrate static inline 198 #ifdef __GENERIC_SOFT_INTERRUPTS 199 void scisoft __P((void *)); 200 #else 201 #ifndef __NO_SOFT_SERIAL_INTERRUPT 202 void scisoft __P((void)); 203 #else 204 void scisoft __P((void *)); 205 #endif 206 #endif 207 integrate void sci_rxsoft __P((struct sci_softc *, struct tty *)); 208 integrate void sci_txsoft __P((struct sci_softc *, struct tty *)); 209 integrate void sci_stsoft __P((struct sci_softc *, struct tty *)); 210 integrate void sci_schedrx __P((struct sci_softc *)); 211 void scidiag __P((void *)); 212 213 #define SCIUNIT_MASK 0x7ffff 214 #define SCIDIALOUT_MASK 0x80000 215 216 #define SCIUNIT(x) (minor(x) & SCIUNIT_MASK) 217 #define SCIDIALOUT(x) (minor(x) & SCIDIALOUT_MASK) 218 219 /* Macros to clear/set/test flags. */ 220 #define SET(t, f) (t) |= (f) 221 #define CLR(t, f) (t) &= ~(f) 222 #define ISSET(t, f) ((t) & (f)) 223 224 /* Hardware flag masks */ 225 #define SCI_HW_NOIEN 0x01 226 #define SCI_HW_FIFO 0x02 227 #define SCI_HW_FLOW 0x08 228 #define SCI_HW_DEV_OK 0x20 229 #define SCI_HW_CONSOLE 0x40 230 #define SCI_HW_KGDB 0x80 231 232 /* Buffer size for character buffer */ 233 #define SCI_RING_SIZE 2048 234 235 /* Stop input when 3/4 of the ring is full; restart when only 1/4 is full. */ 236 u_int sci_rbuf_hiwat = (SCI_RING_SIZE * 1) / 4; 237 u_int sci_rbuf_lowat = (SCI_RING_SIZE * 3) / 4; 238 239 #define CONMODE ((TTYDEF_CFLAG & ~(CSIZE | CSTOPB | PARENB)) | CS8) /* 8N1 */ 240 int sciconscflag = CONMODE; 241 int sciisconsole = 0; 242 243 #ifdef SCICN_SPEED 244 int scicn_speed = SCICN_SPEED; 245 #else 246 int scicn_speed = 9600; 247 #endif 248 249 #define divrnd(n, q) (((n)*2/(q)+1)/2) /* divide and round off */ 250 251 #ifndef __GENERIC_SOFT_INTERRUPTS 252 #ifdef __NO_SOFT_SERIAL_INTERRUPT 253 volatile int sci_softintr_scheduled; 254 struct callout sci_soft_ch = CALLOUT_INITIALIZER; 255 #endif 256 #endif 257 258 u_int sci_rbuf_size = SCI_RING_SIZE; 259 260 struct cfattach sci_ca = { 261 sizeof(struct sci_softc), sci_match, sci_attach 262 }; 263 264 extern struct cfdriver sci_cd; 265 266 cdev_decl(sci); 267 268 void InitializeSci __P((unsigned int)); 269 270 /* 271 * following functions are debugging prupose only 272 */ 273 #define CR 0x0D 274 #define I2C_ADRS (*(volatile unsigned int *)0xa8000000) 275 #define USART_ON (unsigned int)~0x08 276 277 static void WaitFor __P((int)); 278 void PutcSci __P((unsigned char)); 279 void PutStrSci __P((unsigned char *)); 280 int SciErrCheck __P((void)); 281 unsigned char GetcSci __P((void)); 282 int GetStrSci __P((unsigned char *, int)); 283 284 /* 285 * WaitFor 286 * : int mSec; 287 */ 288 static void 289 WaitFor(mSec) 290 int mSec; 291 { 292 293 /* Disable Under Flow interrupt, rising edge, 1/4 */ 294 SHREG_TCR2 = 0x0000; 295 296 /* Set counter value (count down with 4 KHz) */ 297 SHREG_TCNT2 = mSec * 4; 298 299 /* start Channel2 */ 300 SHREG_TSTR |= TSTR_STR2; 301 302 /* wait for under flag ON of channel2 */ 303 while ((SHREG_TCR2 & TCR_UNF) == 0) 304 ; 305 306 /* stop channel2 */ 307 SHREG_TSTR &= ~TSTR_STR2; 308 } 309 310 /* 311 * InitializeSci 312 * : unsigned int bps; 313 * : SCI(Serial Communication Interface) 314 */ 315 316 void 317 InitializeSci(bps) 318 unsigned int bps; 319 { 320 321 /* Initialize SCR */ 322 SHREG_SCSCR = 0x00; 323 324 /* Serial Mode Register */ 325 SHREG_SCSMR = 0x00; /* Async,8bit,NonParity,Even,1Stop,NoMulti */ 326 327 /* Bit Rate Register */ 328 SHREG_SCBRR = divrnd(PCLOCK, 32 * bps) - 1; 329 330 /* 331 * wait 1mSec, because Send/Recv must begin 1 bit period after 332 * BRR is set. 333 */ 334 WaitFor(1); 335 336 /* Send permission, Recieve permission ON */ 337 SHREG_SCSCR = SCSCR_TE | SCSCR_RE; 338 339 /* Serial Status Register */ 340 SHREG_SCSSR &= SCSSR_TDRE; /* Clear Status */ 341 342 #if 0 343 I2C_ADRS &= ~0x08; /* enable RS-232C */ 344 #endif 345 } 346 347 348 /* 349 * PutcSci 350 * : unsigned char c; 351 */ 352 void 353 PutcSci(c) 354 unsigned char c; 355 { 356 357 /* wait for ready */ 358 while ((SHREG_SCSSR & SCSSR_TDRE) == NULL) 359 ; 360 361 /* write send data to send register */ 362 SHREG_SCTDR = c; 363 364 /* clear ready flag */ 365 SHREG_SCSSR &= ~SCSSR_TDRE; 366 367 if (c == '\n') { 368 while ((SHREG_SCSSR & SCSSR_TDRE) == NULL) 369 ; 370 371 SHREG_SCTDR = '\r'; 372 373 SHREG_SCSSR &= ~SCSSR_TDRE; 374 } 375 } 376 377 /* 378 * PutStrSci 379 * : unsigned char *s; 380 */ 381 void 382 PutStrSci(s) 383 unsigned char *s; 384 { 385 #if 0 386 static int SciInit = 0; 387 if (SciInit == 0) { 388 InitializeSci(scicn_speed); 389 SciInit = 1; 390 } 391 #endif 392 393 while (*s) 394 PutcSci(*s++); 395 } 396 397 /* 398 * : SciErrCheck 399 * 0x20 = over run 400 * 0x10 = frame error 401 * 0x80 = parity error 402 */ 403 int 404 SciErrCheck(void) 405 { 406 407 return(SHREG_SCSSR & (SCSSR_ORER | SCSSR_FER | SCSSR_PER)); 408 } 409 410 /* 411 * GetcSci 412 */ 413 unsigned char 414 GetcSci(void) 415 { 416 unsigned char c, err_c; 417 418 while (((err_c = SHREG_SCSSR) 419 & (SCSSR_RDRF | SCSSR_ORER | SCSSR_FER | SCSSR_PER)) == 0) 420 ; 421 if ((err_c & (SCSSR_ORER | SCSSR_FER | SCSSR_PER)) != 0) 422 return(err_c |= 0x80); 423 424 c = SHREG_SCRDR; 425 426 SHREG_SCSSR &= ~SCSSR_RDRF; 427 428 return(c); 429 } 430 431 /* 432 * GetStrSci 433 * : unsigned char *s; 434 * : int size; 435 */ 436 int 437 GetStrSci(s, size) 438 unsigned char *s; 439 int size; 440 { 441 442 for(; size ; size--) { 443 *s = GetcSci(); 444 if (*s & 0x80) 445 return -1; 446 if (*s == CR) { 447 *s = 0; 448 break; 449 } 450 s++; 451 } 452 if (size == 0) 453 *s = 0; 454 return 0; 455 } 456 457 #if 0 458 #define SCI_MAX_UNITS 2 459 #else 460 #define SCI_MAX_UNITS 1 461 #endif 462 463 464 static int 465 sci_match(parent, cfp, aux) 466 struct device *parent; 467 struct cfdata *cfp; 468 void *aux; 469 { 470 struct shb_attach_args *sa = aux; 471 472 if (strcmp(cfp->cf_driver->cd_name, "sci") 473 || cfp->cf_unit >= SCI_MAX_UNITS) 474 return 0; 475 476 sa->ia_iosize = 0x10; 477 return 1; 478 } 479 480 static void 481 sci_attach(parent, self, aux) 482 struct device *parent, *self; 483 void *aux; 484 { 485 struct sci_softc *sc = (struct sci_softc *)self; 486 struct tty *tp; 487 int irq; 488 struct shb_attach_args *ia = aux; 489 490 sc->sc_hwflags = 0; /* XXX */ 491 sc->sc_swflags = 0; /* XXX */ 492 sc->sc_fifolen = 0; /* XXX */ 493 494 irq = ia->ia_irq; 495 496 if (sciisconsole) { 497 SET(sc->sc_hwflags, SCI_HW_CONSOLE); 498 SET(sc->sc_swflags, TIOCFLAG_SOFTCAR); 499 printf("\n%s: console\n", sc->sc_dev.dv_xname); 500 } else { 501 InitializeSci(9600); 502 printf("\n"); 503 } 504 505 callout_init(&sc->sc_diag_ch); 506 507 #if 0 508 if (irq != IRQUNK) { 509 sc->sc_ih = shb_intr_establish(irq, 510 IST_EDGE, IPL_SERIAL, sciintr, sc); 511 } 512 #else 513 if (irq != IRQUNK) { 514 sc->sc_ih = shb_intr_establish(SCI_IRQ, 515 IST_EDGE, IPL_SERIAL, sciintr, sc); 516 } 517 #endif 518 519 SET(sc->sc_hwflags, SCI_HW_DEV_OK); 520 521 tp = ttymalloc(); 522 tp->t_oproc = scistart; 523 tp->t_param = sciparam; 524 tp->t_hwiflow = NULL; 525 526 sc->sc_tty = tp; 527 sc->sc_rbuf = malloc(sci_rbuf_size << 1, M_DEVBUF, M_NOWAIT); 528 if (sc->sc_rbuf == NULL) { 529 printf("%s: unable to allocate ring buffer\n", 530 sc->sc_dev.dv_xname); 531 return; 532 } 533 sc->sc_ebuf = sc->sc_rbuf + (sci_rbuf_size << 1); 534 535 tty_attach(tp); 536 } 537 538 /* 539 * Start or restart transmission. 540 */ 541 static void 542 scistart(tp) 543 struct tty *tp; 544 { 545 struct sci_softc *sc = sci_cd.cd_devs[SCIUNIT(tp->t_dev)]; 546 int s; 547 548 s = spltty(); 549 if (ISSET(tp->t_state, TS_BUSY | TS_TIMEOUT | TS_TTSTOP)) 550 goto out; 551 if (sc->sc_tx_stopped) 552 goto out; 553 554 if (tp->t_outq.c_cc <= tp->t_lowat) { 555 if (ISSET(tp->t_state, TS_ASLEEP)) { 556 CLR(tp->t_state, TS_ASLEEP); 557 wakeup(&tp->t_outq); 558 } 559 selwakeup(&tp->t_wsel); 560 if (tp->t_outq.c_cc == 0) 561 goto out; 562 } 563 564 /* Grab the first contiguous region of buffer space. */ 565 { 566 u_char *tba; 567 int tbc; 568 569 tba = tp->t_outq.c_cf; 570 tbc = ndqb(&tp->t_outq, 0); 571 572 (void)splserial(); 573 574 sc->sc_tba = tba; 575 sc->sc_tbc = tbc; 576 } 577 578 SET(tp->t_state, TS_BUSY); 579 sc->sc_tx_busy = 1; 580 581 /* Enable transmit completion interrupts if necessary. */ 582 SHREG_SCSCR |= SCSCR_TIE | SCSCR_RIE; 583 584 /* Output the first byte of the contiguous buffer. */ 585 { 586 if (sc->sc_tbc > 0) { 587 PutcSci(*(sc->sc_tba)); 588 sc->sc_tba++; 589 sc->sc_tbc--; 590 } 591 } 592 out: 593 splx(s); 594 return; 595 } 596 597 /* 598 * Set SCI tty parameters from termios. 599 * XXX - Should just copy the whole termios after 600 * making sure all the changes could be done. 601 */ 602 static int 603 sciparam(tp, t) 604 struct tty *tp; 605 struct termios *t; 606 { 607 struct sci_softc *sc = sci_cd.cd_devs[SCIUNIT(tp->t_dev)]; 608 int ospeed = t->c_ospeed; 609 int s; 610 611 if (ISSET(sc->sc_dev.dv_flags, DVF_ACTIVE) == 0) 612 return (EIO); 613 614 /* Check requested parameters. */ 615 if (ospeed < 0) 616 return (EINVAL); 617 if (t->c_ispeed && t->c_ispeed != t->c_ospeed) 618 return (EINVAL); 619 620 /* 621 * For the console, always force CLOCAL and !HUPCL, so that the port 622 * is always active. 623 */ 624 if (ISSET(sc->sc_swflags, TIOCFLAG_SOFTCAR) || 625 ISSET(sc->sc_hwflags, SCI_HW_CONSOLE)) { 626 SET(t->c_cflag, CLOCAL); 627 CLR(t->c_cflag, HUPCL); 628 } 629 630 /* 631 * If there were no changes, don't do anything. This avoids dropping 632 * input and improves performance when all we did was frob things like 633 * VMIN and VTIME. 634 */ 635 if (tp->t_ospeed == t->c_ospeed && 636 tp->t_cflag == t->c_cflag) 637 return (0); 638 639 #if 0 640 /* XXX (msaitoh) */ 641 lcr = ISSET(sc->sc_lcr, LCR_SBREAK) | cflag2lcr(t->c_cflag); 642 #endif 643 644 s = splserial(); 645 646 /* 647 * Set the FIFO threshold based on the receive speed. 648 * 649 * * If it's a low speed, it's probably a mouse or some other 650 * interactive device, so set the threshold low. 651 * * If it's a high speed, trim the trigger level down to prevent 652 * overflows. 653 * * Otherwise set it a bit higher. 654 */ 655 #if 0 656 /* XXX (msaitoh) */ 657 if (ISSET(sc->sc_hwflags, SCI_HW_HAYESP)) 658 sc->sc_fifo = FIFO_DMA_MODE | FIFO_ENABLE | FIFO_TRIGGER_8; 659 else if (ISSET(sc->sc_hwflags, SCI_HW_FIFO)) 660 sc->sc_fifo = FIFO_ENABLE | 661 (t->c_ospeed <= 1200 ? FIFO_TRIGGER_1 : 662 t->c_ospeed <= 38400 ? FIFO_TRIGGER_8 : FIFO_TRIGGER_4); 663 else 664 sc->sc_fifo = 0; 665 #endif 666 667 /* And copy to tty. */ 668 tp->t_ispeed = 0; 669 tp->t_ospeed = t->c_ospeed; 670 tp->t_cflag = t->c_cflag; 671 672 if (!sc->sc_heldchange) { 673 if (sc->sc_tx_busy) { 674 sc->sc_heldtbc = sc->sc_tbc; 675 sc->sc_tbc = 0; 676 sc->sc_heldchange = 1; 677 } 678 #if 0 679 /* XXX (msaitoh) */ 680 else 681 sci_loadchannelregs(sc); 682 #endif 683 } 684 685 if (!ISSET(t->c_cflag, CHWFLOW)) { 686 /* Disable the high water mark. */ 687 sc->sc_r_hiwat = 0; 688 sc->sc_r_lowat = 0; 689 if (ISSET(sc->sc_rx_flags, RX_TTY_OVERFLOWED)) { 690 CLR(sc->sc_rx_flags, RX_TTY_OVERFLOWED); 691 sci_schedrx(sc); 692 } 693 } else { 694 sc->sc_r_hiwat = sci_rbuf_hiwat; 695 sc->sc_r_lowat = sci_rbuf_lowat; 696 } 697 698 splx(s); 699 700 #ifdef SCI_DEBUG 701 if (sci_debug) 702 scistatus(sc, "sciparam "); 703 #endif 704 705 if (!ISSET(t->c_cflag, CHWFLOW)) { 706 if (sc->sc_tx_stopped) { 707 sc->sc_tx_stopped = 0; 708 scistart(tp); 709 } 710 } 711 712 return (0); 713 } 714 715 void 716 sci_iflush(sc) 717 struct sci_softc *sc; 718 { 719 unsigned char err_c; 720 volatile unsigned char c; 721 722 if (((err_c = SHREG_SCSSR) 723 & (SCSSR_RDRF | SCSSR_ORER | SCSSR_FER | SCSSR_PER)) != 0) { 724 725 if ((err_c & (SCSSR_ORER | SCSSR_FER | SCSSR_PER)) != 0) 726 return; 727 728 c = SHREG_SCRDR; 729 730 SHREG_SCSSR &= ~SCSSR_RDRF; 731 } 732 } 733 734 int sci_getc __P((void)); 735 void sci_putc __P((int)); 736 737 int 738 sci_getc() 739 { 740 741 return (GetcSci()); 742 } 743 744 void 745 sci_putc(int c) 746 { 747 748 PutcSci(c); 749 } 750 751 int 752 sciopen(dev, flag, mode, p) 753 dev_t dev; 754 int flag, mode; 755 struct proc *p; 756 { 757 int unit = SCIUNIT(dev); 758 struct sci_softc *sc; 759 struct tty *tp; 760 int s, s2; 761 int error; 762 763 if (unit >= sci_cd.cd_ndevs) 764 return (ENXIO); 765 sc = sci_cd.cd_devs[unit]; 766 if (sc == 0 || !ISSET(sc->sc_hwflags, SCI_HW_DEV_OK) || 767 sc->sc_rbuf == NULL) 768 return (ENXIO); 769 770 if (ISSET(sc->sc_dev.dv_flags, DVF_ACTIVE) == 0) 771 return (ENXIO); 772 773 #ifdef KGDB 774 /* 775 * If this is the kgdb port, no other use is permitted. 776 */ 777 if (ISSET(sc->sc_hwflags, SCI_HW_KGDB)) 778 return (EBUSY); 779 #endif 780 781 tp = sc->sc_tty; 782 783 if (ISSET(tp->t_state, TS_ISOPEN) && 784 ISSET(tp->t_state, TS_XCLUDE) && 785 p->p_ucred->cr_uid != 0) 786 return (EBUSY); 787 788 s = spltty(); 789 790 /* 791 * Do the following iff this is a first open. 792 */ 793 if (!ISSET(tp->t_state, TS_ISOPEN) && tp->t_wopen == 0) { 794 struct termios t; 795 796 tp->t_dev = dev; 797 798 s2 = splserial(); 799 800 /* Turn on interrupts. */ 801 SHREG_SCSCR |= SCSCR_TIE | SCSCR_RIE; 802 803 splx(s2); 804 805 /* 806 * Initialize the termios status to the defaults. Add in the 807 * sticky bits from TIOCSFLAGS. 808 */ 809 t.c_ispeed = 0; 810 if (ISSET(sc->sc_hwflags, SCI_HW_CONSOLE)) { 811 t.c_ospeed = scicn_speed; 812 t.c_cflag = sciconscflag; 813 } else { 814 t.c_ospeed = TTYDEF_SPEED; 815 t.c_cflag = TTYDEF_CFLAG; 816 } 817 if (ISSET(sc->sc_swflags, TIOCFLAG_CLOCAL)) 818 SET(t.c_cflag, CLOCAL); 819 if (ISSET(sc->sc_swflags, TIOCFLAG_CRTSCTS)) 820 SET(t.c_cflag, CRTSCTS); 821 if (ISSET(sc->sc_swflags, TIOCFLAG_MDMBUF)) 822 SET(t.c_cflag, MDMBUF); 823 /* Make sure sciparam() will do something. */ 824 tp->t_ospeed = 0; 825 (void) sciparam(tp, &t); 826 tp->t_iflag = TTYDEF_IFLAG; 827 tp->t_oflag = TTYDEF_OFLAG; 828 tp->t_lflag = TTYDEF_LFLAG; 829 ttychars(tp); 830 ttsetwater(tp); 831 832 s2 = splserial(); 833 834 /* Clear the input ring, and unblock. */ 835 sc->sc_rbput = sc->sc_rbget = sc->sc_rbuf; 836 sc->sc_rbavail = sci_rbuf_size; 837 sci_iflush(sc); 838 CLR(sc->sc_rx_flags, RX_ANY_BLOCK); 839 #if 0 840 /* XXX (msaitoh) */ 841 sci_hwiflow(sc); 842 #endif 843 844 #ifdef SCI_DEBUG 845 if (sci_debug) 846 scistatus(sc, "sciopen "); 847 #endif 848 849 splx(s2); 850 } 851 852 splx(s); 853 854 error = ttyopen(tp, SCIDIALOUT(dev), ISSET(flag, O_NONBLOCK)); 855 if (error) 856 goto bad; 857 858 error = (*linesw[tp->t_line].l_open)(dev, tp); 859 if (error) 860 goto bad; 861 862 return (0); 863 864 bad: 865 866 return (error); 867 } 868 869 int 870 sciclose(dev, flag, mode, p) 871 dev_t dev; 872 int flag, mode; 873 struct proc *p; 874 { 875 struct sci_softc *sc = sci_cd.cd_devs[SCIUNIT(dev)]; 876 struct tty *tp = sc->sc_tty; 877 878 /* XXX This is for cons.c. */ 879 if (!ISSET(tp->t_state, TS_ISOPEN)) 880 return (0); 881 882 (*linesw[tp->t_line].l_close)(tp, flag); 883 ttyclose(tp); 884 885 if (ISSET(sc->sc_dev.dv_flags, DVF_ACTIVE) == 0) 886 return (0); 887 888 return (0); 889 } 890 891 int 892 sciread(dev, uio, flag) 893 dev_t dev; 894 struct uio *uio; 895 int flag; 896 { 897 struct sci_softc *sc = sci_cd.cd_devs[SCIUNIT(dev)]; 898 struct tty *tp = sc->sc_tty; 899 900 return ((*linesw[tp->t_line].l_read)(tp, uio, flag)); 901 } 902 903 int 904 sciwrite(dev, uio, flag) 905 dev_t dev; 906 struct uio *uio; 907 int flag; 908 { 909 struct sci_softc *sc = sci_cd.cd_devs[SCIUNIT(dev)]; 910 struct tty *tp = sc->sc_tty; 911 912 return ((*linesw[tp->t_line].l_write)(tp, uio, flag)); 913 } 914 915 struct tty * 916 scitty(dev) 917 dev_t dev; 918 { 919 struct sci_softc *sc = sci_cd.cd_devs[SCIUNIT(dev)]; 920 struct tty *tp = sc->sc_tty; 921 922 return (tp); 923 } 924 925 int 926 sciioctl(dev, cmd, data, flag, p) 927 dev_t dev; 928 u_long cmd; 929 caddr_t data; 930 int flag; 931 struct proc *p; 932 { 933 struct sci_softc *sc = sci_cd.cd_devs[SCIUNIT(dev)]; 934 struct tty *tp = sc->sc_tty; 935 int error; 936 int s; 937 938 if (ISSET(sc->sc_dev.dv_flags, DVF_ACTIVE) == 0) 939 return (EIO); 940 941 error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag, p); 942 if (error >= 0) 943 return (error); 944 945 error = ttioctl(tp, cmd, data, flag, p); 946 if (error >= 0) 947 return (error); 948 949 error = 0; 950 951 s = splserial(); 952 953 switch (cmd) { 954 case TIOCSBRK: 955 sci_break(sc, 1); 956 break; 957 958 case TIOCCBRK: 959 sci_break(sc, 0); 960 break; 961 962 case TIOCGFLAGS: 963 *(int *)data = sc->sc_swflags; 964 break; 965 966 case TIOCSFLAGS: 967 error = suser(p->p_ucred, &p->p_acflag); 968 if (error) 969 break; 970 sc->sc_swflags = *(int *)data; 971 break; 972 973 default: 974 error = ENOTTY; 975 break; 976 } 977 978 splx(s); 979 980 return (error); 981 } 982 983 integrate void 984 sci_schedrx(sc) 985 struct sci_softc *sc; 986 { 987 988 sc->sc_rx_ready = 1; 989 990 /* Wake up the poller. */ 991 #ifdef __GENERIC_SOFT_INTERRUPTS 992 softintr_schedule(sc->sc_si); 993 #else 994 #ifndef __NO_SOFT_SERIAL_INTERRUPT 995 setsoftserial(); 996 #else 997 if (!sci_softintr_scheduled) { 998 sci_softintr_scheduled = 1; 999 callout_reset(&sci_soft_ch, 1, scisoft, NULL); 1000 } 1001 #endif 1002 #endif 1003 } 1004 1005 void 1006 sci_break(sc, onoff) 1007 struct sci_softc *sc; 1008 int onoff; 1009 { 1010 1011 if (onoff) 1012 SHREG_SCSSR &= ~SCSSR_TDRE; 1013 else 1014 SHREG_SCSSR |= SCSSR_TDRE; 1015 1016 #if 0 /* XXX */ 1017 if (!sc->sc_heldchange) { 1018 if (sc->sc_tx_busy) { 1019 sc->sc_heldtbc = sc->sc_tbc; 1020 sc->sc_tbc = 0; 1021 sc->sc_heldchange = 1; 1022 } else 1023 sci_loadchannelregs(sc); 1024 } 1025 #endif 1026 } 1027 1028 /* 1029 * Stop output, e.g., for ^S or output flush. 1030 */ 1031 void 1032 scistop(tp, flag) 1033 struct tty *tp; 1034 int flag; 1035 { 1036 struct sci_softc *sc = sci_cd.cd_devs[SCIUNIT(tp->t_dev)]; 1037 int s; 1038 1039 s = splserial(); 1040 if (ISSET(tp->t_state, TS_BUSY)) { 1041 /* Stop transmitting at the next chunk. */ 1042 sc->sc_tbc = 0; 1043 sc->sc_heldtbc = 0; 1044 if (!ISSET(tp->t_state, TS_TTSTOP)) 1045 SET(tp->t_state, TS_FLUSH); 1046 } 1047 splx(s); 1048 } 1049 1050 void 1051 scidiag(arg) 1052 void *arg; 1053 { 1054 struct sci_softc *sc = arg; 1055 int overflows, floods; 1056 int s; 1057 1058 s = splserial(); 1059 overflows = sc->sc_overflows; 1060 sc->sc_overflows = 0; 1061 floods = sc->sc_floods; 1062 sc->sc_floods = 0; 1063 sc->sc_errors = 0; 1064 splx(s); 1065 1066 log(LOG_WARNING, "%s: %d silo overflow%s, %d ibuf flood%s\n", 1067 sc->sc_dev.dv_xname, 1068 overflows, overflows == 1 ? "" : "s", 1069 floods, floods == 1 ? "" : "s"); 1070 } 1071 1072 integrate void 1073 sci_rxsoft(sc, tp) 1074 struct sci_softc *sc; 1075 struct tty *tp; 1076 { 1077 int (*rint) __P((int c, struct tty *tp)) = linesw[tp->t_line].l_rint; 1078 u_char *get, *end; 1079 u_int cc, scc; 1080 u_char ssr; 1081 int code; 1082 int s; 1083 1084 end = sc->sc_ebuf; 1085 get = sc->sc_rbget; 1086 scc = cc = sci_rbuf_size - sc->sc_rbavail; 1087 1088 if (cc == sci_rbuf_size) { 1089 sc->sc_floods++; 1090 if (sc->sc_errors++ == 0) 1091 callout_reset(&sc->sc_diag_ch, 60 * hz, scidiag, sc); 1092 } 1093 1094 while (cc) { 1095 code = get[0]; 1096 ssr = get[1]; 1097 if (ISSET(ssr, SCSSR_FER | SCSSR_PER)) { 1098 if (ISSET(ssr, SCSSR_FER)) 1099 SET(code, TTY_FE); 1100 if (ISSET(ssr, SCSSR_PER)) 1101 SET(code, TTY_PE); 1102 } 1103 if ((*rint)(code, tp) == -1) { 1104 /* 1105 * The line discipline's buffer is out of space. 1106 */ 1107 if (!ISSET(sc->sc_rx_flags, RX_TTY_BLOCKED)) { 1108 /* 1109 * We're either not using flow control, or the 1110 * line discipline didn't tell us to block for 1111 * some reason. Either way, we have no way to 1112 * know when there's more space available, so 1113 * just drop the rest of the data. 1114 */ 1115 get += cc << 1; 1116 if (get >= end) 1117 get -= sci_rbuf_size << 1; 1118 cc = 0; 1119 } else { 1120 /* 1121 * Don't schedule any more receive processing 1122 * until the line discipline tells us there's 1123 * space available (through scihwiflow()). 1124 * Leave the rest of the data in the input 1125 * buffer. 1126 */ 1127 SET(sc->sc_rx_flags, RX_TTY_OVERFLOWED); 1128 } 1129 break; 1130 } 1131 get += 2; 1132 if (get >= end) 1133 get = sc->sc_rbuf; 1134 cc--; 1135 } 1136 1137 if (cc != scc) { 1138 sc->sc_rbget = get; 1139 s = splserial(); 1140 cc = sc->sc_rbavail += scc - cc; 1141 /* Buffers should be ok again, release possible block. */ 1142 if (cc >= sc->sc_r_lowat) { 1143 if (ISSET(sc->sc_rx_flags, RX_IBUF_OVERFLOWED)) { 1144 CLR(sc->sc_rx_flags, RX_IBUF_OVERFLOWED); 1145 SHREG_SCSCR |= SCSCR_RIE; 1146 } 1147 #if 0 1148 if (ISSET(sc->sc_rx_flags, RX_IBUF_BLOCKED)) { 1149 CLR(sc->sc_rx_flags, RX_IBUF_BLOCKED); 1150 sci_hwiflow(sc); 1151 } 1152 #endif 1153 } 1154 splx(s); 1155 } 1156 } 1157 1158 integrate void 1159 sci_txsoft(sc, tp) 1160 struct sci_softc *sc; 1161 struct tty *tp; 1162 { 1163 1164 CLR(tp->t_state, TS_BUSY); 1165 if (ISSET(tp->t_state, TS_FLUSH)) 1166 CLR(tp->t_state, TS_FLUSH); 1167 else 1168 ndflush(&tp->t_outq, (int)(sc->sc_tba - tp->t_outq.c_cf)); 1169 (*linesw[tp->t_line].l_start)(tp); 1170 } 1171 1172 integrate void 1173 sci_stsoft(sc, tp) 1174 struct sci_softc *sc; 1175 struct tty *tp; 1176 { 1177 #if 0 1178 /* XXX (msaitoh) */ 1179 u_char msr, delta; 1180 int s; 1181 1182 s = splserial(); 1183 msr = sc->sc_msr; 1184 delta = sc->sc_msr_delta; 1185 sc->sc_msr_delta = 0; 1186 splx(s); 1187 1188 if (ISSET(delta, sc->sc_msr_dcd)) { 1189 /* 1190 * Inform the tty layer that carrier detect changed. 1191 */ 1192 (void) (*linesw[tp->t_line].l_modem)(tp, ISSET(msr, MSR_DCD)); 1193 } 1194 1195 if (ISSET(delta, sc->sc_msr_cts)) { 1196 /* Block or unblock output according to flow control. */ 1197 if (ISSET(msr, sc->sc_msr_cts)) { 1198 sc->sc_tx_stopped = 0; 1199 (*linesw[tp->t_line].l_start)(tp); 1200 } else { 1201 sc->sc_tx_stopped = 1; 1202 } 1203 } 1204 1205 #ifdef SCI_DEBUG 1206 if (sci_debug) 1207 scistatus(sc, "sci_stsoft"); 1208 #endif 1209 #endif 1210 } 1211 1212 #ifdef __GENERIC_SOFT_INTERRUPTS 1213 void 1214 scisoft(arg) 1215 void *arg; 1216 { 1217 struct sci_softc *sc = arg; 1218 struct tty *tp; 1219 1220 if (ISSET(sc->sc_dev.dv_flags, DVF_ACTIVE) == 0) 1221 return; 1222 1223 { 1224 #else 1225 void 1226 #ifndef __NO_SOFT_SERIAL_INTERRUPT 1227 scisoft() 1228 #else 1229 scisoft(arg) 1230 void *arg; 1231 #endif 1232 { 1233 struct sci_softc *sc; 1234 struct tty *tp; 1235 int unit; 1236 #ifdef __NO_SOFT_SERIAL_INTERRUPT 1237 int s; 1238 1239 s = splsoftserial(); 1240 sci_softintr_scheduled = 0; 1241 #endif 1242 1243 for (unit = 0; unit < sci_cd.cd_ndevs; unit++) { 1244 sc = sci_cd.cd_devs[unit]; 1245 if (sc == NULL || !ISSET(sc->sc_hwflags, SCI_HW_DEV_OK)) 1246 continue; 1247 1248 if (ISSET(sc->sc_dev.dv_flags, DVF_ACTIVE) == 0) 1249 continue; 1250 1251 tp = sc->sc_tty; 1252 if (tp == NULL) 1253 continue; 1254 if (!ISSET(tp->t_state, TS_ISOPEN) && tp->t_wopen == 0) 1255 continue; 1256 #endif 1257 tp = sc->sc_tty; 1258 1259 if (sc->sc_rx_ready) { 1260 sc->sc_rx_ready = 0; 1261 sci_rxsoft(sc, tp); 1262 } 1263 1264 #if 0 1265 if (sc->sc_st_check) { 1266 sc->sc_st_check = 0; 1267 sci_stsoft(sc, tp); 1268 } 1269 #endif 1270 1271 if (sc->sc_tx_done) { 1272 sc->sc_tx_done = 0; 1273 sci_txsoft(sc, tp); 1274 } 1275 } 1276 1277 #ifndef __GENERIC_SOFT_INTERRUPTS 1278 #ifdef __NO_SOFT_SERIAL_INTERRUPT 1279 splx(s); 1280 #endif 1281 #endif 1282 } 1283 1284 int 1285 sciintr(arg) 1286 void *arg; 1287 { 1288 struct sci_softc *sc = arg; 1289 u_char *put, *end; 1290 u_int cc; 1291 u_short ssr; 1292 1293 if (ISSET(sc->sc_dev.dv_flags, DVF_ACTIVE) == 0) 1294 return (0); 1295 1296 end = sc->sc_ebuf; 1297 put = sc->sc_rbput; 1298 cc = sc->sc_rbavail; 1299 1300 ssr = SHREG_SCSSR; 1301 #if defined(DDB) || defined(KGDB) 1302 if (ISSET(ssr, SCSSR_BRK)) { 1303 #ifdef DDB 1304 if (ISSET(sc->sc_hwflags, SCI_HW_CONSOLE)) { 1305 console_debugger(); 1306 } 1307 #endif 1308 #ifdef KGDB 1309 if (ISSET(sc->sc_hwflags, SCI_HW_KGDB)) { 1310 kgdb_connect(1); 1311 } 1312 #endif 1313 } 1314 #endif /* DDB || KGDB */ 1315 if ((SHREG_SCSSR & SCSSR_RDRF) != 0) { 1316 if (cc > 0) { 1317 put[0] = SHREG_SCRDR; 1318 put[1] = SHREG_SCSSR & 0x00ff; 1319 1320 SHREG_SCSSR &= ~SCSSR_RDRF; 1321 1322 put += 2; 1323 if (put >= end) 1324 put = sc->sc_rbuf; 1325 cc--; 1326 } 1327 1328 /* 1329 * Current string of incoming characters ended because 1330 * no more data was available or we ran out of space. 1331 * Schedule a receive event if any data was received. 1332 * If we're out of space, turn off receive interrupts. 1333 */ 1334 sc->sc_rbput = put; 1335 sc->sc_rbavail = cc; 1336 if (!ISSET(sc->sc_rx_flags, RX_TTY_OVERFLOWED)) 1337 sc->sc_rx_ready = 1; 1338 1339 /* 1340 * See if we are in danger of overflowing a buffer. If 1341 * so, use hardware flow control to ease the pressure. 1342 */ 1343 if (!ISSET(sc->sc_rx_flags, RX_IBUF_BLOCKED) && 1344 cc < sc->sc_r_hiwat) { 1345 SET(sc->sc_rx_flags, RX_IBUF_BLOCKED); 1346 #if 0 1347 sci_hwiflow(sc); 1348 #endif 1349 } 1350 1351 /* 1352 * If we're out of space, disable receive interrupts 1353 * until the queue has drained a bit. 1354 */ 1355 if (!cc) { 1356 SHREG_SCSCR &= ~SCSCR_RIE; 1357 } 1358 } else { 1359 if (SHREG_SCSSR & SCSSR_RDRF) { 1360 SHREG_SCSCR &= ~(SCSCR_TIE | SCSCR_RIE); 1361 } 1362 } 1363 1364 #if 0 1365 msr = bus_space_read_1(iot, ioh, sci_msr); 1366 delta = msr ^ sc->sc_msr; 1367 sc->sc_msr = msr; 1368 if (ISSET(delta, sc->sc_msr_mask)) { 1369 SET(sc->sc_msr_delta, delta); 1370 1371 /* 1372 * Pulse-per-second clock signal on edge of DCD? 1373 */ 1374 if (ISSET(delta, sc->sc_ppsmask)) { 1375 struct timeval tv; 1376 if (ISSET(msr, sc->sc_ppsmask) == 1377 sc->sc_ppsassert) { 1378 /* XXX nanotime() */ 1379 microtime(&tv); 1380 TIMEVAL_TO_TIMESPEC(&tv, 1381 &sc->ppsinfo.assert_timestamp); 1382 if (sc->ppsparam.mode & PPS_OFFSETASSERT) { 1383 timespecadd(&sc->ppsinfo.assert_timestamp, 1384 &sc->ppsparam.assert_offset, 1385 &sc->ppsinfo.assert_timestamp); 1386 TIMESPEC_TO_TIMEVAL(&tv, &sc->ppsinfo.assert_timestamp); 1387 } 1388 1389 #ifdef PPS_SYNC 1390 if (sc->ppsparam.mode & PPS_HARDPPSONASSERT) 1391 hardpps(&tv, tv.tv_usec); 1392 #endif 1393 sc->ppsinfo.assert_sequence++; 1394 sc->ppsinfo.current_mode = 1395 sc->ppsparam.mode; 1396 1397 } else if (ISSET(msr, sc->sc_ppsmask) == 1398 sc->sc_ppsclear) { 1399 /* XXX nanotime() */ 1400 microtime(&tv); 1401 TIMEVAL_TO_TIMESPEC(&tv, 1402 &sc->ppsinfo.clear_timestamp); 1403 if (sc->ppsparam.mode & PPS_OFFSETCLEAR) { 1404 timespecadd(&sc->ppsinfo.clear_timestamp, 1405 &sc->ppsparam.clear_offset, 1406 &sc->ppsinfo.clear_timestamp); 1407 TIMESPEC_TO_TIMEVAL(&tv, &sc->ppsinfo.clear_timestamp); 1408 } 1409 1410 #ifdef PPS_SYNC 1411 if (sc->ppsparam.mode & PPS_HARDPPSONCLEAR) 1412 hardpps(&tv, tv.tv_usec); 1413 #endif 1414 sc->ppsinfo.clear_sequence++; 1415 sc->ppsinfo.current_mode = 1416 sc->ppsparam.mode; 1417 } 1418 } 1419 1420 /* 1421 * Stop output immediately if we lose the output 1422 * flow control signal or carrier detect. 1423 */ 1424 if (ISSET(~msr, sc->sc_msr_mask)) { 1425 sc->sc_tbc = 0; 1426 sc->sc_heldtbc = 0; 1427 #ifdef SCI_DEBUG 1428 if (sci_debug) 1429 scistatus(sc, "sciintr "); 1430 #endif 1431 } 1432 1433 sc->sc_st_check = 1; 1434 } 1435 #endif 1436 1437 /* 1438 * Done handling any receive interrupts. See if data can be 1439 * transmitted as well. Schedule tx done event if no data left 1440 * and tty was marked busy. 1441 */ 1442 if ((SHREG_SCSSR & SCSSR_TDRE) != 0) { 1443 /* 1444 * If we've delayed a parameter change, do it now, and restart 1445 * output. 1446 */ 1447 if (sc->sc_heldchange) { 1448 sc->sc_heldchange = 0; 1449 sc->sc_tbc = sc->sc_heldtbc; 1450 sc->sc_heldtbc = 0; 1451 } 1452 1453 /* Output the next chunk of the contiguous buffer, if any. */ 1454 if (sc->sc_tbc > 0) { 1455 PutcSci(*(sc->sc_tba)); 1456 sc->sc_tba++; 1457 sc->sc_tbc--; 1458 } else { 1459 /* Disable transmit completion interrupts if necessary. */ 1460 #if 0 1461 if (ISSET(sc->sc_ier, IER_ETXRDY)) 1462 #endif 1463 SHREG_SCSCR &= ~SCSCR_TIE; 1464 1465 if (sc->sc_tx_busy) { 1466 sc->sc_tx_busy = 0; 1467 sc->sc_tx_done = 1; 1468 } 1469 } 1470 } 1471 1472 /* Wake up the poller. */ 1473 #ifdef __GENERIC_SOFT_INTERRUPTS 1474 softintr_schedule(sc->sc_si); 1475 #else 1476 #ifndef __NO_SOFT_SERIAL_INTERRUPT 1477 setsoftserial(); 1478 #else 1479 if (!sci_softintr_scheduled) { 1480 sci_softintr_scheduled = 1; 1481 callout_reset(&sci_soft_ch, 1, scisoft, 1); 1482 } 1483 #endif 1484 #endif 1485 1486 #if NRND > 0 && defined(RND_SCI) 1487 rnd_add_uint32(&sc->rnd_source, iir | lsr); 1488 #endif 1489 1490 return (1); 1491 } 1492 1493 void 1494 scicnprobe(cp) 1495 struct consdev *cp; 1496 { 1497 int maj; 1498 1499 /* locate the major number */ 1500 for (maj = 0; maj < nchrdev; maj++) 1501 if (cdevsw[maj].d_open == sciopen) 1502 break; 1503 1504 /* Initialize required fields. */ 1505 cp->cn_dev = makedev(maj, 0); 1506 #ifdef SCICONSOLE 1507 cp->cn_pri = CN_REMOTE; 1508 #else 1509 cp->cn_pri = CN_NORMAL; 1510 #endif 1511 } 1512 1513 #define sci_gets GetStrSci 1514 #define sci_puts PutStrSci 1515 1516 void 1517 scicninit(cp) 1518 struct consdev *cp; 1519 { 1520 1521 InitializeSci(scicn_speed); 1522 sciisconsole = 1; 1523 } 1524 1525 #define sci_getc GetcSci 1526 #define sci_putc PutcSci 1527 1528 int 1529 scicngetc(dev) 1530 dev_t dev; 1531 { 1532 int c; 1533 int s; 1534 1535 s = splserial(); 1536 c = sci_getc(); 1537 splx(s); 1538 1539 return (c); 1540 } 1541 1542 void 1543 scicnputc(dev, c) 1544 dev_t dev; 1545 int c; 1546 { 1547 int s; 1548 1549 s = splserial(); 1550 sci_putc(c); 1551 splx(s); 1552 } 1553