zs.c revision 1.12
1/* $NetBSD: zs.c,v 1.12 1995/12/16 21:45:31 leo Exp $ */ 2 3/* 4 * Copyright (c) 1995 L. Weppelman (Atari modifications) 5 * Copyright (c) 1992, 1993 6 * The Regents of the University of California. All rights reserved. 7 * 8 * This software was developed by the Computer Systems Engineering group 9 * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and 10 * contributed to Berkeley. 11 * 12 * 13 * All advertising materials mentioning features or use of this software 14 * must display the following acknowledgement: 15 * This product includes software developed by the University of 16 * California, Lawrence Berkeley Laboratory. 17 * 18 * Redistribution and use in source and binary forms, with or without 19 * modification, are permitted provided that the following conditions 20 * are met: 21 * 1. Redistributions of source code must retain the above copyright 22 * notice, this list of conditions and the following disclaimer. 23 * 2. Redistributions in binary form must reproduce the above copyright 24 * notice, this list of conditions and the following disclaimer in the 25 * documentation and/or other materials provided with the distribution. 26 * 3. All advertising materials mentioning features or use of this software 27 * must display the following acknowledgement: 28 * This product includes software developed by the University of 29 * California, Berkeley and its contributors. 30 * 4. Neither the name of the University nor the names of its contributors 31 * may be used to endorse or promote products derived from this software 32 * without specific prior written permission. 33 * 34 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 35 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 36 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 37 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 38 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 39 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 40 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 41 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 42 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 43 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 44 * SUCH DAMAGE. 45 * 46 * @(#)zs.c 8.1 (Berkeley) 7/19/93 47 */ 48 49/* 50 * Zilog Z8530 (ZSCC) driver. 51 * 52 * Runs two tty ports (modem2 and serial2) on zs0. 53 * 54 * This driver knows far too much about chip to usage mappings. 55 */ 56#include <sys/param.h> 57#include <sys/systm.h> 58#include <sys/proc.h> 59#include <sys/device.h> 60#include <sys/conf.h> 61#include <sys/file.h> 62#include <sys/ioctl.h> 63#include <sys/tty.h> 64#include <sys/time.h> 65#include <sys/kernel.h> 66#include <sys/syslog.h> 67 68#include <machine/cpu.h> 69#include <machine/iomap.h> 70#include <machine/scu.h> 71#include <machine/mfp.h> 72#include <machine/video.h> 73 74#include <dev/ic/z8530reg.h> 75#include <atari/dev/zsvar.h> 76#include "zs.h" 77#if NZS > 1 78#error "This driver supports only 1 85C30!" 79#endif 80 81#if NZS > 0 82 83#define PCLK (8053976) /* PCLK pin input clock rate */ 84 85#define splzs spl5 86 87/* 88 * Software state per found chip. 89 */ 90struct zs_softc { 91 struct device zi_dev; /* base device */ 92 volatile struct zsdevice *zi_zs; /* chip registers */ 93 struct zs_chanstate zi_cs[2]; /* chan A and B software state */ 94}; 95 96static u_char cb_scheduled = 0; /* Already asked for callback? */ 97/* 98 * Define the registers for a closed port 99 */ 100static u_char zs_init_regs[16] = { 101/* 0 */ 0, 102/* 1 */ 0, 103/* 2 */ 0x60, 104/* 3 */ 0, 105/* 4 */ 0, 106/* 5 */ 0, 107/* 6 */ 0, 108/* 7 */ 0, 109/* 8 */ 0, 110/* 9 */ ZSWR9_VECTOR_INCL_STAT, 111/* 10 */ ZSWR10_NRZ, 112/* 11 */ ZSWR11_TXCLK_BAUD | ZSWR11_RXCLK_BAUD, 113/* 12 */ 0, 114/* 13 */ 0, 115/* 14 */ ZSWR14_BAUD_FROM_PCLK | ZSWR14_BAUD_ENA, 116/* 15 */ 0 117}; 118 119/* 120 * Define the machine dependant clock frequencies 121 * If BRgen feeds sender/receiver we always use a 122 * divisor 16, therefor the division by 16 can as 123 * well be done here. 124 */ 125static u_long zs_freqs_tt[] = { 126 /* 127 * Atari TT, RTxCB is generated by TT-MFP timer C, 128 * which is set to 307.2KHz during initialisation 129 * and never changed afterwards. 130 */ 131 PCLK/16, /* BRgen, PCLK, divisor 16 */ 132 229500, /* BRgen, RTxCA, divisor 16 */ 133 3672000, /* RTxCA, from PCLK4 */ 134 0, /* TRxCA, external */ 135 136 PCLK/16, /* BRgen, PCLK, divisor 16 */ 137 19200, /* BRgen, RTxCB, divisor 16 */ 138 307200, /* RTxCB, from TT-MFP TCO */ 139 2457600 /* TRxCB, from BCLK */ 140}; 141static u_long zs_freqs_falcon[] = { 142 /* 143 * Atari Falcon, XXX no specs available, this might be wrong 144 */ 145 PCLK/16, /* BRgen, PCLK, divisor 16 */ 146 229500, /* BRgen, RTxCA, divisor 16 */ 147 3672000, /* RTxCA, ??? */ 148 0, /* TRxCA, external */ 149 150 PCLK/16, /* BRgen, PCLK, divisor 16 */ 151 229500, /* BRgen, RTxCB, divisor 16 */ 152 3672000, /* RTxCB, ??? */ 153 2457600 /* TRxCB, ??? */ 154}; 155static u_long zs_freqs_generic[] = { 156 /* 157 * other machines, assume only PCLK is available 158 */ 159 PCLK/16, /* BRgen, PCLK, divisor 16 */ 160 0, /* BRgen, RTxCA, divisor 16 */ 161 0, /* RTxCA, unknown */ 162 0, /* TRxCA, unknown */ 163 164 PCLK/16, /* BRgen, PCLK, divisor 16 */ 165 0, /* BRgen, RTxCB, divisor 16 */ 166 0, /* RTxCB, unknown */ 167 0 /* TRxCB, unknown */ 168}; 169static u_long *zs_frequencies; 170 171/* Definition of the driver for autoconfig. */ 172static int zsmatch __P((struct device *, struct cfdata *, void *)); 173static void zsattach __P((struct device *, struct device *, void *)); 174struct cfdriver zscd = { 175 NULL, "zs", (cfmatch_t)zsmatch, zsattach, DV_TTY, 176 sizeof(struct zs_softc), NULL, 0 }; 177 178/* Interrupt handlers. */ 179int zshard __P((long)); 180static int zssoft __P((long)); 181static int zsrint __P((struct zs_chanstate *, volatile struct zschan *)); 182static int zsxint __P((struct zs_chanstate *, volatile struct zschan *)); 183static int zssint __P((struct zs_chanstate *, volatile struct zschan *)); 184 185static struct zs_chanstate *zslist; 186 187/* Routines called from other code. */ 188static void zsstart __P((struct tty *)); 189void zsstop __P((struct tty *, int)); 190static int zsparam __P((struct tty *, struct termios *)); 191static int zsbaudrate __P((int, int, int *, int *, int *, int *)); 192 193/* Routines purely local to this driver. */ 194static void zs_reset __P((volatile struct zschan *, int, int)); 195static int zs_modem __P((struct zs_chanstate *, int, int)); 196static void zs_loadchannelregs __P((volatile struct zschan *, u_char *)); 197 198static int zsshortcuts; /* number of "shortcut" software interrupts */ 199 200static int 201zsmatch(pdp, cfp, auxp) 202struct device *pdp; 203struct cfdata *cfp; 204void *auxp; 205{ 206 if(strcmp("zs", auxp) || cfp->cf_unit != 0) 207 return(0); 208 return(1); 209} 210 211/* 212 * Attach a found zs. 213 */ 214static void 215zsattach(parent, dev, aux) 216struct device *parent; 217struct device *dev; 218void *aux; 219{ 220 register struct zs_softc *zi; 221 register struct zs_chanstate *cs; 222 register volatile struct zsdevice *addr; 223 register struct tty *tp; 224 char tmp; 225 226 addr = (struct zsdevice *)AD_SCC; 227 zi = (struct zs_softc *)dev; 228 zi->zi_zs = addr; 229 cs = zi->zi_cs; 230 231 /* 232 * Get the command register into a known state. 233 */ 234 tmp = addr->zs_chan[ZS_CHAN_A].zc_csr; 235 tmp = addr->zs_chan[ZS_CHAN_A].zc_csr; 236 tmp = addr->zs_chan[ZS_CHAN_B].zc_csr; 237 tmp = addr->zs_chan[ZS_CHAN_B].zc_csr; 238 239 /* 240 * Do a hardware reset. 241 */ 242 ZS_WRITE(&addr->zs_chan[ZS_CHAN_A], 9, ZSWR9_HARD_RESET); 243 delay(50000); /*enough ? */ 244 ZS_WRITE(&addr->zs_chan[ZS_CHAN_A], 9, 0); 245 246 /* 247 * Initialize both channels 248 */ 249 zs_loadchannelregs(&addr->zs_chan[ZS_CHAN_A], zs_init_regs); 250 zs_loadchannelregs(&addr->zs_chan[ZS_CHAN_B], zs_init_regs); 251 252 if(machineid & ATARI_TT) { 253 /* 254 * ininitialise TT-MFP timer C: 307200Hz 255 * timer C and D share one control register: 256 * bits 0-2 control timer D 257 * bits 4-6 control timer C 258 */ 259 int cr = MFP2->mf_tcdcr & 7; 260 MFP2->mf_tcdcr = cr; /* stop timer C */ 261 MFP2->mf_tcdr = 1; /* counter 1 */ 262 cr |= T_Q004 << 4; /* divisor 4 */ 263 MFP2->mf_tcdcr = cr; /* start timer C */ 264 /* 265 * enable scc related interrupts 266 */ 267 SCU->sys_mask |= SCU_SCC; 268 269 zs_frequencies = zs_freqs_tt; 270 } else if (machineid & ATARI_FALCON) { 271 zs_frequencies = zs_freqs_falcon; 272 } else { 273 zs_frequencies = zs_freqs_generic; 274 } 275 276 /* link into interrupt list with order (A,B) (B=A+1) */ 277 cs[0].cs_next = &cs[1]; 278 cs[1].cs_next = zslist; 279 zslist = cs; 280 281 cs->cs_unit = 0; 282 cs->cs_zc = &addr->zs_chan[ZS_CHAN_A]; 283 cs++; 284 cs->cs_unit = 1; 285 cs->cs_zc = &addr->zs_chan[ZS_CHAN_B]; 286 287 printf(": serial2 on channel a and modem2 on channel b\n"); 288} 289 290/* 291 * Open a zs serial port. 292 */ 293int 294zsopen(dev, flags, mode, p) 295dev_t dev; 296int flags; 297int mode; 298struct proc *p; 299{ 300 register struct tty *tp; 301 register struct zs_chanstate *cs; 302 struct zs_softc *zi; 303 int unit = ZS_UNIT(dev); 304 int zs = unit >> 1; 305 int error, s; 306 307 if(zs >= zscd.cd_ndevs || (zi = zscd.cd_devs[zs]) == NULL) 308 return (ENXIO); 309 cs = &zi->zi_cs[unit & 1]; 310 311 /* 312 * When port A (ser02) is selected on the TT, make sure 313 * the port is enabled. 314 */ 315 if((machineid & ATARI_TT) && !(unit & 1)) { 316 SOUND->sd_selr = YM_IOA; 317 SOUND->sd_wdat = SOUND->sd_rdat | PA_SER2; 318 } 319 320 tp = cs->cs_ttyp; 321 if(tp == NULL) { 322 cs->cs_ttyp = tp = ttymalloc(); 323 tp->t_dev = dev; 324 tp->t_oproc = zsstart; 325 tp->t_param = zsparam; 326 } 327 328 s = spltty(); 329 if((tp->t_state & TS_ISOPEN) == 0) { 330 ttychars(tp); 331 if(tp->t_ispeed == 0) { 332 tp->t_iflag = TTYDEF_IFLAG; 333 tp->t_oflag = TTYDEF_OFLAG; 334 tp->t_cflag = TTYDEF_CFLAG; 335 tp->t_lflag = TTYDEF_LFLAG; 336 tp->t_ispeed = tp->t_ospeed = TTYDEF_SPEED; 337 } 338 (void)zsparam(tp, &tp->t_termios); 339 ttsetwater(tp); 340 } 341 else if(tp->t_state & TS_XCLUDE && p->p_ucred->cr_uid != 0) { 342 splx(s); 343 return (EBUSY); 344 } 345 error = 0; 346 for(;;) { 347 /* loop, turning on the device, until carrier present */ 348 zs_modem(cs, ZSWR5_RTS|ZSWR5_DTR, DMSET); 349 350 /* May never get a status intr. if DCD already on. -gwr */ 351 if(cs->cs_zc->zc_csr & ZSRR0_DCD) 352 tp->t_state |= TS_CARR_ON; 353 if(cs->cs_softcar) 354 tp->t_state |= TS_CARR_ON; 355 if(flags & O_NONBLOCK || tp->t_cflag & CLOCAL || 356 tp->t_state & TS_CARR_ON) 357 break; 358 tp->t_state |= TS_WOPEN; 359 if(error = ttysleep(tp, (caddr_t)&tp->t_rawq, TTIPRI | PCATCH, 360 ttopen, 0)) { 361 if(!(tp->t_state & TS_ISOPEN)) { 362 zs_modem(cs, 0, DMSET); 363 tp->t_state &= ~TS_WOPEN; 364 ttwakeup(tp); 365 } 366 splx(s); 367 return error; 368 } 369 } 370 splx(s); 371 if(error == 0) 372 error = linesw[tp->t_line].l_open(dev, tp); 373 if(error) 374 zs_modem(cs, 0, DMSET); 375 return(error); 376} 377 378/* 379 * Close a zs serial port. 380 */ 381int 382zsclose(dev, flags, mode, p) 383dev_t dev; 384int flags; 385int mode; 386struct proc *p; 387{ 388 register struct zs_chanstate *cs; 389 register struct tty *tp; 390 struct zs_softc *zi; 391 int unit = ZS_UNIT(dev); 392 int s; 393 394 zi = zscd.cd_devs[unit >> 1]; 395 cs = &zi->zi_cs[unit & 1]; 396 tp = cs->cs_ttyp; 397 linesw[tp->t_line].l_close(tp, flags); 398 if(tp->t_cflag & HUPCL || tp->t_state & TS_WOPEN || 399 (tp->t_state & TS_ISOPEN) == 0) { 400 zs_modem(cs, 0, DMSET); 401 /* hold low for 1 second */ 402 (void)tsleep((caddr_t)cs, TTIPRI, ttclos, hz); 403 } 404 if(cs->cs_creg[5] & ZSWR5_BREAK) { 405 s = splzs(); 406 cs->cs_preg[5] &= ~ZSWR5_BREAK; 407 cs->cs_creg[5] &= ~ZSWR5_BREAK; 408 ZS_WRITE(cs->cs_zc, 5, cs->cs_creg[5]); 409 splx(s); 410 } 411 ttyclose(tp); 412 413 /* 414 * Drop all lines and cancel interrupts 415 */ 416 zs_loadchannelregs(&zi->zi_zs->zs_chan[unit & 1], zs_init_regs); 417 return (0); 418} 419 420/* 421 * Read/write zs serial port. 422 */ 423int 424zsread(dev, uio, flags) 425dev_t dev; 426struct uio *uio; 427int flags; 428{ 429 register struct zs_chanstate *cs; 430 register struct zs_softc *zi; 431 register struct tty *tp; 432 int unit; 433 434 unit = ZS_UNIT(dev); 435 zi = zscd.cd_devs[unit >> 1]; 436 cs = &zi->zi_cs[unit & 1]; 437 tp = cs->cs_ttyp; 438 439 return(linesw[tp->t_line].l_read(tp, uio, flags)); 440} 441 442int 443zswrite(dev, uio, flags) 444dev_t dev; 445struct uio *uio; 446int flags; 447{ 448 register struct zs_chanstate *cs; 449 register struct zs_softc *zi; 450 register struct tty *tp; 451 int unit; 452 453 unit = ZS_UNIT(dev); 454 zi = zscd.cd_devs[unit >> 1]; 455 cs = &zi->zi_cs[unit & 1]; 456 tp = cs->cs_ttyp; 457 458 return(linesw[tp->t_line].l_write(tp, uio, flags)); 459} 460 461struct tty * 462zstty(dev) 463dev_t dev; 464{ 465 register struct zs_chanstate *cs; 466 register struct zs_softc *zi; 467 int unit; 468 469 unit = ZS_UNIT(dev); 470 zi = zscd.cd_devs[unit >> 1]; 471 cs = &zi->zi_cs[unit & 1]; 472 return(cs->cs_ttyp); 473} 474 475/* 476 * ZS hardware interrupt. Scan all ZS channels. NB: we know here that 477 * channels are kept in (A,B) pairs. 478 * 479 * Do just a little, then get out; set a software interrupt if more 480 * work is needed. 481 * 482 * We deliberately ignore the vectoring Zilog gives us, and match up 483 * only the number of `reset interrupt under service' operations, not 484 * the order. 485 */ 486 487int 488zshard(sr) 489long sr; 490{ 491 register struct zs_chanstate *a; 492#define b (a + 1) 493 register volatile struct zschan *zc; 494 register int rr3, intflags = 0, v, i; 495 496 do { 497 intflags &= ~4; 498 for(a = zslist; a != NULL; a = b->cs_next) { 499 rr3 = ZS_READ(a->cs_zc, 3); 500 if(rr3 & (ZSRR3_IP_A_RX|ZSRR3_IP_A_TX|ZSRR3_IP_A_STAT)) { 501 intflags |= 4|2; 502 zc = a->cs_zc; 503 i = a->cs_rbput; 504 if(rr3 & ZSRR3_IP_A_RX && (v = zsrint(a, zc)) != 0) { 505 a->cs_rbuf[i++ & ZLRB_RING_MASK] = v; 506 intflags |= 1; 507 } 508 if(rr3 & ZSRR3_IP_A_TX && (v = zsxint(a, zc)) != 0) { 509 a->cs_rbuf[i++ & ZLRB_RING_MASK] = v; 510 intflags |= 1; 511 } 512 if(rr3 & ZSRR3_IP_A_STAT && (v = zssint(a, zc)) != 0) { 513 a->cs_rbuf[i++ & ZLRB_RING_MASK] = v; 514 intflags |= 1; 515 } 516 a->cs_rbput = i; 517 } 518 if(rr3 & (ZSRR3_IP_B_RX|ZSRR3_IP_B_TX|ZSRR3_IP_B_STAT)) { 519 intflags |= 4|2; 520 zc = b->cs_zc; 521 i = b->cs_rbput; 522 if(rr3 & ZSRR3_IP_B_RX && (v = zsrint(b, zc)) != 0) { 523 b->cs_rbuf[i++ & ZLRB_RING_MASK] = v; 524 intflags |= 1; 525 } 526 if(rr3 & ZSRR3_IP_B_TX && (v = zsxint(b, zc)) != 0) { 527 b->cs_rbuf[i++ & ZLRB_RING_MASK] = v; 528 intflags |= 1; 529 } 530 if(rr3 & ZSRR3_IP_B_STAT && (v = zssint(b, zc)) != 0) { 531 b->cs_rbuf[i++ & ZLRB_RING_MASK] = v; 532 intflags |= 1; 533 } 534 b->cs_rbput = i; 535 } 536 } 537 } while(intflags & 4); 538#undef b 539 540 if(intflags & 1) { 541 if(BASEPRI(sr)) { 542 spl1(); 543 zsshortcuts++; 544 return(zssoft(sr)); 545 } 546 else if(!cb_scheduled) { 547 cb_scheduled++; 548 add_sicallback(zssoft, 0, 0); 549 } 550 } 551 return(intflags & 2); 552} 553 554static int 555zsrint(cs, zc) 556register struct zs_chanstate *cs; 557register volatile struct zschan *zc; 558{ 559 register int c; 560 561 /* 562 * First read the status, because read of the received char 563 * destroy the status of this char. 564 */ 565 c = ZS_READ(zc, 1); 566 c |= (zc->zc_data << 8); 567 568 /* clear receive error & interrupt condition */ 569 zc->zc_csr = ZSWR0_RESET_ERRORS; 570 zc->zc_csr = ZSWR0_CLR_INTR; 571 572 return(ZRING_MAKE(ZRING_RINT, c)); 573} 574 575static int 576zsxint(cs, zc) 577register struct zs_chanstate *cs; 578register volatile struct zschan *zc; 579{ 580 register int i = cs->cs_tbc; 581 582 if(i == 0) { 583 zc->zc_csr = ZSWR0_RESET_TXINT; 584 zc->zc_csr = ZSWR0_CLR_INTR; 585 return(ZRING_MAKE(ZRING_XINT, 0)); 586 } 587 cs->cs_tbc = i - 1; 588 zc->zc_data = *cs->cs_tba++; 589 zc->zc_csr = ZSWR0_CLR_INTR; 590 return (0); 591} 592 593static int 594zssint(cs, zc) 595register struct zs_chanstate *cs; 596register volatile struct zschan *zc; 597{ 598 register int rr0; 599 600 rr0 = zc->zc_csr; 601 zc->zc_csr = ZSWR0_RESET_STATUS; 602 zc->zc_csr = ZSWR0_CLR_INTR; 603 /* 604 * The chip's hardware flow control is, as noted in zsreg.h, 605 * busted---if the DCD line goes low the chip shuts off the 606 * receiver (!). If we want hardware CTS flow control but do 607 * not have it, and carrier is now on, turn HFC on; if we have 608 * HFC now but carrier has gone low, turn it off. 609 */ 610 if(rr0 & ZSRR0_DCD) { 611 if(cs->cs_ttyp->t_cflag & CCTS_OFLOW && 612 (cs->cs_creg[3] & ZSWR3_HFC) == 0) { 613 cs->cs_creg[3] |= ZSWR3_HFC; 614 ZS_WRITE(zc, 3, cs->cs_creg[3]); 615 } 616 } 617 else { 618 if (cs->cs_creg[3] & ZSWR3_HFC) { 619 cs->cs_creg[3] &= ~ZSWR3_HFC; 620 ZS_WRITE(zc, 3, cs->cs_creg[3]); 621 } 622 } 623 return(ZRING_MAKE(ZRING_SINT, rr0)); 624} 625 626/* 627 * Print out a ring or fifo overrun error message. 628 */ 629static void 630zsoverrun(unit, ptime, what) 631int unit; 632long *ptime; 633char *what; 634{ 635 636 if(*ptime != time.tv_sec) { 637 *ptime = time.tv_sec; 638 log(LOG_WARNING, "zs%d%c: %s overrun\n", unit >> 1, 639 (unit & 1) + 'a', what); 640 } 641} 642 643/* 644 * ZS software interrupt. Scan all channels for deferred interrupts. 645 */ 646int 647zssoft(sr) 648long sr; 649{ 650 register struct zs_chanstate *cs; 651 register volatile struct zschan *zc; 652 register struct linesw *line; 653 register struct tty *tp; 654 register int get, n, c, cc, unit, s; 655 int retval = 0; 656 657 cb_scheduled = 0; 658 s = spltty(); 659 for(cs = zslist; cs != NULL; cs = cs->cs_next) { 660 get = cs->cs_rbget; 661again: 662 n = cs->cs_rbput; /* atomic */ 663 if(get == n) /* nothing more on this line */ 664 continue; 665 retval = 1; 666 unit = cs->cs_unit; /* set up to handle interrupts */ 667 zc = cs->cs_zc; 668 tp = cs->cs_ttyp; 669 line = &linesw[tp->t_line]; 670 /* 671 * Compute the number of interrupts in the receive ring. 672 * If the count is overlarge, we lost some events, and 673 * must advance to the first valid one. It may get 674 * overwritten if more data are arriving, but this is 675 * too expensive to check and gains nothing (we already 676 * lost out; all we can do at this point is trade one 677 * kind of loss for another). 678 */ 679 n -= get; 680 if(n > ZLRB_RING_SIZE) { 681 zsoverrun(unit, &cs->cs_rotime, "ring"); 682 get += n - ZLRB_RING_SIZE; 683 n = ZLRB_RING_SIZE; 684 } 685 while(--n >= 0) { 686 /* race to keep ahead of incoming interrupts */ 687 c = cs->cs_rbuf[get++ & ZLRB_RING_MASK]; 688 switch (ZRING_TYPE(c)) { 689 690 case ZRING_RINT: 691 c = ZRING_VALUE(c); 692 if(c & ZSRR1_DO) 693 zsoverrun(unit, &cs->cs_fotime, "fifo"); 694 cc = c >> 8; 695 if(c & ZSRR1_FE) 696 cc |= TTY_FE; 697 if(c & ZSRR1_PE) 698 cc |= TTY_PE; 699 line->l_rint(cc, tp); 700 break; 701 702 case ZRING_XINT: 703 /* 704 * Transmit done: change registers and resume, 705 * or clear BUSY. 706 */ 707 if(cs->cs_heldchange) { 708 int sps; 709 710 sps = splzs(); 711 c = zc->zc_csr; 712 if((c & ZSRR0_DCD) == 0) 713 cs->cs_preg[3] &= ~ZSWR3_HFC; 714 bcopy((caddr_t)cs->cs_preg, 715 (caddr_t)cs->cs_creg, 16); 716 zs_loadchannelregs(zc, cs->cs_creg); 717 splx(sps); 718 cs->cs_heldchange = 0; 719 if(cs->cs_heldtbc 720 && (tp->t_state & TS_TTSTOP) == 0) { 721 cs->cs_tbc = cs->cs_heldtbc - 1; 722 zc->zc_data = *cs->cs_tba++; 723 goto again; 724 } 725 } 726 tp->t_state &= ~TS_BUSY; 727 if(tp->t_state & TS_FLUSH) 728 tp->t_state &= ~TS_FLUSH; 729 else ndflush(&tp->t_outq,cs->cs_tba 730 - (caddr_t)tp->t_outq.c_cf); 731 line->l_start(tp); 732 break; 733 734 case ZRING_SINT: 735 /* 736 * Status line change. HFC bit is run in 737 * hardware interrupt, to avoid locking 738 * at splzs here. 739 */ 740 c = ZRING_VALUE(c); 741 if((c ^ cs->cs_rr0) & ZSRR0_DCD) { 742 cc = (c & ZSRR0_DCD) != 0; 743 if(line->l_modem(tp, cc) == 0) 744 zs_modem(cs, ZSWR5_RTS|ZSWR5_DTR, 745 cc ? DMBIS : DMBIC); 746 } 747 cs->cs_rr0 = c; 748 break; 749 750 default: 751 log(LOG_ERR, "zs%d%c: bad ZRING_TYPE (%x)\n", 752 unit >> 1, (unit & 1) + 'a', c); 753 break; 754 } 755 } 756 cs->cs_rbget = get; 757 goto again; 758 } 759 splx(s); 760 return (retval); 761} 762 763int 764zsioctl(dev, cmd, data, flag, p) 765dev_t dev; 766u_long cmd; 767caddr_t data; 768int flag; 769struct proc *p; 770{ 771 int unit = ZS_UNIT(dev); 772 struct zs_softc *zi = zscd.cd_devs[unit >> 1]; 773 register struct tty *tp = zi->zi_cs[unit & 1].cs_ttyp; 774 register int error, s; 775 register struct zs_chanstate *cs = &zi->zi_cs[unit & 1]; 776 777 error = linesw[tp->t_line].l_ioctl(tp, cmd, data, flag, p); 778 if(error >= 0) 779 return(error); 780 error = ttioctl(tp, cmd, data, flag, p); 781 if(error >= 0) 782 return (error); 783 784 switch (cmd) { 785 case TIOCSBRK: 786 s = splzs(); 787 cs->cs_preg[5] |= ZSWR5_BREAK; 788 cs->cs_creg[5] |= ZSWR5_BREAK; 789 ZS_WRITE(cs->cs_zc, 5, cs->cs_creg[5]); 790 splx(s); 791 break; 792 case TIOCCBRK: 793 s = splzs(); 794 cs->cs_preg[5] &= ~ZSWR5_BREAK; 795 cs->cs_creg[5] &= ~ZSWR5_BREAK; 796 ZS_WRITE(cs->cs_zc, 5, cs->cs_creg[5]); 797 splx(s); 798 break; 799 case TIOCGFLAGS: { 800 int bits = 0; 801 802 if(cs->cs_softcar) 803 bits |= TIOCFLAG_SOFTCAR; 804 if(cs->cs_creg[15] & ZSWR15_DCD_IE) 805 bits |= TIOCFLAG_CLOCAL; 806 if(cs->cs_creg[3] & ZSWR3_HFC) 807 bits |= TIOCFLAG_CRTSCTS; 808 *(int *)data = bits; 809 break; 810 } 811 case TIOCSFLAGS: { 812 int userbits, driverbits = 0; 813 814 error = suser(p->p_ucred, &p->p_acflag); 815 if(error != 0) 816 return (EPERM); 817 818 userbits = *(int *)data; 819 820 /* 821 * can have `local' or `softcar', and `rtscts' or `mdmbuf' 822 # defaulting to software flow control. 823 */ 824 if(userbits & TIOCFLAG_SOFTCAR && userbits & TIOCFLAG_CLOCAL) 825 return(EINVAL); 826 if(userbits & TIOCFLAG_MDMBUF) /* don't support this (yet?) */ 827 return(ENODEV); 828 829 s = splzs(); 830 if((userbits & TIOCFLAG_SOFTCAR)) { 831 cs->cs_softcar = 1; /* turn on softcar */ 832 cs->cs_preg[15] &= ~ZSWR15_DCD_IE; /* turn off dcd */ 833 cs->cs_creg[15] &= ~ZSWR15_DCD_IE; 834 ZS_WRITE(cs->cs_zc, 15, cs->cs_creg[15]); 835 } 836 else if(userbits & TIOCFLAG_CLOCAL) { 837 cs->cs_softcar = 0; /* turn off softcar */ 838 cs->cs_preg[15] |= ZSWR15_DCD_IE; /* turn on dcd */ 839 cs->cs_creg[15] |= ZSWR15_DCD_IE; 840 ZS_WRITE(cs->cs_zc, 15, cs->cs_creg[15]); 841 tp->t_termios.c_cflag |= CLOCAL; 842 } 843 if(userbits & TIOCFLAG_CRTSCTS) { 844 cs->cs_preg[15] |= ZSWR15_CTS_IE; 845 cs->cs_creg[15] |= ZSWR15_CTS_IE; 846 ZS_WRITE(cs->cs_zc, 15, cs->cs_creg[15]); 847 cs->cs_preg[3] |= ZSWR3_HFC; 848 cs->cs_creg[3] |= ZSWR3_HFC; 849 ZS_WRITE(cs->cs_zc, 3, cs->cs_creg[3]); 850 tp->t_termios.c_cflag |= CRTSCTS; 851 } 852 else { 853 /* no mdmbuf, so we must want software flow control */ 854 cs->cs_preg[15] &= ~ZSWR15_CTS_IE; 855 cs->cs_creg[15] &= ~ZSWR15_CTS_IE; 856 ZS_WRITE(cs->cs_zc, 15, cs->cs_creg[15]); 857 cs->cs_preg[3] &= ~ZSWR3_HFC; 858 cs->cs_creg[3] &= ~ZSWR3_HFC; 859 ZS_WRITE(cs->cs_zc, 3, cs->cs_creg[3]); 860 tp->t_termios.c_cflag &= ~CRTSCTS; 861 } 862 splx(s); 863 break; 864 } 865 case TIOCSDTR: 866 zs_modem(cs, ZSWR5_DTR, DMBIS); 867 break; 868 case TIOCCDTR: 869 zs_modem(cs, ZSWR5_DTR, DMBIC); 870 break; 871 case TIOCMGET: 872 zs_modem(cs, 0, DMGET); 873 break; 874 case TIOCMSET: 875 case TIOCMBIS: 876 case TIOCMBIC: 877 default: 878 return (ENOTTY); 879 } 880 return (0); 881} 882 883/* 884 * Start or restart transmission. 885 */ 886static void 887zsstart(tp) 888register struct tty *tp; 889{ 890 register struct zs_chanstate *cs; 891 register int s, nch; 892 int unit = ZS_UNIT(tp->t_dev); 893 struct zs_softc *zi = zscd.cd_devs[unit >> 1]; 894 895 cs = &zi->zi_cs[unit & 1]; 896 s = spltty(); 897 898 /* 899 * If currently active or delaying, no need to do anything. 900 */ 901 if(tp->t_state & (TS_TIMEOUT | TS_BUSY | TS_TTSTOP)) 902 goto out; 903 904 /* 905 * If there are sleepers, and output has drained below low 906 * water mark, awaken. 907 */ 908 if(tp->t_outq.c_cc <= tp->t_lowat) { 909 if(tp->t_state & TS_ASLEEP) { 910 tp->t_state &= ~TS_ASLEEP; 911 wakeup((caddr_t)&tp->t_outq); 912 } 913 selwakeup(&tp->t_wsel); 914 } 915 916 nch = ndqb(&tp->t_outq, 0); /* XXX */ 917 if(nch) { 918 register char *p = tp->t_outq.c_cf; 919 920 /* mark busy, enable tx done interrupts, & send first byte */ 921 tp->t_state |= TS_BUSY; 922 (void) splzs(); 923 cs->cs_preg[1] |= ZSWR1_TIE; 924 cs->cs_creg[1] |= ZSWR1_TIE; 925 ZS_WRITE(cs->cs_zc, 1, cs->cs_creg[1]); 926 cs->cs_zc->zc_data = *p; 927 cs->cs_tba = p + 1; 928 cs->cs_tbc = nch - 1; 929 } else { 930 /* 931 * Nothing to send, turn off transmit done interrupts. 932 * This is useful if something is doing polled output. 933 */ 934 (void) splzs(); 935 cs->cs_preg[1] &= ~ZSWR1_TIE; 936 cs->cs_creg[1] &= ~ZSWR1_TIE; 937 ZS_WRITE(cs->cs_zc, 1, cs->cs_creg[1]); 938 } 939out: 940 splx(s); 941} 942 943/* 944 * Stop output, e.g., for ^S or output flush. 945 */ 946void 947zsstop(tp, flag) 948register struct tty *tp; 949 int flag; 950{ 951 register struct zs_chanstate *cs; 952 register int s, unit = ZS_UNIT(tp->t_dev); 953 struct zs_softc *zi = zscd.cd_devs[unit >> 1]; 954 955 cs = &zi->zi_cs[unit & 1]; 956 s = splzs(); 957 if(tp->t_state & TS_BUSY) { 958 /* 959 * Device is transmitting; must stop it. 960 */ 961 cs->cs_tbc = 0; 962 if ((tp->t_state & TS_TTSTOP) == 0) 963 tp->t_state |= TS_FLUSH; 964 } 965 splx(s); 966} 967 968/* 969 * Set ZS tty parameters from termios. 970 * 971 * This routine makes use of the fact that only registers 972 * 1, 3, 4, 5, 9, 10, 11, 12, 13, 14, and 15 are written. 973 */ 974static int 975zsparam(tp, t) 976register struct tty *tp; 977register struct termios *t; 978{ 979 int unit = ZS_UNIT(tp->t_dev); 980 struct zs_softc *zi = zscd.cd_devs[unit >> 1]; 981 register struct zs_chanstate *cs = &zi->zi_cs[unit & 1]; 982 int cdiv, clkm, brgm, tcon; 983 register int tmp, tmp5, cflag, s; 984 985 tmp = t->c_ospeed; 986 tmp5 = t->c_ispeed; 987 if(tmp < 0 || (tmp5 && tmp5 != tmp)) 988 return(EINVAL); 989 if(tmp == 0) { 990 /* stty 0 => drop DTR and RTS */ 991 zs_modem(cs, 0, DMSET); 992 return(0); 993 } 994 tmp = zsbaudrate(unit, tmp, &cdiv, &clkm, &brgm, &tcon); 995 if (tmp < 0) 996 return(EINVAL); 997 tp->t_ispeed = tp->t_ospeed = tmp; 998 999 cflag = tp->t_cflag = t->c_cflag; 1000 if (cflag & CSTOPB) 1001 cdiv |= ZSWR4_TWOSB; 1002 else 1003 cdiv |= ZSWR4_ONESB; 1004 if (!(cflag & PARODD)) 1005 cdiv |= ZSWR4_EVENP; 1006 if (cflag & PARENB) 1007 cdiv |= ZSWR4_PARENB; 1008 1009 switch(cflag & CSIZE) { 1010 case CS5: 1011 tmp = ZSWR3_RX_5; 1012 tmp5 = ZSWR5_TX_5; 1013 break; 1014 case CS6: 1015 tmp = ZSWR3_RX_6; 1016 tmp5 = ZSWR5_TX_6; 1017 break; 1018 case CS7: 1019 tmp = ZSWR3_RX_7; 1020 tmp5 = ZSWR5_TX_7; 1021 break; 1022 case CS8: 1023 default: 1024 tmp = ZSWR3_RX_8; 1025 tmp5 = ZSWR5_TX_8; 1026 break; 1027 } 1028 tmp |= ZSWR3_RX_ENABLE; 1029 tmp5 |= ZSWR5_TX_ENABLE | ZSWR5_DTR | ZSWR5_RTS; 1030 1031 /* 1032 * Block interrupts so that state will not 1033 * be altered until we are done setting it up. 1034 */ 1035 s = splzs(); 1036 cs->cs_preg[4] = cdiv; 1037 cs->cs_preg[11] = clkm; 1038 cs->cs_preg[12] = tcon; 1039 cs->cs_preg[13] = tcon >> 8; 1040 cs->cs_preg[14] = brgm; 1041 cs->cs_preg[1] = ZSWR1_RIE | ZSWR1_TIE | ZSWR1_SIE; 1042 cs->cs_preg[9] = ZSWR9_MASTER_IE | ZSWR9_VECTOR_INCL_STAT; 1043 cs->cs_preg[10] = ZSWR10_NRZ; 1044 cs->cs_preg[15] = ZSWR15_BREAK_IE | ZSWR15_DCD_IE; 1045 1046 /* 1047 * Output hardware flow control on the chip is horrendous: if 1048 * carrier detect drops, the receiver is disabled. Hence we 1049 * can only do this when the carrier is on. 1050 */ 1051 if(cflag & CCTS_OFLOW && cs->cs_zc->zc_csr & ZSRR0_DCD) 1052 tmp |= ZSWR3_HFC; 1053 cs->cs_preg[3] = tmp; 1054 cs->cs_preg[5] = tmp5; 1055 1056 /* 1057 * If nothing is being transmitted, set up new current values, 1058 * else mark them as pending. 1059 */ 1060 if(cs->cs_heldchange == 0) { 1061 if (cs->cs_ttyp->t_state & TS_BUSY) { 1062 cs->cs_heldtbc = cs->cs_tbc; 1063 cs->cs_tbc = 0; 1064 cs->cs_heldchange = 1; 1065 } else { 1066 bcopy((caddr_t)cs->cs_preg, (caddr_t)cs->cs_creg, 16); 1067 zs_loadchannelregs(cs->cs_zc, cs->cs_creg); 1068 } 1069 } 1070 splx(s); 1071 return (0); 1072} 1073 1074/* 1075 * search for the best matching baudrate 1076 */ 1077static int 1078zsbaudrate(unit, wanted, divisor, clockmode, brgenmode, timeconst) 1079int unit, wanted, *divisor, *clockmode, *brgenmode, *timeconst; 1080{ 1081 int bestdiff, bestbps, source; 1082 1083 unit = (unit & 1) << 2; 1084 for (source = 0; source < 4; ++source) { 1085 long freq = zs_frequencies[unit + source]; 1086 int diff, bps, div, clkm, brgm, tcon; 1087 switch (source) { 1088 case 0: /* BRgen, PCLK */ 1089 brgm = ZSWR14_BAUD_ENA|ZSWR14_BAUD_FROM_PCLK; 1090 break; 1091 case 1: /* BRgen, RTxC */ 1092 brgm = ZSWR14_BAUD_ENA; 1093 break; 1094 case 2: /* RTxC */ 1095 clkm = ZSWR11_RXCLK_RTXC|ZSWR11_TXCLK_RTXC; 1096 break; 1097 case 3: /* TRxC */ 1098 clkm = ZSWR11_RXCLK_TRXC|ZSWR11_TXCLK_TRXC; 1099 break; 1100 } 1101 switch (source) { 1102 case 0: 1103 case 1: 1104 div = ZSWR4_CLK_X16; 1105 clkm = ZSWR11_RXCLK_BAUD|ZSWR11_TXCLK_BAUD; 1106 tcon = BPS_TO_TCONST(freq, wanted); 1107 if (tcon < 0) 1108 tcon = 0; 1109 bps = TCONST_TO_BPS(freq, tcon); 1110 break; 1111 case 2: 1112 case 3: 1113 { int b1 = freq / 16, d1 = abs(b1 - wanted); 1114 int b2 = freq / 32, d2 = abs(b2 - wanted); 1115 int b3 = freq / 64, d3 = abs(b3 - wanted); 1116 1117 if (d1 < d2 && d1 < d3) { 1118 div = ZSWR4_CLK_X16; 1119 bps = b1; 1120 } else if (d2 < d3 && d2 < d1) { 1121 div = ZSWR4_CLK_X32; 1122 bps = b2; 1123 } else { 1124 div = ZSWR4_CLK_X64; 1125 bps = b3; 1126 } 1127 brgm = tcon = 0; 1128 break; 1129 } 1130 } 1131 diff = abs(bps - wanted); 1132 if (!source || diff < bestdiff) { 1133 *divisor = div; 1134 *clockmode = clkm; 1135 *brgenmode = brgm; 1136 *timeconst = tcon; 1137 bestbps = bps; 1138 bestdiff = diff; 1139 if (diff == 0) 1140 break; 1141 } 1142 } 1143 /* Allow deviations upto 5% */ 1144 if (20 * bestdiff > wanted) 1145 return -1; 1146 return bestbps; 1147} 1148 1149/* 1150 * Raise or lower modem control (DTR/RTS) signals. If a character is 1151 * in transmission, the change is deferred. 1152 */ 1153static int 1154zs_modem(cs, bits, how) 1155struct zs_chanstate *cs; 1156int bits, how; 1157{ 1158 int s, mbits; 1159 1160 bits &= ZSWR5_DTR | ZSWR5_RTS; 1161 1162 s = splzs(); 1163 mbits = cs->cs_preg[5] & (ZSWR5_DTR | ZSWR5_RTS); 1164 1165 switch(how) { 1166 case DMSET: 1167 mbits = bits; 1168 break; 1169 case DMBIS: 1170 mbits |= bits; 1171 break; 1172 case DMBIC: 1173 mbits &= ~bits; 1174 break; 1175 case DMGET: 1176 splx(s); 1177 return(mbits); 1178 } 1179 1180 cs->cs_preg[5] = (cs->cs_preg[5] & ~(ZSWR5_DTR | ZSWR5_RTS)) | mbits; 1181 if(cs->cs_heldchange == 0) { 1182 if(cs->cs_ttyp->t_state & TS_BUSY) { 1183 cs->cs_heldtbc = cs->cs_tbc; 1184 cs->cs_tbc = 0; 1185 cs->cs_heldchange = 1; 1186 } 1187 else { 1188 ZS_WRITE(cs->cs_zc, 5, cs->cs_creg[5]); 1189 } 1190 } 1191 splx(s); 1192 return(0); 1193} 1194 1195/* 1196 * Write the given register set to the given zs channel in the proper order. 1197 * The channel must not be transmitting at the time. The receiver will 1198 * be disabled for the time it takes to write all the registers. 1199 */ 1200static void 1201zs_loadchannelregs(zc, reg) 1202volatile struct zschan *zc; 1203u_char *reg; 1204{ 1205 int i; 1206 1207 zc->zc_csr = ZSM_RESET_ERR; /* reset error condition */ 1208 i = zc->zc_data; /* drain fifo */ 1209 i = zc->zc_data; 1210 i = zc->zc_data; 1211 ZS_WRITE(zc, 4, reg[4]); 1212 ZS_WRITE(zc, 10, reg[10]); 1213 ZS_WRITE(zc, 3, reg[3] & ~ZSWR3_RX_ENABLE); 1214 ZS_WRITE(zc, 5, reg[5] & ~ZSWR5_TX_ENABLE); 1215 ZS_WRITE(zc, 1, reg[1]); 1216 ZS_WRITE(zc, 9, reg[9]); 1217 ZS_WRITE(zc, 11, reg[11]); 1218 ZS_WRITE(zc, 12, reg[12]); 1219 ZS_WRITE(zc, 13, reg[13]); 1220 ZS_WRITE(zc, 14, reg[14]); 1221 ZS_WRITE(zc, 15, reg[15]); 1222 ZS_WRITE(zc, 3, reg[3]); 1223 ZS_WRITE(zc, 5, reg[5]); 1224} 1225#endif /* NZS > 1 */ 1226