1 /* $NetBSD: sci.c,v 1.9 2000/06/19 09:32:00 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 SHREG_SCSSR &= ~(SCSSR_ORER | SCSSR_FER | SCSSR_PER); 423 return(err_c |= 0x80); 424 } 425 426 c = SHREG_SCRDR; 427 428 SHREG_SCSSR &= ~SCSSR_RDRF; 429 430 return(c); 431 } 432 433 /* 434 * GetStrSci 435 * : unsigned char *s; 436 * : int size; 437 */ 438 int 439 GetStrSci(s, size) 440 unsigned char *s; 441 int size; 442 { 443 444 for(; size ; size--) { 445 *s = GetcSci(); 446 if (*s & 0x80) 447 return -1; 448 if (*s == CR) { 449 *s = 0; 450 break; 451 } 452 s++; 453 } 454 if (size == 0) 455 *s = 0; 456 return 0; 457 } 458 459 #if 0 460 #define SCI_MAX_UNITS 2 461 #else 462 #define SCI_MAX_UNITS 1 463 #endif 464 465 466 static int 467 sci_match(parent, cfp, aux) 468 struct device *parent; 469 struct cfdata *cfp; 470 void *aux; 471 { 472 struct shb_attach_args *sa = aux; 473 474 if (strcmp(cfp->cf_driver->cd_name, "sci") 475 || cfp->cf_unit >= SCI_MAX_UNITS) 476 return 0; 477 478 sa->ia_iosize = 0x10; 479 return 1; 480 } 481 482 static void 483 sci_attach(parent, self, aux) 484 struct device *parent, *self; 485 void *aux; 486 { 487 struct sci_softc *sc = (struct sci_softc *)self; 488 struct tty *tp; 489 int irq; 490 struct shb_attach_args *ia = aux; 491 492 sc->sc_hwflags = 0; /* XXX */ 493 sc->sc_swflags = 0; /* XXX */ 494 sc->sc_fifolen = 0; /* XXX */ 495 496 irq = ia->ia_irq; 497 498 if (sciisconsole) { 499 SET(sc->sc_hwflags, SCI_HW_CONSOLE); 500 SET(sc->sc_swflags, TIOCFLAG_SOFTCAR); 501 printf("\n%s: console\n", sc->sc_dev.dv_xname); 502 } else { 503 InitializeSci(9600); 504 printf("\n"); 505 } 506 507 callout_init(&sc->sc_diag_ch); 508 509 #if 0 510 if (irq != IRQUNK) { 511 sc->sc_ih = shb_intr_establish(irq, 512 IST_EDGE, IPL_SERIAL, sciintr, sc); 513 } 514 #else 515 if (irq != IRQUNK) { 516 sc->sc_ih = shb_intr_establish(SCI_IRQ, 517 IST_EDGE, IPL_SERIAL, sciintr, sc); 518 } 519 #endif 520 521 SET(sc->sc_hwflags, SCI_HW_DEV_OK); 522 523 tp = ttymalloc(); 524 tp->t_oproc = scistart; 525 tp->t_param = sciparam; 526 tp->t_hwiflow = NULL; 527 528 sc->sc_tty = tp; 529 sc->sc_rbuf = malloc(sci_rbuf_size << 1, M_DEVBUF, M_NOWAIT); 530 if (sc->sc_rbuf == NULL) { 531 printf("%s: unable to allocate ring buffer\n", 532 sc->sc_dev.dv_xname); 533 return; 534 } 535 sc->sc_ebuf = sc->sc_rbuf + (sci_rbuf_size << 1); 536 537 tty_attach(tp); 538 } 539 540 /* 541 * Start or restart transmission. 542 */ 543 static void 544 scistart(tp) 545 struct tty *tp; 546 { 547 struct sci_softc *sc = sci_cd.cd_devs[SCIUNIT(tp->t_dev)]; 548 int s; 549 550 s = spltty(); 551 if (ISSET(tp->t_state, TS_BUSY | TS_TIMEOUT | TS_TTSTOP)) 552 goto out; 553 if (sc->sc_tx_stopped) 554 goto out; 555 556 if (tp->t_outq.c_cc <= tp->t_lowat) { 557 if (ISSET(tp->t_state, TS_ASLEEP)) { 558 CLR(tp->t_state, TS_ASLEEP); 559 wakeup(&tp->t_outq); 560 } 561 selwakeup(&tp->t_wsel); 562 if (tp->t_outq.c_cc == 0) 563 goto out; 564 } 565 566 /* Grab the first contiguous region of buffer space. */ 567 { 568 u_char *tba; 569 int tbc; 570 571 tba = tp->t_outq.c_cf; 572 tbc = ndqb(&tp->t_outq, 0); 573 574 (void)splserial(); 575 576 sc->sc_tba = tba; 577 sc->sc_tbc = tbc; 578 } 579 580 SET(tp->t_state, TS_BUSY); 581 sc->sc_tx_busy = 1; 582 583 /* Enable transmit completion interrupts if necessary. */ 584 SHREG_SCSCR |= SCSCR_TIE | SCSCR_RIE; 585 586 /* Output the first byte of the contiguous buffer. */ 587 { 588 if (sc->sc_tbc > 0) { 589 PutcSci(*(sc->sc_tba)); 590 sc->sc_tba++; 591 sc->sc_tbc--; 592 } 593 } 594 out: 595 splx(s); 596 return; 597 } 598 599 /* 600 * Set SCI tty parameters from termios. 601 * XXX - Should just copy the whole termios after 602 * making sure all the changes could be done. 603 */ 604 static int 605 sciparam(tp, t) 606 struct tty *tp; 607 struct termios *t; 608 { 609 struct sci_softc *sc = sci_cd.cd_devs[SCIUNIT(tp->t_dev)]; 610 int ospeed = t->c_ospeed; 611 int s; 612 613 if (ISSET(sc->sc_dev.dv_flags, DVF_ACTIVE) == 0) 614 return (EIO); 615 616 /* Check requested parameters. */ 617 if (ospeed < 0) 618 return (EINVAL); 619 if (t->c_ispeed && t->c_ispeed != t->c_ospeed) 620 return (EINVAL); 621 622 /* 623 * For the console, always force CLOCAL and !HUPCL, so that the port 624 * is always active. 625 */ 626 if (ISSET(sc->sc_swflags, TIOCFLAG_SOFTCAR) || 627 ISSET(sc->sc_hwflags, SCI_HW_CONSOLE)) { 628 SET(t->c_cflag, CLOCAL); 629 CLR(t->c_cflag, HUPCL); 630 } 631 632 /* 633 * If there were no changes, don't do anything. This avoids dropping 634 * input and improves performance when all we did was frob things like 635 * VMIN and VTIME. 636 */ 637 if (tp->t_ospeed == t->c_ospeed && 638 tp->t_cflag == t->c_cflag) 639 return (0); 640 641 #if 0 642 /* XXX (msaitoh) */ 643 lcr = ISSET(sc->sc_lcr, LCR_SBREAK) | cflag2lcr(t->c_cflag); 644 #endif 645 646 s = splserial(); 647 648 /* 649 * Set the FIFO threshold based on the receive speed. 650 * 651 * * If it's a low speed, it's probably a mouse or some other 652 * interactive device, so set the threshold low. 653 * * If it's a high speed, trim the trigger level down to prevent 654 * overflows. 655 * * Otherwise set it a bit higher. 656 */ 657 #if 0 658 /* XXX (msaitoh) */ 659 if (ISSET(sc->sc_hwflags, SCI_HW_HAYESP)) 660 sc->sc_fifo = FIFO_DMA_MODE | FIFO_ENABLE | FIFO_TRIGGER_8; 661 else if (ISSET(sc->sc_hwflags, SCI_HW_FIFO)) 662 sc->sc_fifo = FIFO_ENABLE | 663 (t->c_ospeed <= 1200 ? FIFO_TRIGGER_1 : 664 t->c_ospeed <= 38400 ? FIFO_TRIGGER_8 : FIFO_TRIGGER_4); 665 else 666 sc->sc_fifo = 0; 667 #endif 668 669 /* And copy to tty. */ 670 tp->t_ispeed = 0; 671 tp->t_ospeed = t->c_ospeed; 672 tp->t_cflag = t->c_cflag; 673 674 if (!sc->sc_heldchange) { 675 if (sc->sc_tx_busy) { 676 sc->sc_heldtbc = sc->sc_tbc; 677 sc->sc_tbc = 0; 678 sc->sc_heldchange = 1; 679 } 680 #if 0 681 /* XXX (msaitoh) */ 682 else 683 sci_loadchannelregs(sc); 684 #endif 685 } 686 687 if (!ISSET(t->c_cflag, CHWFLOW)) { 688 /* Disable the high water mark. */ 689 sc->sc_r_hiwat = 0; 690 sc->sc_r_lowat = 0; 691 if (ISSET(sc->sc_rx_flags, RX_TTY_OVERFLOWED)) { 692 CLR(sc->sc_rx_flags, RX_TTY_OVERFLOWED); 693 sci_schedrx(sc); 694 } 695 } else { 696 sc->sc_r_hiwat = sci_rbuf_hiwat; 697 sc->sc_r_lowat = sci_rbuf_lowat; 698 } 699 700 splx(s); 701 702 #ifdef SCI_DEBUG 703 if (sci_debug) 704 scistatus(sc, "sciparam "); 705 #endif 706 707 if (!ISSET(t->c_cflag, CHWFLOW)) { 708 if (sc->sc_tx_stopped) { 709 sc->sc_tx_stopped = 0; 710 scistart(tp); 711 } 712 } 713 714 return (0); 715 } 716 717 void 718 sci_iflush(sc) 719 struct sci_softc *sc; 720 { 721 unsigned char err_c; 722 volatile unsigned char c; 723 724 if (((err_c = SHREG_SCSSR) 725 & (SCSSR_RDRF | SCSSR_ORER | SCSSR_FER | SCSSR_PER)) != 0) { 726 727 if ((err_c & (SCSSR_ORER | SCSSR_FER | SCSSR_PER)) != 0) { 728 SHREG_SCSSR &= ~(SCSSR_ORER | SCSSR_FER | SCSSR_PER); 729 return; 730 } 731 732 c = SHREG_SCRDR; 733 734 SHREG_SCSSR &= ~SCSSR_RDRF; 735 } 736 } 737 738 int sci_getc __P((void)); 739 void sci_putc __P((int)); 740 741 int 742 sci_getc() 743 { 744 745 return (GetcSci()); 746 } 747 748 void 749 sci_putc(int c) 750 { 751 752 PutcSci(c); 753 } 754 755 int 756 sciopen(dev, flag, mode, p) 757 dev_t dev; 758 int flag, mode; 759 struct proc *p; 760 { 761 int unit = SCIUNIT(dev); 762 struct sci_softc *sc; 763 struct tty *tp; 764 int s, s2; 765 int error; 766 767 if (unit >= sci_cd.cd_ndevs) 768 return (ENXIO); 769 sc = sci_cd.cd_devs[unit]; 770 if (sc == 0 || !ISSET(sc->sc_hwflags, SCI_HW_DEV_OK) || 771 sc->sc_rbuf == NULL) 772 return (ENXIO); 773 774 if (ISSET(sc->sc_dev.dv_flags, DVF_ACTIVE) == 0) 775 return (ENXIO); 776 777 #ifdef KGDB 778 /* 779 * If this is the kgdb port, no other use is permitted. 780 */ 781 if (ISSET(sc->sc_hwflags, SCI_HW_KGDB)) 782 return (EBUSY); 783 #endif 784 785 tp = sc->sc_tty; 786 787 if (ISSET(tp->t_state, TS_ISOPEN) && 788 ISSET(tp->t_state, TS_XCLUDE) && 789 p->p_ucred->cr_uid != 0) 790 return (EBUSY); 791 792 s = spltty(); 793 794 /* 795 * Do the following iff this is a first open. 796 */ 797 if (!ISSET(tp->t_state, TS_ISOPEN) && tp->t_wopen == 0) { 798 struct termios t; 799 800 tp->t_dev = dev; 801 802 s2 = splserial(); 803 804 /* Turn on interrupts. */ 805 SHREG_SCSCR |= SCSCR_TIE | SCSCR_RIE; 806 807 splx(s2); 808 809 /* 810 * Initialize the termios status to the defaults. Add in the 811 * sticky bits from TIOCSFLAGS. 812 */ 813 t.c_ispeed = 0; 814 if (ISSET(sc->sc_hwflags, SCI_HW_CONSOLE)) { 815 t.c_ospeed = scicn_speed; 816 t.c_cflag = sciconscflag; 817 } else { 818 t.c_ospeed = TTYDEF_SPEED; 819 t.c_cflag = TTYDEF_CFLAG; 820 } 821 if (ISSET(sc->sc_swflags, TIOCFLAG_CLOCAL)) 822 SET(t.c_cflag, CLOCAL); 823 if (ISSET(sc->sc_swflags, TIOCFLAG_CRTSCTS)) 824 SET(t.c_cflag, CRTSCTS); 825 if (ISSET(sc->sc_swflags, TIOCFLAG_MDMBUF)) 826 SET(t.c_cflag, MDMBUF); 827 /* Make sure sciparam() will do something. */ 828 tp->t_ospeed = 0; 829 (void) sciparam(tp, &t); 830 tp->t_iflag = TTYDEF_IFLAG; 831 tp->t_oflag = TTYDEF_OFLAG; 832 tp->t_lflag = TTYDEF_LFLAG; 833 ttychars(tp); 834 ttsetwater(tp); 835 836 s2 = splserial(); 837 838 /* Clear the input ring, and unblock. */ 839 sc->sc_rbput = sc->sc_rbget = sc->sc_rbuf; 840 sc->sc_rbavail = sci_rbuf_size; 841 sci_iflush(sc); 842 CLR(sc->sc_rx_flags, RX_ANY_BLOCK); 843 #if 0 844 /* XXX (msaitoh) */ 845 sci_hwiflow(sc); 846 #endif 847 848 #ifdef SCI_DEBUG 849 if (sci_debug) 850 scistatus(sc, "sciopen "); 851 #endif 852 853 splx(s2); 854 } 855 856 splx(s); 857 858 error = ttyopen(tp, SCIDIALOUT(dev), ISSET(flag, O_NONBLOCK)); 859 if (error) 860 goto bad; 861 862 error = (*linesw[tp->t_line].l_open)(dev, tp); 863 if (error) 864 goto bad; 865 866 return (0); 867 868 bad: 869 870 return (error); 871 } 872 873 int 874 sciclose(dev, flag, mode, p) 875 dev_t dev; 876 int flag, mode; 877 struct proc *p; 878 { 879 struct sci_softc *sc = sci_cd.cd_devs[SCIUNIT(dev)]; 880 struct tty *tp = sc->sc_tty; 881 882 /* XXX This is for cons.c. */ 883 if (!ISSET(tp->t_state, TS_ISOPEN)) 884 return (0); 885 886 (*linesw[tp->t_line].l_close)(tp, flag); 887 ttyclose(tp); 888 889 if (ISSET(sc->sc_dev.dv_flags, DVF_ACTIVE) == 0) 890 return (0); 891 892 return (0); 893 } 894 895 int 896 sciread(dev, uio, flag) 897 dev_t dev; 898 struct uio *uio; 899 int flag; 900 { 901 struct sci_softc *sc = sci_cd.cd_devs[SCIUNIT(dev)]; 902 struct tty *tp = sc->sc_tty; 903 904 return ((*linesw[tp->t_line].l_read)(tp, uio, flag)); 905 } 906 907 int 908 sciwrite(dev, uio, flag) 909 dev_t dev; 910 struct uio *uio; 911 int flag; 912 { 913 struct sci_softc *sc = sci_cd.cd_devs[SCIUNIT(dev)]; 914 struct tty *tp = sc->sc_tty; 915 916 return ((*linesw[tp->t_line].l_write)(tp, uio, flag)); 917 } 918 919 struct tty * 920 scitty(dev) 921 dev_t dev; 922 { 923 struct sci_softc *sc = sci_cd.cd_devs[SCIUNIT(dev)]; 924 struct tty *tp = sc->sc_tty; 925 926 return (tp); 927 } 928 929 int 930 sciioctl(dev, cmd, data, flag, p) 931 dev_t dev; 932 u_long cmd; 933 caddr_t data; 934 int flag; 935 struct proc *p; 936 { 937 struct sci_softc *sc = sci_cd.cd_devs[SCIUNIT(dev)]; 938 struct tty *tp = sc->sc_tty; 939 int error; 940 int s; 941 942 if (ISSET(sc->sc_dev.dv_flags, DVF_ACTIVE) == 0) 943 return (EIO); 944 945 error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag, p); 946 if (error >= 0) 947 return (error); 948 949 error = ttioctl(tp, cmd, data, flag, p); 950 if (error >= 0) 951 return (error); 952 953 error = 0; 954 955 s = splserial(); 956 957 switch (cmd) { 958 case TIOCSBRK: 959 sci_break(sc, 1); 960 break; 961 962 case TIOCCBRK: 963 sci_break(sc, 0); 964 break; 965 966 case TIOCGFLAGS: 967 *(int *)data = sc->sc_swflags; 968 break; 969 970 case TIOCSFLAGS: 971 error = suser(p->p_ucred, &p->p_acflag); 972 if (error) 973 break; 974 sc->sc_swflags = *(int *)data; 975 break; 976 977 default: 978 error = ENOTTY; 979 break; 980 } 981 982 splx(s); 983 984 return (error); 985 } 986 987 integrate void 988 sci_schedrx(sc) 989 struct sci_softc *sc; 990 { 991 992 sc->sc_rx_ready = 1; 993 994 /* Wake up the poller. */ 995 #ifdef __GENERIC_SOFT_INTERRUPTS 996 softintr_schedule(sc->sc_si); 997 #else 998 #ifndef __NO_SOFT_SERIAL_INTERRUPT 999 setsoftserial(); 1000 #else 1001 if (!sci_softintr_scheduled) { 1002 sci_softintr_scheduled = 1; 1003 callout_reset(&sci_soft_ch, 1, scisoft, NULL); 1004 } 1005 #endif 1006 #endif 1007 } 1008 1009 void 1010 sci_break(sc, onoff) 1011 struct sci_softc *sc; 1012 int onoff; 1013 { 1014 1015 if (onoff) 1016 SHREG_SCSSR &= ~SCSSR_TDRE; 1017 else 1018 SHREG_SCSSR |= SCSSR_TDRE; 1019 1020 #if 0 /* XXX */ 1021 if (!sc->sc_heldchange) { 1022 if (sc->sc_tx_busy) { 1023 sc->sc_heldtbc = sc->sc_tbc; 1024 sc->sc_tbc = 0; 1025 sc->sc_heldchange = 1; 1026 } else 1027 sci_loadchannelregs(sc); 1028 } 1029 #endif 1030 } 1031 1032 /* 1033 * Stop output, e.g., for ^S or output flush. 1034 */ 1035 void 1036 scistop(tp, flag) 1037 struct tty *tp; 1038 int flag; 1039 { 1040 struct sci_softc *sc = sci_cd.cd_devs[SCIUNIT(tp->t_dev)]; 1041 int s; 1042 1043 s = splserial(); 1044 if (ISSET(tp->t_state, TS_BUSY)) { 1045 /* Stop transmitting at the next chunk. */ 1046 sc->sc_tbc = 0; 1047 sc->sc_heldtbc = 0; 1048 if (!ISSET(tp->t_state, TS_TTSTOP)) 1049 SET(tp->t_state, TS_FLUSH); 1050 } 1051 splx(s); 1052 } 1053 1054 void 1055 scidiag(arg) 1056 void *arg; 1057 { 1058 struct sci_softc *sc = arg; 1059 int overflows, floods; 1060 int s; 1061 1062 s = splserial(); 1063 overflows = sc->sc_overflows; 1064 sc->sc_overflows = 0; 1065 floods = sc->sc_floods; 1066 sc->sc_floods = 0; 1067 sc->sc_errors = 0; 1068 splx(s); 1069 1070 log(LOG_WARNING, "%s: %d silo overflow%s, %d ibuf flood%s\n", 1071 sc->sc_dev.dv_xname, 1072 overflows, overflows == 1 ? "" : "s", 1073 floods, floods == 1 ? "" : "s"); 1074 } 1075 1076 integrate void 1077 sci_rxsoft(sc, tp) 1078 struct sci_softc *sc; 1079 struct tty *tp; 1080 { 1081 int (*rint) __P((int c, struct tty *tp)) = linesw[tp->t_line].l_rint; 1082 u_char *get, *end; 1083 u_int cc, scc; 1084 u_char ssr; 1085 int code; 1086 int s; 1087 1088 end = sc->sc_ebuf; 1089 get = sc->sc_rbget; 1090 scc = cc = sci_rbuf_size - sc->sc_rbavail; 1091 1092 if (cc == sci_rbuf_size) { 1093 sc->sc_floods++; 1094 if (sc->sc_errors++ == 0) 1095 callout_reset(&sc->sc_diag_ch, 60 * hz, scidiag, sc); 1096 } 1097 1098 while (cc) { 1099 code = get[0]; 1100 ssr = get[1]; 1101 if (ISSET(ssr, SCSSR_FER | SCSSR_PER)) { 1102 if (ISSET(ssr, SCSSR_FER)) 1103 SET(code, TTY_FE); 1104 if (ISSET(ssr, SCSSR_PER)) 1105 SET(code, TTY_PE); 1106 } 1107 if ((*rint)(code, tp) == -1) { 1108 /* 1109 * The line discipline's buffer is out of space. 1110 */ 1111 if (!ISSET(sc->sc_rx_flags, RX_TTY_BLOCKED)) { 1112 /* 1113 * We're either not using flow control, or the 1114 * line discipline didn't tell us to block for 1115 * some reason. Either way, we have no way to 1116 * know when there's more space available, so 1117 * just drop the rest of the data. 1118 */ 1119 get += cc << 1; 1120 if (get >= end) 1121 get -= sci_rbuf_size << 1; 1122 cc = 0; 1123 } else { 1124 /* 1125 * Don't schedule any more receive processing 1126 * until the line discipline tells us there's 1127 * space available (through scihwiflow()). 1128 * Leave the rest of the data in the input 1129 * buffer. 1130 */ 1131 SET(sc->sc_rx_flags, RX_TTY_OVERFLOWED); 1132 } 1133 break; 1134 } 1135 get += 2; 1136 if (get >= end) 1137 get = sc->sc_rbuf; 1138 cc--; 1139 } 1140 1141 if (cc != scc) { 1142 sc->sc_rbget = get; 1143 s = splserial(); 1144 cc = sc->sc_rbavail += scc - cc; 1145 /* Buffers should be ok again, release possible block. */ 1146 if (cc >= sc->sc_r_lowat) { 1147 if (ISSET(sc->sc_rx_flags, RX_IBUF_OVERFLOWED)) { 1148 CLR(sc->sc_rx_flags, RX_IBUF_OVERFLOWED); 1149 SHREG_SCSCR |= SCSCR_RIE; 1150 } 1151 #if 0 1152 if (ISSET(sc->sc_rx_flags, RX_IBUF_BLOCKED)) { 1153 CLR(sc->sc_rx_flags, RX_IBUF_BLOCKED); 1154 sci_hwiflow(sc); 1155 } 1156 #endif 1157 } 1158 splx(s); 1159 } 1160 } 1161 1162 integrate void 1163 sci_txsoft(sc, tp) 1164 struct sci_softc *sc; 1165 struct tty *tp; 1166 { 1167 1168 CLR(tp->t_state, TS_BUSY); 1169 if (ISSET(tp->t_state, TS_FLUSH)) 1170 CLR(tp->t_state, TS_FLUSH); 1171 else 1172 ndflush(&tp->t_outq, (int)(sc->sc_tba - tp->t_outq.c_cf)); 1173 (*linesw[tp->t_line].l_start)(tp); 1174 } 1175 1176 integrate void 1177 sci_stsoft(sc, tp) 1178 struct sci_softc *sc; 1179 struct tty *tp; 1180 { 1181 #if 0 1182 /* XXX (msaitoh) */ 1183 u_char msr, delta; 1184 int s; 1185 1186 s = splserial(); 1187 msr = sc->sc_msr; 1188 delta = sc->sc_msr_delta; 1189 sc->sc_msr_delta = 0; 1190 splx(s); 1191 1192 if (ISSET(delta, sc->sc_msr_dcd)) { 1193 /* 1194 * Inform the tty layer that carrier detect changed. 1195 */ 1196 (void) (*linesw[tp->t_line].l_modem)(tp, ISSET(msr, MSR_DCD)); 1197 } 1198 1199 if (ISSET(delta, sc->sc_msr_cts)) { 1200 /* Block or unblock output according to flow control. */ 1201 if (ISSET(msr, sc->sc_msr_cts)) { 1202 sc->sc_tx_stopped = 0; 1203 (*linesw[tp->t_line].l_start)(tp); 1204 } else { 1205 sc->sc_tx_stopped = 1; 1206 } 1207 } 1208 1209 #ifdef SCI_DEBUG 1210 if (sci_debug) 1211 scistatus(sc, "sci_stsoft"); 1212 #endif 1213 #endif 1214 } 1215 1216 #ifdef __GENERIC_SOFT_INTERRUPTS 1217 void 1218 scisoft(arg) 1219 void *arg; 1220 { 1221 struct sci_softc *sc = arg; 1222 struct tty *tp; 1223 1224 if (ISSET(sc->sc_dev.dv_flags, DVF_ACTIVE) == 0) 1225 return; 1226 1227 { 1228 #else 1229 void 1230 #ifndef __NO_SOFT_SERIAL_INTERRUPT 1231 scisoft() 1232 #else 1233 scisoft(arg) 1234 void *arg; 1235 #endif 1236 { 1237 struct sci_softc *sc; 1238 struct tty *tp; 1239 int unit; 1240 #ifdef __NO_SOFT_SERIAL_INTERRUPT 1241 int s; 1242 1243 s = splsoftserial(); 1244 sci_softintr_scheduled = 0; 1245 #endif 1246 1247 for (unit = 0; unit < sci_cd.cd_ndevs; unit++) { 1248 sc = sci_cd.cd_devs[unit]; 1249 if (sc == NULL || !ISSET(sc->sc_hwflags, SCI_HW_DEV_OK)) 1250 continue; 1251 1252 if (ISSET(sc->sc_dev.dv_flags, DVF_ACTIVE) == 0) 1253 continue; 1254 1255 tp = sc->sc_tty; 1256 if (tp == NULL) 1257 continue; 1258 if (!ISSET(tp->t_state, TS_ISOPEN) && tp->t_wopen == 0) 1259 continue; 1260 #endif 1261 tp = sc->sc_tty; 1262 1263 if (sc->sc_rx_ready) { 1264 sc->sc_rx_ready = 0; 1265 sci_rxsoft(sc, tp); 1266 } 1267 1268 #if 0 1269 if (sc->sc_st_check) { 1270 sc->sc_st_check = 0; 1271 sci_stsoft(sc, tp); 1272 } 1273 #endif 1274 1275 if (sc->sc_tx_done) { 1276 sc->sc_tx_done = 0; 1277 sci_txsoft(sc, tp); 1278 } 1279 } 1280 1281 #ifndef __GENERIC_SOFT_INTERRUPTS 1282 #ifdef __NO_SOFT_SERIAL_INTERRUPT 1283 splx(s); 1284 #endif 1285 #endif 1286 } 1287 1288 int 1289 sciintr(arg) 1290 void *arg; 1291 { 1292 struct sci_softc *sc = arg; 1293 u_char *put, *end; 1294 u_int cc; 1295 u_short ssr; 1296 1297 if (ISSET(sc->sc_dev.dv_flags, DVF_ACTIVE) == 0) 1298 return (0); 1299 1300 end = sc->sc_ebuf; 1301 put = sc->sc_rbput; 1302 cc = sc->sc_rbavail; 1303 1304 ssr = SHREG_SCSSR; 1305 #if defined(DDB) || defined(KGDB) 1306 if (ISSET(ssr, SCSSR_BRK)) { 1307 #ifdef DDB 1308 if (ISSET(sc->sc_hwflags, SCI_HW_CONSOLE)) { 1309 console_debugger(); 1310 } 1311 #endif 1312 #ifdef KGDB 1313 if (ISSET(sc->sc_hwflags, SCI_HW_KGDB)) { 1314 kgdb_connect(1); 1315 } 1316 #endif 1317 } 1318 #endif /* DDB || KGDB */ 1319 if ((SHREG_SCSSR & SCSSR_RDRF) != 0) { 1320 if (cc > 0) { 1321 put[0] = SHREG_SCRDR; 1322 put[1] = SHREG_SCSSR & 0x00ff; 1323 1324 SHREG_SCSSR &= ~(SCSSR_ORER | SCSSR_FER | SCSSR_PER | 1325 SCSSR_RDRF); 1326 1327 put += 2; 1328 if (put >= end) 1329 put = sc->sc_rbuf; 1330 cc--; 1331 } 1332 1333 /* 1334 * Current string of incoming characters ended because 1335 * no more data was available or we ran out of space. 1336 * Schedule a receive event if any data was received. 1337 * If we're out of space, turn off receive interrupts. 1338 */ 1339 sc->sc_rbput = put; 1340 sc->sc_rbavail = cc; 1341 if (!ISSET(sc->sc_rx_flags, RX_TTY_OVERFLOWED)) 1342 sc->sc_rx_ready = 1; 1343 1344 /* 1345 * See if we are in danger of overflowing a buffer. If 1346 * so, use hardware flow control to ease the pressure. 1347 */ 1348 if (!ISSET(sc->sc_rx_flags, RX_IBUF_BLOCKED) && 1349 cc < sc->sc_r_hiwat) { 1350 SET(sc->sc_rx_flags, RX_IBUF_BLOCKED); 1351 #if 0 1352 sci_hwiflow(sc); 1353 #endif 1354 } 1355 1356 /* 1357 * If we're out of space, disable receive interrupts 1358 * until the queue has drained a bit. 1359 */ 1360 if (!cc) { 1361 SHREG_SCSCR &= ~SCSCR_RIE; 1362 } 1363 } else { 1364 if (SHREG_SCSSR & SCSSR_RDRF) { 1365 SHREG_SCSCR &= ~(SCSCR_TIE | SCSCR_RIE); 1366 } 1367 } 1368 1369 #if 0 1370 msr = bus_space_read_1(iot, ioh, sci_msr); 1371 delta = msr ^ sc->sc_msr; 1372 sc->sc_msr = msr; 1373 if (ISSET(delta, sc->sc_msr_mask)) { 1374 SET(sc->sc_msr_delta, delta); 1375 1376 /* 1377 * Pulse-per-second clock signal on edge of DCD? 1378 */ 1379 if (ISSET(delta, sc->sc_ppsmask)) { 1380 struct timeval tv; 1381 if (ISSET(msr, sc->sc_ppsmask) == 1382 sc->sc_ppsassert) { 1383 /* XXX nanotime() */ 1384 microtime(&tv); 1385 TIMEVAL_TO_TIMESPEC(&tv, 1386 &sc->ppsinfo.assert_timestamp); 1387 if (sc->ppsparam.mode & PPS_OFFSETASSERT) { 1388 timespecadd(&sc->ppsinfo.assert_timestamp, 1389 &sc->ppsparam.assert_offset, 1390 &sc->ppsinfo.assert_timestamp); 1391 TIMESPEC_TO_TIMEVAL(&tv, &sc->ppsinfo.assert_timestamp); 1392 } 1393 1394 #ifdef PPS_SYNC 1395 if (sc->ppsparam.mode & PPS_HARDPPSONASSERT) 1396 hardpps(&tv, tv.tv_usec); 1397 #endif 1398 sc->ppsinfo.assert_sequence++; 1399 sc->ppsinfo.current_mode = 1400 sc->ppsparam.mode; 1401 1402 } else if (ISSET(msr, sc->sc_ppsmask) == 1403 sc->sc_ppsclear) { 1404 /* XXX nanotime() */ 1405 microtime(&tv); 1406 TIMEVAL_TO_TIMESPEC(&tv, 1407 &sc->ppsinfo.clear_timestamp); 1408 if (sc->ppsparam.mode & PPS_OFFSETCLEAR) { 1409 timespecadd(&sc->ppsinfo.clear_timestamp, 1410 &sc->ppsparam.clear_offset, 1411 &sc->ppsinfo.clear_timestamp); 1412 TIMESPEC_TO_TIMEVAL(&tv, &sc->ppsinfo.clear_timestamp); 1413 } 1414 1415 #ifdef PPS_SYNC 1416 if (sc->ppsparam.mode & PPS_HARDPPSONCLEAR) 1417 hardpps(&tv, tv.tv_usec); 1418 #endif 1419 sc->ppsinfo.clear_sequence++; 1420 sc->ppsinfo.current_mode = 1421 sc->ppsparam.mode; 1422 } 1423 } 1424 1425 /* 1426 * Stop output immediately if we lose the output 1427 * flow control signal or carrier detect. 1428 */ 1429 if (ISSET(~msr, sc->sc_msr_mask)) { 1430 sc->sc_tbc = 0; 1431 sc->sc_heldtbc = 0; 1432 #ifdef SCI_DEBUG 1433 if (sci_debug) 1434 scistatus(sc, "sciintr "); 1435 #endif 1436 } 1437 1438 sc->sc_st_check = 1; 1439 } 1440 #endif 1441 1442 /* 1443 * Done handling any receive interrupts. See if data can be 1444 * transmitted as well. Schedule tx done event if no data left 1445 * and tty was marked busy. 1446 */ 1447 if ((SHREG_SCSSR & SCSSR_TDRE) != 0) { 1448 /* 1449 * If we've delayed a parameter change, do it now, and restart 1450 * output. 1451 */ 1452 if (sc->sc_heldchange) { 1453 sc->sc_heldchange = 0; 1454 sc->sc_tbc = sc->sc_heldtbc; 1455 sc->sc_heldtbc = 0; 1456 } 1457 1458 /* Output the next chunk of the contiguous buffer, if any. */ 1459 if (sc->sc_tbc > 0) { 1460 PutcSci(*(sc->sc_tba)); 1461 sc->sc_tba++; 1462 sc->sc_tbc--; 1463 } else { 1464 /* Disable transmit completion interrupts if necessary. */ 1465 #if 0 1466 if (ISSET(sc->sc_ier, IER_ETXRDY)) 1467 #endif 1468 SHREG_SCSCR &= ~SCSCR_TIE; 1469 1470 if (sc->sc_tx_busy) { 1471 sc->sc_tx_busy = 0; 1472 sc->sc_tx_done = 1; 1473 } 1474 } 1475 } 1476 1477 /* Wake up the poller. */ 1478 #ifdef __GENERIC_SOFT_INTERRUPTS 1479 softintr_schedule(sc->sc_si); 1480 #else 1481 #ifndef __NO_SOFT_SERIAL_INTERRUPT 1482 setsoftserial(); 1483 #else 1484 if (!sci_softintr_scheduled) { 1485 sci_softintr_scheduled = 1; 1486 callout_reset(&sci_soft_ch, 1, scisoft, 1); 1487 } 1488 #endif 1489 #endif 1490 1491 #if NRND > 0 && defined(RND_SCI) 1492 rnd_add_uint32(&sc->rnd_source, iir | lsr); 1493 #endif 1494 1495 return (1); 1496 } 1497 1498 void 1499 scicnprobe(cp) 1500 struct consdev *cp; 1501 { 1502 int maj; 1503 1504 /* locate the major number */ 1505 for (maj = 0; maj < nchrdev; maj++) 1506 if (cdevsw[maj].d_open == sciopen) 1507 break; 1508 1509 /* Initialize required fields. */ 1510 cp->cn_dev = makedev(maj, 0); 1511 #ifdef SCICONSOLE 1512 cp->cn_pri = CN_REMOTE; 1513 #else 1514 cp->cn_pri = CN_NORMAL; 1515 #endif 1516 } 1517 1518 #define sci_gets GetStrSci 1519 #define sci_puts PutStrSci 1520 1521 void 1522 scicninit(cp) 1523 struct consdev *cp; 1524 { 1525 1526 InitializeSci(scicn_speed); 1527 sciisconsole = 1; 1528 } 1529 1530 #define sci_getc GetcSci 1531 #define sci_putc PutcSci 1532 1533 int 1534 scicngetc(dev) 1535 dev_t dev; 1536 { 1537 int c; 1538 int s; 1539 1540 s = splserial(); 1541 c = sci_getc(); 1542 splx(s); 1543 1544 return (c); 1545 } 1546 1547 void 1548 scicnputc(dev, c) 1549 dev_t dev; 1550 int c; 1551 { 1552 int s; 1553 1554 s = splserial(); 1555 sci_putc(c); 1556 splx(s); 1557 } 1558