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