1 /* 2 * Copyright (c) 1992, 1993 3 * The Regents of the University of California. All rights reserved. 4 * 5 * This software was developed by the Computer Systems Engineering group 6 * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and 7 * contributed to Berkeley. 8 * 9 * All advertising materials mentioning features or use of this software 10 * must display the following acknowledgement: 11 * This product includes software developed by the University of 12 * California, Lawrence Berkeley Laboratory. 13 * 14 * Redistribution and use in source and binary forms, with or without 15 * modification, are permitted provided that the following conditions 16 * are met: 17 * 1. Redistributions of source code must retain the above copyright 18 * notice, this list of conditions and the following disclaimer. 19 * 2. Redistributions in binary form must reproduce the above copyright 20 * notice, this list of conditions and the following disclaimer in the 21 * documentation and/or other materials provided with the distribution. 22 * 3. All advertising materials mentioning features or use of this software 23 * must display the following acknowledgement: 24 * This product includes software developed by the University of 25 * California, Berkeley and its contributors. 26 * 4. Neither the name of the University nor the names of its contributors 27 * may be used to endorse or promote products derived from this software 28 * without specific prior written permission. 29 * 30 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 31 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 32 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 33 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 34 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 35 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 36 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 37 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 38 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 39 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 40 * SUCH DAMAGE. 41 * 42 * @(#)zs.c 8.1 (Berkeley) 7/19/93 43 * 44 * from: Header: zs.c,v 1.30 93/07/19 23:44:42 torek Exp 45 * $Id: zs.c,v 1.12 1994/08/20 09:11:02 deraadt Exp $ 46 */ 47 48 /* 49 * Zilog Z8530 (ZSCC) driver. 50 * 51 * Runs two tty ports (ttya and ttyb) on zs0, 52 * and runs a keyboard and mouse on zs1. 53 * 54 * This driver knows far too much about chip to usage mappings. 55 */ 56 #define NZS 2 /* XXX */ 57 58 #include <sys/param.h> 59 #include <sys/proc.h> 60 #include <sys/device.h> 61 #include <sys/conf.h> 62 #include <sys/file.h> 63 #include <sys/ioctl.h> 64 #include <sys/tty.h> 65 #include <sys/time.h> 66 #include <sys/kernel.h> 67 #include <sys/syslog.h> 68 69 #include <machine/autoconf.h> 70 #include <machine/cpu.h> 71 72 #include <sparc/sparc/vaddrs.h> 73 #include <sparc/sparc/auxreg.h> 74 75 #include <machine/kbd.h> 76 #include <sparc/dev/zsreg.h> 77 #include <sparc/dev/zsvar.h> 78 79 #ifdef KGDB 80 #include <machine/remote-sl.h> 81 #endif 82 83 #define ZSMAJOR 12 /* XXX */ 84 85 #define ZS_KBD 2 /* XXX */ 86 #define ZS_MOUSE 3 /* XXX */ 87 88 /* the magic number below was stolen from the Sprite source. */ 89 #define PCLK (19660800/4) /* PCLK pin input clock rate */ 90 91 /* 92 * Select software interrupt bit based on TTY ipl. 93 */ 94 #if PIL_TTY == 1 95 # define IE_ZSSOFT IE_L1 96 #elif PIL_TTY == 4 97 # define IE_ZSSOFT IE_L4 98 #elif PIL_TTY == 6 99 # define IE_ZSSOFT IE_L6 100 #else 101 # error "no suitable software interrupt bit" 102 #endif 103 104 /* 105 * Software state per found chip. This would be called `zs_softc', 106 * but the previous driver had a rather different zs_softc.... 107 */ 108 struct zsinfo { 109 struct device zi_dev; /* base device */ 110 volatile struct zsdevice *zi_zs;/* chip registers */ 111 struct zs_chanstate zi_cs[2]; /* channel A and B software state */ 112 }; 113 114 struct tty *zs_tty[NZS * 2]; /* XXX should be dynamic */ 115 116 /* Definition of the driver for autoconfig. */ 117 static int zsmatch(struct device *, struct cfdata *, void *); 118 static void zsattach(struct device *, struct device *, void *); 119 struct cfdriver zscd = 120 { NULL, "zs", zsmatch, zsattach, DV_TTY, sizeof(struct zsinfo) }; 121 122 /* Interrupt handlers. */ 123 static int zshard(void *); 124 static struct intrhand levelhard = { zshard }; 125 static int zssoft(void *); 126 static struct intrhand levelsoft = { zssoft }; 127 128 struct zs_chanstate *zslist; 129 130 /* Routines called from other code. */ 131 static void zsiopen(struct tty *); 132 static void zsiclose(struct tty *); 133 static void zsstart(struct tty *); 134 void zsstop(struct tty *, int); 135 static int zsparam(struct tty *, struct termios *); 136 137 /* Routines purely local to this driver. */ 138 static int zs_getspeed(volatile struct zschan *); 139 static void zs_reset(volatile struct zschan *, int, int); 140 static void zs_modem(struct zs_chanstate *, int); 141 static void zs_loadchannelregs(volatile struct zschan *, u_char *); 142 143 /* Console stuff. */ 144 static struct tty *zs_ctty; /* console `struct tty *' */ 145 static int zs_consin = -1, zs_consout = -1; 146 static int zscnputc(int); /* console putc function */ 147 static volatile struct zschan *zs_conschan; 148 static struct tty *zs_checkcons(struct zsinfo *, int, struct zs_chanstate *); 149 150 #ifdef KGDB 151 /* KGDB stuff. Must reboot to change zs_kgdbunit. */ 152 extern int kgdb_dev, kgdb_rate; 153 static int zs_kgdb_savedspeed; 154 static void zs_checkkgdb(int, struct zs_chanstate *, struct tty *); 155 #endif 156 157 extern volatile struct zsdevice *findzs(int); 158 static volatile struct zsdevice *zsaddr[NZS]; /* XXX, but saves work */ 159 160 /* 161 * Console keyboard L1-A processing is done in the hardware interrupt code, 162 * so we need to duplicate some of the console keyboard decode state. (We 163 * must not use the regular state as the hardware code keeps ahead of the 164 * software state: the software state tracks the most recent ring input but 165 * the hardware state tracks the most recent ZSCC input.) See also kbd.h. 166 */ 167 static struct conk_state { /* console keyboard state */ 168 char conk_id; /* true => ID coming up (console only) */ 169 char conk_l1; /* true => L1 pressed (console only) */ 170 } zsconk_state; 171 172 int zshardscope; 173 int zsshortcuts; /* number of "shortcut" software interrupts */ 174 175 #ifdef SUN4 176 static u_char 177 zs_read(zc, reg) 178 volatile struct zschan *zc; 179 u_char reg; 180 { 181 u_char val; 182 183 zc->zc_csr = reg; 184 ZS_DELAY(); 185 val = zc->zc_csr; 186 ZS_DELAY(); 187 return val; 188 } 189 190 static u_char 191 zs_write(zc, reg, val) 192 volatile struct zschan *zc; 193 u_char reg, val; 194 { 195 zc->zc_csr = reg; 196 ZS_DELAY(); 197 zc->zc_csr = val; 198 ZS_DELAY(); 199 return val; 200 } 201 #endif /* SUN4 */ 202 203 /* 204 * Match slave number to zs unit number, so that misconfiguration will 205 * not set up the keyboard as ttya, etc. 206 */ 207 static int 208 zsmatch(struct device *parent, struct cfdata *cf, void *aux) 209 { 210 struct romaux *ra = aux; 211 212 return (getpropint(ra->ra_node, "slave", -2) == cf->cf_unit); 213 } 214 215 /* 216 * Attach a found zs. 217 * 218 * USE ROM PROPERTIES port-a-ignore-cd AND port-b-ignore-cd FOR 219 * SOFT CARRIER, AND keyboard PROPERTY FOR KEYBOARD/MOUSE? 220 */ 221 static void 222 zsattach(struct device *parent, struct device *dev, void *aux) 223 { 224 register int zs = dev->dv_unit, unit; 225 register struct zsinfo *zi; 226 register struct zs_chanstate *cs; 227 register volatile struct zsdevice *addr; 228 register struct tty *tp, *ctp; 229 register struct romaux *ra = aux; 230 int pri, softcar; 231 static int didintr, prevpri; 232 233 if ((addr = zsaddr[zs]) == NULL) 234 addr = zsaddr[zs] = findzs(zs); 235 if ((void *)addr != ra->ra_vaddr) 236 panic("zsattach"); 237 if (ra->ra_nintr != 1) { 238 printf(": expected 1 interrupt, got %d\n", ra->ra_nintr); 239 return; 240 } 241 pri = ra->ra_intr[0].int_pri; 242 printf(" pri %d, softpri %d\n", pri, PIL_TTY); 243 if (!didintr) { 244 didintr = 1; 245 prevpri = pri; 246 intr_establish(pri, &levelhard); 247 intr_establish(PIL_TTY, &levelsoft); 248 } else if (pri != prevpri) 249 panic("broken zs interrupt scheme"); 250 zi = (struct zsinfo *)dev; 251 zi->zi_zs = addr; 252 unit = zs * 2; 253 cs = zi->zi_cs; 254 255 if(!zs_tty[unit]) 256 zs_tty[unit] = ttymalloc(); 257 tp = zs_tty[unit]; 258 if(!zs_tty[unit+1]) 259 zs_tty[unit+1] = ttymalloc(); 260 261 if (unit == 0) { 262 /* Get software carrier flags from options node in OPENPROM. */ 263 extern int optionsnode; 264 265 softcar = 0; 266 if (*getpropstring(optionsnode, "ttya-ignore-cd") == 't') 267 softcar |= 1; 268 if (*getpropstring(optionsnode, "ttyb-ignore-cd") == 't') 269 softcar |= 2; 270 } else 271 softcar = dev->dv_cfdata->cf_flags; 272 273 /* link into interrupt list with order (A,B) (B=A+1) */ 274 cs[0].cs_next = &cs[1]; 275 cs[1].cs_next = zslist; 276 zslist = cs; 277 278 cs->cs_unit = unit; 279 cs->cs_speed = zs_getspeed(&addr->zs_chan[CHAN_A]); 280 cs->cs_softcar = softcar & 1; 281 cs->cs_zc = &addr->zs_chan[CHAN_A]; 282 tp->t_dev = makedev(ZSMAJOR, unit); 283 tp->t_oproc = zsstart; 284 tp->t_param = zsparam; 285 if ((ctp = zs_checkcons(zi, unit, cs)) != NULL) 286 tp = ctp; 287 cs->cs_ttyp = tp; 288 #ifdef KGDB 289 if (ctp == NULL) 290 zs_checkkgdb(unit, cs, tp); 291 #endif 292 if (unit == ZS_KBD) { 293 /* 294 * Keyboard: tell /dev/kbd driver how to talk to us. 295 */ 296 tp->t_ispeed = tp->t_ospeed = cs->cs_speed; 297 tp->t_cflag = CS8; 298 kbd_serial(tp, zsiopen, zsiclose); 299 cs->cs_conk = 1; /* do L1-A processing */ 300 } 301 unit++; 302 cs++; 303 tp = zs_tty[unit]; 304 cs->cs_unit = unit; 305 cs->cs_speed = zs_getspeed(&addr->zs_chan[CHAN_B]); 306 cs->cs_softcar = softcar & 2; 307 cs->cs_zc = &addr->zs_chan[CHAN_B]; 308 tp->t_dev = makedev(ZSMAJOR, unit); 309 tp->t_oproc = zsstart; 310 tp->t_param = zsparam; 311 if ((ctp = zs_checkcons(zi, unit, cs)) != NULL) 312 tp = ctp; 313 cs->cs_ttyp = tp; 314 #ifdef KGDB 315 if (ctp == NULL) 316 zs_checkkgdb(unit, cs, tp); 317 #endif 318 if (unit == ZS_MOUSE) { 319 /* 320 * Mouse: tell /dev/mouse driver how to talk to us. 321 */ 322 tp->t_ispeed = tp->t_ospeed = cs->cs_speed; 323 tp->t_cflag = CS8; 324 ms_serial(tp, zsiopen, zsiclose); 325 } 326 } 327 328 /* 329 * Put a channel in a known state. Interrupts may be left disabled 330 * or enabled, as desired. 331 */ 332 static void 333 zs_reset(zc, inten, speed) 334 volatile struct zschan *zc; 335 int inten, speed; 336 { 337 int tconst; 338 static u_char reg[16] = { 339 0, 340 0, 341 0, 342 ZSWR3_RX_8 | ZSWR3_RX_ENABLE, 343 ZSWR4_CLK_X16 | ZSWR4_ONESB | ZSWR4_EVENP, 344 ZSWR5_TX_8 | ZSWR5_TX_ENABLE, 345 0, 346 0, 347 0, 348 0, 349 ZSWR10_NRZ, 350 ZSWR11_TXCLK_BAUD | ZSWR11_RXCLK_BAUD, 351 0, 352 0, 353 ZSWR14_BAUD_FROM_PCLK | ZSWR14_BAUD_ENA, 354 ZSWR15_BREAK_IE | ZSWR15_DCD_IE, 355 }; 356 357 reg[9] = inten ? ZSWR9_MASTER_IE | ZSWR9_NO_VECTOR : ZSWR9_NO_VECTOR; 358 tconst = BPS_TO_TCONST(PCLK / 16, speed); 359 reg[12] = tconst; 360 reg[13] = tconst >> 8; 361 zs_loadchannelregs(zc, reg); 362 } 363 364 /* 365 * Declare the given tty (which is in fact &cons) as a console input 366 * or output. This happens before the zs chip is attached; the hookup 367 * is finished later, in zs_setcons() below. 368 * 369 * This is used only for ports a and b. The console keyboard is decoded 370 * independently (we always send unit-2 input to /dev/kbd, which will 371 * direct it to /dev/console if appropriate). 372 */ 373 void 374 zsconsole(tp, unit, out, fnstop) 375 register struct tty *tp; 376 register int unit; 377 int out; 378 void (**fnstop) __P((struct tty *, int)); 379 { 380 extern int (*v_putc)(); 381 int zs; 382 volatile struct zsdevice *addr; 383 384 if (unit >= ZS_KBD) 385 panic("zsconsole"); 386 if (out) { 387 zs_consout = unit; 388 zs = unit >> 1; 389 if ((addr = zsaddr[zs]) == NULL) 390 addr = zsaddr[zs] = findzs(zs); 391 zs_conschan = (unit & 1) == 0 ? &addr->zs_chan[CHAN_A] : 392 &addr->zs_chan[CHAN_B]; 393 v_putc = zscnputc; 394 } else 395 zs_consin = unit; 396 if(fnstop) 397 *fnstop = &zsstop; 398 zs_ctty = tp; 399 } 400 401 /* 402 * Polled console output putchar. 403 */ 404 static int 405 zscnputc(c) 406 int c; 407 { 408 register volatile struct zschan *zc = zs_conschan; 409 register int s; 410 411 if (c == '\n') 412 zscnputc('\r'); 413 /* 414 * Must block output interrupts (i.e., raise to >= splzs) without 415 * lowering current ipl. Need a better way. 416 */ 417 s = splhigh(); 418 #ifdef SUN4C /* XXX */ 419 if (s <= (12 << 8)) 420 (void) splzs(); 421 #endif 422 while ((zc->zc_csr & ZSRR0_TX_READY) == 0) 423 ZS_DELAY(); 424 zc->zc_data = c; 425 ZS_DELAY(); 426 splx(s); 427 } 428 429 /* 430 * Set up the given unit as console input, output, both, or neither, as 431 * needed. Return console tty if it is to receive console input. 432 */ 433 static struct tty * 434 zs_checkcons(struct zsinfo *zi, int unit, struct zs_chanstate *cs) 435 { 436 register struct tty *tp; 437 char *i, *o; 438 439 if ((tp = zs_ctty) == NULL) 440 return (0); 441 i = zs_consin == unit ? "input" : NULL; 442 o = zs_consout == unit ? "output" : NULL; 443 if (i == NULL && o == NULL) 444 return (0); 445 446 /* rewire the minor device (gack) */ 447 tp->t_dev = makedev(major(tp->t_dev), unit); 448 449 /* 450 * Rewire input and/or output. Note that baud rate reflects 451 * input settings, not output settings, but we can do no better 452 * if the console is split across two ports. 453 * 454 * XXX split consoles don't work anyway -- this needs to be 455 * thrown away and redone 456 */ 457 if (i) { 458 tp->t_param = zsparam; 459 tp->t_ispeed = tp->t_ospeed = cs->cs_speed; 460 tp->t_cflag = CS8; 461 ttsetwater(tp); 462 } 463 if (o) { 464 tp->t_oproc = zsstart; 465 } 466 printf("%s%c: console %s\n", 467 zi->zi_dev.dv_xname, (unit & 1) + 'a', i ? (o ? "i/o" : i) : o); 468 cs->cs_consio = 1; 469 cs->cs_brkabort = 1; 470 return (tp); 471 } 472 473 #ifdef KGDB 474 /* 475 * The kgdb zs port, if any, was altered at boot time (see zs_kgdb_init). 476 * Pick up the current speed and character size and restore the original 477 * speed. 478 */ 479 static void 480 zs_checkkgdb(int unit, struct zs_chanstate *cs, struct tty *tp) 481 { 482 483 if (kgdb_dev == makedev(ZSMAJOR, unit)) { 484 tp->t_ispeed = tp->t_ospeed = kgdb_rate; 485 tp->t_cflag = CS8; 486 cs->cs_kgdb = 1; 487 cs->cs_speed = zs_kgdb_savedspeed; 488 (void) zsparam(tp, &tp->t_termios); 489 } 490 } 491 #endif 492 493 /* 494 * Compute the current baud rate given a ZSCC channel. 495 */ 496 static int 497 zs_getspeed(zc) 498 register volatile struct zschan *zc; 499 { 500 register int tconst; 501 502 tconst = ZS_READ(zc, 12); 503 tconst |= ZS_READ(zc, 13) << 8; 504 return (TCONST_TO_BPS(PCLK / 16, tconst)); 505 } 506 507 508 /* 509 * Do an internal open. 510 */ 511 static void 512 zsiopen(struct tty *tp) 513 { 514 515 (void) zsparam(tp, &tp->t_termios); 516 ttsetwater(tp); 517 tp->t_state = TS_ISOPEN | TS_CARR_ON; 518 } 519 520 /* 521 * Do an internal close. Eventually we should shut off the chip when both 522 * ports on it are closed. 523 */ 524 static void 525 zsiclose(struct tty *tp) 526 { 527 528 ttylclose(tp, 0); /* ??? */ 529 ttyclose(tp); /* ??? */ 530 tp->t_state = 0; 531 } 532 533 534 /* 535 * Open a zs serial port. This interface may not be used to open 536 * the keyboard and mouse ports. (XXX) 537 */ 538 int 539 zsopen(dev_t dev, int flags, int mode, struct proc *p) 540 { 541 register struct tty *tp; 542 register struct zs_chanstate *cs; 543 struct zsinfo *zi; 544 int unit = minor(dev), zs = unit >> 1, error, s; 545 546 if (zs >= zscd.cd_ndevs || (zi = zscd.cd_devs[zs]) == NULL || 547 unit == ZS_KBD || unit == ZS_MOUSE) 548 return (ENXIO); 549 cs = &zi->zi_cs[unit & 1]; 550 if (cs->cs_consio) 551 return (ENXIO); /* ??? */ 552 tp = cs->cs_ttyp; 553 s = spltty(); 554 if ((tp->t_state & TS_ISOPEN) == 0) { 555 ttychars(tp); 556 if (tp->t_ispeed == 0) { 557 tp->t_iflag = TTYDEF_IFLAG; 558 tp->t_oflag = TTYDEF_OFLAG; 559 tp->t_cflag = TTYDEF_CFLAG; 560 tp->t_lflag = TTYDEF_LFLAG; 561 tp->t_ispeed = tp->t_ospeed = cs->cs_speed; 562 } 563 (void) zsparam(tp, &tp->t_termios); 564 ttsetwater(tp); 565 } else if (tp->t_state & TS_XCLUDE && p->p_ucred->cr_uid != 0) { 566 splx(s); 567 return (EBUSY); 568 } 569 error = 0; 570 for (;;) { 571 /* loop, turning on the device, until carrier present */ 572 zs_modem(cs, 1); 573 if (cs->cs_softcar) 574 tp->t_state |= TS_CARR_ON; 575 if (flags & O_NONBLOCK || tp->t_cflag & CLOCAL || 576 tp->t_state & TS_CARR_ON) 577 break; 578 tp->t_state |= TS_WOPEN; 579 if (error = ttysleep(tp, (caddr_t)&tp->t_rawq, TTIPRI | PCATCH, 580 ttopen, 0)) 581 break; 582 } 583 splx(s); 584 if (error == 0) 585 error = linesw[tp->t_line].l_open(dev, tp); 586 if (error) 587 zs_modem(cs, 0); 588 return (error); 589 } 590 591 /* 592 * Close a zs serial port. 593 */ 594 int 595 zsclose(dev_t dev, int flags, int mode, struct proc *p) 596 { 597 register struct zs_chanstate *cs; 598 register struct tty *tp; 599 struct zsinfo *zi; 600 int unit = minor(dev), s; 601 602 zi = zscd.cd_devs[unit >> 1]; 603 cs = &zi->zi_cs[unit & 1]; 604 tp = cs->cs_ttyp; 605 linesw[tp->t_line].l_close(tp, flags); 606 if (tp->t_cflag & HUPCL || tp->t_state & TS_WOPEN || 607 (tp->t_state & TS_ISOPEN) == 0) { 608 zs_modem(cs, 0); 609 /* hold low for 1 second */ 610 (void) tsleep((caddr_t)cs, TTIPRI, ttclos, hz); 611 } 612 if (cs->cs_creg[5] & ZSWR5_BREAK) 613 { 614 s = splzs(); 615 cs->cs_preg[5] &= ~ZSWR5_BREAK; 616 cs->cs_creg[5] &= ~ZSWR5_BREAK; 617 ZS_WRITE(cs->cs_zc, 5, cs->cs_creg[5]); 618 splx(s); 619 } 620 ttyclose(tp); 621 #ifdef KGDB 622 /* Reset the speed if we're doing kgdb on this port */ 623 if (cs->cs_kgdb) { 624 tp->t_ispeed = tp->t_ospeed = kgdb_rate; 625 (void) zsparam(tp, &tp->t_termios); 626 } 627 #endif 628 return (0); 629 } 630 631 /* 632 * Read/write zs serial port. 633 */ 634 int 635 zsread(dev_t dev, struct uio *uio, int flags) 636 { 637 register struct tty *tp = zs_tty[minor(dev)]; 638 639 return (linesw[tp->t_line].l_read(tp, uio, flags)); 640 } 641 642 int 643 zswrite(dev_t dev, struct uio *uio, int flags) 644 { 645 register struct tty *tp = zs_tty[minor(dev)]; 646 647 return (linesw[tp->t_line].l_write(tp, uio, flags)); 648 } 649 650 /* 651 * ZS hardware interrupt. Scan all ZS channels. NB: we know here that 652 * channels are kept in (A,B) pairs. 653 * 654 * Do just a little, then get out; set a software interrupt if more 655 * work is needed. 656 * 657 * We deliberately ignore the vectoring Zilog gives us, and match up 658 * only the number of `reset interrupt under service' operations, not 659 * the order. 660 */ 661 /* ARGSUSED */ 662 int 663 zshard(void *intrarg) 664 { 665 register struct zs_chanstate *a; 666 #define b (a + 1) 667 register volatile struct zschan *zc; 668 register int rr3, intflags = 0, v, i; 669 static int zsrint(struct zs_chanstate *, volatile struct zschan *); 670 static int zsxint(struct zs_chanstate *, volatile struct zschan *); 671 static int zssint(struct zs_chanstate *, volatile struct zschan *); 672 673 for (a = zslist; a != NULL; a = b->cs_next) { 674 rr3 = ZS_READ(a->cs_zc, 3); 675 if (rr3 & (ZSRR3_IP_A_RX|ZSRR3_IP_A_TX|ZSRR3_IP_A_STAT)) { 676 intflags |= 2; 677 zc = a->cs_zc; 678 i = a->cs_rbput; 679 if (rr3 & ZSRR3_IP_A_RX && (v = zsrint(a, zc)) != 0) { 680 a->cs_rbuf[i++ & ZLRB_RING_MASK] = v; 681 intflags |= 1; 682 } 683 if (rr3 & ZSRR3_IP_A_TX && (v = zsxint(a, zc)) != 0) { 684 a->cs_rbuf[i++ & ZLRB_RING_MASK] = v; 685 intflags |= 1; 686 } 687 if (rr3 & ZSRR3_IP_A_STAT && (v = zssint(a, zc)) != 0) { 688 a->cs_rbuf[i++ & ZLRB_RING_MASK] = v; 689 intflags |= 1; 690 } 691 a->cs_rbput = i; 692 } 693 if (rr3 & (ZSRR3_IP_B_RX|ZSRR3_IP_B_TX|ZSRR3_IP_B_STAT)) { 694 intflags |= 2; 695 zc = b->cs_zc; 696 i = b->cs_rbput; 697 if (rr3 & ZSRR3_IP_B_RX && (v = zsrint(b, zc)) != 0) { 698 b->cs_rbuf[i++ & ZLRB_RING_MASK] = v; 699 intflags |= 1; 700 } 701 if (rr3 & ZSRR3_IP_B_TX && (v = zsxint(b, zc)) != 0) { 702 b->cs_rbuf[i++ & ZLRB_RING_MASK] = v; 703 intflags |= 1; 704 } 705 if (rr3 & ZSRR3_IP_B_STAT && (v = zssint(b, zc)) != 0) { 706 b->cs_rbuf[i++ & ZLRB_RING_MASK] = v; 707 intflags |= 1; 708 } 709 b->cs_rbput = i; 710 } 711 } 712 #undef b 713 if (intflags & 1) { 714 #ifdef SUN4C /* XXX -- but this will go away when zshard moves to locore.s */ 715 struct clockframe *p = intrarg; 716 717 if ((p->psr & PSR_PIL) < (PIL_TTY << 8)) { 718 zsshortcuts++; 719 (void) spltty(); 720 if (zshardscope) { 721 LED_ON; 722 LED_OFF; 723 } 724 return (zssoft(intrarg)); 725 } 726 #endif 727 ienab_bis(IE_ZSSOFT); 728 } 729 return (intflags & 2); 730 } 731 732 static int 733 zsrint(register struct zs_chanstate *cs, register volatile struct zschan *zc) 734 { 735 register int c = zc->zc_data; 736 737 if (cs->cs_conk) { 738 register struct conk_state *conk = &zsconk_state; 739 740 /* 741 * Check here for console abort function, so that we 742 * can abort even when interrupts are locking up the 743 * machine. 744 */ 745 if (c == KBD_RESET) { 746 conk->conk_id = 1; /* ignore next byte */ 747 conk->conk_l1 = 0; 748 } else if (conk->conk_id) 749 conk->conk_id = 0; /* stop ignoring bytes */ 750 else if (c == KBD_L1) 751 conk->conk_l1 = 1; /* L1 went down */ 752 else if (c == (KBD_L1|KBD_UP)) 753 conk->conk_l1 = 0; /* L1 went up */ 754 else if (c == KBD_A && conk->conk_l1) { 755 zsabort(); 756 conk->conk_l1 = 0; /* we never see the up */ 757 goto clearit; /* eat the A after L1-A */ 758 } 759 } 760 #ifdef KGDB 761 if (c == FRAME_START && cs->cs_kgdb && 762 (cs->cs_ttyp->t_state & TS_ISOPEN) == 0) { 763 zskgdb(cs->cs_unit); 764 goto clearit; 765 } 766 #endif 767 /* compose receive character and status */ 768 c <<= 8; 769 c |= ZS_READ(zc, 1); 770 771 /* clear receive error & interrupt condition */ 772 zc->zc_csr = ZSWR0_RESET_ERRORS; 773 zc->zc_csr = ZSWR0_CLR_INTR; 774 775 return (ZRING_MAKE(ZRING_RINT, c)); 776 777 clearit: 778 zc->zc_csr = ZSWR0_RESET_ERRORS; 779 zc->zc_csr = ZSWR0_CLR_INTR; 780 return (0); 781 } 782 783 static int 784 zsxint(register struct zs_chanstate *cs, register volatile struct zschan *zc) 785 { 786 register int i = cs->cs_tbc; 787 788 if (i == 0) { 789 zc->zc_csr = ZSWR0_RESET_TXINT; 790 zc->zc_csr = ZSWR0_CLR_INTR; 791 return (ZRING_MAKE(ZRING_XINT, 0)); 792 } 793 cs->cs_tbc = i - 1; 794 zc->zc_data = *cs->cs_tba++; 795 zc->zc_csr = ZSWR0_CLR_INTR; 796 return (0); 797 } 798 799 static int 800 zssint(register struct zs_chanstate *cs, register volatile struct zschan *zc) 801 { 802 register int rr0; 803 804 rr0 = zc->zc_csr; 805 zc->zc_csr = ZSWR0_RESET_STATUS; 806 zc->zc_csr = ZSWR0_CLR_INTR; 807 /* 808 * The chip's hardware flow control is, as noted in zsreg.h, 809 * busted---if the DCD line goes low the chip shuts off the 810 * receiver (!). If we want hardware CTS flow control but do 811 * not have it, and carrier is now on, turn HFC on; if we have 812 * HFC now but carrier has gone low, turn it off. 813 */ 814 if (rr0 & ZSRR0_DCD) { 815 if (cs->cs_ttyp->t_cflag & CCTS_OFLOW && 816 (cs->cs_creg[3] & ZSWR3_HFC) == 0) { 817 cs->cs_creg[3] |= ZSWR3_HFC; 818 ZS_WRITE(zc, 3, cs->cs_creg[3]); 819 } 820 } else { 821 if (cs->cs_creg[3] & ZSWR3_HFC) { 822 cs->cs_creg[3] &= ~ZSWR3_HFC; 823 ZS_WRITE(zc, 3, cs->cs_creg[3]); 824 } 825 } 826 if ((rr0 & ZSRR0_BREAK) && cs->cs_brkabort) { 827 #ifdef SUN4 828 /* 829 * XXX This might not be necessary. Test and 830 * delete if it isn't. 831 */ 832 while (zc->zc_csr & ZSRR0_BREAK) 833 ZS_DELAY(); 834 #endif 835 zsabort(); 836 return (0); 837 } 838 return (ZRING_MAKE(ZRING_SINT, rr0)); 839 } 840 841 zsabort() 842 { 843 844 #ifdef DDB 845 Debugger(); 846 #else 847 printf("stopping on keyboard abort\n"); 848 callrom(); 849 #endif 850 } 851 852 #ifdef KGDB 853 /* 854 * KGDB framing character received: enter kernel debugger. This probably 855 * should time out after a few seconds to avoid hanging on spurious input. 856 */ 857 zskgdb(int unit) 858 { 859 860 printf("zs%d%c: kgdb interrupt\n", unit >> 1, (unit & 1) + 'a'); 861 kgdb_connect(1); 862 } 863 #endif 864 865 /* 866 * Print out a ring or fifo overrun error message. 867 */ 868 static void 869 zsoverrun(int unit, long *ptime, char *what) 870 { 871 872 if (*ptime != time.tv_sec) { 873 *ptime = time.tv_sec; 874 log(LOG_WARNING, "zs%d%c: %s overrun\n", unit >> 1, 875 (unit & 1) + 'a', what); 876 } 877 } 878 879 /* 880 * ZS software interrupt. Scan all channels for deferred interrupts. 881 */ 882 int 883 zssoft(void *arg) 884 { 885 register struct zs_chanstate *cs; 886 register volatile struct zschan *zc; 887 register struct linesw *line; 888 register struct tty *tp; 889 register int get, n, c, cc, unit, s; 890 891 for (cs = zslist; cs != NULL; cs = cs->cs_next) { 892 get = cs->cs_rbget; 893 again: 894 n = cs->cs_rbput; /* atomic */ 895 if (get == n) /* nothing more on this line */ 896 continue; 897 unit = cs->cs_unit; /* set up to handle interrupts */ 898 zc = cs->cs_zc; 899 tp = cs->cs_ttyp; 900 line = &linesw[tp->t_line]; 901 /* 902 * Compute the number of interrupts in the receive ring. 903 * If the count is overlarge, we lost some events, and 904 * must advance to the first valid one. It may get 905 * overwritten if more data are arriving, but this is 906 * too expensive to check and gains nothing (we already 907 * lost out; all we can do at this point is trade one 908 * kind of loss for another). 909 */ 910 n -= get; 911 if (n > ZLRB_RING_SIZE) { 912 zsoverrun(unit, &cs->cs_rotime, "ring"); 913 get += n - ZLRB_RING_SIZE; 914 n = ZLRB_RING_SIZE; 915 } 916 while (--n >= 0) { 917 /* race to keep ahead of incoming interrupts */ 918 c = cs->cs_rbuf[get++ & ZLRB_RING_MASK]; 919 switch (ZRING_TYPE(c)) { 920 921 case ZRING_RINT: 922 c = ZRING_VALUE(c); 923 if (c & ZSRR1_DO) 924 zsoverrun(unit, &cs->cs_fotime, "fifo"); 925 cc = c >> 8; 926 if (c & ZSRR1_FE) 927 cc |= TTY_FE; 928 if (c & ZSRR1_PE) 929 cc |= TTY_PE; 930 /* 931 * this should be done through 932 * bstreams XXX gag choke 933 */ 934 if (unit == ZS_KBD) 935 kbd_rint(cc); 936 else if (unit == ZS_MOUSE) 937 ms_rint(cc); 938 else 939 line->l_rint(cc, tp); 940 break; 941 942 case ZRING_XINT: 943 /* 944 * Transmit done: change registers and resume, 945 * or clear BUSY. 946 */ 947 if (cs->cs_heldchange) { 948 s = splzs(); 949 c = zc->zc_csr; 950 if ((c & ZSRR0_DCD) == 0) 951 cs->cs_preg[3] &= ~ZSWR3_HFC; 952 bcopy((caddr_t)cs->cs_preg, 953 (caddr_t)cs->cs_creg, 16); 954 zs_loadchannelregs(zc, cs->cs_creg); 955 splx(s); 956 cs->cs_heldchange = 0; 957 if (cs->cs_heldtbc && 958 (tp->t_state & TS_TTSTOP) == 0) { 959 cs->cs_tbc = cs->cs_heldtbc - 1; 960 zc->zc_data = *cs->cs_tba++; 961 goto again; 962 } 963 } 964 tp->t_state &= ~TS_BUSY; 965 if (tp->t_state & TS_FLUSH) 966 tp->t_state &= ~TS_FLUSH; 967 else 968 ndflush(&tp->t_outq, 969 cs->cs_tba - (caddr_t)tp->t_outq.c_cf); 970 line->l_start(tp); 971 break; 972 973 case ZRING_SINT: 974 /* 975 * Status line change. HFC bit is run in 976 * hardware interrupt, to avoid locking 977 * at splzs here. 978 */ 979 c = ZRING_VALUE(c); 980 if ((c ^ cs->cs_rr0) & ZSRR0_DCD) { 981 cc = (c & ZSRR0_DCD) != 0; 982 if (line->l_modem(tp, cc) == 0) 983 zs_modem(cs, cc); 984 } 985 cs->cs_rr0 = c; 986 break; 987 988 default: 989 log(LOG_ERR, "zs%d%c: bad ZRING_TYPE (%x)\n", 990 unit >> 1, (unit & 1) + 'a', c); 991 break; 992 } 993 } 994 cs->cs_rbget = get; 995 goto again; 996 } 997 return (1); 998 } 999 1000 int 1001 zsioctl(dev_t dev, int cmd, caddr_t data, int flag, struct proc *p) 1002 { 1003 int unit = minor(dev); 1004 struct zsinfo *zi = zscd.cd_devs[unit >> 1]; 1005 register struct tty *tp = zi->zi_cs[unit & 1].cs_ttyp; 1006 register int error, s; 1007 register struct zs_chanstate *cs = &zi->zi_cs[unit & 1]; 1008 1009 error = linesw[tp->t_line].l_ioctl(tp, cmd, data, flag, p); 1010 if (error >= 0) 1011 return (error); 1012 error = ttioctl(tp, cmd, data, flag, p); 1013 if (error >= 0) 1014 return (error); 1015 1016 switch (cmd) { 1017 1018 case TIOCSBRK: 1019 { 1020 s = splzs(); 1021 cs->cs_preg[5] |= ZSWR5_BREAK; 1022 cs->cs_creg[5] |= ZSWR5_BREAK; 1023 ZS_WRITE(cs->cs_zc, 5, cs->cs_creg[5]); 1024 splx(s); 1025 break; 1026 } 1027 1028 case TIOCCBRK: 1029 { 1030 s = splzs(); 1031 cs->cs_preg[5] &= ~ZSWR5_BREAK; 1032 cs->cs_creg[5] &= ~ZSWR5_BREAK; 1033 ZS_WRITE(cs->cs_zc, 5, cs->cs_creg[5]); 1034 splx(s); 1035 break; 1036 } 1037 1038 case TIOCSDTR: 1039 1040 case TIOCCDTR: 1041 1042 case TIOCMSET: 1043 1044 case TIOCMBIS: 1045 1046 case TIOCMBIC: 1047 1048 case TIOCMGET: 1049 1050 default: 1051 return (ENOTTY); 1052 } 1053 return (0); 1054 } 1055 1056 /* 1057 * Start or restart transmission. 1058 */ 1059 static void 1060 zsstart(register struct tty *tp) 1061 { 1062 register struct zs_chanstate *cs; 1063 register int s, nch; 1064 int unit = minor(tp->t_dev); 1065 struct zsinfo *zi = zscd.cd_devs[unit >> 1]; 1066 1067 cs = &zi->zi_cs[unit & 1]; 1068 s = spltty(); 1069 1070 /* 1071 * If currently active or delaying, no need to do anything. 1072 */ 1073 if (tp->t_state & (TS_TIMEOUT | TS_BUSY | TS_TTSTOP)) 1074 goto out; 1075 1076 /* 1077 * If there are sleepers, and output has drained below low 1078 * water mark, awaken. 1079 */ 1080 if (tp->t_outq.c_cc <= tp->t_lowat) { 1081 if (tp->t_state & TS_ASLEEP) { 1082 tp->t_state &= ~TS_ASLEEP; 1083 wakeup((caddr_t)&tp->t_outq); 1084 } 1085 selwakeup(&tp->t_wsel); 1086 } 1087 1088 nch = ndqb(&tp->t_outq, 0); /* XXX */ 1089 if (nch) { 1090 register char *p = tp->t_outq.c_cf; 1091 1092 /* mark busy, enable tx done interrupts, & send first byte */ 1093 tp->t_state |= TS_BUSY; 1094 (void) splzs(); 1095 cs->cs_preg[1] |= ZSWR1_TIE; 1096 cs->cs_creg[1] |= ZSWR1_TIE; 1097 ZS_WRITE(cs->cs_zc, 1, cs->cs_creg[1]); 1098 cs->cs_zc->zc_data = *p; 1099 cs->cs_tba = p + 1; 1100 cs->cs_tbc = nch - 1; 1101 } else { 1102 /* 1103 * Nothing to send, turn off transmit done interrupts. 1104 * This is useful if something is doing polled output. 1105 */ 1106 (void) splzs(); 1107 cs->cs_preg[1] &= ~ZSWR1_TIE; 1108 cs->cs_creg[1] &= ~ZSWR1_TIE; 1109 ZS_WRITE(cs->cs_zc, 1, cs->cs_creg[1]); 1110 } 1111 out: 1112 splx(s); 1113 } 1114 1115 /* 1116 * Stop output, e.g., for ^S or output flush. 1117 */ 1118 void 1119 zsstop(register struct tty *tp, int flag) 1120 { 1121 register struct zs_chanstate *cs; 1122 register int s, unit = minor(tp->t_dev); 1123 struct zsinfo *zi = zscd.cd_devs[unit >> 1]; 1124 1125 cs = &zi->zi_cs[unit & 1]; 1126 s = splzs(); 1127 if (tp->t_state & TS_BUSY) { 1128 /* 1129 * Device is transmitting; must stop it. 1130 */ 1131 cs->cs_tbc = 0; 1132 if ((tp->t_state & TS_TTSTOP) == 0) 1133 tp->t_state |= TS_FLUSH; 1134 } 1135 splx(s); 1136 } 1137 1138 /* 1139 * Set ZS tty parameters from termios. 1140 * 1141 * This routine makes use of the fact that only registers 1142 * 1, 3, 4, 5, 9, 10, 11, 12, 13, 14, and 15 are written. 1143 */ 1144 static int 1145 zsparam(register struct tty *tp, register struct termios *t) 1146 { 1147 int unit = minor(tp->t_dev); 1148 struct zsinfo *zi = zscd.cd_devs[unit >> 1]; 1149 register struct zs_chanstate *cs = &zi->zi_cs[unit & 1]; 1150 register int tmp, tmp5, cflag, s; 1151 1152 /* 1153 * Because PCLK is only run at 4.9 MHz, the fastest we 1154 * can go is 51200 baud (this corresponds to TC=1). 1155 * This is somewhat unfortunate as there is no real 1156 * reason we should not be able to handle higher rates. 1157 */ 1158 tmp = t->c_ospeed; 1159 if (tmp < 0 || (t->c_ispeed && t->c_ispeed != tmp)) 1160 return (EINVAL); 1161 if (tmp == 0) { 1162 /* stty 0 => drop DTR and RTS */ 1163 zs_modem(cs, 0); 1164 return (0); 1165 } 1166 tmp = BPS_TO_TCONST(PCLK / 16, tmp); 1167 if (tmp < 2) 1168 return (EINVAL); 1169 1170 cflag = t->c_cflag; 1171 tp->t_ispeed = tp->t_ospeed = TCONST_TO_BPS(PCLK / 16, tmp); 1172 tp->t_cflag = cflag; 1173 1174 /* 1175 * Block interrupts so that state will not 1176 * be altered until we are done setting it up. 1177 */ 1178 s = splzs(); 1179 cs->cs_preg[12] = tmp; 1180 cs->cs_preg[13] = tmp >> 8; 1181 cs->cs_preg[1] = ZSWR1_RIE | ZSWR1_TIE | ZSWR1_SIE; 1182 switch (cflag & CSIZE) { 1183 case CS5: 1184 tmp = ZSWR3_RX_5; 1185 tmp5 = ZSWR5_TX_5; 1186 break; 1187 case CS6: 1188 tmp = ZSWR3_RX_6; 1189 tmp5 = ZSWR5_TX_6; 1190 break; 1191 case CS7: 1192 tmp = ZSWR3_RX_7; 1193 tmp5 = ZSWR5_TX_7; 1194 break; 1195 case CS8: 1196 default: 1197 tmp = ZSWR3_RX_8; 1198 tmp5 = ZSWR5_TX_8; 1199 break; 1200 } 1201 1202 /* 1203 * Output hardware flow control on the chip is horrendous: if 1204 * carrier detect drops, the receiver is disabled. Hence we 1205 * can only do this when the carrier is on. 1206 */ 1207 if (cflag & CCTS_OFLOW && cs->cs_zc->zc_csr & ZSRR0_DCD) 1208 tmp |= ZSWR3_HFC | ZSWR3_RX_ENABLE; 1209 else 1210 tmp |= ZSWR3_RX_ENABLE; 1211 cs->cs_preg[3] = tmp; 1212 cs->cs_preg[5] = tmp5 | ZSWR5_TX_ENABLE | ZSWR5_DTR | ZSWR5_RTS; 1213 1214 tmp = ZSWR4_CLK_X16 | (cflag & CSTOPB ? ZSWR4_TWOSB : ZSWR4_ONESB); 1215 if ((cflag & PARODD) == 0) 1216 tmp |= ZSWR4_EVENP; 1217 if (cflag & PARENB) 1218 tmp |= ZSWR4_PARENB; 1219 cs->cs_preg[4] = tmp; 1220 cs->cs_preg[9] = ZSWR9_MASTER_IE | ZSWR9_NO_VECTOR; 1221 cs->cs_preg[10] = ZSWR10_NRZ; 1222 cs->cs_preg[11] = ZSWR11_TXCLK_BAUD | ZSWR11_RXCLK_BAUD; 1223 cs->cs_preg[14] = ZSWR14_BAUD_FROM_PCLK | ZSWR14_BAUD_ENA; 1224 cs->cs_preg[15] = ZSWR15_BREAK_IE | ZSWR15_DCD_IE; 1225 1226 /* 1227 * If nothing is being transmitted, set up new current values, 1228 * else mark them as pending. 1229 */ 1230 if (cs->cs_heldchange == 0) { 1231 if (cs->cs_ttyp->t_state & TS_BUSY) { 1232 cs->cs_heldtbc = cs->cs_tbc; 1233 cs->cs_tbc = 0; 1234 cs->cs_heldchange = 1; 1235 } else { 1236 bcopy((caddr_t)cs->cs_preg, (caddr_t)cs->cs_creg, 16); 1237 zs_loadchannelregs(cs->cs_zc, cs->cs_creg); 1238 } 1239 } 1240 splx(s); 1241 return (0); 1242 } 1243 1244 /* 1245 * Raise or lower modem control (DTR/RTS) signals. If a character is 1246 * in transmission, the change is deferred. 1247 */ 1248 static void 1249 zs_modem(struct zs_chanstate *cs, int onoff) 1250 { 1251 int s, bis, and; 1252 1253 if (onoff) { 1254 bis = ZSWR5_DTR | ZSWR5_RTS; 1255 and = ~0; 1256 } else { 1257 bis = 0; 1258 and = ~(ZSWR5_DTR | ZSWR5_RTS); 1259 } 1260 s = splzs(); 1261 cs->cs_preg[5] = (cs->cs_preg[5] | bis) & and; 1262 if (cs->cs_heldchange == 0) { 1263 if (cs->cs_ttyp->t_state & TS_BUSY) { 1264 cs->cs_heldtbc = cs->cs_tbc; 1265 cs->cs_tbc = 0; 1266 cs->cs_heldchange = 1; 1267 } else { 1268 cs->cs_creg[5] = (cs->cs_creg[5] | bis) & and; 1269 ZS_WRITE(cs->cs_zc, 5, cs->cs_creg[5]); 1270 } 1271 } 1272 splx(s); 1273 } 1274 1275 /* 1276 * Write the given register set to the given zs channel in the proper order. 1277 * The channel must not be transmitting at the time. The receiver will 1278 * be disabled for the time it takes to write all the registers. 1279 */ 1280 static void 1281 zs_loadchannelregs(volatile struct zschan *zc, u_char *reg) 1282 { 1283 int i; 1284 1285 zc->zc_csr = ZSM_RESET_ERR; /* reset error condition */ 1286 i = zc->zc_data; /* drain fifo */ 1287 i = zc->zc_data; 1288 i = zc->zc_data; 1289 ZS_WRITE(zc, 4, reg[4]); 1290 ZS_WRITE(zc, 10, reg[10]); 1291 ZS_WRITE(zc, 3, reg[3] & ~ZSWR3_RX_ENABLE); 1292 ZS_WRITE(zc, 5, reg[5] & ~ZSWR5_TX_ENABLE); 1293 ZS_WRITE(zc, 1, reg[1]); 1294 ZS_WRITE(zc, 9, reg[9]); 1295 ZS_WRITE(zc, 11, reg[11]); 1296 ZS_WRITE(zc, 12, reg[12]); 1297 ZS_WRITE(zc, 13, reg[13]); 1298 ZS_WRITE(zc, 14, reg[14]); 1299 ZS_WRITE(zc, 15, reg[15]); 1300 ZS_WRITE(zc, 3, reg[3]); 1301 ZS_WRITE(zc, 5, reg[5]); 1302 } 1303 1304 #ifdef KGDB 1305 /* 1306 * Get a character from the given kgdb channel. Called at splhigh(). 1307 */ 1308 static int 1309 zs_kgdb_getc(void *arg) 1310 { 1311 register volatile struct zschan *zc = (volatile struct zschan *)arg; 1312 1313 while ((zc->zc_csr & ZSRR0_RX_READY) == 0) 1314 continue; 1315 return (zc->zc_data); 1316 } 1317 1318 /* 1319 * Put a character to the given kgdb channel. Called at splhigh(). 1320 */ 1321 static void 1322 zs_kgdb_putc(void *arg, int c) 1323 { 1324 register volatile struct zschan *zc = (volatile struct zschan *)arg; 1325 1326 while ((zc->zc_csr & ZSRR0_TX_READY) == 0) 1327 continue; 1328 zc->zc_data = c; 1329 } 1330 1331 /* 1332 * Set up for kgdb; called at boot time before configuration. 1333 * KGDB interrupts will be enabled later when zs0 is configured. 1334 */ 1335 void 1336 zs_kgdb_init() 1337 { 1338 volatile struct zsdevice *addr; 1339 volatile struct zschan *zc; 1340 int unit, zs; 1341 1342 if (major(kgdb_dev) != ZSMAJOR) 1343 return; 1344 unit = minor(kgdb_dev); 1345 /* 1346 * Unit must be 0 or 1 (zs0). 1347 */ 1348 if ((unsigned)unit >= ZS_KBD) { 1349 printf("zs_kgdb_init: bad minor dev %d\n", unit); 1350 return; 1351 } 1352 zs = unit >> 1; 1353 if ((addr = zsaddr[zs]) == NULL) 1354 addr = zsaddr[zs] = findzs(zs); 1355 unit &= 1; 1356 zc = unit == 0 ? &addr->zs_chan[CHAN_A] : &addr->zs_chan[CHAN_B]; 1357 zs_kgdb_savedspeed = zs_getspeed(zc); 1358 printf("zs_kgdb_init: attaching zs%d%c at %d baud\n", 1359 zs, unit + 'a', kgdb_rate); 1360 zs_reset(zc, 1, kgdb_rate); 1361 kgdb_attach(zs_kgdb_getc, zs_kgdb_putc, (void *)zc); 1362 } 1363 #endif /* KGDB */ 1364