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