1 /*- 2 * cyclades cyclom-y serial driver 3 * Andrew Herbert <[email protected]>, 17 August 1993 4 * 5 * SPDX-License-Identifier: BSD-3-Clause 6 * 7 * Copyright (c) 1993 Andrew Herbert. 8 * All rights reserved. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 3. The name Andrew Herbert may not be used to endorse or promote products 19 * derived from this software without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY ``AS IS'' AND ANY EXPRESS OR IMPLIED 22 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 23 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN 24 * NO EVENT SHALL I BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 25 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 26 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 27 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 28 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 29 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 30 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 */ 32 33 #include <sys/cdefs.h> 34 __FBSDID("$FreeBSD$"); 35 36 #include "opt_compat.h" 37 38 /* 39 * TODO: 40 * Atomic COR change. 41 * Consoles. 42 */ 43 44 /* 45 * Temporary compile-time configuration options. 46 */ 47 #define RxFifoThreshold (CD1400_RX_FIFO_SIZE / 2) 48 /* Number of chars in the receiver FIFO before an 49 * an interrupt is generated. Should depend on 50 * line speed. Needs to be about 6 on a 486DX33 51 * for 4 active ports at 115200 bps. Why doesn't 52 * 10 work? 53 */ 54 #define PollMode /* Use polling-based irq service routine, not the 55 * hardware svcack lines. Must be defined for 56 * Cyclom-16Y boards. Less efficient for Cyclom-8Ys, 57 * and stops 4 * 115200 bps from working. 58 */ 59 #undef Smarts /* Enable slightly more CD1400 intelligence. Mainly 60 * the output CR/LF processing, plus we can avoid a 61 * few checks usually done in ttyinput(). 62 * 63 * XXX not fully implemented, and not particularly 64 * worthwhile. 65 */ 66 #undef CyDebug /* Include debugging code (not very expensive). */ 67 68 /* These will go away. */ 69 #undef SOFT_CTS_OFLOW 70 #define SOFT_HOTCHAR 71 72 #include <sys/param.h> 73 #include <sys/systm.h> 74 #include <sys/bus.h> 75 #include <sys/conf.h> 76 #include <sys/fcntl.h> 77 #include <sys/interrupt.h> 78 #include <sys/kernel.h> 79 #include <sys/lock.h> 80 #include <sys/malloc.h> 81 #include <sys/mutex.h> 82 #include <sys/serial.h> 83 #include <sys/syslog.h> 84 #include <sys/tty.h> 85 86 #include <machine/psl.h> 87 88 #include <dev/ic/cd1400.h> 89 90 #include <dev/cy/cyreg.h> 91 #include <dev/cy/cyvar.h> 92 93 #define NCY 10 /* KLUDGE */ 94 95 #define NPORTS (NCY * CY_MAX_PORTS) 96 97 #define CY_MAX_PORTS (CD1400_NO_OF_CHANNELS * CY_MAX_CD1400s) 98 99 /* We encode the cyclom unit number (cyu) in spare bits in the IVR's. */ 100 #define CD1400_xIVR_CHAN_SHIFT 3 101 #define CD1400_xIVR_CHAN 0x1F 102 103 /* 104 * ETC states. com->etc may also contain a hardware ETC command value, 105 * meaning that execution of that command is pending. 106 */ 107 #define ETC_NONE 0 /* we depend on bzero() setting this */ 108 #define ETC_BREAK_STARTING 1 109 #define ETC_BREAK_STARTED 2 110 #define ETC_BREAK_ENDING 3 111 #define ETC_BREAK_ENDED 4 112 113 #define LOTS_OF_EVENTS 64 /* helps separate urgent events from input */ 114 115 /* 116 * com state bits. 117 * (CS_BUSY | CS_TTGO) and (CS_BUSY | CS_TTGO | CS_ODEVREADY) must be higher 118 * than the other bits so that they can be tested as a group without masking 119 * off the low bits. 120 * 121 * The following com and tty flags correspond closely: 122 * CS_BUSY = TS_BUSY (maintained by cystart(), cypoll() and 123 * comstop()) 124 * CS_TTGO = ~TS_TTSTOP (maintained by cyparam() and cystart()) 125 * CS_CTS_OFLOW = CCTS_OFLOW (maintained by cyparam()) 126 * CS_RTS_IFLOW = CRTS_IFLOW (maintained by cyparam()) 127 * TS_FLUSH is not used. 128 * XXX I think TIOCSETA doesn't clear TS_TTSTOP when it clears IXON. 129 * XXX CS_*FLOW should be CF_*FLOW in com->flags (control flags not state). 130 */ 131 #define CS_BUSY 0x80 /* output in progress */ 132 #define CS_TTGO 0x40 /* output not stopped by XOFF */ 133 #define CS_ODEVREADY 0x20 /* external device h/w ready (CTS) */ 134 #define CS_CHECKMSR 1 /* check of MSR scheduled */ 135 #define CS_CTS_OFLOW 2 /* use CTS output flow control */ 136 #define CS_ODONE 4 /* output completed */ 137 #define CS_RTS_IFLOW 8 /* use RTS input flow control */ 138 #define CSE_ODONE 1 /* output transmitted */ 139 140 static char const * const error_desc[] = { 141 #define CE_OVERRUN 0 142 "silo overflow", 143 #define CE_INTERRUPT_BUF_OVERFLOW 1 144 "interrupt-level buffer overflow", 145 #define CE_TTY_BUF_OVERFLOW 2 146 "tty-level buffer overflow", 147 }; 148 149 #define CE_NTYPES 3 150 #define CE_RECORD(com, errnum) (++(com)->delta_error_counts[errnum]) 151 152 #ifdef SMP 153 #define COM_LOCK() mtx_lock_spin(&cy_lock) 154 #define COM_UNLOCK() mtx_unlock_spin(&cy_lock) 155 #else 156 #define COM_LOCK() 157 #define COM_UNLOCK() 158 #endif 159 160 /* types. XXX - should be elsewhere */ 161 typedef u_char bool_t; /* boolean */ 162 163 /* queue of linear buffers */ 164 struct lbq { 165 u_char *l_head; /* next char to process */ 166 u_char *l_tail; /* one past the last char to process */ 167 struct lbq *l_next; /* next in queue */ 168 bool_t l_queued; /* nonzero if queued */ 169 }; 170 171 /* com device structure */ 172 struct com_s { 173 u_char state; /* miscellaneous flag bits */ 174 u_char etc; /* pending Embedded Transmit Command */ 175 u_char extra_state; /* more flag bits, separate for order trick */ 176 u_char gfrcr_image; /* copy of value read from GFRCR */ 177 u_char mcr_dtr; /* MCR bit that is wired to DTR */ 178 u_char mcr_image; /* copy of value written to MCR */ 179 u_char mcr_rts; /* MCR bit that is wired to RTS */ 180 int unit; /* unit number */ 181 182 /* 183 * The high level of the driver never reads status registers directly 184 * because there would be too many side effects to handle conveniently. 185 * Instead, it reads copies of the registers stored here by the 186 * interrupt handler. 187 */ 188 u_char last_modem_status; /* last MSR read by intr handler */ 189 u_char prev_modem_status; /* last MSR handled by high level */ 190 191 u_char *ibuf; /* start of input buffer */ 192 u_char *ibufend; /* end of input buffer */ 193 u_char *ibufold; /* old input buffer, to be freed */ 194 u_char *ihighwater; /* threshold in input buffer */ 195 u_char *iptr; /* next free spot in input buffer */ 196 int ibufsize; /* size of ibuf (not include error bytes) */ 197 int ierroff; /* offset of error bytes in ibuf */ 198 199 struct lbq obufq; /* head of queue of output buffers */ 200 struct lbq obufs[2]; /* output buffers */ 201 202 int cy_align; /* index for register alignment */ 203 cy_addr cy_iobase; /* base address of this port's cyclom */ 204 cy_addr iobase; /* base address of this port's cd1400 */ 205 int mcr_rts_reg; /* cd1400 reg number of reg holding mcr_rts */ 206 207 struct tty *tp; /* cross reference */ 208 209 u_long bytes_in; /* statistics */ 210 u_long bytes_out; 211 u_int delta_error_counts[CE_NTYPES]; 212 u_long error_counts[CE_NTYPES]; 213 214 u_int recv_exception; /* exception chars received */ 215 u_int mdm; /* modem signal changes */ 216 #ifdef CyDebug 217 u_int start_count; /* no. of calls to cystart() */ 218 u_int start_real; /* no. of calls that did something */ 219 #endif 220 u_char car; /* CD1400 CAR shadow (if first unit in cd) */ 221 u_char channel_control;/* CD1400 CCR control command shadow */ 222 u_char cor[3]; /* CD1400 COR1-3 shadows */ 223 u_char intr_enable; /* CD1400 SRER shadow */ 224 225 /* 226 * Data area for output buffers. Someday we should build the output 227 * buffer queue without copying data. 228 */ 229 u_char obuf1[256]; 230 u_char obuf2[256]; 231 }; 232 233 devclass_t cy_devclass; 234 char cy_driver_name[] = "cy"; 235 236 static void cd1400_channel_cmd(struct com_s *com, int cmd); 237 static void cd1400_channel_cmd_wait(struct com_s *com); 238 static void cd_etc(struct com_s *com, int etc); 239 static int cd_getreg(struct com_s *com, int reg); 240 static void cd_setreg(struct com_s *com, int reg, int val); 241 static void cyinput(struct com_s *com); 242 static int cyparam(struct tty *tp, struct termios *t); 243 static void cypoll(void *arg); 244 static void cysettimeout(void); 245 static int cysetwater(struct com_s *com, speed_t speed); 246 static int cyspeed(speed_t speed, u_long cy_clock, int *prescaler_io); 247 static void cystart(struct tty *tp); 248 static void comstop(struct tty *tp, int rw); 249 static timeout_t cywakeup; 250 static void disc_optim(struct tty *tp, struct termios *t, 251 struct com_s *com); 252 253 static t_break_t cybreak; 254 static t_modem_t cymodem; 255 static t_open_t cyopen; 256 static t_close_t cyclose; 257 258 #ifdef CyDebug 259 void cystatus(int unit); 260 #endif 261 262 static struct mtx cy_lock; 263 static int cy_inited; 264 265 /* table and macro for fast conversion from a unit number to its com struct */ 266 static struct com_s *p_cy_addr[NPORTS]; 267 #define cy_addr(unit) (p_cy_addr[unit]) 268 269 static u_int cy_events; /* input chars + weighted output completions */ 270 static void *cy_fast_ih; 271 static void *cy_slow_ih; 272 static int cy_timeout; 273 static int cy_timeouts_until_log; 274 static struct callout_handle cy_timeout_handle 275 = CALLOUT_HANDLE_INITIALIZER(&cy_timeout_handle); 276 277 #ifdef CyDebug 278 static u_int cd_inbs; 279 static u_int cy_inbs; 280 static u_int cd_outbs; 281 static u_int cy_outbs; 282 static u_int cy_svrr_probes; 283 static u_int cy_timeouts; 284 #endif 285 286 static int cy_chip_offset[] = { 287 0x0000, 0x0400, 0x0800, 0x0c00, 0x0200, 0x0600, 0x0a00, 0x0e00, 288 }; 289 static int cy_nr_cd1400s[NCY]; 290 static int cy_total_devices; 291 #undef RxFifoThreshold 292 static int volatile RxFifoThreshold = (CD1400_RX_FIFO_SIZE / 2); 293 294 int 295 cy_units(cy_addr cy_iobase, int cy_align) 296 { 297 int cyu; 298 u_char firmware_version; 299 int i; 300 cy_addr iobase; 301 302 for (cyu = 0; cyu < CY_MAX_CD1400s; ++cyu) { 303 iobase = cy_iobase + (cy_chip_offset[cyu] << cy_align); 304 305 /* wait for chip to become ready for new command */ 306 for (i = 0; i < 10; i++) { 307 DELAY(50); 308 if (!cd_inb(iobase, CD1400_CCR, cy_align)) 309 break; 310 } 311 312 /* clear the GFRCR register */ 313 cd_outb(iobase, CD1400_GFRCR, cy_align, 0); 314 315 /* issue a reset command */ 316 cd_outb(iobase, CD1400_CCR, cy_align, 317 CD1400_CCR_CMDRESET | CD1400_CCR_FULLRESET); 318 319 /* XXX bogus initialization to avoid a gcc bug/warning. */ 320 firmware_version = 0; 321 322 /* wait for the CD1400 to initialize itself */ 323 for (i = 0; i < 200; i++) { 324 DELAY(50); 325 326 /* retrieve firmware version */ 327 firmware_version = cd_inb(iobase, CD1400_GFRCR, 328 cy_align); 329 if ((firmware_version & 0xf0) == 0x40) 330 break; 331 } 332 333 /* 334 * Anything in the 0x40-0x4F range is fine. 335 * If one CD1400 is bad then we don't support higher 336 * numbered good ones on this board. 337 */ 338 if ((firmware_version & 0xf0) != 0x40) 339 break; 340 } 341 return (cyu); 342 } 343 344 void * 345 cyattach_common(cy_addr cy_iobase, int cy_align) 346 { 347 int adapter; 348 int cyu; 349 u_char firmware_version; 350 cy_addr iobase; 351 int ncyu; 352 int unit; 353 struct tty *tp; 354 355 while (cy_inited != 2) 356 if (atomic_cmpset_int(&cy_inited, 0, 1)) { 357 mtx_init(&cy_lock, cy_driver_name, NULL, MTX_SPIN); 358 atomic_store_rel_int(&cy_inited, 2); 359 } 360 361 adapter = cy_total_devices; 362 if ((u_int)adapter >= NCY) { 363 printf( 364 "cy%d: can't attach adapter: insufficient cy devices configured\n", 365 adapter); 366 return (NULL); 367 } 368 ncyu = cy_units(cy_iobase, cy_align); 369 if (ncyu == 0) 370 return (NULL); 371 cy_nr_cd1400s[adapter] = ncyu; 372 cy_total_devices++; 373 374 unit = adapter * CY_MAX_PORTS; 375 for (cyu = 0; cyu < ncyu; ++cyu) { 376 int cdu; 377 378 iobase = (cy_addr) (cy_iobase 379 + (cy_chip_offset[cyu] << cy_align)); 380 firmware_version = cd_inb(iobase, CD1400_GFRCR, cy_align); 381 382 /* Set up a receive timeout period of than 1+ ms. */ 383 cd_outb(iobase, CD1400_PPR, cy_align, 384 howmany(CY_CLOCK(firmware_version) 385 / CD1400_PPR_PRESCALER, 1000)); 386 387 for (cdu = 0; cdu < CD1400_NO_OF_CHANNELS; ++cdu, ++unit) { 388 struct com_s *com; 389 int s; 390 391 com = malloc(sizeof *com, M_DEVBUF, M_NOWAIT | M_ZERO); 392 if (com == NULL) 393 break; 394 com->unit = unit; 395 com->gfrcr_image = firmware_version; 396 if (CY_RTS_DTR_SWAPPED(firmware_version)) { 397 com->mcr_dtr = CD1400_MSVR1_RTS; 398 com->mcr_rts = CD1400_MSVR2_DTR; 399 com->mcr_rts_reg = CD1400_MSVR2; 400 } else { 401 com->mcr_dtr = CD1400_MSVR2_DTR; 402 com->mcr_rts = CD1400_MSVR1_RTS; 403 com->mcr_rts_reg = CD1400_MSVR1; 404 } 405 com->obufs[0].l_head = com->obuf1; 406 com->obufs[1].l_head = com->obuf2; 407 408 com->cy_align = cy_align; 409 com->cy_iobase = cy_iobase; 410 com->iobase = iobase; 411 com->car = ~CD1400_CAR_CHAN; 412 413 tp = com->tp = ttyalloc(); 414 tp->t_open = cyopen; 415 tp->t_close = cyclose; 416 tp->t_oproc = cystart; 417 tp->t_stop = comstop; 418 tp->t_param = cyparam; 419 tp->t_break = cybreak; 420 tp->t_modem = cymodem; 421 tp->t_sc = com; 422 423 if (cysetwater(com, tp->t_init_in.c_ispeed) != 0) { 424 free(com, M_DEVBUF); 425 return (NULL); 426 } 427 428 s = spltty(); 429 cy_addr(unit) = com; 430 splx(s); 431 432 if (cy_fast_ih == NULL) { 433 swi_add(&tty_intr_event, "cy", cypoll, NULL, SWI_TTY, 0, 434 &cy_fast_ih); 435 swi_add(&clk_intr_event, "cy", cypoll, NULL, SWI_CLOCK, 0, 436 &cy_slow_ih); 437 } 438 ttycreate(tp, TS_CALLOUT, "c%r%r", 439 adapter, unit % CY_MAX_PORTS); 440 } 441 } 442 443 /* ensure an edge for the next interrupt */ 444 cy_outb(cy_iobase, CY_CLEAR_INTR, cy_align, 0); 445 446 return (cy_addr(adapter * CY_MAX_PORTS)); 447 } 448 449 static int 450 cyopen(struct tty *tp, struct cdev *dev) 451 { 452 struct com_s *com; 453 int s; 454 455 com = tp->t_sc; 456 s = spltty(); 457 /* 458 * We jump to this label after all non-interrupted sleeps to pick 459 * up any changes of the device state. 460 */ 461 462 /* Encode per-board unit in LIVR for access in intr routines. */ 463 cd_setreg(com, CD1400_LIVR, 464 (com->unit & CD1400_xIVR_CHAN) << CD1400_xIVR_CHAN_SHIFT); 465 466 /* 467 * Flush fifos. This requires a full channel reset which 468 * also disables the transmitter and receiver. Recover 469 * from this. 470 */ 471 cd1400_channel_cmd(com, 472 CD1400_CCR_CMDRESET | CD1400_CCR_CHANRESET); 473 cd1400_channel_cmd(com, com->channel_control); 474 475 critical_enter(); 476 COM_LOCK(); 477 com->prev_modem_status = com->last_modem_status 478 = cd_getreg(com, CD1400_MSVR2); 479 cd_setreg(com, CD1400_SRER, 480 com->intr_enable 481 = CD1400_SRER_MDMCH | CD1400_SRER_RXDATA); 482 COM_UNLOCK(); 483 critical_exit(); 484 cysettimeout(); 485 return (0); 486 } 487 488 489 static void 490 cyclose(struct tty *tp) 491 { 492 cy_addr iobase; 493 struct com_s *com; 494 int s; 495 int unit; 496 497 com = tp->t_sc; 498 unit = com->unit; 499 iobase = com->iobase; 500 s = spltty(); 501 /* XXX */ 502 critical_enter(); 503 COM_LOCK(); 504 com->etc = ETC_NONE; 505 cd_setreg(com, CD1400_COR2, com->cor[1] &= ~CD1400_COR2_ETC); 506 COM_UNLOCK(); 507 critical_exit(); 508 cd_etc(com, CD1400_ETC_STOPBREAK); 509 cd1400_channel_cmd(com, CD1400_CCR_CMDRESET | CD1400_CCR_FTF); 510 511 { 512 critical_enter(); 513 COM_LOCK(); 514 cd_setreg(com, CD1400_SRER, com->intr_enable = 0); 515 COM_UNLOCK(); 516 critical_exit(); 517 tp = com->tp; 518 if ((tp->t_cflag & HUPCL) 519 /* 520 * XXX we will miss any carrier drop between here and the 521 * next open. Perhaps we should watch DCD even when the 522 * port is closed; it is not sufficient to check it at 523 * the next open because it might go up and down while 524 * we're not watching. 525 */ 526 || (!tp->t_actout 527 && !(com->prev_modem_status & CD1400_MSVR2_CD) 528 && !(tp->t_init_in.c_cflag & CLOCAL)) 529 || !(tp->t_state & TS_ISOPEN)) { 530 (void)cymodem(tp, 0, SER_DTR); 531 532 /* Disable receiver (leave transmitter enabled). */ 533 com->channel_control = CD1400_CCR_CMDCHANCTL 534 | CD1400_CCR_XMTEN 535 | CD1400_CCR_RCVDIS; 536 cd1400_channel_cmd(com, com->channel_control); 537 538 ttydtrwaitstart(tp); 539 } 540 } 541 tp->t_actout = FALSE; 542 wakeup(&tp->t_actout); 543 wakeup(TSA_CARR_ON(tp)); /* restart any wopeners */ 544 splx(s); 545 } 546 547 /* 548 * This function: 549 * a) needs to be called with COM_LOCK() held, and 550 * b) needs to return with COM_LOCK() held. 551 */ 552 static void 553 cyinput(struct com_s *com) 554 { 555 u_char *buf; 556 int incc; 557 u_char line_status; 558 int recv_data; 559 struct tty *tp; 560 561 buf = com->ibuf; 562 tp = com->tp; 563 if (!(tp->t_state & TS_ISOPEN)) { 564 cy_events -= (com->iptr - com->ibuf); 565 com->iptr = com->ibuf; 566 return; 567 } 568 if (tp->t_state & TS_CAN_BYPASS_L_RINT) { 569 /* 570 * Avoid the grotesquely inefficient lineswitch routine 571 * (ttyinput) in "raw" mode. It usually takes about 450 572 * instructions (that's without canonical processing or echo!). 573 * slinput is reasonably fast (usually 40 instructions plus 574 * call overhead). 575 */ 576 577 do { 578 /* 579 * This may look odd, but it is using save-and-enable 580 * semantics instead of the save-and-disable semantics 581 * that are used everywhere else. 582 */ 583 COM_UNLOCK(); 584 critical_exit(); 585 incc = com->iptr - buf; 586 if (tp->t_rawq.c_cc + incc > tp->t_ihiwat 587 && (com->state & CS_RTS_IFLOW 588 || tp->t_iflag & IXOFF) 589 && !(tp->t_state & TS_TBLOCK)) 590 ttyblock(tp); 591 com->delta_error_counts[CE_TTY_BUF_OVERFLOW] 592 += b_to_q((char *)buf, incc, &tp->t_rawq); 593 buf += incc; 594 tk_nin += incc; 595 tk_rawcc += incc; 596 tp->t_rawcc += incc; 597 ttwakeup(tp); 598 if (tp->t_state & TS_TTSTOP 599 && (tp->t_iflag & IXANY 600 || tp->t_cc[VSTART] == tp->t_cc[VSTOP])) { 601 tp->t_state &= ~TS_TTSTOP; 602 tp->t_lflag &= ~FLUSHO; 603 cystart(tp); 604 } 605 critical_enter(); 606 COM_LOCK(); 607 } while (buf < com->iptr); 608 } else { 609 do { 610 /* 611 * This may look odd, but it is using save-and-enable 612 * semantics instead of the save-and-disable semantics 613 * that are used everywhere else. 614 */ 615 COM_UNLOCK(); 616 critical_exit(); 617 line_status = buf[com->ierroff]; 618 recv_data = *buf++; 619 if (line_status 620 & (CD1400_RDSR_BREAK | CD1400_RDSR_FE | CD1400_RDSR_OE | CD1400_RDSR_PE)) { 621 if (line_status & CD1400_RDSR_BREAK) 622 recv_data |= TTY_BI; 623 if (line_status & CD1400_RDSR_FE) 624 recv_data |= TTY_FE; 625 if (line_status & CD1400_RDSR_OE) 626 recv_data |= TTY_OE; 627 if (line_status & CD1400_RDSR_PE) 628 recv_data |= TTY_PE; 629 } 630 ttyld_rint(tp, recv_data); 631 critical_enter(); 632 COM_LOCK(); 633 } while (buf < com->iptr); 634 } 635 cy_events -= (com->iptr - com->ibuf); 636 com->iptr = com->ibuf; 637 638 /* 639 * There is now room for another low-level buffer full of input, 640 * so enable RTS if it is now disabled and there is room in the 641 * high-level buffer. 642 */ 643 if ((com->state & CS_RTS_IFLOW) && !(com->mcr_image & com->mcr_rts) && 644 !(tp->t_state & TS_TBLOCK)) 645 cd_setreg(com, com->mcr_rts_reg, 646 com->mcr_image |= com->mcr_rts); 647 } 648 649 int 650 cyintr(void *vcom) 651 { 652 struct com_s *basecom; 653 int baseu; 654 int cy_align; 655 cy_addr cy_iobase; 656 int cyu; 657 cy_addr iobase; 658 u_char status; 659 int unit; 660 661 COM_LOCK(); /* XXX could this be placed down lower in the loop? */ 662 663 basecom = (struct com_s *)vcom; 664 baseu = basecom->unit; 665 cy_align = basecom->cy_align; 666 cy_iobase = basecom->cy_iobase; 667 unit = baseu / CY_MAX_PORTS; 668 669 /* check each CD1400 in turn */ 670 for (cyu = 0; cyu < cy_nr_cd1400s[unit]; ++cyu) { 671 iobase = (cy_addr) (cy_iobase 672 + (cy_chip_offset[cyu] << cy_align)); 673 /* poll to see if it has any work */ 674 status = cd_inb(iobase, CD1400_SVRR, cy_align); 675 if (status == 0) 676 continue; // XXX - FILTER_STRAY? 677 #ifdef CyDebug 678 ++cy_svrr_probes; 679 #endif 680 /* service requests as appropriate, giving priority to RX */ 681 if (status & CD1400_SVRR_RXRDY) { 682 struct com_s *com; 683 u_int count; 684 u_char *ioptr; 685 u_char line_status; 686 u_char recv_data; 687 u_char serv_type; 688 #ifdef PollMode 689 u_char save_rir; 690 #endif 691 692 #ifdef PollMode 693 save_rir = cd_inb(iobase, CD1400_RIR, cy_align); 694 695 /* enter rx service */ 696 cd_outb(iobase, CD1400_CAR, cy_align, save_rir); 697 cy_addr(baseu + cyu * CD1400_NO_OF_CHANNELS)->car 698 = save_rir & CD1400_CAR_CHAN; 699 700 serv_type = cd_inb(iobase, CD1400_RIVR, cy_align); 701 com = cy_addr(baseu 702 + ((serv_type >> CD1400_xIVR_CHAN_SHIFT) 703 & CD1400_xIVR_CHAN)); 704 #else 705 /* ack receive service */ 706 serv_type = cy_inb(iobase, CY8_SVCACKR, cy_align); 707 708 com = cy_addr(baseu + 709 + ((serv_type >> CD1400_xIVR_CHAN_SHIFT) 710 & CD1400_xIVR_CHAN)); 711 #endif 712 713 if (serv_type & CD1400_RIVR_EXCEPTION) { 714 ++com->recv_exception; 715 line_status = cd_inb(iobase, CD1400_RDSR, cy_align); 716 /* break/unnattached error bits or real input? */ 717 recv_data = cd_inb(iobase, CD1400_RDSR, cy_align); 718 #ifndef SOFT_HOTCHAR 719 if (line_status & CD1400_RDSR_SPECIAL 720 && com->tp->t_hotchar != 0) 721 swi_sched(cy_fast_ih, 0); 722 723 #endif 724 #if 1 /* XXX "intelligent" PFO error handling would break O error handling */ 725 if (line_status & (CD1400_RDSR_PE|CD1400_RDSR_FE|CD1400_RDSR_BREAK)) { 726 /* 727 Don't store PE if IGNPAR and BI if IGNBRK, 728 this hack allows "raw" tty optimization 729 works even if IGN* is set. 730 */ 731 if ( com->tp == NULL 732 || !(com->tp->t_state & TS_ISOPEN) 733 || ((line_status & (CD1400_RDSR_PE|CD1400_RDSR_FE)) 734 && (com->tp->t_iflag & IGNPAR)) 735 || ((line_status & CD1400_RDSR_BREAK) 736 && (com->tp->t_iflag & IGNBRK))) 737 goto cont; 738 if ( (line_status & (CD1400_RDSR_PE|CD1400_RDSR_FE)) 739 && (com->tp->t_state & TS_CAN_BYPASS_L_RINT) 740 && ((line_status & CD1400_RDSR_FE) 741 || ((line_status & CD1400_RDSR_PE) 742 && (com->tp->t_iflag & INPCK)))) 743 recv_data = 0; 744 } 745 #endif /* 1 */ 746 ++com->bytes_in; 747 #ifdef SOFT_HOTCHAR 748 if (com->tp->t_hotchar != 0 && recv_data == com->tp->t_hotchar) 749 swi_sched(cy_fast_ih, 0); 750 #endif 751 ioptr = com->iptr; 752 if (ioptr >= com->ibufend) 753 CE_RECORD(com, CE_INTERRUPT_BUF_OVERFLOW); 754 else { 755 if (com->tp != NULL && com->tp->t_do_timestamp) 756 microtime(&com->tp->t_timestamp); 757 ++cy_events; 758 ioptr[0] = recv_data; 759 ioptr[com->ierroff] = line_status; 760 com->iptr = ++ioptr; 761 if (ioptr == com->ihighwater 762 && com->state & CS_RTS_IFLOW) 763 cd_outb(iobase, com->mcr_rts_reg, 764 cy_align, 765 com->mcr_image &= 766 ~com->mcr_rts); 767 if (line_status & CD1400_RDSR_OE) 768 CE_RECORD(com, CE_OVERRUN); 769 } 770 goto cont; 771 } else { 772 int ifree; 773 774 count = cd_inb(iobase, CD1400_RDCR, cy_align); 775 if (!count) 776 goto cont; 777 com->bytes_in += count; 778 ioptr = com->iptr; 779 ifree = com->ibufend - ioptr; 780 if (count > ifree) { 781 count -= ifree; 782 cy_events += ifree; 783 if (ifree != 0) { 784 if (com->tp != NULL && com->tp->t_do_timestamp) 785 microtime(&com->tp->t_timestamp); 786 do { 787 recv_data = cd_inb(iobase, 788 CD1400_RDSR, 789 cy_align); 790 #ifdef SOFT_HOTCHAR 791 if (com->tp->t_hotchar != 0 792 && recv_data 793 == com->tp->t_hotchar) 794 swi_sched(cy_fast_ih, 795 0); 796 #endif 797 ioptr[0] = recv_data; 798 ioptr[com->ierroff] = 0; 799 ++ioptr; 800 } while (--ifree != 0); 801 } 802 com->delta_error_counts 803 [CE_INTERRUPT_BUF_OVERFLOW] += count; 804 do { 805 recv_data = cd_inb(iobase, CD1400_RDSR, 806 cy_align); 807 #ifdef SOFT_HOTCHAR 808 if (com->tp->t_hotchar != 0 809 && recv_data == com->tp->t_hotchar) 810 swi_sched(cy_fast_ih, 0); 811 #endif 812 } while (--count != 0); 813 } else { 814 if (com->tp != NULL && com->tp->t_do_timestamp) 815 microtime(&com->tp->t_timestamp); 816 if (ioptr <= com->ihighwater 817 && ioptr + count > com->ihighwater 818 && com->state & CS_RTS_IFLOW) 819 cd_outb(iobase, com->mcr_rts_reg, 820 cy_align, 821 com->mcr_image 822 &= ~com->mcr_rts); 823 cy_events += count; 824 do { 825 recv_data = cd_inb(iobase, CD1400_RDSR, 826 cy_align); 827 #ifdef SOFT_HOTCHAR 828 if (com->tp->t_hotchar != 0 829 && recv_data == com->tp->t_hotchar) 830 swi_sched(cy_fast_ih, 0); 831 #endif 832 ioptr[0] = recv_data; 833 ioptr[com->ierroff] = 0; 834 ++ioptr; 835 } while (--count != 0); 836 } 837 com->iptr = ioptr; 838 } 839 cont: 840 841 /* terminate service context */ 842 #ifdef PollMode 843 cd_outb(iobase, CD1400_RIR, cy_align, 844 save_rir 845 & ~(CD1400_RIR_RDIREQ | CD1400_RIR_RBUSY)); 846 #else 847 cd_outb(iobase, CD1400_EOSRR, cy_align, 0); 848 #endif 849 } 850 if (status & CD1400_SVRR_MDMCH) { 851 struct com_s *com; 852 u_char modem_status; 853 #ifdef PollMode 854 u_char save_mir; 855 #else 856 u_char vector; 857 #endif 858 859 #ifdef PollMode 860 save_mir = cd_inb(iobase, CD1400_MIR, cy_align); 861 862 /* enter modem service */ 863 cd_outb(iobase, CD1400_CAR, cy_align, save_mir); 864 cy_addr(baseu + cyu * CD1400_NO_OF_CHANNELS)->car 865 = save_mir & CD1400_CAR_CHAN; 866 867 com = cy_addr(baseu + cyu * CD1400_NO_OF_CHANNELS 868 + (save_mir & CD1400_MIR_CHAN)); 869 #else 870 /* ack modem service */ 871 vector = cy_inb(iobase, CY8_SVCACKM, cy_align); 872 873 com = cy_addr(baseu 874 + ((vector >> CD1400_xIVR_CHAN_SHIFT) 875 & CD1400_xIVR_CHAN)); 876 #endif 877 ++com->mdm; 878 modem_status = cd_inb(iobase, CD1400_MSVR2, cy_align); 879 if (modem_status != com->last_modem_status) { 880 /* 881 * Schedule high level to handle DCD changes. Note 882 * that we don't use the delta bits anywhere. Some 883 * UARTs mess them up, and it's easy to remember the 884 * previous bits and calculate the delta. 885 */ 886 com->last_modem_status = modem_status; 887 if (!(com->state & CS_CHECKMSR)) { 888 cy_events += LOTS_OF_EVENTS; 889 com->state |= CS_CHECKMSR; 890 swi_sched(cy_fast_ih, 0); 891 } 892 893 #ifdef SOFT_CTS_OFLOW 894 /* handle CTS change immediately for crisp flow ctl */ 895 if (com->state & CS_CTS_OFLOW) { 896 if (modem_status & CD1400_MSVR2_CTS) { 897 com->state |= CS_ODEVREADY; 898 if (com->state >= (CS_BUSY | CS_TTGO 899 | CS_ODEVREADY) 900 && !(com->intr_enable 901 & CD1400_SRER_TXRDY)) 902 cd_outb(iobase, CD1400_SRER, 903 cy_align, 904 com->intr_enable 905 = com->intr_enable 906 & ~CD1400_SRER_TXMPTY 907 | CD1400_SRER_TXRDY); 908 } else { 909 com->state &= ~CS_ODEVREADY; 910 if (com->intr_enable 911 & CD1400_SRER_TXRDY) 912 cd_outb(iobase, CD1400_SRER, 913 cy_align, 914 com->intr_enable 915 = com->intr_enable 916 & ~CD1400_SRER_TXRDY 917 | CD1400_SRER_TXMPTY); 918 } 919 } 920 #endif 921 } 922 923 /* terminate service context */ 924 #ifdef PollMode 925 cd_outb(iobase, CD1400_MIR, cy_align, 926 save_mir 927 & ~(CD1400_MIR_RDIREQ | CD1400_MIR_RBUSY)); 928 #else 929 cd_outb(iobase, CD1400_EOSRR, cy_align, 0); 930 #endif 931 } 932 if (status & CD1400_SVRR_TXRDY) { 933 struct com_s *com; 934 #ifdef PollMode 935 u_char save_tir; 936 #else 937 u_char vector; 938 #endif 939 940 #ifdef PollMode 941 save_tir = cd_inb(iobase, CD1400_TIR, cy_align); 942 943 /* enter tx service */ 944 cd_outb(iobase, CD1400_CAR, cy_align, save_tir); 945 cy_addr(baseu + cyu * CD1400_NO_OF_CHANNELS)->car 946 = save_tir & CD1400_CAR_CHAN; 947 948 com = cy_addr(baseu 949 + cyu * CD1400_NO_OF_CHANNELS 950 + (save_tir & CD1400_TIR_CHAN)); 951 #else 952 /* ack transmit service */ 953 vector = cy_inb(iobase, CY8_SVCACKT, cy_align); 954 955 com = cy_addr(baseu 956 + ((vector >> CD1400_xIVR_CHAN_SHIFT) 957 & CD1400_xIVR_CHAN)); 958 #endif 959 960 if (com->etc != ETC_NONE) { 961 if (com->intr_enable & CD1400_SRER_TXRDY) { 962 /* 963 * Here due to sloppy SRER_TXRDY 964 * enabling. Ignore. Come back when 965 * tx is empty. 966 */ 967 cd_outb(iobase, CD1400_SRER, cy_align, 968 com->intr_enable 969 = (com->intr_enable 970 & ~CD1400_SRER_TXRDY) 971 | CD1400_SRER_TXMPTY); 972 goto terminate_tx_service; 973 } 974 switch (com->etc) { 975 case CD1400_ETC_SENDBREAK: 976 case CD1400_ETC_STOPBREAK: 977 /* 978 * Start the command. Come back on 979 * next tx empty interrupt, hopefully 980 * after command has been executed. 981 */ 982 cd_outb(iobase, CD1400_COR2, cy_align, 983 com->cor[1] |= CD1400_COR2_ETC); 984 cd_outb(iobase, CD1400_TDR, cy_align, 985 CD1400_ETC_CMD); 986 cd_outb(iobase, CD1400_TDR, cy_align, 987 com->etc); 988 if (com->etc == CD1400_ETC_SENDBREAK) 989 com->etc = ETC_BREAK_STARTING; 990 else 991 com->etc = ETC_BREAK_ENDING; 992 goto terminate_tx_service; 993 case ETC_BREAK_STARTING: 994 /* 995 * BREAK is now on. Continue with 996 * SRER_TXMPTY processing, hopefully 997 * don't come back. 998 */ 999 com->etc = ETC_BREAK_STARTED; 1000 break; 1001 case ETC_BREAK_STARTED: 1002 /* 1003 * Came back due to sloppy SRER_TXMPTY 1004 * enabling. Hope again. 1005 */ 1006 break; 1007 case ETC_BREAK_ENDING: 1008 /* 1009 * BREAK is now off. Continue with 1010 * SRER_TXMPTY processing and don't 1011 * come back. The SWI handler will 1012 * restart tx interrupts if necessary. 1013 */ 1014 cd_outb(iobase, CD1400_COR2, cy_align, 1015 com->cor[1] 1016 &= ~CD1400_COR2_ETC); 1017 com->etc = ETC_BREAK_ENDED; 1018 if (!(com->state & CS_ODONE)) { 1019 cy_events += LOTS_OF_EVENTS; 1020 com->state |= CS_ODONE; 1021 swi_sched(cy_fast_ih, 0); 1022 } 1023 break; 1024 case ETC_BREAK_ENDED: 1025 /* 1026 * Shouldn't get here. Hope again. 1027 */ 1028 break; 1029 } 1030 } 1031 if (com->intr_enable & CD1400_SRER_TXMPTY) { 1032 if (!(com->extra_state & CSE_ODONE)) { 1033 cy_events += LOTS_OF_EVENTS; 1034 com->extra_state |= CSE_ODONE; 1035 swi_sched(cy_fast_ih, 0); 1036 } 1037 cd_outb(iobase, CD1400_SRER, cy_align, 1038 com->intr_enable 1039 &= ~CD1400_SRER_TXMPTY); 1040 goto terminate_tx_service; 1041 } 1042 if (com->state >= (CS_BUSY | CS_TTGO | CS_ODEVREADY)) { 1043 u_char *ioptr; 1044 u_int ocount; 1045 1046 ioptr = com->obufq.l_head; 1047 ocount = com->obufq.l_tail - ioptr; 1048 if (ocount > CD1400_TX_FIFO_SIZE) 1049 ocount = CD1400_TX_FIFO_SIZE; 1050 com->bytes_out += ocount; 1051 do 1052 cd_outb(iobase, CD1400_TDR, cy_align, 1053 *ioptr++); 1054 while (--ocount != 0); 1055 com->obufq.l_head = ioptr; 1056 if (ioptr >= com->obufq.l_tail) { 1057 struct lbq *qp; 1058 1059 qp = com->obufq.l_next; 1060 qp->l_queued = FALSE; 1061 qp = qp->l_next; 1062 if (qp != NULL) { 1063 com->obufq.l_head = qp->l_head; 1064 com->obufq.l_tail = qp->l_tail; 1065 com->obufq.l_next = qp; 1066 } else { 1067 /* output just completed */ 1068 com->state &= ~CS_BUSY; 1069 1070 /* 1071 * The setting of CSE_ODONE may be 1072 * stale here. We currently only 1073 * use it when CS_BUSY is set, and 1074 * fixing it when we clear CS_BUSY 1075 * is easiest. 1076 */ 1077 if (com->extra_state & CSE_ODONE) { 1078 cy_events -= LOTS_OF_EVENTS; 1079 com->extra_state &= ~CSE_ODONE; 1080 } 1081 1082 cd_outb(iobase, CD1400_SRER, cy_align, 1083 com->intr_enable 1084 = (com->intr_enable 1085 & ~CD1400_SRER_TXRDY) 1086 | CD1400_SRER_TXMPTY); 1087 } 1088 if (!(com->state & CS_ODONE)) { 1089 cy_events += LOTS_OF_EVENTS; 1090 com->state |= CS_ODONE; 1091 1092 /* handle at high level ASAP */ 1093 swi_sched(cy_fast_ih, 0); 1094 } 1095 } 1096 } 1097 1098 /* terminate service context */ 1099 terminate_tx_service: 1100 #ifdef PollMode 1101 cd_outb(iobase, CD1400_TIR, cy_align, 1102 save_tir 1103 & ~(CD1400_TIR_RDIREQ | CD1400_TIR_RBUSY)); 1104 #else 1105 cd_outb(iobase, CD1400_EOSRR, cy_align, 0); 1106 #endif 1107 } 1108 } 1109 1110 /* ensure an edge for the next interrupt */ 1111 cy_outb(cy_iobase, CY_CLEAR_INTR, cy_align, 0); 1112 1113 swi_sched(cy_slow_ih, SWI_DELAY); 1114 1115 COM_UNLOCK(); 1116 return (FILTER_HANDLED); 1117 } 1118 1119 static void 1120 cybreak(struct tty *tp, int sig) 1121 { 1122 struct com_s *com; 1123 1124 com = tp->t_sc; 1125 if (sig) 1126 cd_etc(com, CD1400_ETC_SENDBREAK); 1127 else 1128 cd_etc(com, CD1400_ETC_STOPBREAK); 1129 } 1130 1131 static void 1132 cypoll(void *arg) 1133 { 1134 int unit; 1135 1136 #ifdef CyDebug 1137 ++cy_timeouts; 1138 #endif 1139 if (cy_events == 0) 1140 return; 1141 repeat: 1142 for (unit = 0; unit < NPORTS; ++unit) { 1143 struct com_s *com; 1144 int incc; 1145 struct tty *tp; 1146 1147 com = cy_addr(unit); 1148 if (com == NULL) 1149 continue; 1150 tp = com->tp; 1151 if (tp == NULL) { 1152 /* 1153 * XXX forget any events related to closed devices 1154 * (actually never opened devices) so that we don't 1155 * loop. 1156 */ 1157 critical_enter(); 1158 COM_LOCK(); 1159 incc = com->iptr - com->ibuf; 1160 com->iptr = com->ibuf; 1161 if (com->state & CS_CHECKMSR) { 1162 incc += LOTS_OF_EVENTS; 1163 com->state &= ~CS_CHECKMSR; 1164 } 1165 cy_events -= incc; 1166 COM_UNLOCK(); 1167 critical_exit(); 1168 if (incc != 0) 1169 log(LOG_DEBUG, 1170 "cy%d: %d events for device with no tp\n", 1171 unit, incc); 1172 continue; 1173 } 1174 if (com->iptr != com->ibuf) { 1175 critical_enter(); 1176 COM_LOCK(); 1177 cyinput(com); 1178 COM_UNLOCK(); 1179 critical_exit(); 1180 } 1181 if (com->state & CS_CHECKMSR) { 1182 u_char delta_modem_status; 1183 1184 critical_enter(); 1185 COM_LOCK(); 1186 cyinput(com); 1187 delta_modem_status = com->last_modem_status 1188 ^ com->prev_modem_status; 1189 com->prev_modem_status = com->last_modem_status; 1190 cy_events -= LOTS_OF_EVENTS; 1191 com->state &= ~CS_CHECKMSR; 1192 COM_UNLOCK(); 1193 critical_exit(); 1194 if (delta_modem_status & CD1400_MSVR2_CD) 1195 ttyld_modem(tp, 1196 com->prev_modem_status & CD1400_MSVR2_CD); 1197 } 1198 if (com->extra_state & CSE_ODONE) { 1199 critical_enter(); 1200 COM_LOCK(); 1201 cy_events -= LOTS_OF_EVENTS; 1202 com->extra_state &= ~CSE_ODONE; 1203 COM_UNLOCK(); 1204 critical_exit(); 1205 if (!(com->state & CS_BUSY)) { 1206 tp->t_state &= ~TS_BUSY; 1207 ttwwakeup(com->tp); 1208 } 1209 if (com->etc != ETC_NONE) { 1210 if (com->etc == ETC_BREAK_ENDED) 1211 com->etc = ETC_NONE; 1212 wakeup(&com->etc); 1213 } 1214 } 1215 if (com->state & CS_ODONE) { 1216 critical_enter(); 1217 COM_LOCK(); 1218 cy_events -= LOTS_OF_EVENTS; 1219 com->state &= ~CS_ODONE; 1220 COM_UNLOCK(); 1221 critical_exit(); 1222 ttyld_start(tp); 1223 } 1224 if (cy_events == 0) 1225 break; 1226 } 1227 if (cy_events >= LOTS_OF_EVENTS) 1228 goto repeat; 1229 } 1230 1231 static int 1232 cyparam(struct tty *tp, struct termios *t) 1233 { 1234 int bits; 1235 int cflag; 1236 struct com_s *com; 1237 u_char cor_change; 1238 u_long cy_clock; 1239 int idivisor; 1240 int iflag; 1241 int iprescaler; 1242 int itimeout; 1243 int odivisor; 1244 int oprescaler; 1245 u_char opt; 1246 int s; 1247 1248 com = tp->t_sc; 1249 1250 /* check requested parameters */ 1251 cy_clock = CY_CLOCK(com->gfrcr_image); 1252 idivisor = cyspeed(t->c_ispeed, cy_clock, &iprescaler); 1253 if (idivisor <= 0) 1254 return (EINVAL); 1255 odivisor = cyspeed(t->c_ospeed != 0 ? t->c_ospeed : tp->t_ospeed, 1256 cy_clock, &oprescaler); 1257 if (odivisor <= 0) 1258 return (EINVAL); 1259 1260 /* parameters are OK, convert them to the com struct and the device */ 1261 s = spltty(); 1262 if (t->c_ospeed == 0) 1263 (void)cymodem(tp, 0, SER_DTR); 1264 else 1265 (void)cymodem(tp, SER_DTR, 0); 1266 1267 (void) cysetwater(com, t->c_ispeed); 1268 1269 /* XXX we don't actually change the speed atomically. */ 1270 1271 cd_setreg(com, CD1400_RBPR, idivisor); 1272 cd_setreg(com, CD1400_RCOR, iprescaler); 1273 cd_setreg(com, CD1400_TBPR, odivisor); 1274 cd_setreg(com, CD1400_TCOR, oprescaler); 1275 1276 /* 1277 * channel control 1278 * receiver enable 1279 * transmitter enable (always set) 1280 */ 1281 cflag = t->c_cflag; 1282 opt = CD1400_CCR_CMDCHANCTL | CD1400_CCR_XMTEN 1283 | (cflag & CREAD ? CD1400_CCR_RCVEN : CD1400_CCR_RCVDIS); 1284 if (opt != com->channel_control) { 1285 com->channel_control = opt; 1286 cd1400_channel_cmd(com, opt); 1287 } 1288 1289 #ifdef Smarts 1290 /* set special chars */ 1291 /* XXX if one is _POSIX_VDISABLE, can't use some others */ 1292 if (t->c_cc[VSTOP] != _POSIX_VDISABLE) 1293 cd_setreg(com, CD1400_SCHR1, t->c_cc[VSTOP]); 1294 if (t->c_cc[VSTART] != _POSIX_VDISABLE) 1295 cd_setreg(com, CD1400_SCHR2, t->c_cc[VSTART]); 1296 if (t->c_cc[VINTR] != _POSIX_VDISABLE) 1297 cd_setreg(com, CD1400_SCHR3, t->c_cc[VINTR]); 1298 if (t->c_cc[VSUSP] != _POSIX_VDISABLE) 1299 cd_setreg(com, CD1400_SCHR4, t->c_cc[VSUSP]); 1300 #endif 1301 1302 /* 1303 * set channel option register 1 - 1304 * parity mode 1305 * stop bits 1306 * char length 1307 */ 1308 opt = 0; 1309 /* parity */ 1310 if (cflag & PARENB) { 1311 if (cflag & PARODD) 1312 opt |= CD1400_COR1_PARODD; 1313 opt |= CD1400_COR1_PARNORMAL; 1314 } 1315 iflag = t->c_iflag; 1316 if (!(iflag & INPCK)) 1317 opt |= CD1400_COR1_NOINPCK; 1318 bits = 1 + 1; 1319 /* stop bits */ 1320 if (cflag & CSTOPB) { 1321 ++bits; 1322 opt |= CD1400_COR1_STOP2; 1323 } 1324 /* char length */ 1325 switch (cflag & CSIZE) { 1326 case CS5: 1327 bits += 5; 1328 opt |= CD1400_COR1_CS5; 1329 break; 1330 case CS6: 1331 bits += 6; 1332 opt |= CD1400_COR1_CS6; 1333 break; 1334 case CS7: 1335 bits += 7; 1336 opt |= CD1400_COR1_CS7; 1337 break; 1338 default: 1339 bits += 8; 1340 opt |= CD1400_COR1_CS8; 1341 break; 1342 } 1343 cor_change = 0; 1344 if (opt != com->cor[0]) { 1345 cor_change |= CD1400_CCR_COR1; 1346 cd_setreg(com, CD1400_COR1, com->cor[0] = opt); 1347 } 1348 1349 /* 1350 * Set receive time-out period, normally to max(one char time, 5 ms). 1351 */ 1352 itimeout = howmany(1000 * bits, t->c_ispeed); 1353 #ifdef SOFT_HOTCHAR 1354 #define MIN_RTP 1 1355 #else 1356 #define MIN_RTP 5 1357 #endif 1358 if (itimeout < MIN_RTP) 1359 itimeout = MIN_RTP; 1360 if (!(t->c_lflag & ICANON) && t->c_cc[VMIN] != 0 && t->c_cc[VTIME] != 0 1361 && t->c_cc[VTIME] * 10 > itimeout) 1362 itimeout = t->c_cc[VTIME] * 10; 1363 if (itimeout > 255) 1364 itimeout = 255; 1365 cd_setreg(com, CD1400_RTPR, itimeout); 1366 1367 /* 1368 * set channel option register 2 - 1369 * flow control 1370 */ 1371 opt = 0; 1372 #ifdef Smarts 1373 if (iflag & IXANY) 1374 opt |= CD1400_COR2_IXANY; 1375 if (iflag & IXOFF) 1376 opt |= CD1400_COR2_IXOFF; 1377 #endif 1378 #ifndef SOFT_CTS_OFLOW 1379 if (cflag & CCTS_OFLOW) 1380 opt |= CD1400_COR2_CCTS_OFLOW; 1381 #endif 1382 critical_enter(); 1383 COM_LOCK(); 1384 if (opt != com->cor[1]) { 1385 cor_change |= CD1400_CCR_COR2; 1386 cd_setreg(com, CD1400_COR2, com->cor[1] = opt); 1387 } 1388 COM_UNLOCK(); 1389 critical_exit(); 1390 1391 /* 1392 * set channel option register 3 - 1393 * receiver FIFO interrupt threshold 1394 * flow control 1395 */ 1396 opt = RxFifoThreshold; 1397 #ifdef Smarts 1398 if (t->c_lflag & ICANON) 1399 opt |= CD1400_COR3_SCD34; /* detect INTR & SUSP chars */ 1400 if (iflag & IXOFF) 1401 /* detect and transparently handle START and STOP chars */ 1402 opt |= CD1400_COR3_FCT | CD1400_COR3_SCD12; 1403 #endif 1404 if (opt != com->cor[2]) { 1405 cor_change |= CD1400_CCR_COR3; 1406 cd_setreg(com, CD1400_COR3, com->cor[2] = opt); 1407 } 1408 1409 /* notify the CD1400 if COR1-3 have changed */ 1410 if (cor_change) 1411 cd1400_channel_cmd(com, CD1400_CCR_CMDCORCHG | cor_change); 1412 1413 /* 1414 * set channel option register 4 - 1415 * CR/NL processing 1416 * break processing 1417 * received exception processing 1418 */ 1419 opt = 0; 1420 if (iflag & IGNCR) 1421 opt |= CD1400_COR4_IGNCR; 1422 #ifdef Smarts 1423 /* 1424 * we need a new ttyinput() for this, as we don't want to 1425 * have ICRNL && INLCR being done in both layers, or to have 1426 * synchronisation problems 1427 */ 1428 if (iflag & ICRNL) 1429 opt |= CD1400_COR4_ICRNL; 1430 if (iflag & INLCR) 1431 opt |= CD1400_COR4_INLCR; 1432 #endif 1433 if (iflag & IGNBRK) 1434 opt |= CD1400_COR4_IGNBRK | CD1400_COR4_NOBRKINT; 1435 /* 1436 * The `-ignbrk -brkint parmrk' case is not handled by the hardware, 1437 * so only tell the hardware about -brkint if -parmrk. 1438 */ 1439 if (!(iflag & (BRKINT | PARMRK))) 1440 opt |= CD1400_COR4_NOBRKINT; 1441 #if 0 1442 /* XXX using this "intelligence" breaks reporting of overruns. */ 1443 if (iflag & IGNPAR) 1444 opt |= CD1400_COR4_PFO_DISCARD; 1445 else { 1446 if (iflag & PARMRK) 1447 opt |= CD1400_COR4_PFO_ESC; 1448 else 1449 opt |= CD1400_COR4_PFO_NUL; 1450 } 1451 #else 1452 opt |= CD1400_COR4_PFO_EXCEPTION; 1453 #endif 1454 cd_setreg(com, CD1400_COR4, opt); 1455 1456 /* 1457 * set channel option register 5 - 1458 */ 1459 opt = 0; 1460 if (iflag & ISTRIP) 1461 opt |= CD1400_COR5_ISTRIP; 1462 if (t->c_iflag & IEXTEN) 1463 /* enable LNEXT (e.g. ctrl-v quoting) handling */ 1464 opt |= CD1400_COR5_LNEXT; 1465 #ifdef Smarts 1466 if (t->c_oflag & ONLCR) 1467 opt |= CD1400_COR5_ONLCR; 1468 if (t->c_oflag & OCRNL) 1469 opt |= CD1400_COR5_OCRNL; 1470 #endif 1471 cd_setreg(com, CD1400_COR5, opt); 1472 1473 /* 1474 * We always generate modem status change interrupts for CD changes. 1475 * Among other things, this is necessary to track TS_CARR_ON for 1476 * pstat to print even when the driver doesn't care. CD changes 1477 * should be rare so interrupts for them are not worth extra code to 1478 * avoid. We avoid interrupts for other modem status changes (except 1479 * for CTS changes when SOFT_CTS_OFLOW is configured) since this is 1480 * simplest and best. 1481 */ 1482 1483 /* 1484 * set modem change option register 1 1485 * generate modem interrupts on which 1 -> 0 input transitions 1486 * also controls auto-DTR output flow-control, which we don't use 1487 */ 1488 opt = CD1400_MCOR1_CDzd; 1489 #ifdef SOFT_CTS_OFLOW 1490 if (cflag & CCTS_OFLOW) 1491 opt |= CD1400_MCOR1_CTSzd; 1492 #endif 1493 cd_setreg(com, CD1400_MCOR1, opt); 1494 1495 /* 1496 * set modem change option register 2 1497 * generate modem interrupts on specific 0 -> 1 input transitions 1498 */ 1499 opt = CD1400_MCOR2_CDod; 1500 #ifdef SOFT_CTS_OFLOW 1501 if (cflag & CCTS_OFLOW) 1502 opt |= CD1400_MCOR2_CTSod; 1503 #endif 1504 cd_setreg(com, CD1400_MCOR2, opt); 1505 1506 /* 1507 * XXX should have done this long ago, but there is too much state 1508 * to change all atomically. 1509 */ 1510 critical_enter(); 1511 COM_LOCK(); 1512 1513 com->state &= ~CS_TTGO; 1514 if (!(tp->t_state & TS_TTSTOP)) 1515 com->state |= CS_TTGO; 1516 if (cflag & CRTS_IFLOW) { 1517 com->state |= CS_RTS_IFLOW; 1518 /* 1519 * If CS_RTS_IFLOW just changed from off to on, the change 1520 * needs to be propagated to CD1400_MSVR1_RTS. This isn't urgent, 1521 * so do it later by calling cystart() instead of repeating 1522 * a lot of code from cystart() here. 1523 */ 1524 } else if (com->state & CS_RTS_IFLOW) { 1525 com->state &= ~CS_RTS_IFLOW; 1526 /* 1527 * CS_RTS_IFLOW just changed from on to off. Force CD1400_MSVR1_RTS 1528 * on here, since cystart() won't do it later. 1529 */ 1530 cd_setreg(com, com->mcr_rts_reg, 1531 com->mcr_image |= com->mcr_rts); 1532 } 1533 1534 /* 1535 * Set up state to handle output flow control. 1536 * XXX - worth handling MDMBUF (DCD) flow control at the lowest level? 1537 * Now has 10+ msec latency, while CTS flow has 50- usec latency. 1538 */ 1539 com->state |= CS_ODEVREADY; 1540 #ifdef SOFT_CTS_OFLOW 1541 com->state &= ~CS_CTS_OFLOW; 1542 if (cflag & CCTS_OFLOW) { 1543 com->state |= CS_CTS_OFLOW; 1544 if (!(com->last_modem_status & CD1400_MSVR2_CTS)) 1545 com->state &= ~CS_ODEVREADY; 1546 } 1547 #endif 1548 /* XXX shouldn't call functions while intrs are disabled. */ 1549 disc_optim(tp, t, com); 1550 #if 0 1551 /* 1552 * Recover from fiddling with CS_TTGO. We used to call cyintr1() 1553 * unconditionally, but that defeated the careful discarding of 1554 * stale input in cyopen(). 1555 */ 1556 if (com->state >= (CS_BUSY | CS_TTGO)) 1557 cyintr1(com); 1558 #endif 1559 if (com->state >= (CS_BUSY | CS_TTGO | CS_ODEVREADY)) { 1560 if (!(com->intr_enable & CD1400_SRER_TXRDY)) 1561 cd_setreg(com, CD1400_SRER, 1562 com->intr_enable 1563 = (com->intr_enable & ~CD1400_SRER_TXMPTY) 1564 | CD1400_SRER_TXRDY); 1565 } else { 1566 if (com->intr_enable & CD1400_SRER_TXRDY) 1567 cd_setreg(com, CD1400_SRER, 1568 com->intr_enable 1569 = (com->intr_enable & ~CD1400_SRER_TXRDY) 1570 | CD1400_SRER_TXMPTY); 1571 } 1572 1573 COM_UNLOCK(); 1574 critical_exit(); 1575 splx(s); 1576 cystart(tp); 1577 if (com->ibufold != NULL) { 1578 free(com->ibufold, M_DEVBUF); 1579 com->ibufold = NULL; 1580 } 1581 return (0); 1582 } 1583 1584 static int 1585 cysetwater(struct com_s *com, speed_t speed) 1586 { 1587 int cp4ticks; 1588 u_char *ibuf; 1589 int ibufsize; 1590 struct tty *tp; 1591 1592 /* 1593 * Make the buffer size large enough to handle a softtty interrupt 1594 * latency of about 2 ticks without loss of throughput or data 1595 * (about 3 ticks if input flow control is not used or not honoured, 1596 * but a bit less for CS5-CS7 modes). 1597 */ 1598 cp4ticks = speed / 10 / hz * 4; 1599 for (ibufsize = 128; ibufsize < cp4ticks;) 1600 ibufsize <<= 1; 1601 if (ibufsize == com->ibufsize) { 1602 return (0); 1603 } 1604 1605 /* 1606 * Allocate input buffer. The extra factor of 2 in the size is 1607 * to allow for an error byte for each input byte. 1608 */ 1609 ibuf = malloc(2 * ibufsize, M_DEVBUF, M_NOWAIT); 1610 if (ibuf == NULL) { 1611 return (ENOMEM); 1612 } 1613 1614 /* Initialize non-critical variables. */ 1615 com->ibufold = com->ibuf; 1616 com->ibufsize = ibufsize; 1617 tp = com->tp; 1618 if (tp != NULL) { 1619 tp->t_ififosize = 2 * ibufsize; 1620 tp->t_ispeedwat = (speed_t)-1; 1621 tp->t_ospeedwat = (speed_t)-1; 1622 } 1623 1624 /* 1625 * Read current input buffer, if any. Continue with interrupts 1626 * disabled. 1627 */ 1628 critical_enter(); 1629 COM_LOCK(); 1630 if (com->iptr != com->ibuf) 1631 cyinput(com); 1632 1633 /*- 1634 * Initialize critical variables, including input buffer watermarks. 1635 * The external device is asked to stop sending when the buffer 1636 * exactly reaches high water, or when the high level requests it. 1637 * The high level is notified immediately (rather than at a later 1638 * clock tick) when this watermark is reached. 1639 * The buffer size is chosen so the watermark should almost never 1640 * be reached. 1641 * The low watermark is invisibly 0 since the buffer is always 1642 * emptied all at once. 1643 */ 1644 com->iptr = com->ibuf = ibuf; 1645 com->ibufend = ibuf + ibufsize; 1646 com->ierroff = ibufsize; 1647 com->ihighwater = ibuf + 3 * ibufsize / 4; 1648 1649 COM_UNLOCK(); 1650 critical_exit(); 1651 return (0); 1652 } 1653 1654 static void 1655 cystart(struct tty *tp) 1656 { 1657 struct com_s *com; 1658 int s; 1659 #ifdef CyDebug 1660 bool_t started; 1661 #endif 1662 1663 com = tp->t_sc; 1664 s = spltty(); 1665 1666 #ifdef CyDebug 1667 ++com->start_count; 1668 started = FALSE; 1669 #endif 1670 1671 critical_enter(); 1672 COM_LOCK(); 1673 if (tp->t_state & TS_TTSTOP) { 1674 com->state &= ~CS_TTGO; 1675 if (com->intr_enable & CD1400_SRER_TXRDY) 1676 cd_setreg(com, CD1400_SRER, 1677 com->intr_enable 1678 = (com->intr_enable & ~CD1400_SRER_TXRDY) 1679 | CD1400_SRER_TXMPTY); 1680 } else { 1681 com->state |= CS_TTGO; 1682 if (com->state >= (CS_BUSY | CS_TTGO | CS_ODEVREADY) 1683 && !(com->intr_enable & CD1400_SRER_TXRDY)) 1684 cd_setreg(com, CD1400_SRER, 1685 com->intr_enable 1686 = (com->intr_enable & ~CD1400_SRER_TXMPTY) 1687 | CD1400_SRER_TXRDY); 1688 } 1689 if (tp->t_state & TS_TBLOCK) { 1690 if (com->mcr_image & com->mcr_rts && com->state & CS_RTS_IFLOW) 1691 #if 0 1692 outb(com->modem_ctl_port, com->mcr_image &= ~CD1400_MSVR1_RTS); 1693 #else 1694 cd_setreg(com, com->mcr_rts_reg, 1695 com->mcr_image &= ~com->mcr_rts); 1696 #endif 1697 } else { 1698 if (!(com->mcr_image & com->mcr_rts) 1699 && com->iptr < com->ihighwater 1700 && com->state & CS_RTS_IFLOW) 1701 #if 0 1702 outb(com->modem_ctl_port, com->mcr_image |= CD1400_MSVR1_RTS); 1703 #else 1704 cd_setreg(com, com->mcr_rts_reg, 1705 com->mcr_image |= com->mcr_rts); 1706 #endif 1707 } 1708 COM_UNLOCK(); 1709 critical_exit(); 1710 if (tp->t_state & (TS_TIMEOUT | TS_TTSTOP)) { 1711 ttwwakeup(tp); 1712 splx(s); 1713 return; 1714 } 1715 if (tp->t_outq.c_cc != 0) { 1716 struct lbq *qp; 1717 struct lbq *next; 1718 1719 if (!com->obufs[0].l_queued) { 1720 #ifdef CyDebug 1721 started = TRUE; 1722 #endif 1723 com->obufs[0].l_tail 1724 = com->obuf1 + q_to_b(&tp->t_outq, com->obuf1, 1725 sizeof com->obuf1); 1726 com->obufs[0].l_next = NULL; 1727 com->obufs[0].l_queued = TRUE; 1728 critical_enter(); 1729 COM_LOCK(); 1730 if (com->state & CS_BUSY) { 1731 qp = com->obufq.l_next; 1732 while ((next = qp->l_next) != NULL) 1733 qp = next; 1734 qp->l_next = &com->obufs[0]; 1735 } else { 1736 com->obufq.l_head = com->obufs[0].l_head; 1737 com->obufq.l_tail = com->obufs[0].l_tail; 1738 com->obufq.l_next = &com->obufs[0]; 1739 com->state |= CS_BUSY; 1740 if (com->state >= (CS_BUSY | CS_TTGO 1741 | CS_ODEVREADY)) 1742 cd_setreg(com, CD1400_SRER, 1743 com->intr_enable 1744 = (com->intr_enable 1745 & ~CD1400_SRER_TXMPTY) 1746 | CD1400_SRER_TXRDY); 1747 } 1748 COM_UNLOCK(); 1749 critical_exit(); 1750 } 1751 if (tp->t_outq.c_cc != 0 && !com->obufs[1].l_queued) { 1752 #ifdef CyDebug 1753 started = TRUE; 1754 #endif 1755 com->obufs[1].l_tail 1756 = com->obuf2 + q_to_b(&tp->t_outq, com->obuf2, 1757 sizeof com->obuf2); 1758 com->obufs[1].l_next = NULL; 1759 com->obufs[1].l_queued = TRUE; 1760 critical_enter(); 1761 COM_LOCK(); 1762 if (com->state & CS_BUSY) { 1763 qp = com->obufq.l_next; 1764 while ((next = qp->l_next) != NULL) 1765 qp = next; 1766 qp->l_next = &com->obufs[1]; 1767 } else { 1768 com->obufq.l_head = com->obufs[1].l_head; 1769 com->obufq.l_tail = com->obufs[1].l_tail; 1770 com->obufq.l_next = &com->obufs[1]; 1771 com->state |= CS_BUSY; 1772 if (com->state >= (CS_BUSY | CS_TTGO 1773 | CS_ODEVREADY)) 1774 cd_setreg(com, CD1400_SRER, 1775 com->intr_enable 1776 = (com->intr_enable 1777 & ~CD1400_SRER_TXMPTY) 1778 | CD1400_SRER_TXRDY); 1779 } 1780 COM_UNLOCK(); 1781 critical_exit(); 1782 } 1783 tp->t_state |= TS_BUSY; 1784 } 1785 #ifdef CyDebug 1786 if (started) 1787 ++com->start_real; 1788 #endif 1789 #if 0 1790 critical_enter(); 1791 COM_LOCK(); 1792 if (com->state >= (CS_BUSY | CS_TTGO)) 1793 cyintr1(com); /* fake interrupt to start output */ 1794 COM_UNLOCK(); 1795 critical_exit(); 1796 #endif 1797 ttwwakeup(tp); 1798 splx(s); 1799 } 1800 1801 static void 1802 comstop(struct tty *tp, int rw) 1803 { 1804 struct com_s *com; 1805 bool_t wakeup_etc; 1806 1807 com = tp->t_sc; 1808 wakeup_etc = FALSE; 1809 critical_enter(); 1810 COM_LOCK(); 1811 if (rw & FWRITE) { 1812 com->obufs[0].l_queued = FALSE; 1813 com->obufs[1].l_queued = FALSE; 1814 if (com->extra_state & CSE_ODONE) { 1815 cy_events -= LOTS_OF_EVENTS; 1816 com->extra_state &= ~CSE_ODONE; 1817 if (com->etc != ETC_NONE) { 1818 if (com->etc == ETC_BREAK_ENDED) 1819 com->etc = ETC_NONE; 1820 wakeup_etc = TRUE; 1821 } 1822 } 1823 com->tp->t_state &= ~TS_BUSY; 1824 if (com->state & CS_ODONE) 1825 cy_events -= LOTS_OF_EVENTS; 1826 com->state &= ~(CS_ODONE | CS_BUSY); 1827 } 1828 if (rw & FREAD) { 1829 /* XXX no way to reset only input fifo. */ 1830 cy_events -= (com->iptr - com->ibuf); 1831 com->iptr = com->ibuf; 1832 } 1833 COM_UNLOCK(); 1834 critical_exit(); 1835 if (wakeup_etc) 1836 wakeup(&com->etc); 1837 if (rw & FWRITE && com->etc == ETC_NONE) 1838 cd1400_channel_cmd(com, CD1400_CCR_CMDRESET | CD1400_CCR_FTF); 1839 cystart(tp); 1840 } 1841 1842 static int 1843 cymodem(struct tty *tp, int sigon, int sigoff) 1844 { 1845 struct com_s *com; 1846 int mcr; 1847 int msr; 1848 1849 com = tp->t_sc; 1850 if (sigon == 0 && sigoff == 0) { 1851 sigon = 0; 1852 mcr = com->mcr_image; 1853 if (mcr & com->mcr_dtr) 1854 sigon |= SER_DTR; 1855 if (mcr & com->mcr_rts) 1856 /* XXX wired on for Cyclom-8Ys */ 1857 sigon |= SER_RTS; 1858 1859 /* 1860 * We must read the modem status from the hardware because 1861 * we don't generate modem status change interrupts for all 1862 * changes, so com->prev_modem_status is not guaranteed to 1863 * be up to date. This is safe, unlike for sio, because 1864 * reading the status register doesn't clear pending modem 1865 * status change interrupts. 1866 */ 1867 msr = cd_getreg(com, CD1400_MSVR2); 1868 1869 if (msr & CD1400_MSVR2_CTS) 1870 sigon |= SER_CTS; 1871 if (msr & CD1400_MSVR2_CD) 1872 sigon |= SER_DCD; 1873 if (msr & CD1400_MSVR2_DSR) 1874 sigon |= SER_DSR; 1875 if (msr & CD1400_MSVR2_RI) 1876 /* XXX not connected except for Cyclom-16Y? */ 1877 sigon |= SER_RI; 1878 return (sigon); 1879 } 1880 mcr = com->mcr_image; 1881 if (sigon & SER_DTR) 1882 mcr |= com->mcr_dtr; 1883 if (sigoff & SER_DTR) 1884 mcr &= ~com->mcr_dtr; 1885 if (sigon & SER_RTS) 1886 mcr |= com->mcr_rts; 1887 if (sigoff & SER_RTS) 1888 mcr &= ~com->mcr_rts; 1889 critical_enter(); 1890 COM_LOCK(); 1891 com->mcr_image = mcr; 1892 cd_setreg(com, CD1400_MSVR1, mcr); 1893 cd_setreg(com, CD1400_MSVR2, mcr); 1894 COM_UNLOCK(); 1895 critical_exit(); 1896 return (0); 1897 } 1898 1899 static void 1900 cysettimeout() 1901 { 1902 struct com_s *com; 1903 bool_t someopen; 1904 int unit; 1905 1906 /* 1907 * Set our timeout period to 1 second if no polled devices are open. 1908 * Otherwise set it to max(1/200, 1/hz). 1909 * Enable timeouts iff some device is open. 1910 */ 1911 untimeout(cywakeup, (void *)NULL, cy_timeout_handle); 1912 cy_timeout = hz; 1913 someopen = FALSE; 1914 for (unit = 0; unit < NPORTS; ++unit) { 1915 com = cy_addr(unit); 1916 if (com != NULL && com->tp != NULL 1917 && com->tp->t_state & TS_ISOPEN) { 1918 someopen = TRUE; 1919 } 1920 } 1921 if (someopen) { 1922 cy_timeouts_until_log = hz / cy_timeout; 1923 cy_timeout_handle = timeout(cywakeup, (void *)NULL, 1924 cy_timeout); 1925 } else { 1926 /* Flush error messages, if any. */ 1927 cy_timeouts_until_log = 1; 1928 cywakeup((void *)NULL); 1929 untimeout(cywakeup, (void *)NULL, cy_timeout_handle); 1930 } 1931 } 1932 1933 static void 1934 cywakeup(void *chan) 1935 { 1936 struct com_s *com; 1937 int unit; 1938 1939 cy_timeout_handle = timeout(cywakeup, (void *)NULL, cy_timeout); 1940 1941 /* 1942 * Check for and log errors, but not too often. 1943 */ 1944 if (--cy_timeouts_until_log > 0) 1945 return; 1946 cy_timeouts_until_log = hz / cy_timeout; 1947 for (unit = 0; unit < NPORTS; ++unit) { 1948 int errnum; 1949 1950 com = cy_addr(unit); 1951 if (com == NULL) 1952 continue; 1953 for (errnum = 0; errnum < CE_NTYPES; ++errnum) { 1954 u_int delta; 1955 u_long total; 1956 1957 critical_enter(); 1958 COM_LOCK(); 1959 delta = com->delta_error_counts[errnum]; 1960 com->delta_error_counts[errnum] = 0; 1961 COM_UNLOCK(); 1962 critical_exit(); 1963 if (delta == 0) 1964 continue; 1965 total = com->error_counts[errnum] += delta; 1966 log(LOG_ERR, "cy%d: %u more %s%s (total %lu)\n", 1967 unit, delta, error_desc[errnum], 1968 delta == 1 ? "" : "s", total); 1969 } 1970 } 1971 } 1972 1973 static void 1974 disc_optim(struct tty *tp, struct termios *t, struct com_s *com) 1975 { 1976 #ifndef SOFT_HOTCHAR 1977 u_char opt; 1978 #endif 1979 1980 ttyldoptim(tp); 1981 #ifndef SOFT_HOTCHAR 1982 opt = com->cor[2] & ~CD1400_COR3_SCD34; 1983 if (com->tp->t_hotchar != 0) { 1984 cd_setreg(com, CD1400_SCHR3, com->tp->t_hotchar); 1985 cd_setreg(com, CD1400_SCHR4, com->tp->t_hotchar); 1986 opt |= CD1400_COR3_SCD34; 1987 } 1988 if (opt != com->cor[2]) { 1989 cd_setreg(com, CD1400_COR3, com->cor[2] = opt); 1990 cd1400_channel_cmd(com, CD1400_CCR_CMDCORCHG | CD1400_CCR_COR3); 1991 } 1992 #endif 1993 } 1994 1995 #ifdef Smarts 1996 /* standard line discipline input routine */ 1997 int 1998 cyinput(int c, struct tty *tp) 1999 { 2000 /* XXX duplicate ttyinput(), but without the IXOFF/IXON/ISTRIP/IPARMRK 2001 * bits, as they are done by the CD1400. Hardly worth the effort, 2002 * given that high-throughput session are raw anyhow. 2003 */ 2004 } 2005 #endif /* Smarts */ 2006 2007 static int 2008 cyspeed(speed_t speed, u_long cy_clock, int *prescaler_io) 2009 { 2010 int actual; 2011 int error; 2012 int divider; 2013 int prescaler; 2014 int prescaler_unit; 2015 2016 if (speed == 0) 2017 return (0); 2018 if (speed < 0 || speed > 150000) 2019 return (-1); 2020 2021 /* determine which prescaler to use */ 2022 for (prescaler_unit = 4, prescaler = 2048; prescaler_unit; 2023 prescaler_unit--, prescaler >>= 2) { 2024 if (cy_clock / prescaler / speed > 63) 2025 break; 2026 } 2027 2028 divider = (cy_clock / prescaler * 2 / speed + 1) / 2; /* round off */ 2029 if (divider > 255) 2030 divider = 255; 2031 actual = cy_clock/prescaler/divider; 2032 2033 /* 10 times error in percent: */ 2034 error = ((actual - (long)speed) * 2000 / (long)speed + 1) / 2; 2035 2036 /* 3.0% max error tolerance */ 2037 if (error < -30 || error > 30) 2038 return (-1); 2039 2040 *prescaler_io = prescaler_unit; 2041 return (divider); 2042 } 2043 2044 static void 2045 cd1400_channel_cmd(struct com_s *com, int cmd) 2046 { 2047 cd1400_channel_cmd_wait(com); 2048 cd_setreg(com, CD1400_CCR, cmd); 2049 cd1400_channel_cmd_wait(com); 2050 } 2051 2052 static void 2053 cd1400_channel_cmd_wait(struct com_s *com) 2054 { 2055 struct timeval start; 2056 struct timeval tv; 2057 long usec; 2058 2059 if (cd_getreg(com, CD1400_CCR) == 0) 2060 return; 2061 microtime(&start); 2062 for (;;) { 2063 if (cd_getreg(com, CD1400_CCR) == 0) 2064 return; 2065 microtime(&tv); 2066 usec = 1000000 * (tv.tv_sec - start.tv_sec) + 2067 tv.tv_usec - start.tv_usec; 2068 if (usec >= 5000) { 2069 log(LOG_ERR, 2070 "cy%d: channel command timeout (%ld usec)\n", 2071 com->unit, usec); 2072 return; 2073 } 2074 } 2075 } 2076 2077 static void 2078 cd_etc(struct com_s *com, int etc) 2079 { 2080 2081 /* 2082 * We can't change the hardware's ETC state while there are any 2083 * characters in the tx fifo, since those characters would be 2084 * interpreted as commands! Unputting characters from the fifo 2085 * is difficult, so we wait up to 12 character times for the fifo 2086 * to drain. The command will be delayed for up to 2 character 2087 * times for the tx to become empty. Unputting characters from 2088 * the tx holding and shift registers is impossible, so we wait 2089 * for the tx to become empty so that the command is sure to be 2090 * executed soon after we issue it. 2091 */ 2092 critical_enter(); 2093 COM_LOCK(); 2094 if (com->etc == etc) 2095 goto wait; 2096 if ((etc == CD1400_ETC_SENDBREAK 2097 && (com->etc == ETC_BREAK_STARTING 2098 || com->etc == ETC_BREAK_STARTED)) 2099 || (etc == CD1400_ETC_STOPBREAK 2100 && (com->etc == ETC_BREAK_ENDING || com->etc == ETC_BREAK_ENDED 2101 || com->etc == ETC_NONE))) { 2102 COM_UNLOCK(); 2103 critical_exit(); 2104 return; 2105 } 2106 com->etc = etc; 2107 cd_setreg(com, CD1400_SRER, 2108 com->intr_enable 2109 = (com->intr_enable & ~CD1400_SRER_TXRDY) | CD1400_SRER_TXMPTY); 2110 wait: 2111 COM_UNLOCK(); 2112 critical_exit(); 2113 while (com->etc == etc 2114 && tsleep(&com->etc, TTIPRI | PCATCH, "cyetc", 0) == 0) 2115 continue; 2116 } 2117 2118 static int 2119 cd_getreg(struct com_s *com, int reg) 2120 { 2121 struct com_s *basecom; 2122 u_char car; 2123 int cy_align; 2124 cy_addr iobase; 2125 #ifdef SMP 2126 int need_unlock; 2127 #endif 2128 int val; 2129 2130 basecom = cy_addr(com->unit & ~(CD1400_NO_OF_CHANNELS - 1)); 2131 car = com->unit & CD1400_CAR_CHAN; 2132 cy_align = com->cy_align; 2133 iobase = com->iobase; 2134 critical_enter(); 2135 #ifdef SMP 2136 need_unlock = 0; 2137 if (!mtx_owned(&cy_lock)) { 2138 COM_LOCK(); 2139 need_unlock = 1; 2140 } 2141 #endif 2142 if (basecom->car != car) 2143 cd_outb(iobase, CD1400_CAR, cy_align, basecom->car = car); 2144 val = cd_inb(iobase, reg, cy_align); 2145 #ifdef SMP 2146 if (need_unlock) 2147 COM_UNLOCK(); 2148 #endif 2149 critical_exit(); 2150 return (val); 2151 } 2152 2153 static void 2154 cd_setreg(struct com_s *com, int reg, int val) 2155 { 2156 struct com_s *basecom; 2157 u_char car; 2158 int cy_align; 2159 cy_addr iobase; 2160 #ifdef SMP 2161 int need_unlock; 2162 #endif 2163 2164 basecom = cy_addr(com->unit & ~(CD1400_NO_OF_CHANNELS - 1)); 2165 car = com->unit & CD1400_CAR_CHAN; 2166 cy_align = com->cy_align; 2167 iobase = com->iobase; 2168 critical_enter(); 2169 #ifdef SMP 2170 need_unlock = 0; 2171 if (!mtx_owned(&cy_lock)) { 2172 COM_LOCK(); 2173 need_unlock = 1; 2174 } 2175 #endif 2176 if (basecom->car != car) 2177 cd_outb(iobase, CD1400_CAR, cy_align, basecom->car = car); 2178 cd_outb(iobase, reg, cy_align, val); 2179 #ifdef SMP 2180 if (need_unlock) 2181 COM_UNLOCK(); 2182 #endif 2183 critical_exit(); 2184 } 2185 2186 #ifdef CyDebug 2187 /* useful in ddb */ 2188 void 2189 cystatus(int unit) 2190 { 2191 struct com_s *com; 2192 cy_addr iobase; 2193 u_int ocount; 2194 struct tty *tp; 2195 2196 com = cy_addr(unit); 2197 printf("info for channel %d\n", unit); 2198 printf("------------------\n"); 2199 printf("total cyclom service probes:\t%d\n", cy_svrr_probes); 2200 printf("calls to upper layer:\t\t%d\n", cy_timeouts); 2201 if (com == NULL) 2202 return; 2203 iobase = com->iobase; 2204 printf("\n"); 2205 printf("cd1400 base address:\\tt%p\n", iobase); 2206 printf("saved channel_control:\t\t0x%02x\n", com->channel_control); 2207 printf("saved cor1-3:\t\t\t0x%02x 0x%02x 0x%02x\n", 2208 com->cor[0], com->cor[1], com->cor[2]); 2209 printf("service request enable reg:\t0x%02x (0x%02x cached)\n", 2210 cd_getreg(com, CD1400_SRER), com->intr_enable); 2211 printf("service request register:\t0x%02x\n", 2212 cd_inb(iobase, CD1400_SVRR, com->cy_align)); 2213 printf("modem status:\t\t\t0x%02x (0x%02x cached)\n", 2214 cd_getreg(com, CD1400_MSVR2), com->prev_modem_status); 2215 printf("rx/tx/mdm interrupt registers:\t0x%02x 0x%02x 0x%02x\n", 2216 cd_inb(iobase, CD1400_RIR, com->cy_align), 2217 cd_inb(iobase, CD1400_TIR, com->cy_align), 2218 cd_inb(iobase, CD1400_MIR, com->cy_align)); 2219 printf("\n"); 2220 printf("com state:\t\t\t0x%02x\n", com->state); 2221 printf("calls to cystart():\t\t%d (%d useful)\n", 2222 com->start_count, com->start_real); 2223 printf("rx buffer chars free:\t\t%d\n", com->iptr - com->ibuf); 2224 ocount = 0; 2225 if (com->obufs[0].l_queued) 2226 ocount += com->obufs[0].l_tail - com->obufs[0].l_head; 2227 if (com->obufs[1].l_queued) 2228 ocount += com->obufs[1].l_tail - com->obufs[1].l_head; 2229 printf("tx buffer chars:\t\t%u\n", ocount); 2230 printf("received chars:\t\t\t%d\n", com->bytes_in); 2231 printf("received exceptions:\t\t%d\n", com->recv_exception); 2232 printf("modem signal deltas:\t\t%d\n", com->mdm); 2233 printf("transmitted chars:\t\t%d\n", com->bytes_out); 2234 printf("\n"); 2235 tp = com->tp; 2236 if (tp != NULL) { 2237 printf("tty state:\t\t\t0x%08x\n", tp->t_state); 2238 printf( 2239 "upper layer queue lengths:\t%d raw, %d canon, %d output\n", 2240 tp->t_rawq.c_cc, tp->t_canq.c_cc, tp->t_outq.c_cc); 2241 } else 2242 printf("tty state:\t\t\tclosed\n"); 2243 } 2244 #endif /* CyDebug */ 2245