1 /* $NetBSD: scif.c,v 1.35 2003/08/07 16:29:28 agc 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. Neither the name of the University nor the names of its contributors 78 * may be used to endorse or promote products derived from this software 79 * without specific prior written permission. 80 * 81 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 82 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 83 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 84 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 85 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 86 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 87 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 88 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 89 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 90 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 91 * SUCH DAMAGE. 92 * 93 * @(#)com.c 7.5 (Berkeley) 5/16/91 94 */ 95 96 /* 97 * SH internal serial driver 98 * 99 * This code is derived from both z8530tty.c and com.c 100 */ 101 102 #include <sys/cdefs.h> 103 __KERNEL_RCSID(0, "$NetBSD: scif.c,v 1.35 2003/08/07 16:29:28 agc Exp $"); 104 105 #include "opt_kgdb.h" 106 #include "opt_scif.h" 107 108 #include <sys/param.h> 109 #include <sys/systm.h> 110 #include <sys/tty.h> 111 #include <sys/proc.h> 112 #include <sys/conf.h> 113 #include <sys/file.h> 114 #include <sys/syslog.h> 115 #include <sys/kernel.h> 116 #include <sys/device.h> 117 #include <sys/malloc.h> 118 #include <sys/kgdb.h> 119 120 #include <dev/cons.h> 121 122 #include <sh3/clock.h> 123 #include <sh3/exception.h> 124 #include <sh3/scifreg.h> 125 #include <machine/intr.h> 126 127 #include <sh3/dev/scifvar.h> 128 129 #include "locators.h" 130 131 static void scifstart(struct tty *); 132 static int scifparam(struct tty *, struct termios *); 133 static int kgdb_attached; 134 135 void scifcnprobe(struct consdev *); 136 void scifcninit(struct consdev *); 137 void scifcnputc(dev_t, int); 138 int scifcngetc(dev_t); 139 void scifcnpoolc(dev_t, int); 140 void scif_intr_init(void); 141 int scifintr(void *); 142 143 struct scif_softc { 144 struct device sc_dev; /* boilerplate */ 145 struct tty *sc_tty; 146 void *sc_si; 147 148 struct callout sc_diag_ch; 149 150 #if 0 151 bus_space_tag_t sc_iot; /* ISA i/o space identifier */ 152 bus_space_handle_t sc_ioh; /* ISA io handle */ 153 154 int sc_drq; 155 156 int sc_frequency; 157 #endif 158 159 u_int sc_overflows, 160 sc_floods, 161 sc_errors; /* number of retries so far */ 162 u_char sc_status[7]; /* copy of registers */ 163 164 int sc_hwflags; 165 int sc_swflags; 166 u_int sc_fifolen; 167 168 u_int sc_r_hiwat, 169 sc_r_lowat; 170 u_char *volatile sc_rbget, 171 *volatile sc_rbput; 172 volatile u_int sc_rbavail; 173 u_char *sc_rbuf, 174 *sc_ebuf; 175 176 u_char *sc_tba; /* transmit buffer address */ 177 u_int sc_tbc, /* transmit byte count */ 178 sc_heldtbc; 179 180 volatile u_char sc_rx_flags, 181 #define RX_TTY_BLOCKED 0x01 182 #define RX_TTY_OVERFLOWED 0x02 183 #define RX_IBUF_BLOCKED 0x04 184 #define RX_IBUF_OVERFLOWED 0x08 185 #define RX_ANY_BLOCK 0x0f 186 sc_tx_busy, /* working on an output chunk */ 187 sc_tx_done, /* done with one output chunk */ 188 sc_tx_stopped, /* H/W level stop (lost CTS) */ 189 sc_st_check, /* got a status interrupt */ 190 sc_rx_ready; 191 192 volatile u_char sc_heldchange; 193 }; 194 195 /* controller driver configuration */ 196 static int scif_match(struct device *, struct cfdata *, void *); 197 static void scif_attach(struct device *, struct device *, void *); 198 199 void scif_break(struct scif_softc *, int); 200 void scif_iflush(struct scif_softc *); 201 202 #define integrate static inline 203 #ifdef __HAVE_GENERIC_SOFT_INTERRUPTS 204 void scifsoft(void *); 205 #else 206 #ifndef __NO_SOFT_SERIAL_INTERRUPT 207 void scifsoft(void); 208 #else 209 void scifsoft(void *); 210 #endif 211 #endif 212 integrate void scif_rxsoft(struct scif_softc *, struct tty *); 213 integrate void scif_txsoft(struct scif_softc *, struct tty *); 214 integrate void scif_stsoft(struct scif_softc *, struct tty *); 215 integrate void scif_schedrx(struct scif_softc *); 216 void scifdiag(void *); 217 218 219 #define SCIFUNIT_MASK 0x7ffff 220 #define SCIFDIALOUT_MASK 0x80000 221 222 #define SCIFUNIT(x) (minor(x) & SCIFUNIT_MASK) 223 #define SCIFDIALOUT(x) (minor(x) & SCIFDIALOUT_MASK) 224 225 /* Macros to clear/set/test flags. */ 226 #define SET(t, f) (t) |= (f) 227 #define CLR(t, f) (t) &= ~(f) 228 #define ISSET(t, f) ((t) & (f)) 229 230 /* Hardware flag masks */ 231 #define SCIF_HW_NOIEN 0x01 232 #define SCIF_HW_FIFO 0x02 233 #define SCIF_HW_FLOW 0x08 234 #define SCIF_HW_DEV_OK 0x20 235 #define SCIF_HW_CONSOLE 0x40 236 #define SCIF_HW_KGDB 0x80 237 238 /* Buffer size for character buffer */ 239 #define SCIF_RING_SIZE 2048 240 241 /* Stop input when 3/4 of the ring is full; restart when only 1/4 is full. */ 242 u_int scif_rbuf_hiwat = (SCIF_RING_SIZE * 1) / 4; 243 u_int scif_rbuf_lowat = (SCIF_RING_SIZE * 3) / 4; 244 245 #define CONMODE ((TTYDEF_CFLAG & ~(CSIZE | CSTOPB | PARENB)) | CS8) /* 8N1 */ 246 int scifconscflag = CONMODE; 247 int scifisconsole = 0; 248 249 #ifdef SCIFCN_SPEED 250 unsigned int scifcn_speed = SCIFCN_SPEED; 251 #else 252 unsigned int scifcn_speed = 9600; 253 #endif 254 255 #define divrnd(n, q) (((n)*2/(q)+1)/2) /* divide and round off */ 256 257 #ifndef __HAVE_GENERIC_SOFT_INTERRUPTS 258 #ifdef __NO_SOFT_SERIAL_INTERRUPT 259 volatile int scif_softintr_scheduled; 260 struct callout scif_soft_ch = CALLOUT_INITIALIZER; 261 #endif 262 #endif 263 264 u_int scif_rbuf_size = SCIF_RING_SIZE; 265 266 CFATTACH_DECL(scif, sizeof(struct scif_softc), 267 scif_match, scif_attach, NULL, NULL); 268 269 extern struct cfdriver scif_cd; 270 271 dev_type_open(scifopen); 272 dev_type_close(scifclose); 273 dev_type_read(scifread); 274 dev_type_write(scifwrite); 275 dev_type_ioctl(scifioctl); 276 dev_type_stop(scifstop); 277 dev_type_tty(sciftty); 278 dev_type_poll(scifpoll); 279 280 const struct cdevsw scif_cdevsw = { 281 scifopen, scifclose, scifread, scifwrite, scifioctl, 282 scifstop, sciftty, scifpoll, nommap, ttykqfilter, D_TTY 283 }; 284 285 void InitializeScif (unsigned int); 286 287 /* 288 * following functions are debugging prupose only 289 */ 290 #define CR 0x0D 291 #define USART_ON (unsigned int)~0x08 292 293 void scif_putc(unsigned char); 294 unsigned char scif_getc(void); 295 int ScifErrCheck(void); 296 297 /* 298 * InitializeScif 299 * : unsigned int bps; 300 * : SCIF(Serial Communication Interface) 301 */ 302 303 void 304 InitializeScif(unsigned int bps) 305 { 306 307 /* Initialize SCR */ 308 SHREG_SCSCR2 = 0x00; 309 310 #if 0 311 SHREG_SCFCR2 = SCFCR2_TFRST | SCFCR2_RFRST | SCFCR2_MCE; 312 #else 313 SHREG_SCFCR2 = SCFCR2_TFRST | SCFCR2_RFRST; 314 #endif 315 /* Serial Mode Register */ 316 SHREG_SCSMR2 = 0x00; /* 8bit,NonParity,Even,1Stop */ 317 318 /* Bit Rate Register */ 319 SHREG_SCBRR2 = divrnd(sh_clock_get_pclock(), 32 * bps) - 1; 320 321 /* 322 * wait 1mSec, because Send/Recv must begin 1 bit period after 323 * BRR is set. 324 */ 325 delay(1000); 326 327 #if 0 328 SHREG_SCFCR2 = FIFO_RCV_TRIGGER_14 | FIFO_XMT_TRIGGER_1 | SCFCR2_MCE; 329 #else 330 SHREG_SCFCR2 = FIFO_RCV_TRIGGER_14 | FIFO_XMT_TRIGGER_1; 331 #endif 332 333 /* Send permission, Receive permission ON */ 334 SHREG_SCSCR2 = SCSCR2_TE | SCSCR2_RE; 335 336 /* Serial Status Register */ 337 SHREG_SCSSR2 &= SCSSR2_TDFE; /* Clear Status */ 338 } 339 340 341 /* 342 * scif_putc 343 * : unsigned char c; 344 */ 345 346 void 347 scif_putc(unsigned char c) 348 { 349 350 /* wait for ready */ 351 while ((SHREG_SCFDR2 & SCFDR2_TXCNT) == SCFDR2_TXF_FULL) 352 ; 353 354 /* write send data to send register */ 355 SHREG_SCFTDR2 = c; 356 357 /* clear ready flag */ 358 SHREG_SCSSR2 &= ~(SCSSR2_TDFE | SCSSR2_TEND); 359 } 360 361 /* 362 * : ScifErrCheck 363 * 0x80 = error 364 * 0x08 = frame error 365 * 0x04 = parity error 366 */ 367 int 368 ScifErrCheck(void) 369 { 370 371 return(SHREG_SCSSR2 & (SCSSR2_ER | SCSSR2_FER | SCSSR2_PER)); 372 } 373 374 /* 375 * scif_getc 376 */ 377 unsigned char 378 scif_getc(void) 379 { 380 unsigned char c, err_c; 381 #ifdef SH4 382 unsigned short err_c2; 383 #endif 384 385 while (1) { 386 /* wait for ready */ 387 while ((SHREG_SCFDR2 & SCFDR2_RECVCNT) == 0) 388 ; 389 390 c = SHREG_SCFRDR2; 391 err_c = SHREG_SCSSR2; 392 SHREG_SCSSR2 &= ~(SCSSR2_ER | SCSSR2_BRK | SCSSR2_RDF 393 | SCSSR2_DR); 394 #ifdef SH4 395 if (CPU_IS_SH4) { 396 err_c2 = SHREG_SCLSR2; 397 SHREG_SCLSR2 &= ~SCLSR2_ORER; 398 } 399 #endif 400 if ((err_c & (SCSSR2_ER | SCSSR2_BRK | SCSSR2_FER 401 | SCSSR2_PER)) == 0) { 402 #ifdef SH4 403 if (CPU_IS_SH4 && ((err_c2 & SCLSR2_ORER) == 0)) 404 #endif 405 return(c); 406 } 407 } 408 409 } 410 411 #if 0 412 #define SCIF_MAX_UNITS 2 413 #else 414 #define SCIF_MAX_UNITS 1 415 #endif 416 417 418 static int 419 scif_match(struct device *parent, struct cfdata *cfp, void *aux) 420 { 421 422 if (strcmp(cfp->cf_name, "scif") 423 || cfp->cf_unit >= SCIF_MAX_UNITS) 424 return 0; 425 426 return 1; 427 } 428 429 static void 430 scif_attach(struct device *parent, struct device *self, void *aux) 431 { 432 struct scif_softc *sc = (struct scif_softc *)self; 433 struct tty *tp; 434 435 sc->sc_hwflags = 0; /* XXX */ 436 sc->sc_swflags = 0; /* XXX */ 437 sc->sc_fifolen = 16; 438 439 if (scifisconsole || kgdb_attached) { 440 /* InitializeScif(scifcn_speed); */ 441 SET(sc->sc_hwflags, SCIF_HW_CONSOLE); 442 SET(sc->sc_swflags, TIOCFLAG_SOFTCAR); 443 if (kgdb_attached) { 444 SET(sc->sc_hwflags, SCIF_HW_KGDB); 445 printf("\n%s: kgdb\n", sc->sc_dev.dv_xname); 446 } else { 447 printf("\n%s: console\n", sc->sc_dev.dv_xname); 448 } 449 } else { 450 InitializeScif(9600); 451 printf("\n"); 452 } 453 454 callout_init(&sc->sc_diag_ch); 455 #ifdef SH4 456 intc_intr_establish(SH4_INTEVT_SCIF_ERI, IST_LEVEL, IPL_SERIAL, 457 scifintr, sc); 458 intc_intr_establish(SH4_INTEVT_SCIF_RXI, IST_LEVEL, IPL_SERIAL, 459 scifintr, sc); 460 intc_intr_establish(SH4_INTEVT_SCIF_BRI, IST_LEVEL, IPL_SERIAL, 461 scifintr, sc); 462 intc_intr_establish(SH4_INTEVT_SCIF_TXI, IST_LEVEL, IPL_SERIAL, 463 scifintr, sc); 464 #else 465 intc_intr_establish(SH7709_INTEVT2_SCIF_ERI, IST_LEVEL, IPL_SERIAL, 466 scifintr, sc); 467 intc_intr_establish(SH7709_INTEVT2_SCIF_RXI, IST_LEVEL, IPL_SERIAL, 468 scifintr, sc); 469 intc_intr_establish(SH7709_INTEVT2_SCIF_BRI, IST_LEVEL, IPL_SERIAL, 470 scifintr, sc); 471 intc_intr_establish(SH7709_INTEVT2_SCIF_TXI, IST_LEVEL, IPL_SERIAL, 472 scifintr, sc); 473 #endif 474 475 #ifdef __HAVE_GENERIC_SOFT_INTERRUPTS 476 sc->sc_si = softintr_establish(IPL_SOFTSERIAL, scifsoft, sc); 477 #endif 478 SET(sc->sc_hwflags, SCIF_HW_DEV_OK); 479 480 tp = ttymalloc(); 481 tp->t_oproc = scifstart; 482 tp->t_param = scifparam; 483 tp->t_hwiflow = NULL; 484 485 sc->sc_tty = tp; 486 sc->sc_rbuf = malloc(scif_rbuf_size << 1, M_DEVBUF, M_NOWAIT); 487 if (sc->sc_rbuf == NULL) { 488 printf("%s: unable to allocate ring buffer\n", 489 sc->sc_dev.dv_xname); 490 return; 491 } 492 sc->sc_ebuf = sc->sc_rbuf + (scif_rbuf_size << 1); 493 494 tty_attach(tp); 495 } 496 497 /* 498 * Start or restart transmission. 499 */ 500 static void 501 scifstart(struct tty *tp) 502 { 503 struct scif_softc *sc = scif_cd.cd_devs[SCIFUNIT(tp->t_dev)]; 504 int s; 505 506 s = spltty(); 507 if (ISSET(tp->t_state, TS_BUSY | TS_TIMEOUT | TS_TTSTOP)) 508 goto out; 509 if (sc->sc_tx_stopped) 510 goto out; 511 512 if (tp->t_outq.c_cc <= tp->t_lowat) { 513 if (ISSET(tp->t_state, TS_ASLEEP)) { 514 CLR(tp->t_state, TS_ASLEEP); 515 wakeup(&tp->t_outq); 516 } 517 selwakeup(&tp->t_wsel); 518 if (tp->t_outq.c_cc == 0) 519 goto out; 520 } 521 522 /* Grab the first contiguous region of buffer space. */ 523 { 524 u_char *tba; 525 int tbc; 526 527 tba = tp->t_outq.c_cf; 528 tbc = ndqb(&tp->t_outq, 0); 529 530 (void)splserial(); 531 532 sc->sc_tba = tba; 533 sc->sc_tbc = tbc; 534 } 535 536 SET(tp->t_state, TS_BUSY); 537 sc->sc_tx_busy = 1; 538 539 /* Enable transmit completion interrupts if necessary. */ 540 SHREG_SCSCR2 |= SCSCR2_TIE | SCSCR2_RIE; 541 542 /* Output the first chunk of the contiguous buffer. */ 543 { 544 int n; 545 int max; 546 int i; 547 548 n = sc->sc_tbc; 549 max = sc->sc_fifolen - ((SHREG_SCFDR2 & SCFDR2_TXCNT) >> 8); 550 if (n > max) 551 n = max; 552 553 for (i = 0; i < n; i++) { 554 scif_putc(*(sc->sc_tba)); 555 sc->sc_tba++; 556 } 557 sc->sc_tbc -= n; 558 } 559 out: 560 splx(s); 561 return; 562 } 563 564 /* 565 * Set SCIF tty parameters from termios. 566 * XXX - Should just copy the whole termios after 567 * making sure all the changes could be done. 568 */ 569 static int 570 scifparam(struct tty *tp, struct termios *t) 571 { 572 struct scif_softc *sc = scif_cd.cd_devs[SCIFUNIT(tp->t_dev)]; 573 int ospeed = t->c_ospeed; 574 int s; 575 576 if (ISSET(sc->sc_dev.dv_flags, DVF_ACTIVE) == 0) 577 return (EIO); 578 579 /* Check requested parameters. */ 580 if (ospeed < 0) 581 return (EINVAL); 582 if (t->c_ispeed && t->c_ispeed != t->c_ospeed) 583 return (EINVAL); 584 585 /* 586 * For the console, always force CLOCAL and !HUPCL, so that the port 587 * is always active. 588 */ 589 if (ISSET(sc->sc_swflags, TIOCFLAG_SOFTCAR) || 590 ISSET(sc->sc_hwflags, SCIF_HW_CONSOLE)) { 591 SET(t->c_cflag, CLOCAL); 592 CLR(t->c_cflag, HUPCL); 593 } 594 595 /* 596 * If there were no changes, don't do anything. This avoids dropping 597 * input and improves performance when all we did was frob things like 598 * VMIN and VTIME. 599 */ 600 if (tp->t_ospeed == t->c_ospeed && 601 tp->t_cflag == t->c_cflag) 602 return (0); 603 604 #if 0 605 /* XXX (msaitoh) */ 606 lcr = ISSET(sc->sc_lcr, LCR_SBREAK) | cflag2lcr(t->c_cflag); 607 #endif 608 609 s = splserial(); 610 611 /* 612 * Set the flow control pins depending on the current flow control 613 * mode. 614 */ 615 if (ISSET(t->c_cflag, CRTSCTS)) { 616 SHREG_SCFCR2 |= SCFCR2_MCE; 617 } else { 618 SHREG_SCFCR2 &= ~SCFCR2_MCE; 619 } 620 621 SHREG_SCBRR2 = divrnd(sh_clock_get_pclock(), 32 * ospeed) -1; 622 623 /* 624 * Set the FIFO threshold based on the receive speed. 625 * 626 * * If it's a low speed, it's probably a mouse or some other 627 * interactive device, so set the threshold low. 628 * * If it's a high speed, trim the trigger level down to prevent 629 * overflows. 630 * * Otherwise set it a bit higher. 631 */ 632 #if 0 633 /* XXX (msaitoh) */ 634 if (ISSET(sc->sc_hwflags, SCIF_HW_HAYESP)) 635 sc->sc_fifo = FIFO_DMA_MODE | FIFO_ENABLE | FIFO_TRIGGER_8; 636 else if (ISSET(sc->sc_hwflags, SCIF_HW_FIFO)) 637 sc->sc_fifo = FIFO_ENABLE | 638 (t->c_ospeed <= 1200 ? FIFO_TRIGGER_1 : 639 t->c_ospeed <= 38400 ? FIFO_TRIGGER_8 : FIFO_TRIGGER_4); 640 else 641 sc->sc_fifo = 0; 642 #endif 643 644 /* And copy to tty. */ 645 tp->t_ispeed = 0; 646 tp->t_ospeed = t->c_ospeed; 647 tp->t_cflag = t->c_cflag; 648 649 if (!sc->sc_heldchange) { 650 if (sc->sc_tx_busy) { 651 sc->sc_heldtbc = sc->sc_tbc; 652 sc->sc_tbc = 0; 653 sc->sc_heldchange = 1; 654 } 655 #if 0 656 /* XXX (msaitoh) */ 657 else 658 scif_loadchannelregs(sc); 659 #endif 660 } 661 662 if (!ISSET(t->c_cflag, CHWFLOW)) { 663 /* Disable the high water mark. */ 664 sc->sc_r_hiwat = 0; 665 sc->sc_r_lowat = 0; 666 if (ISSET(sc->sc_rx_flags, RX_TTY_OVERFLOWED)) { 667 CLR(sc->sc_rx_flags, RX_TTY_OVERFLOWED); 668 scif_schedrx(sc); 669 } 670 } else { 671 sc->sc_r_hiwat = scif_rbuf_hiwat; 672 sc->sc_r_lowat = scif_rbuf_lowat; 673 } 674 675 splx(s); 676 677 #ifdef SCIF_DEBUG 678 if (scif_debug) 679 scifstatus(sc, "scifparam "); 680 #endif 681 682 if (!ISSET(t->c_cflag, CHWFLOW)) { 683 if (sc->sc_tx_stopped) { 684 sc->sc_tx_stopped = 0; 685 scifstart(tp); 686 } 687 } 688 689 return (0); 690 } 691 692 void 693 scif_iflush(struct scif_softc *sc) 694 { 695 int i; 696 unsigned char c; 697 698 i = SHREG_SCFDR2 & SCFDR2_RECVCNT; 699 700 while (i > 0) { 701 c = SHREG_SCFRDR2; 702 SHREG_SCSSR2 &= ~(SCSSR2_RDF | SCSSR2_DR); 703 i--; 704 } 705 } 706 707 int 708 scifopen(dev_t dev, int flag, int mode, struct proc *p) 709 { 710 int unit = SCIFUNIT(dev); 711 struct scif_softc *sc; 712 struct tty *tp; 713 int s, s2; 714 int error; 715 716 if (unit >= scif_cd.cd_ndevs) 717 return (ENXIO); 718 sc = scif_cd.cd_devs[unit]; 719 if (sc == 0 || !ISSET(sc->sc_hwflags, SCIF_HW_DEV_OK) || 720 sc->sc_rbuf == NULL) 721 return (ENXIO); 722 723 if (ISSET(sc->sc_dev.dv_flags, DVF_ACTIVE) == 0) 724 return (ENXIO); 725 726 #ifdef KGDB 727 /* 728 * If this is the kgdb port, no other use is permitted. 729 */ 730 if (ISSET(sc->sc_hwflags, SCIF_HW_KGDB)) 731 return (EBUSY); 732 #endif /* KGDB */ 733 734 tp = sc->sc_tty; 735 736 if (ISSET(tp->t_state, TS_ISOPEN) && 737 ISSET(tp->t_state, TS_XCLUDE) && 738 p->p_ucred->cr_uid != 0) 739 return (EBUSY); 740 741 s = spltty(); 742 743 /* 744 * Do the following iff this is a first open. 745 */ 746 if (!ISSET(tp->t_state, TS_ISOPEN) && tp->t_wopen == 0) { 747 struct termios t; 748 749 tp->t_dev = dev; 750 751 s2 = splserial(); 752 753 /* Turn on interrupts. */ 754 SHREG_SCSCR2 |= SCSCR2_TIE | SCSCR2_RIE; 755 756 splx(s2); 757 758 /* 759 * Initialize the termios status to the defaults. Add in the 760 * sticky bits from TIOCSFLAGS. 761 */ 762 t.c_ispeed = 0; 763 if (ISSET(sc->sc_hwflags, SCIF_HW_CONSOLE)) { 764 t.c_ospeed = scifcn_speed; /* XXX (msaitoh) */ 765 t.c_cflag = scifconscflag; 766 } else { 767 t.c_ospeed = TTYDEF_SPEED; 768 t.c_cflag = TTYDEF_CFLAG; 769 } 770 if (ISSET(sc->sc_swflags, TIOCFLAG_CLOCAL)) 771 SET(t.c_cflag, CLOCAL); 772 if (ISSET(sc->sc_swflags, TIOCFLAG_CRTSCTS)) 773 SET(t.c_cflag, CRTSCTS); 774 if (ISSET(sc->sc_swflags, TIOCFLAG_MDMBUF)) 775 SET(t.c_cflag, MDMBUF); 776 /* Make sure scifparam() will do something. */ 777 tp->t_ospeed = 0; 778 (void) scifparam(tp, &t); 779 tp->t_iflag = TTYDEF_IFLAG; 780 tp->t_oflag = TTYDEF_OFLAG; 781 tp->t_lflag = TTYDEF_LFLAG; 782 ttychars(tp); 783 ttsetwater(tp); 784 785 s2 = splserial(); 786 787 /* Clear the input ring, and unblock. */ 788 sc->sc_rbput = sc->sc_rbget = sc->sc_rbuf; 789 sc->sc_rbavail = scif_rbuf_size; 790 scif_iflush(sc); 791 CLR(sc->sc_rx_flags, RX_ANY_BLOCK); 792 #if 0 793 /* XXX (msaitoh) */ 794 scif_hwiflow(sc); 795 #endif 796 797 #ifdef SCIF_DEBUG 798 if (scif_debug) 799 scifstatus(sc, "scifopen "); 800 #endif 801 802 splx(s2); 803 } 804 805 splx(s); 806 807 error = ttyopen(tp, SCIFDIALOUT(dev), ISSET(flag, O_NONBLOCK)); 808 if (error) 809 goto bad; 810 811 error = (*tp->t_linesw->l_open)(dev, tp); 812 if (error) 813 goto bad; 814 815 return (0); 816 817 bad: 818 819 return (error); 820 } 821 822 int 823 scifclose(dev_t dev, int flag, int mode, struct proc *p) 824 { 825 struct scif_softc *sc = scif_cd.cd_devs[SCIFUNIT(dev)]; 826 struct tty *tp = sc->sc_tty; 827 828 /* XXX This is for cons.c. */ 829 if (!ISSET(tp->t_state, TS_ISOPEN)) 830 return (0); 831 832 (*tp->t_linesw->l_close)(tp, flag); 833 ttyclose(tp); 834 835 if (ISSET(sc->sc_dev.dv_flags, DVF_ACTIVE) == 0) 836 return (0); 837 838 return (0); 839 } 840 841 int 842 scifread(dev_t dev, struct uio *uio, int flag) 843 { 844 struct scif_softc *sc = scif_cd.cd_devs[SCIFUNIT(dev)]; 845 struct tty *tp = sc->sc_tty; 846 847 return ((*tp->t_linesw->l_read)(tp, uio, flag)); 848 } 849 850 int 851 scifwrite(dev_t dev, struct uio *uio, int flag) 852 { 853 struct scif_softc *sc = scif_cd.cd_devs[SCIFUNIT(dev)]; 854 struct tty *tp = sc->sc_tty; 855 856 return ((*tp->t_linesw->l_write)(tp, uio, flag)); 857 } 858 859 int 860 scifpoll(dev_t dev, int events, struct proc *p) 861 { 862 struct scif_softc *sc = scif_cd.cd_devs[SCIFUNIT(dev)]; 863 struct tty *tp = sc->sc_tty; 864 865 return ((*tp->t_linesw->l_poll)(tp, events, p)); 866 } 867 868 struct tty * 869 sciftty(dev_t dev) 870 { 871 struct scif_softc *sc = scif_cd.cd_devs[SCIFUNIT(dev)]; 872 struct tty *tp = sc->sc_tty; 873 874 return (tp); 875 } 876 877 int 878 scifioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p) 879 { 880 struct scif_softc *sc = scif_cd.cd_devs[SCIFUNIT(dev)]; 881 struct tty *tp = sc->sc_tty; 882 int error; 883 int s; 884 885 if (ISSET(sc->sc_dev.dv_flags, DVF_ACTIVE) == 0) 886 return (EIO); 887 888 error = (*tp->t_linesw->l_ioctl)(tp, cmd, data, flag, p); 889 if (error != EPASSTHROUGH) 890 return (error); 891 892 error = ttioctl(tp, cmd, data, flag, p); 893 if (error != EPASSTHROUGH) 894 return (error); 895 896 error = 0; 897 898 s = splserial(); 899 900 switch (cmd) { 901 case TIOCSBRK: 902 scif_break(sc, 1); 903 break; 904 905 case TIOCCBRK: 906 scif_break(sc, 0); 907 break; 908 909 case TIOCGFLAGS: 910 *(int *)data = sc->sc_swflags; 911 break; 912 913 case TIOCSFLAGS: 914 error = suser(p->p_ucred, &p->p_acflag); 915 if (error) 916 break; 917 sc->sc_swflags = *(int *)data; 918 break; 919 920 default: 921 error = EPASSTHROUGH; 922 break; 923 } 924 925 splx(s); 926 927 return (error); 928 } 929 930 integrate void 931 scif_schedrx(struct scif_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 (!scif_softintr_scheduled) { 944 scif_softintr_scheduled = 1; 945 callout_reset(&scif_soft_ch, 1, scifsoft, NULL); 946 } 947 #endif 948 #endif 949 } 950 951 void 952 scif_break(struct scif_softc *sc, int onoff) 953 { 954 955 if (onoff) 956 SHREG_SCSSR2 &= ~SCSSR2_TDFE; 957 else 958 SHREG_SCSSR2 |= SCSSR2_TDFE; 959 960 #if 0 /* XXX */ 961 if (!sc->sc_heldchange) { 962 if (sc->sc_tx_busy) { 963 sc->sc_heldtbc = sc->sc_tbc; 964 sc->sc_tbc = 0; 965 sc->sc_heldchange = 1; 966 } else 967 scif_loadchannelregs(sc); 968 } 969 #endif 970 } 971 972 /* 973 * Stop output, e.g., for ^S or output flush. 974 */ 975 void 976 scifstop(struct tty *tp, int flag) 977 { 978 struct scif_softc *sc = scif_cd.cd_devs[SCIFUNIT(tp->t_dev)]; 979 int s; 980 981 s = splserial(); 982 if (ISSET(tp->t_state, TS_BUSY)) { 983 /* Stop transmitting at the next chunk. */ 984 sc->sc_tbc = 0; 985 sc->sc_heldtbc = 0; 986 if (!ISSET(tp->t_state, TS_TTSTOP)) 987 SET(tp->t_state, TS_FLUSH); 988 } 989 splx(s); 990 } 991 992 void 993 scif_intr_init() 994 { 995 /* XXX */ 996 } 997 998 void 999 scifdiag(void *arg) 1000 { 1001 struct scif_softc *sc = arg; 1002 int overflows, floods; 1003 int s; 1004 1005 s = splserial(); 1006 overflows = sc->sc_overflows; 1007 sc->sc_overflows = 0; 1008 floods = sc->sc_floods; 1009 sc->sc_floods = 0; 1010 sc->sc_errors = 0; 1011 splx(s); 1012 1013 log(LOG_WARNING, "%s: %d silo overflow%s, %d ibuf flood%s\n", 1014 sc->sc_dev.dv_xname, 1015 overflows, overflows == 1 ? "" : "s", 1016 floods, floods == 1 ? "" : "s"); 1017 } 1018 1019 integrate void 1020 scif_rxsoft(struct scif_softc *sc, struct tty *tp) 1021 { 1022 int (*rint)(int c, struct tty *tp) = tp->t_linesw->l_rint; 1023 u_char *get, *end; 1024 u_int cc, scc; 1025 u_char ssr2; 1026 int code; 1027 int s; 1028 1029 end = sc->sc_ebuf; 1030 get = sc->sc_rbget; 1031 scc = cc = scif_rbuf_size - sc->sc_rbavail; 1032 1033 if (cc == scif_rbuf_size) { 1034 sc->sc_floods++; 1035 if (sc->sc_errors++ == 0) 1036 callout_reset(&sc->sc_diag_ch, 60 * hz, scifdiag, sc); 1037 } 1038 1039 while (cc) { 1040 code = get[0]; 1041 ssr2 = get[1]; 1042 if (ISSET(ssr2, SCSSR2_BRK | SCSSR2_FER | SCSSR2_PER)) { 1043 if (ISSET(ssr2, SCSSR2_BRK | SCSSR2_FER)) 1044 SET(code, TTY_FE); 1045 if (ISSET(ssr2, SCSSR2_PER)) 1046 SET(code, TTY_PE); 1047 } 1048 if ((*rint)(code, tp) == -1) { 1049 /* 1050 * The line discipline's buffer is out of space. 1051 */ 1052 if (!ISSET(sc->sc_rx_flags, RX_TTY_BLOCKED)) { 1053 /* 1054 * We're either not using flow control, or the 1055 * line discipline didn't tell us to block for 1056 * some reason. Either way, we have no way to 1057 * know when there's more space available, so 1058 * just drop the rest of the data. 1059 */ 1060 get += cc << 1; 1061 if (get >= end) 1062 get -= scif_rbuf_size << 1; 1063 cc = 0; 1064 } else { 1065 /* 1066 * Don't schedule any more receive processing 1067 * until the line discipline tells us there's 1068 * space available (through scifhwiflow()). 1069 * Leave the rest of the data in the input 1070 * buffer. 1071 */ 1072 SET(sc->sc_rx_flags, RX_TTY_OVERFLOWED); 1073 } 1074 break; 1075 } 1076 get += 2; 1077 if (get >= end) 1078 get = sc->sc_rbuf; 1079 cc--; 1080 } 1081 1082 if (cc != scc) { 1083 sc->sc_rbget = get; 1084 s = splserial(); 1085 cc = sc->sc_rbavail += scc - cc; 1086 /* Buffers should be ok again, release possible block. */ 1087 if (cc >= sc->sc_r_lowat) { 1088 if (ISSET(sc->sc_rx_flags, RX_IBUF_OVERFLOWED)) { 1089 CLR(sc->sc_rx_flags, RX_IBUF_OVERFLOWED); 1090 SHREG_SCSCR2 |= SCSCR2_RIE; 1091 } 1092 #if 0 1093 if (ISSET(sc->sc_rx_flags, RX_IBUF_BLOCKED)) { 1094 CLR(sc->sc_rx_flags, RX_IBUF_BLOCKED); 1095 scif_hwiflow(sc); 1096 } 1097 #endif 1098 } 1099 splx(s); 1100 } 1101 } 1102 1103 integrate void 1104 scif_txsoft(struct scif_softc *sc, struct tty *tp) 1105 { 1106 1107 CLR(tp->t_state, TS_BUSY); 1108 if (ISSET(tp->t_state, TS_FLUSH)) 1109 CLR(tp->t_state, TS_FLUSH); 1110 else 1111 ndflush(&tp->t_outq, (int)(sc->sc_tba - tp->t_outq.c_cf)); 1112 (*tp->t_linesw->l_start)(tp); 1113 } 1114 1115 integrate void 1116 scif_stsoft(struct scif_softc *sc, struct tty *tp) 1117 { 1118 #if 0 1119 /* XXX (msaitoh) */ 1120 u_char msr, delta; 1121 int s; 1122 1123 s = splserial(); 1124 msr = sc->sc_msr; 1125 delta = sc->sc_msr_delta; 1126 sc->sc_msr_delta = 0; 1127 splx(s); 1128 1129 if (ISSET(delta, sc->sc_msr_dcd)) { 1130 /* 1131 * Inform the tty layer that carrier detect changed. 1132 */ 1133 (void) (*tp->t_linesw->l_modem)(tp, ISSET(msr, MSR_DCD)); 1134 } 1135 1136 if (ISSET(delta, sc->sc_msr_cts)) { 1137 /* Block or unblock output according to flow control. */ 1138 if (ISSET(msr, sc->sc_msr_cts)) { 1139 sc->sc_tx_stopped = 0; 1140 (*tp->t_linesw->l_start)(tp); 1141 } else { 1142 sc->sc_tx_stopped = 1; 1143 } 1144 } 1145 1146 #ifdef SCIF_DEBUG 1147 if (scif_debug) 1148 scifstatus(sc, "scif_stsoft"); 1149 #endif 1150 #endif 1151 } 1152 1153 #ifdef __HAVE_GENERIC_SOFT_INTERRUPTS 1154 void 1155 scifsoft(void *arg) 1156 { 1157 struct scif_softc *sc = arg; 1158 struct tty *tp; 1159 1160 if (ISSET(sc->sc_dev.dv_flags, DVF_ACTIVE) == 0) 1161 return; 1162 1163 { 1164 #else 1165 void 1166 #ifndef __NO_SOFT_SERIAL_INTERRUPT 1167 scifsoft() 1168 #else 1169 scifsoft(void *arg) 1170 #endif 1171 { 1172 struct scif_softc *sc; 1173 struct tty *tp; 1174 int unit; 1175 #ifdef __NO_SOFT_SERIAL_INTERRUPT 1176 int s; 1177 1178 s = splsoftserial(); 1179 scif_softintr_scheduled = 0; 1180 #endif 1181 1182 for (unit = 0; unit < scif_cd.cd_ndevs; unit++) { 1183 sc = scif_cd.cd_devs[unit]; 1184 if (sc == NULL || !ISSET(sc->sc_hwflags, SCIF_HW_DEV_OK)) 1185 continue; 1186 1187 if (ISSET(sc->sc_dev.dv_flags, DVF_ACTIVE) == 0) 1188 continue; 1189 1190 tp = sc->sc_tty; 1191 if (tp == NULL) 1192 continue; 1193 if (!ISSET(tp->t_state, TS_ISOPEN) && tp->t_wopen == 0) 1194 continue; 1195 #endif 1196 tp = sc->sc_tty; 1197 1198 if (sc->sc_rx_ready) { 1199 sc->sc_rx_ready = 0; 1200 scif_rxsoft(sc, tp); 1201 } 1202 1203 #if 0 1204 if (sc->sc_st_check) { 1205 sc->sc_st_check = 0; 1206 scif_stsoft(sc, tp); 1207 } 1208 #endif 1209 1210 if (sc->sc_tx_done) { 1211 sc->sc_tx_done = 0; 1212 scif_txsoft(sc, tp); 1213 } 1214 } 1215 1216 #ifndef __HAVE_GENERIC_SOFT_INTERRUPTS 1217 #ifdef __NO_SOFT_SERIAL_INTERRUPT 1218 splx(s); 1219 #endif 1220 #endif 1221 } 1222 1223 int 1224 scifintr(void *arg) 1225 { 1226 struct scif_softc *sc = arg; 1227 u_char *put, *end; 1228 u_int cc; 1229 u_short ssr2; 1230 int count; 1231 1232 if (ISSET(sc->sc_dev.dv_flags, DVF_ACTIVE) == 0) 1233 return (0); 1234 1235 end = sc->sc_ebuf; 1236 put = sc->sc_rbput; 1237 cc = sc->sc_rbavail; 1238 1239 do { 1240 ssr2 = SHREG_SCSSR2; 1241 if (ISSET(ssr2, SCSSR2_BRK)) { 1242 SHREG_SCSSR2 &= ~(SCSSR2_ER | SCSSR2_BRK | SCSSR2_DR); 1243 #ifdef DDB 1244 if (ISSET(sc->sc_hwflags, SCIF_HW_CONSOLE)) { 1245 console_debugger(); 1246 } 1247 #endif /* DDB */ 1248 #ifdef KGDB 1249 if (ISSET(sc->sc_hwflags, SCIF_HW_KGDB)) { 1250 kgdb_connect(1); 1251 } 1252 #endif /* KGDB */ 1253 } 1254 count = SHREG_SCFDR2 & SCFDR2_RECVCNT; 1255 if (count != 0) { 1256 while (1) { 1257 u_char c = SHREG_SCFRDR2; 1258 u_char err = (u_char)(SHREG_SCSSR2 & 0x00ff); 1259 1260 SHREG_SCSSR2 &= ~(SCSSR2_ER | SCSSR2_RDF | SCSSR2_DR); 1261 #ifdef SH4 1262 if (CPU_IS_SH4) 1263 SHREG_SCLSR2 &= ~SCLSR2_ORER; 1264 #endif 1265 if ((cc > 0) && (count > 0)) { 1266 put[0] = c; 1267 put[1] = err; 1268 put += 2; 1269 if (put >= end) 1270 put = sc->sc_rbuf; 1271 cc--; 1272 count--; 1273 } else 1274 break; 1275 } 1276 1277 /* 1278 * Current string of incoming characters ended because 1279 * no more data was available or we ran out of space. 1280 * Schedule a receive event if any data was received. 1281 * If we're out of space, turn off receive interrupts. 1282 */ 1283 sc->sc_rbput = put; 1284 sc->sc_rbavail = cc; 1285 if (!ISSET(sc->sc_rx_flags, RX_TTY_OVERFLOWED)) 1286 sc->sc_rx_ready = 1; 1287 1288 /* 1289 * See if we are in danger of overflowing a buffer. If 1290 * so, use hardware flow control to ease the pressure. 1291 */ 1292 if (!ISSET(sc->sc_rx_flags, RX_IBUF_BLOCKED) && 1293 cc < sc->sc_r_hiwat) { 1294 SET(sc->sc_rx_flags, RX_IBUF_BLOCKED); 1295 #if 0 1296 scif_hwiflow(sc); 1297 #endif 1298 } 1299 1300 /* 1301 * If we're out of space, disable receive interrupts 1302 * until the queue has drained a bit. 1303 */ 1304 if (!cc) { 1305 SET(sc->sc_rx_flags, RX_IBUF_OVERFLOWED); 1306 SHREG_SCSCR2 &= ~SCSCR2_RIE; 1307 } 1308 } else { 1309 if (SHREG_SCSSR2 & (SCSSR2_RDF | SCSSR2_DR)) { 1310 SHREG_SCSCR2 &= ~(SCSCR2_TIE | SCSCR2_RIE); 1311 delay(10); 1312 SHREG_SCSCR2 |= SCSCR2_TIE | SCSCR2_RIE; 1313 continue; 1314 } 1315 } 1316 } while (SHREG_SCSSR2 & (SCSSR2_RDF | SCSSR2_DR)); 1317 1318 #if 0 1319 msr = bus_space_read_1(iot, ioh, scif_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 SCIF_DEBUG 1382 if (scif_debug) 1383 scifstatus(sc, "scifintr "); 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_SCFDR2 & SCFDR2_TXCNT) >> 8) != 16) { /* XXX (msaitoh) */ 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 int n; 1410 int max; 1411 int i; 1412 1413 n = sc->sc_tbc; 1414 max = sc->sc_fifolen - 1415 ((SHREG_SCFDR2 & SCFDR2_TXCNT) >> 8); 1416 if (n > max) 1417 n = max; 1418 1419 for (i = 0; i < n; i++) { 1420 scif_putc(*(sc->sc_tba)); 1421 sc->sc_tba++; 1422 } 1423 sc->sc_tbc -= n; 1424 } else { 1425 /* Disable transmit completion interrupts if necessary. */ 1426 #if 0 1427 if (ISSET(sc->sc_ier, IER_ETXRDY)) 1428 #endif 1429 SHREG_SCSCR2 &= ~SCSCR2_TIE; 1430 1431 if (sc->sc_tx_busy) { 1432 sc->sc_tx_busy = 0; 1433 sc->sc_tx_done = 1; 1434 } 1435 } 1436 } 1437 1438 /* Wake up the poller. */ 1439 #ifdef __HAVE_GENERIC_SOFT_INTERRUPTS 1440 softintr_schedule(sc->sc_si); 1441 #else 1442 #ifndef __NO_SOFT_SERIAL_INTERRUPT 1443 setsoftserial(); 1444 #else 1445 if (!scif_softintr_scheduled) { 1446 scif_softintr_scheduled = 1; 1447 callout_reset(&scif_soft_ch, 1, scifsoft, NULL); 1448 } 1449 #endif 1450 #endif 1451 1452 #if NRND > 0 && defined(RND_SCIF) 1453 rnd_add_uint32(&sc->rnd_source, iir | lsr); 1454 #endif 1455 1456 return (1); 1457 } 1458 1459 void 1460 scifcnprobe(struct consdev *cp) 1461 { 1462 int maj; 1463 1464 /* locate the major number */ 1465 maj = cdevsw_lookup_major(&scif_cdevsw); 1466 1467 /* Initialize required fields. */ 1468 cp->cn_dev = makedev(maj, 0); 1469 #ifdef SCIFCONSOLE 1470 cp->cn_pri = CN_REMOTE; 1471 #else 1472 cp->cn_pri = CN_NORMAL; 1473 #endif 1474 } 1475 1476 void 1477 scifcninit(struct consdev *cp) 1478 { 1479 1480 InitializeScif(scifcn_speed); 1481 scifisconsole = 1; 1482 } 1483 1484 int 1485 scifcngetc(dev_t dev) 1486 { 1487 int c; 1488 int s; 1489 1490 s = splserial(); 1491 c = scif_getc(); 1492 splx(s); 1493 1494 return (c); 1495 } 1496 1497 void 1498 scifcnputc(dev_t dev, int c) 1499 { 1500 int s; 1501 1502 s = splserial(); 1503 scif_putc((u_char)c); 1504 splx(s); 1505 } 1506 1507 #ifdef KGDB 1508 int 1509 scif_kgdb_init() 1510 { 1511 1512 if (strcmp(kgdb_devname, "scif") != 0) 1513 return (1); 1514 1515 if (scifisconsole) 1516 return (1); /* can't share with console */ 1517 1518 InitializeScif(kgdb_rate); 1519 1520 kgdb_attach((int (*)(void *))scifcngetc, 1521 (void (*)(void *, int))scifcnputc, NULL); 1522 kgdb_dev = 123; /* unneeded, only to satisfy some tests */ 1523 kgdb_attached = 1; 1524 1525 return (0); 1526 } 1527 #endif /* KGDB */ 1528