si.c revision 16403
1/* 2 * Device driver for Specialix range (SI/XIO) of serial line multiplexors. 3 * 4 * Copyright (C) 1990, 1992 Specialix International, 5 * Copyright (C) 1993, Andy Rutter <andy@acronym.co.uk> 6 * Copyright (C) 1995, Peter Wemm <peter@haywire.dialix.com> 7 * 8 * Originally derived from: SunOS 4.x version 9 * Ported from BSDI version to FreeBSD by Peter Wemm. 10 * 11 * Redistribution and use in source and binary forms, with or without 12 * modification, are permitted provided that the following conditions 13 * are met: 14 * 1. Redistributions of source code must retain the above copyright 15 * notices, this list of conditions and the following disclaimer. 16 * 2. Redistributions in binary form must reproduce the above copyright 17 * notices, this list of conditions and the following disclaimer in the 18 * documentation and/or other materials provided with the distribution. 19 * 3. All advertising materials mentioning features or use of this software 20 * must display the following acknowledgement: 21 * This product includes software developed by Andy Rutter of 22 * Advanced Methods and Tools Ltd. based on original information 23 * from Specialix International. 24 * 4. Neither the name of Advanced Methods and Tools, nor Specialix 25 * International may be used to endorse or promote products derived from 26 * this software without specific prior written permission. 27 * 28 * THIS SOFTWARE IS PROVIDED BY ``AS IS'' AND ANY EXPRESS OR IMPLIED 29 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 30 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN 31 * NO EVENT SHALL THE AUTHORS BE LIABLE. 32 * 33 * $Id: si.c,v 1.43 1996/06/12 05:03:50 gpalmer Exp $ 34 */ 35 36#ifndef lint 37static const char si_copyright1[] = "@(#) (C) Specialix International, 1990,1992", 38 si_copyright2[] = "@(#) (C) Andy Rutter 1993", 39 si_copyright3[] = "@(#) (C) Peter Wemm 1995"; 40#endif /* not lint */ 41 42#include <sys/param.h> 43#include <sys/systm.h> 44#include <sys/ioctl.h> 45#include <sys/tty.h> 46#include <sys/ttydefaults.h> 47#include <sys/proc.h> 48#include <sys/conf.h> 49#include <sys/file.h> 50#include <sys/uio.h> 51#include <sys/dkstat.h> 52#include <sys/kernel.h> 53#include <sys/syslog.h> 54#include <sys/malloc.h> 55#include <sys/sysctl.h> 56#include <sys/devconf.h> 57#ifdef DEVFS 58#include <sys/devfsext.h> 59#endif /*DEVFS*/ 60 61#include <machine/clock.h> 62 63#include <vm/vm.h> 64#include <vm/vm_param.h> 65#include <vm/pmap.h> 66 67#include <i386/isa/icu.h> 68#include <i386/isa/isa.h> 69#include <i386/isa/isa_device.h> 70 71#include <i386/isa/sireg.h> 72#include <machine/si.h> 73#include <machine/stdarg.h> 74 75#include "si.h" 76 77/* 78 * This device driver is designed to interface the Specialix International 79 * range of serial multiplexor cards (SI/XIO) to BSDI/386 on an ISA bus machine. 80 * 81 * The controller is interfaced to the host via dual port ram 82 * and a (programmable - SIHOST2) interrupt at IRQ 11,12 or 15. 83 */ 84 85#define POLL /* turn on poller to generate buffer empty interrupt */ 86#define SI_DEF_HWFLOW /* turn on default CRTSCTS flow control */ 87#define SI_I_HIGH_WATER (TTYHOG - 2 * SI_BUFFERSIZE) 88#define INT_COUNT 25000 /* max of 125 ints per second */ 89#define RXINT_COUNT 1 /* one rxint per 10 milliseconds */ 90 91enum si_mctl { GET, SET, BIS, BIC }; 92 93static void si_command __P((struct si_port *, int, int)); 94static int si_modem __P((struct si_port *, enum si_mctl, int)); 95static void si_write_enable __P((struct si_port *, int)); 96static int si_Sioctl __P((dev_t, int, caddr_t, int, struct proc *)); 97static void si_start __P((struct tty *)); 98static void si_lstart __P((struct si_port *)); 99static void si_disc_optim __P((struct tty *tp, struct termios *t, 100 struct si_port *pp)); 101static void sihardclose __P((struct si_port *pp)); 102static void sidtrwakeup __P((void *chan)); 103 104static int siparam __P((struct tty *, struct termios *)); 105 106static void si_registerdev __P((struct isa_device *id)); 107static int siprobe __P((struct isa_device *id)); 108static int siattach __P((struct isa_device *id)); 109static void si_modem_state __P((struct si_port *pp, struct tty *tp, int hi_ip)); 110 111struct isa_driver sidriver = 112 { siprobe, siattach, "si" }; 113 114 115static d_open_t siopen; 116static d_close_t siclose; 117static d_read_t siread; 118static d_write_t siwrite; 119static d_ioctl_t siioctl; 120static d_stop_t sistop; 121static d_devtotty_t sidevtotty; 122 123#define CDEV_MAJOR 68 124static struct cdevsw si_cdevsw = 125 { siopen, siclose, siread, siwrite, /*68*/ 126 siioctl, sistop, noreset, sidevtotty,/* si */ 127 ttselect, nommap, NULL, "si", NULL, -1 }; 128 129 130#ifdef SI_DEBUG /* use: ``options "SI_DEBUG"'' in your config file */ 131 132static void si_dprintf __P((struct si_port *pp, int flags, const char *fmt, 133 ...)); 134static char *si_mctl2str __P((enum si_mctl cmd)); 135 136#define DPRINT(x) si_dprintf x 137 138#else 139#define DPRINT(x) /* void */ 140#endif 141 142static int si_Nports; 143static int si_Nmodules; 144static int si_debug = 0; /* data, not bss, so it's patchable */ 145 146static struct tty *si_tty; 147 148/* where the firmware lives; defined in si_code.c */ 149extern int si_dsize; 150extern unsigned char si_download[]; 151 152struct si_softc { 153 int sc_type; /* adapter type */ 154 char *sc_typename; /* adapter type string */ 155 156 struct si_port *sc_ports; /* port structures for this card */ 157 158 caddr_t sc_paddr; /* physical addr of iomem */ 159 caddr_t sc_maddr; /* kvaddr of iomem */ 160 int sc_nport; /* # ports on this card */ 161 int sc_irq; /* copy of attach irq */ 162 int sc_eisa_iobase; /* EISA io port address */ 163 int sc_eisa_irqbits; 164 struct kern_devconf sc_kdc; 165#ifdef DEVFS 166 struct { 167 void *ttyd; 168 void *cuaa; 169 void *ttyl; 170 void *ttyi; 171 } devfs_token[32]; /* what is the max per card? */ 172 void *control_token; 173#endif 174}; 175static struct si_softc si_softc[NSI]; /* up to 4 elements */ 176 177#ifndef B2000 /* not standard, but the hardware knows it. */ 178# define B2000 2000 179#endif 180static struct speedtab bdrates[] = { 181 B75, CLK75, /* 0x0 */ 182 B110, CLK110, /* 0x1 */ 183 B150, CLK150, /* 0x3 */ 184 B300, CLK300, /* 0x4 */ 185 B600, CLK600, /* 0x5 */ 186 B1200, CLK1200, /* 0x6 */ 187 B2000, CLK2000, /* 0x7 */ 188 B2400, CLK2400, /* 0x8 */ 189 B4800, CLK4800, /* 0x9 */ 190 B9600, CLK9600, /* 0xb */ 191 B19200, CLK19200, /* 0xc */ 192 B38400, CLK38400, /* 0x2 (out of order!) */ 193 B57600, CLK57600, /* 0xd */ 194 B115200, CLK110, /* 0x1 (dupe!, 110 baud on "si") */ 195 -1, -1 196}; 197 198 199/* populated with approx character/sec rates - translated at card 200 * initialisation time to chars per tick of the clock */ 201static int done_chartimes = 0; 202static struct speedtab chartimes[] = { 203 B75, 8, 204 B110, 11, 205 B150, 15, 206 B300, 30, 207 B600, 60, 208 B1200, 120, 209 B2000, 200, 210 B2400, 240, 211 B4800, 480, 212 B9600, 960, 213 B19200, 1920, 214 B38400, 3840, 215 B57600, 5760, 216 B115200, 11520, 217 -1, -1 218}; 219static volatile int in_intr = 0; /* Inside interrupt handler? */ 220 221static int si_default_rate = TTYDEF_SPEED; 222static int si_default_iflag = 0; 223static int si_default_oflag = 0; 224static int si_default_lflag = 0; 225#ifdef SI_DEF_HWFLOW 226static int si_default_cflag = TTYDEF_CFLAG | CRTSCTS; 227#else 228static int si_default_cflag = TTYDEF_CFLAG; 229#endif 230 231#ifdef POLL 232static int si_pollrate; /* in addition to irq */ 233 234SYSCTL_INT(_machdep, OID_AUTO, si_pollrate, CTLFLAG_RW, &si_pollrate, 0, ""); 235 236static int init_finished = 0; 237static void si_poll __P((void *)); 238#endif 239 240/* 241 * Array of adapter types and the corresponding RAM size. The order of 242 * entries here MUST match the ordinal of the adapter type. 243 */ 244static char *si_type[] = { 245 "EMPTY", 246 "SIHOST", 247 "SI2", /* MCA */ 248 "SIHOST2", 249 "SIEISA", 250}; 251 252 253static struct kern_devconf si_kdc[NSI] = { { 254 0, 0, 0, /* filled in by dev_attach */ 255 "si", 0, { MDDT_ISA, 0, "tty" }, 256 isa_generic_externalize, 0, 0, ISA_EXTERNALLEN, 257 &kdc_isa0, /* parent */ 258 0, /* parent data */ 259 DC_UNCONFIGURED, /* state */ 260 "Specialix SI/XIO Host adapter", 261 DC_CLS_SERIAL, /* class */ 262} }; 263 264static void 265si_registerdev(id) 266 struct isa_device *id; 267{ 268 if (id->id_unit != 0) { 269 bcopy(&si_kdc[0], &si_kdc[id->id_unit], sizeof(si_kdc[0])); 270 } 271 si_kdc[id->id_unit].kdc_unit = id->id_unit; 272 si_kdc[id->id_unit].kdc_isa = id; 273 si_kdc[id->id_unit].kdc_state = DC_UNCONFIGURED; 274 dev_attach(&si_kdc[id->id_unit]); 275} 276 277/* Look for a valid board at the given mem addr */ 278static int 279siprobe(id) 280 struct isa_device *id; 281{ 282 struct si_softc *sc; 283 int type; 284 u_int i, ramsize; 285 volatile BYTE was, *ux; 286 volatile unsigned char *maddr; 287 unsigned char *paddr; 288 289 si_registerdev(id); 290 291 si_pollrate = (hz / 10); /* 10 per second */ 292 293 maddr = id->id_maddr; /* virtual address... */ 294 paddr = (caddr_t)vtophys(id->id_maddr); /* physical address... */ 295 296 DPRINT((0, DBG_AUTOBOOT, "si%d: probe at virtual=0x%x physical=0x%x\n", 297 id->id_unit, id->id_maddr, paddr)); 298 299 /* 300 * this is a lie, but it's easier than trying to handle caching 301 * and ram conflicts in the >1M and <16M region. 302 */ 303 if ((caddr_t)paddr < (caddr_t)IOM_BEGIN || 304 (caddr_t)paddr >= (caddr_t)IOM_END) { 305 printf("si%d: iomem (%lx) out of range\n", 306 id->id_unit, (long)paddr); 307 return(0); 308 } 309 310 if (id->id_unit >= NSI) { 311 /* THIS IS IMPOSSIBLE */ 312 return(0); 313 } 314 315 if (((u_int)paddr & 0x7fff) != 0) { 316 DPRINT((0, DBG_AUTOBOOT|DBG_FAIL, 317 "si%d: iomem (%x) not on 32k boundary\n", 318 id->id_unit, paddr)); 319 return(0); 320 } 321 322 323 for (i=0; i < NSI; i++) { 324 if ((sc = &si_softc[i]) == NULL) 325 continue; 326 if ((caddr_t)sc->sc_paddr == (caddr_t)paddr) { 327 DPRINT((0, DBG_AUTOBOOT|DBG_FAIL, 328 "si%d: iomem (%x) already configured to si%d\n", 329 id->id_unit, sc->sc_paddr, i)); 330 return(0); 331 } 332 } 333 334#if NEISA > 0 335 if (id->id_iobase > 0x0fff) { /* EISA card */ 336 int irq, port; 337 unsigned long base; 338 int eisa_irqs[] = { 0,IRQ1,IRQ2,IRQ3,IRQ4,IRQ5,IRQ6,IRQ7, 339 IRQ8,IRQ9,IRQ10,IRQ11,IRQ12,IRQ13,IRQ14,IRQ15 }; 340 341 port = id->id_iobase; 342 base = (inb(port+1) << 24) | (inb(port) << 16); 343 irq = ((inb(port+2) >> 4) & 0xf); 344 345 id->id_irq = eisa_irqs[irq]; 346 347 DPRINT((0, DBG_AUTOBOOT, 348 "si%d: EISA base %x, irq %x, id_irq %x, port %x\n", 349 id->id_unit, base, irq, id->id_irq, port)); 350 351 if ((id->id_irq&(IRQ1|IRQ2|IRQ8|IRQ13)) != 0) 352 goto bad_irq; 353 354 id->id_iobase &= 0xf000; 355 id->id_iosize = 0x0fff; 356 357 type = EISA; 358 outb(p+2, (BYTE)irq << 4); 359 360 sc->sc_eisa_iobase = p; 361 sc->sc_eisa_irqbits = irq << 4; 362 ramsize = SIEISA_RAMSIZE; 363 goto got_card; 364 } 365#endif 366 367 /* Is there anything out there? (0x17 is just an arbitrary number) */ 368 *maddr = 0x17; 369 if (*maddr != 0x17) { 370 DPRINT((0, DBG_AUTOBOOT|DBG_FAIL, 371 "si%d: 0x17 check fail at phys 0x%x\n", 372 id->id_unit, paddr)); 373fail: 374 return(0); 375 } 376 /* 377 * OK, now to see if whatever responded is really an SI card. 378 * Try for a MK II first (SIHOST2) 379 */ 380 for (i=SIPLSIG; i<SIPLSIG+8; i++) 381 if ((*(maddr+i) & 7) != (~(BYTE)i & 7)) 382 goto try_mk1; 383 384 /* It must be an SIHOST2 */ 385 *(maddr + SIPLRESET) = 0; 386 *(maddr + SIPLIRQCLR) = 0; 387 *(maddr + SIPLIRQSET) = 0x10; 388 type = SIHOST2; 389 ramsize = SIHOST2_RAMSIZE; 390 goto got_card; 391 392 /* 393 * Its not a MK II, so try for a MK I (SIHOST) 394 */ 395try_mk1: 396 *(maddr+SIRESET) = 0x0; /* reset the card */ 397 *(maddr+SIINTCL) = 0x0; /* clear int */ 398 *(maddr+SIRAM) = 0x17; 399 if (*(maddr+SIRAM) != (BYTE)0x17) 400 goto fail; 401 *(maddr+0x7ff8) = 0x17; 402 if (*(maddr+0x7ff8) != (BYTE)0x17) { 403 DPRINT((0, DBG_AUTOBOOT|DBG_FAIL, 404 "si%d: 0x17 check fail at phys 0x%x = 0x%x\n", 405 id->id_unit, paddr+0x77f8, *(maddr+0x77f8))); 406 goto fail; 407 } 408 409 /* It must be an SIHOST (maybe?) - there must be a better way XXXX */ 410 type = SIHOST; 411 ramsize = SIHOST_RAMSIZE; 412 413got_card: 414 DPRINT((0, DBG_AUTOBOOT, "si%d: found type %d card, try memory test\n", 415 id->id_unit, type)); 416 /* Try the acid test */ 417 ux = (BYTE *)(maddr + SIRAM); 418 for (i=0; i<ramsize; i++, ux++) 419 *ux = (BYTE)(i&0xff); 420 ux = (BYTE *)(maddr + SIRAM); 421 for (i=0; i<ramsize; i++, ux++) { 422 if ((was = *ux) != (BYTE)(i&0xff)) { 423 DPRINT((0, DBG_AUTOBOOT|DBG_FAIL, 424 "si%d: match fail at phys 0x%x, was %x should be %x\n", 425 id->id_unit, paddr+i, was, i&0xff)); 426 goto fail; 427 } 428 } 429 430 /* clear out the RAM */ 431 ux = (BYTE *)(maddr + SIRAM); 432 for (i=0; i<ramsize; i++) 433 *ux++ = 0; 434 ux = (BYTE *)(maddr + SIRAM); 435 for (i=0; i<ramsize; i++) { 436 if ((was = *ux++) != 0) { 437 DPRINT((0, DBG_AUTOBOOT|DBG_FAIL, 438 "si%d: clear fail at phys 0x%x, was %x\n", 439 id->id_unit, paddr+i, was)); 440 goto fail; 441 } 442 } 443 444 /* 445 * Success, we've found a valid board, now fill in 446 * the adapter structure. 447 */ 448 switch (type) { 449 case SIHOST2: 450 if ((id->id_irq&(IRQ11|IRQ12|IRQ15)) == 0) { 451bad_irq: 452 DPRINT((0, DBG_AUTOBOOT|DBG_FAIL, 453 "si%d: bad IRQ value - %d\n", 454 id->id_unit, id->id_irq)); 455 return(0); 456 } 457 id->id_msize = SIHOST2_MEMSIZE; 458 break; 459 case SIHOST: 460 if ((id->id_irq&(IRQ11|IRQ12|IRQ15)) == 0) { 461 goto bad_irq; 462 } 463 id->id_msize = SIHOST_MEMSIZE; 464 break; 465 case SIEISA: 466 id->id_msize = SIEISA_MEMSIZE; 467 break; 468 case SI2: /* MCA */ 469 default: 470 printf("si%d: %s not supported\n", id->id_unit, si_type[type]); 471 return(0); 472 } 473 si_softc[id->id_unit].sc_type = type; 474 si_softc[id->id_unit].sc_typename = si_type[type]; 475 return(-1); /* -1 == found */ 476} 477 478/* 479 * Attach the device. Initialize the card. 480 */ 481static int 482siattach(id) 483 struct isa_device *id; 484{ 485 int unit = id->id_unit; 486 struct si_softc *sc = &si_softc[unit]; 487 struct si_port *pp; 488 volatile struct si_channel *ccbp; 489 volatile struct si_reg *regp; 490 volatile caddr_t maddr; 491 struct si_module *modp; 492 struct tty *tp; 493 struct speedtab *spt; 494 int nmodule, nport, x, y; 495 int uart_type; 496 497 DPRINT((0, DBG_AUTOBOOT, "si%d: siattach\n", id->id_unit)); 498 499 sc->sc_paddr = (caddr_t)vtophys(id->id_maddr); 500 sc->sc_maddr = id->id_maddr; 501 sc->sc_irq = id->id_irq; 502 503 sc->sc_ports = NULL; /* mark as uninitialised */ 504 505 maddr = sc->sc_maddr; 506 507 /* 508 * OK, now lets download the firmware and try and boot the CPU.. 509 */ 510 511 DPRINT((0, DBG_DOWNLOAD, "si%d: si_download: nbytes %d\n", 512 id->id_unit, si_dsize)); 513 bcopy(si_download, maddr, si_dsize); 514 515 switch (sc->sc_type) { 516 case SIEISA: 517#if NEISA > 0 518 /* modify the Z280 firmware to tell it that it's on an EISA */ 519 *(maddr+0x42) = 1; 520 outb(sc->sc_eisa_iobase+2, sc->sc_eisa_irqbits | 4); 521 (void)inb(sc->sc_eisa_iobase+3); /* reset interrupt */ 522 break; 523#endif /* fall-through if not EISA */ 524 case SI2: 525 /* 526 * must get around to converting the code for 527 * these one day, if FreeBSD ever supports it. 528 */ 529 return 0; 530 case SIHOST: 531 *(maddr+SIRESET_CL) = 0; 532 *(maddr+SIINTCL_CL) = 0; 533 break; 534 case SIHOST2: 535 *(maddr+SIPLRESET) = 0x10; 536 switch (sc->sc_irq) { 537 case IRQ11: 538 *(maddr+SIPLIRQ11) = 0x10; 539 break; 540 case IRQ12: 541 *(maddr+SIPLIRQ12) = 0x10; 542 break; 543 case IRQ15: 544 *(maddr+SIPLIRQ15) = 0x10; 545 break; 546 } 547 *(maddr+SIPLIRQCLR) = 0x10; 548 break; 549 } 550 551 DELAY(1000000); /* wait around for a second */ 552 553 regp = (struct si_reg *)maddr; 554 y = 0; 555 /* wait max of 5 sec for init OK */ 556 while (regp->initstat == 0 && y++ < 10) { 557 DELAY(500000); 558 } 559 switch (regp->initstat) { 560 case 0: 561 printf("si%d: startup timeout - aborting\n", unit); 562 sc->sc_type = SIEMPTY; 563 return 0; 564 case 1: 565 /* set throttle to 125 intr per second */ 566 regp->int_count = INT_COUNT; 567 /* rx intr max of 25 timer per second */ 568 regp->rx_int_count = RXINT_COUNT; 569 regp->int_pending = 0; /* no intr pending */ 570 regp->int_scounter = 0; /* reset counter */ 571 break; 572 case 0xff: 573 /* 574 * No modules found, so give up on this one. 575 */ 576 printf("si%d: %s - no ports found\n", unit, 577 si_type[sc->sc_type]); 578 return 0; 579 default: 580 printf("si%d: Z280 version error - initstat %x\n", 581 unit, regp->initstat); 582 return 0; 583 } 584 585 /* 586 * First time around the ports just count them in order 587 * to allocate some memory. 588 */ 589 nport = 0; 590 modp = (struct si_module *)(maddr + 0x80); 591 for (;;) { 592 DPRINT((0, DBG_DOWNLOAD, "si%d: ccb addr 0x%x\n", unit, modp)); 593 switch (modp->sm_type & (~MMASK)) { 594 case M232: 595 case M422: 596 DPRINT((0, DBG_DOWNLOAD, 597 "si%d: Found 232/422 module, %d ports\n", 598 unit, (int)(modp->sm_type & MMASK))); 599 600 /* this is a firmware issue */ 601 if (si_Nports == SI_MAXPORTPERCARD) { 602 printf("si%d: extra ports ignored\n", unit); 603 continue; 604 } 605 606 x = modp->sm_type & MMASK; 607 nport += x; 608 si_Nports += x; 609 si_Nmodules++; 610 break; 611 default: 612 printf("si%d: unknown module type %d\n", 613 unit, modp->sm_type); 614 break; 615 } 616 if (modp->sm_next == 0) 617 break; 618 modp = (struct si_module *) 619 (maddr + (unsigned)(modp->sm_next & 0x7fff)); 620 } 621 sc->sc_ports = (struct si_port *)malloc(sizeof(struct si_port) * nport, 622 M_DEVBUF, M_NOWAIT); 623 if (sc->sc_ports == 0) { 624mem_fail: 625 printf("si%d: fail to malloc memory for port structs\n", 626 unit); 627 return 0; 628 } 629 bzero(sc->sc_ports, sizeof(struct si_port) * nport); 630 sc->sc_nport = nport; 631 632 /* 633 * allocate tty structures for ports 634 */ 635 tp = (struct tty *)malloc(sizeof(*tp) * nport, M_DEVBUF, M_NOWAIT); 636 if (tp == 0) 637 goto mem_fail; 638 bzero(tp, sizeof(*tp) * nport); 639 si_tty = tp; 640 641 /* mark the device state as attached */ 642 si_kdc[unit].kdc_state = DC_BUSY; 643 644 /* 645 * Scan round the ports again, this time initialising. 646 */ 647 pp = sc->sc_ports; 648 nmodule = 0; 649 modp = (struct si_module *)(maddr + 0x80); 650 uart_type = 0; 651 for (;;) { 652 switch (modp->sm_type & (~MMASK)) { 653 case M232: 654 case M422: 655 nmodule++; 656 nport = (modp->sm_type & MMASK); 657 ccbp = (struct si_channel *)((char *)modp+0x100); 658 if (uart_type == 0) 659 uart_type = ccbp->type; 660 for (x = 0; x < nport; x++, pp++, ccbp++) { 661 pp->sp_ccb = ccbp; /* save the address */ 662 pp->sp_tty = tp++; 663 pp->sp_pend = IDLE_CLOSE; 664 pp->sp_state = 0; /* internal flag */ 665 pp->sp_dtr_wait = 3 * hz; 666 pp->sp_iin.c_iflag = si_default_iflag; 667 pp->sp_iin.c_oflag = si_default_oflag; 668 pp->sp_iin.c_cflag = si_default_cflag; 669 pp->sp_iin.c_lflag = si_default_lflag; 670 termioschars(&pp->sp_iin); 671 pp->sp_iin.c_ispeed = pp->sp_iin.c_ospeed = 672 si_default_rate; 673 pp->sp_iout = pp->sp_iin; 674 } 675 break; 676 default: 677 break; 678 } 679 if (modp->sm_next == 0) { 680 printf("si%d: card: %s, ports: %d, modules: %d (type: %d)\n", 681 unit, 682 sc->sc_typename, 683 sc->sc_nport, 684 nmodule, 685 uart_type); 686 break; 687 } 688 modp = (struct si_module *) 689 (maddr + (unsigned)(modp->sm_next & 0x7fff)); 690 } 691 if (done_chartimes == 0) { 692 for (spt = chartimes ; spt->sp_speed != -1; spt++) { 693 if ((spt->sp_code /= hz) == 0) 694 spt->sp_code = 1; 695 } 696 done_chartimes = 1; 697 } 698 699#ifdef DEVFS 700/* path name devsw minor type uid gid perm*/ 701 for ( x = 0; x < sc->sc_nport; x++ ) { 702 y = x + 1; /* For sync with the manuals that start at 1 */ 703 sc->devfs_token[x].ttyd = devfs_add_devswf( 704 &si_cdevsw, x, 705 DV_CHR, 0, 0, 0600, "ttyA%02d", y); 706 sc->devfs_token[x].cuaa = devfs_add_devswf( 707 &si_cdevsw, x + 128, 708 DV_CHR, 0, 0, 0600, "cuaA%02d", y); 709 sc->devfs_token[x].ttyi = devfs_add_devswf( 710 &si_cdevsw, x + 0x10000, 711 DV_CHR, 0, 0, 0600, "ttyiA%02d", y); 712 sc->devfs_token[x].ttyl = devfs_add_devswf( 713 &si_cdevsw, x + 0x20000, 714 DV_CHR, 0, 0, 0600, "ttylA%02d", y); 715 } 716 sc->control_token = 717 devfs_add_devswf(&si_cdevsw, 0x40000, DV_CHR, 0, 0, 0600, 718 "si_control"); 719#endif 720 return (1); 721} 722 723static int 724siopen(dev, flag, mode, p) 725 dev_t dev; 726 int flag, mode; 727 struct proc *p; 728{ 729 int oldspl, error; 730 int card, port; 731 register struct si_softc *sc; 732 register struct tty *tp; 733 volatile struct si_channel *ccbp; 734 struct si_port *pp; 735 int mynor = minor(dev); 736 737 /* quickly let in /dev/si_control */ 738 if (IS_CONTROLDEV(mynor)) { 739 if (error = suser(p->p_ucred, &p->p_acflag)) 740 return(error); 741 return(0); 742 } 743 744 card = SI_CARD(mynor); 745 if (card >= NSI) 746 return (ENXIO); 747 sc = &si_softc[card]; 748 749 if (sc->sc_type == SIEMPTY) { 750 DPRINT((0, DBG_OPEN|DBG_FAIL, "si%d: type %s??\n", 751 card, sc->sc_typename)); 752 return(ENXIO); 753 } 754 755 port = SI_PORT(mynor); 756 if (port >= sc->sc_nport) { 757 DPRINT((0, DBG_OPEN|DBG_FAIL, "si%d: nports %d\n", 758 card, sc->sc_nport)); 759 return(ENXIO); 760 } 761 762#ifdef POLL 763 /* 764 * We've now got a device, so start the poller. 765 */ 766 if (init_finished == 0) { 767 timeout(si_poll, (caddr_t)0L, si_pollrate); 768 init_finished = 1; 769 } 770#endif 771 772 /* initial/lock device */ 773 if (IS_STATE(mynor)) { 774 return(0); 775 } 776 777 pp = sc->sc_ports + port; 778 tp = pp->sp_tty; /* the "real" tty */ 779 ccbp = pp->sp_ccb; /* Find control block */ 780 DPRINT((pp, DBG_ENTRY|DBG_OPEN, "siopen(%x,%x,%x,%x)\n", 781 dev, flag, mode, p)); 782 783 oldspl = spltty(); /* Keep others out */ 784 error = 0; 785 786open_top: 787 while (pp->sp_state & SS_DTR_OFF) { 788 error = tsleep(&pp->sp_dtr_wait, TTIPRI|PCATCH, "sidtr", 0); 789 if (error != 0) 790 goto out; 791 } 792 793 if (tp->t_state & TS_ISOPEN) { 794 /* 795 * The device is open, so everything has been initialised. 796 * handle conflicts. 797 */ 798 if (IS_CALLOUT(mynor)) { 799 if (!pp->sp_active_out) { 800 error = EBUSY; 801 goto out; 802 } 803 } else { 804 if (pp->sp_active_out) { 805 if (flag & O_NONBLOCK) { 806 error = EBUSY; 807 goto out; 808 } 809 error = tsleep(&pp->sp_active_out, 810 TTIPRI|PCATCH, "sibi", 0); 811 if (error != 0) 812 goto out; 813 goto open_top; 814 } 815 } 816 if (tp->t_state & TS_XCLUDE && p->p_ucred->cr_uid != 0) { 817 DPRINT((pp, DBG_OPEN|DBG_FAIL, 818 "already open and EXCLUSIVE set\n")); 819 error = EBUSY; 820 goto out; 821 } 822 } else { 823 /* 824 * The device isn't open, so there are no conflicts. 825 * Initialize it. Avoid sleep... :-) 826 */ 827 DPRINT((pp, DBG_OPEN, "first open\n")); 828 tp->t_oproc = si_start; 829 tp->t_param = siparam; 830 tp->t_dev = dev; 831 tp->t_termios = mynor & SI_CALLOUT_MASK 832 ? pp->sp_iout : pp->sp_iin; 833 834 (void) si_modem(pp, SET, TIOCM_DTR|TIOCM_RTS); 835 836 ++pp->sp_wopeners; /* in case of sleep in siparam */ 837 838 error = siparam(tp, &tp->t_termios); 839 840 --pp->sp_wopeners; 841 if (error != 0) 842 goto out; 843 /* XXX: we should goto_top if siparam slept */ 844 845 ttsetwater(tp); 846 847 /* set initial DCD state */ 848 pp->sp_last_hi_ip = ccbp->hi_ip; 849 if ((pp->sp_last_hi_ip & IP_DCD) || IS_CALLOUT(mynor)) { 850 (*linesw[tp->t_line].l_modem)(tp, 1); 851 } 852 } 853 854 /* whoops! we beat the close! */ 855 if (pp->sp_state & SS_CLOSING) { 856 /* try and stop it from proceeding to bash the hardware */ 857 pp->sp_state &= ~SS_CLOSING; 858 } 859 860 /* 861 * Wait for DCD if necessary 862 */ 863 if (!(tp->t_state & TS_CARR_ON) 864 && !IS_CALLOUT(mynor) 865 && !(tp->t_cflag & CLOCAL) 866 && !(flag & O_NONBLOCK)) { 867 ++pp->sp_wopeners; 868 DPRINT((pp, DBG_OPEN, "sleeping for carrier\n")); 869 error = tsleep(TSA_CARR_ON(tp), TTIPRI|PCATCH, "sidcd", 0); 870 --pp->sp_wopeners; 871 if (error != 0) 872 goto out; 873 goto open_top; 874 } 875 876 error = (*linesw[tp->t_line].l_open)(dev, tp); 877 si_disc_optim(tp, &tp->t_termios, pp); 878 if (tp->t_state & TS_ISOPEN && IS_CALLOUT(mynor)) 879 pp->sp_active_out = TRUE; 880 881 pp->sp_state |= SS_OPEN; /* made it! */ 882 883out: 884 splx(oldspl); 885 886 DPRINT((pp, DBG_OPEN, "leaving siopen\n")); 887 888 if (!(tp->t_state & TS_ISOPEN) && pp->sp_wopeners == 0) 889 sihardclose(pp); 890 891 return(error); 892} 893 894static int 895siclose(dev, flag, mode, p) 896 dev_t dev; 897 int flag, mode; 898 struct proc *p; 899{ 900 register struct si_port *pp; 901 register struct tty *tp; 902 int oldspl; 903 int error = 0; 904 int mynor = minor(dev); 905 906 if (IS_SPECIAL(mynor)) 907 return(0); 908 909 oldspl = spltty(); 910 911 pp = MINOR2PP(mynor); 912 tp = pp->sp_tty; 913 914 DPRINT((pp, DBG_ENTRY|DBG_CLOSE, "siclose(%x,%x,%x,%x) sp_state:%x\n", 915 dev, flag, mode, p, pp->sp_state)); 916 917 /* did we sleep and loose a race? */ 918 if (pp->sp_state & SS_CLOSING) { 919 /* error = ESOMETING? */ 920 goto out; 921 } 922 923 /* begin race detection.. */ 924 pp->sp_state |= SS_CLOSING; 925 926 si_write_enable(pp, 0); /* block writes for ttywait() */ 927 928 /* THIS MAY SLEEP IN TTYWAIT!!! */ 929 (*linesw[tp->t_line].l_close)(tp, flag); 930 931 si_write_enable(pp, 1); 932 933 /* did we sleep and somebody started another open? */ 934 if (!(pp->sp_state & SS_CLOSING)) { 935 /* error = ESOMETING? */ 936 goto out; 937 } 938 /* ok. we are now still on the right track.. nuke the hardware */ 939 940 if (pp->sp_state & SS_LSTART) { 941 untimeout((timeout_func_t)si_lstart, (caddr_t)pp); 942 pp->sp_state &= ~SS_LSTART; 943 } 944 945 sistop(tp, FREAD | FWRITE); 946 947 sihardclose(pp); 948 ttyclose(tp); 949 pp->sp_state &= ~SS_OPEN; 950 951out: 952 DPRINT((pp, DBG_CLOSE|DBG_EXIT, "close done, returning\n")); 953 splx(oldspl); 954 return(error); 955} 956 957static void 958sihardclose(pp) 959 struct si_port *pp; 960{ 961 int oldspl; 962 struct tty *tp; 963 volatile struct si_channel *ccbp; 964 965 oldspl = spltty(); 966 967 tp = pp->sp_tty; 968 ccbp = pp->sp_ccb; /* Find control block */ 969 if (tp->t_cflag & HUPCL 970 || !pp->sp_active_out 971 && !(ccbp->hi_ip & IP_DCD) 972 && !(pp->sp_iin.c_cflag && CLOCAL) 973 || !(tp->t_state & TS_ISOPEN)) { 974 975 (void) si_modem(pp, BIC, TIOCM_DTR|TIOCM_RTS); 976 (void) si_command(pp, FCLOSE, SI_NOWAIT); 977 978 if (pp->sp_dtr_wait != 0) { 979 timeout(sidtrwakeup, pp, pp->sp_dtr_wait); 980 pp->sp_state |= SS_DTR_OFF; 981 } 982 983 } 984 pp->sp_active_out = FALSE; 985 wakeup((caddr_t)&pp->sp_active_out); 986 wakeup(TSA_CARR_ON(tp)); 987 988 splx(oldspl); 989} 990 991 992/* 993 * called at splsoftclock()... 994 */ 995static void 996sidtrwakeup(chan) 997 void *chan; 998{ 999 struct si_port *pp; 1000 int oldspl; 1001 1002 oldspl = spltty(); 1003 1004 pp = (struct si_port *)chan; 1005 pp->sp_state &= ~SS_DTR_OFF; 1006 wakeup(&pp->sp_dtr_wait); 1007 1008 splx(oldspl); 1009} 1010 1011/* 1012 * User level stuff - read and write 1013 */ 1014static int 1015siread(dev, uio, flag) 1016 register dev_t dev; 1017 struct uio *uio; 1018 int flag; 1019{ 1020 register struct tty *tp; 1021 int mynor = minor(dev); 1022 1023 if (IS_SPECIAL(mynor)) { 1024 DPRINT((0, DBG_ENTRY|DBG_FAIL|DBG_READ, "siread(CONTROLDEV!!)\n")); 1025 return(ENODEV); 1026 } 1027 tp = MINOR2TP(mynor); 1028 DPRINT((TP2PP(tp), DBG_ENTRY|DBG_READ, 1029 "siread(%x,%x,%x)\n", dev, uio, flag)); 1030 return ((*linesw[tp->t_line].l_read)(tp, uio, flag)); 1031} 1032 1033 1034static int 1035siwrite(dev, uio, flag) 1036 dev_t dev; 1037 struct uio *uio; 1038 int flag; 1039{ 1040 register struct si_port *pp; 1041 register struct tty *tp; 1042 int error = 0; 1043 int mynor = minor(dev); 1044 int oldspl; 1045 1046 if (IS_SPECIAL(mynor)) { 1047 DPRINT((0, DBG_ENTRY|DBG_FAIL|DBG_WRITE, "siwrite(CONTROLDEV!!)\n")); 1048 return(ENODEV); 1049 } 1050 pp = MINOR2PP(mynor); 1051 tp = pp->sp_tty; 1052 DPRINT((pp, DBG_WRITE, "siwrite(%x,%x,%x)\n", dev, uio, flag)); 1053 1054 oldspl = spltty(); 1055 /* 1056 * If writes are currently blocked, wait on the "real" tty 1057 */ 1058 while (pp->sp_state & SS_BLOCKWRITE) { 1059 pp->sp_state |= SS_WAITWRITE; 1060 DPRINT((pp, DBG_WRITE, "in siwrite, wait for SS_BLOCKWRITE to clear\n")); 1061 if (error = ttysleep(tp, (caddr_t)pp, TTOPRI|PCATCH, 1062 "siwrite", 0)) 1063 goto out; 1064 } 1065 1066 error = (*linesw[tp->t_line].l_write)(tp, uio, flag); 1067out: 1068 splx(oldspl); 1069 return (error); 1070} 1071 1072 1073static struct tty * 1074sidevtotty(dev_t dev) 1075{ 1076 struct si_port *pp; 1077 int mynor = minor(dev); 1078 struct si_softc *sc = &si_softc[SI_CARD(mynor)]; 1079 1080 if (IS_SPECIAL(mynor)) 1081 return(NULL); 1082 if (SI_PORT(mynor) >= sc->sc_nport) 1083 return(NULL); 1084 pp = MINOR2PP(mynor); 1085 return (pp->sp_tty); 1086} 1087 1088static int 1089siioctl(dev, cmd, data, flag, p) 1090 dev_t dev; 1091 int cmd; 1092 caddr_t data; 1093 int flag; 1094 struct proc *p; 1095{ 1096 struct si_port *pp; 1097 register struct tty *tp; 1098 int error; 1099 int mynor = minor(dev); 1100 int oldspl; 1101 int blocked = 0; 1102#if defined(COMPAT_43) 1103 int oldcmd; 1104 struct termios term; 1105#endif 1106 1107 if (IS_SI_IOCTL(cmd)) 1108 return(si_Sioctl(dev, cmd, data, flag, p)); 1109 1110 pp = MINOR2PP(mynor); 1111 tp = pp->sp_tty; 1112 1113 DPRINT((pp, DBG_ENTRY|DBG_IOCTL, "siioctl(%x,%x,%x,%x)\n", 1114 dev, cmd, data, flag)); 1115 if (IS_STATE(mynor)) { 1116 struct termios *ct; 1117 1118 switch (mynor & SI_STATE_MASK) { 1119 case SI_INIT_STATE_MASK: 1120 ct = IS_CALLOUT(mynor) ? &pp->sp_iout : &pp->sp_iin; 1121 break; 1122 case SI_LOCK_STATE_MASK: 1123 ct = IS_CALLOUT(mynor) ? &pp->sp_iout : &pp->sp_iin; 1124 break; 1125 default: 1126 return (ENODEV); 1127 } 1128 switch (cmd) { 1129 case TIOCSETA: 1130 error = suser(p->p_ucred, &p->p_acflag); 1131 if (error != 0) 1132 return (error); 1133 *ct = *(struct termios *)data; 1134 return (0); 1135 case TIOCGETA: 1136 *(struct termios *)data = *ct; 1137 return (0); 1138 case TIOCGETD: 1139 *(int *)data = TTYDISC; 1140 return (0); 1141 case TIOCGWINSZ: 1142 bzero(data, sizeof(struct winsize)); 1143 return (0); 1144 default: 1145 return (ENOTTY); 1146 } 1147 } 1148 /* 1149 * Do the old-style ioctl compat routines... 1150 */ 1151#if defined(COMPAT_43) 1152 term = tp->t_termios; 1153 oldcmd = cmd; 1154 error = ttsetcompat(tp, &cmd, data, &term); 1155 if (error != 0) 1156 return (error); 1157 if (cmd != oldcmd) 1158 data = (caddr_t)&term; 1159#endif 1160 /* 1161 * Do the initial / lock state business 1162 */ 1163 if (cmd == TIOCSETA || cmd == TIOCSETAW || cmd == TIOCSETAF) { 1164 int cc; 1165 struct termios *dt = (struct termios *)data; 1166 struct termios *lt = mynor & SI_CALLOUT_MASK 1167 ? &pp->sp_lout : &pp->sp_lin; 1168 1169 dt->c_iflag = (tp->t_iflag & lt->c_iflag) 1170 | (dt->c_iflag & ~lt->c_iflag); 1171 dt->c_oflag = (tp->t_oflag & lt->c_oflag) 1172 | (dt->c_oflag & ~lt->c_oflag); 1173 dt->c_cflag = (tp->t_cflag & lt->c_cflag) 1174 | (dt->c_cflag & ~lt->c_cflag); 1175 dt->c_lflag = (tp->t_lflag & lt->c_lflag) 1176 | (dt->c_lflag & ~lt->c_lflag); 1177 for (cc = 0; cc < NCCS; ++cc) 1178 if (lt->c_cc[cc] != 0) 1179 dt->c_cc[cc] = tp->t_cc[cc]; 1180 if (lt->c_ispeed != 0) 1181 dt->c_ispeed = tp->t_ispeed; 1182 if (lt->c_ospeed != 0) 1183 dt->c_ospeed = tp->t_ospeed; 1184 } 1185 1186 /* 1187 * Block user-level writes to give the ttywait() 1188 * a chance to completely drain for commands 1189 * that require the port to be in a quiescent state. 1190 */ 1191 switch (cmd) { 1192 case TIOCSETAW: case TIOCSETAF: 1193 case TIOCDRAIN: case TIOCSETP: 1194 blocked++; /* block writes for ttywait() and siparam() */ 1195 si_write_enable(pp, 0); 1196 } 1197 1198 error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag, p); 1199 if (error >= 0) 1200 goto out; 1201 1202 oldspl = spltty(); 1203 1204 error = ttioctl(tp, cmd, data, flag); 1205 si_disc_optim(tp, &tp->t_termios, pp); 1206 if (error >= 0) 1207 goto outspl; 1208 1209 switch (cmd) { 1210 case TIOCSBRK: 1211 si_command(pp, SBREAK, SI_NOWAIT); 1212 break; 1213 case TIOCCBRK: 1214 si_command(pp, EBREAK, SI_NOWAIT); 1215 break; 1216 case TIOCSDTR: 1217 (void) si_modem(pp, SET, TIOCM_DTR|TIOCM_RTS); 1218 break; 1219 case TIOCCDTR: 1220 (void) si_modem(pp, SET, 0); 1221 break; 1222 case TIOCMSET: 1223 (void) si_modem(pp, SET, *(int *)data); 1224 break; 1225 case TIOCMBIS: 1226 (void) si_modem(pp, BIS, *(int *)data); 1227 break; 1228 case TIOCMBIC: 1229 (void) si_modem(pp, BIC, *(int *)data); 1230 break; 1231 case TIOCMGET: 1232 *(int *)data = si_modem(pp, GET, 0); 1233 break; 1234 case TIOCMSDTRWAIT: 1235 /* must be root since the wait applies to following logins */ 1236 error = suser(p->p_ucred, &p->p_acflag); 1237 if (error != 0) { 1238 goto outspl; 1239 } 1240 pp->sp_dtr_wait = *(int *)data * hz / 100; 1241 break; 1242 case TIOCMGDTRWAIT: 1243 *(int *)data = pp->sp_dtr_wait * 100 / hz; 1244 break; 1245 1246 default: 1247 error = ENOTTY; 1248 } 1249 error = 0; 1250outspl: 1251 splx(oldspl); 1252out: 1253 DPRINT((pp, DBG_IOCTL|DBG_EXIT, "siioctl ret %d\n", error)); 1254 if (blocked) 1255 si_write_enable(pp, 1); 1256 return(error); 1257} 1258 1259/* 1260 * Handle the Specialix ioctls. All MUST be called via the CONTROL device 1261 */ 1262static int 1263si_Sioctl(dev_t dev, int cmd, caddr_t data, int flag, struct proc *p) 1264{ 1265 struct si_softc *xsc; 1266 register struct si_port *xpp; 1267 volatile struct si_reg *regp; 1268 struct si_tcsi *dp; 1269 struct si_pstat *sps; 1270 int *ip, error = 0; 1271 int oldspl; 1272 int card, port; 1273 int mynor = minor(dev); 1274 1275 DPRINT((0, DBG_ENTRY|DBG_IOCTL, "si_Sioctl(%x,%x,%x,%x)\n", 1276 dev, cmd, data, flag)); 1277 1278#if 1 1279 DPRINT((0, DBG_IOCTL, "TCSI_PORT=%x\n", TCSI_PORT)); 1280 DPRINT((0, DBG_IOCTL, "TCSI_CCB=%x\n", TCSI_CCB)); 1281 DPRINT((0, DBG_IOCTL, "TCSI_TTY=%x\n", TCSI_TTY)); 1282#endif 1283 1284 if (!IS_CONTROLDEV(mynor)) { 1285 DPRINT((0, DBG_IOCTL|DBG_FAIL, "not called from control device!\n")); 1286 return(ENODEV); 1287 } 1288 1289 oldspl = spltty(); /* better safe than sorry */ 1290 1291 ip = (int *)data; 1292 1293#define SUCHECK if (error = suser(p->p_ucred, &p->p_acflag)) goto out 1294 1295 switch (cmd) { 1296 case TCSIPORTS: 1297 *ip = si_Nports; 1298 goto out; 1299 case TCSIMODULES: 1300 *ip = si_Nmodules; 1301 goto out; 1302 case TCSISDBG_ALL: 1303 SUCHECK; 1304 si_debug = *ip; 1305 goto out; 1306 case TCSIGDBG_ALL: 1307 *ip = si_debug; 1308 goto out; 1309 default: 1310 /* 1311 * Check that a controller for this port exists 1312 */ 1313 1314 /* may also be a struct si_pstat, a superset of si_tcsi */ 1315 1316 dp = (struct si_tcsi *)data; 1317 sps = (struct si_pstat *)data; 1318 card = dp->tc_card; 1319 xsc = &si_softc[card]; /* check.. */ 1320 if (card < 0 || card >= NSI || xsc->sc_type == SIEMPTY) { 1321 error = ENOENT; 1322 goto out; 1323 } 1324 /* 1325 * And check that a port exists 1326 */ 1327 port = dp->tc_port; 1328 if (port < 0 || port >= xsc->sc_nport) { 1329 error = ENOENT; 1330 goto out; 1331 } 1332 xpp = xsc->sc_ports + port; 1333 regp = (struct si_reg *)xsc->sc_maddr; 1334 } 1335 1336 switch (cmd) { 1337 case TCSIDEBUG: 1338#ifdef SI_DEBUG 1339 SUCHECK; 1340 if (xpp->sp_debug) 1341 xpp->sp_debug = 0; 1342 else { 1343 xpp->sp_debug = DBG_ALL; 1344 DPRINT((xpp, DBG_IOCTL, "debug toggled %s\n", 1345 (xpp->sp_debug&DBG_ALL)?"ON":"OFF")); 1346 } 1347 break; 1348#else 1349 error = ENODEV; 1350 goto out; 1351#endif 1352 case TCSISDBG_LEVEL: 1353 case TCSIGDBG_LEVEL: 1354#ifdef SI_DEBUG 1355 if (cmd == TCSIGDBG_LEVEL) { 1356 dp->tc_dbglvl = xpp->sp_debug; 1357 } else { 1358 SUCHECK; 1359 xpp->sp_debug = dp->tc_dbglvl; 1360 } 1361 break; 1362#else 1363 error = ENODEV; 1364 goto out; 1365#endif 1366 case TCSIGRXIT: 1367 dp->tc_int = regp->rx_int_count; 1368 break; 1369 case TCSIRXIT: 1370 SUCHECK; 1371 regp->rx_int_count = dp->tc_int; 1372 break; 1373 case TCSIGIT: 1374 dp->tc_int = regp->int_count; 1375 break; 1376 case TCSIIT: 1377 SUCHECK; 1378 regp->int_count = dp->tc_int; 1379 break; 1380 case TCSISTATE: 1381 dp->tc_int = xpp->sp_ccb->hi_ip; 1382 break; 1383 /* these next three use a different structure */ 1384 case TCSI_PORT: 1385 SUCHECK; 1386 sps->tc_siport = *xpp; 1387 break; 1388 case TCSI_CCB: 1389 SUCHECK; 1390 sps->tc_ccb = *xpp->sp_ccb; 1391 break; 1392 case TCSI_TTY: 1393 SUCHECK; 1394 sps->tc_tty = *xpp->sp_tty; 1395 break; 1396 default: 1397 error = EINVAL; 1398 goto out; 1399 } 1400out: 1401 splx(oldspl); 1402 return(error); /* success */ 1403} 1404 1405/* 1406 * siparam() : Configure line params 1407 * called at spltty(); 1408 * this may sleep, does not flush, nor wait for drain, nor block writes 1409 * caller must arrange this if it's important.. 1410 */ 1411static int 1412siparam(tp, t) 1413 register struct tty *tp; 1414 register struct termios *t; 1415{ 1416 register struct si_port *pp = TP2PP(tp); 1417 volatile struct si_channel *ccbp; 1418 int oldspl, cflag, iflag, oflag, lflag; 1419 int error = 0; /* shutup gcc */ 1420 int ispeed = 0; /* shutup gcc */ 1421 int ospeed = 0; /* shutup gcc */ 1422 BYTE val; 1423 1424 DPRINT((pp, DBG_ENTRY|DBG_PARAM, "siparam(%x,%x)\n", tp, t)); 1425 cflag = t->c_cflag; 1426 iflag = t->c_iflag; 1427 oflag = t->c_oflag; 1428 lflag = t->c_lflag; 1429 DPRINT((pp, DBG_PARAM, "OFLAG 0x%x CFLAG 0x%x IFLAG 0x%x LFLAG 0x%x\n", 1430 oflag, cflag, iflag, lflag)); 1431 1432 1433 /* if not hung up.. */ 1434 if (t->c_ospeed != 0) { 1435 /* translate baud rate to firmware values */ 1436 ospeed = ttspeedtab(t->c_ospeed, bdrates); 1437 ispeed = t->c_ispeed ? 1438 ttspeedtab(t->c_ispeed, bdrates) : ospeed; 1439 1440 /* enforce legit baud rate */ 1441 if (ospeed < 0 || ispeed < 0) 1442 return (EINVAL); 1443 } 1444 1445 1446 oldspl = spltty(); 1447 1448 ccbp = pp->sp_ccb; 1449 1450 /* ========== set hi_break ========== */ 1451 val = 0; 1452 if (iflag & IGNBRK) /* Breaks */ 1453 val |= BR_IGN; 1454 if (iflag & BRKINT) /* Interrupt on break? */ 1455 val |= BR_INT; 1456 if (iflag & PARMRK) /* Parity mark? */ 1457 val |= BR_PARMRK; 1458 if (iflag & IGNPAR) /* Ignore chars with parity errors? */ 1459 val |= BR_PARIGN; 1460 ccbp->hi_break = val; 1461 1462 /* ========== set hi_csr ========== */ 1463 /* if not hung up.. */ 1464 if (t->c_ospeed != 0) { 1465 /* Set I/O speeds */ 1466 val = (ispeed << 4) | ospeed; 1467 } 1468 ccbp->hi_csr = val; 1469 1470 /* ========== set hi_mr2 ========== */ 1471 val = 0; 1472 if (cflag & CSTOPB) /* Stop bits */ 1473 val |= MR2_2_STOP; 1474 else 1475 val |= MR2_1_STOP; 1476 /* 1477 * Enable H/W RTS/CTS handshaking. The default TA/MTA is 1478 * a DCE, hence the reverse sense of RTS and CTS 1479 */ 1480 /* Output Flow - RTS must be raised before data can be sent */ 1481 if (cflag & CCTS_OFLOW) 1482 val |= MR2_RTSCONT; 1483 1484 ccbp->hi_mr1 = val; 1485 1486 /* ========== set hi_mr1 ========== */ 1487 val = 0; 1488 if (!(cflag & PARENB)) /* Parity */ 1489 val |= MR1_NONE; 1490 else 1491 val |= MR1_WITH; 1492 if (cflag & PARODD) 1493 val |= MR1_ODD; 1494 1495 if ((cflag & CS8) == CS8) { /* 8 data bits? */ 1496 val |= MR1_8_BITS; 1497 } else if ((cflag & CS7) == CS7) { /* 7 data bits? */ 1498 val |= MR1_7_BITS; 1499 } else if ((cflag & CS6) == CS6) { /* 6 data bits? */ 1500 val |= MR1_6_BITS; 1501 } else { /* Must be 5 */ 1502 val |= MR1_5_BITS; 1503 } 1504 /* 1505 * Enable H/W RTS/CTS handshaking. The default TA/MTA is 1506 * a DCE, hence the reverse sense of RTS and CTS 1507 */ 1508 /* Input Flow - CTS is raised when port is ready to receive data */ 1509 if (cflag & CRTS_IFLOW) 1510 val |= MR1_CTSCONT; 1511 1512 ccbp->hi_mr1 = val; 1513 1514 /* ========== set hi_mask ========== */ 1515 val = 0xff; 1516 if ((cflag & CS8) == CS8) { /* 8 data bits? */ 1517 val &= 0xFF; 1518 } else if ((cflag & CS7) == CS7) { /* 7 data bits? */ 1519 val &= 0x7F; 1520 } else if ((cflag & CS6) == CS6) { /* 6 data bits? */ 1521 val &= 0x3F; 1522 } else { /* Must be 5 */ 1523 val &= 0x1F; 1524 } 1525 if (iflag & ISTRIP) 1526 val &= 0x7F; 1527 1528 ccbp->hi_mask = val; 1529 1530 /* ========== set hi_prtcl ========== */ 1531 val = 0; 1532 /* Monitor DCD etc. if a modem */ 1533 if (!(cflag & CLOCAL)) 1534 val |= SP_DCEN; 1535 if (iflag & IXANY) 1536 val |= SP_TANY; 1537 if (iflag & IXON) 1538 val |= SP_TXEN; 1539 if (iflag & IXOFF) 1540 val |= SP_RXEN; 1541 if (iflag & INPCK) 1542 val |= SP_PAEN; 1543 1544 ccbp->hi_prtcl = val; 1545 1546 1547 /* ========== set hi_{rx|tx}{on|off} ========== */ 1548 /* XXX: the card TOTALLY shields us from the flow control... */ 1549 ccbp->hi_txon = t->c_cc[VSTART]; 1550 ccbp->hi_txoff = t->c_cc[VSTOP]; 1551 1552 ccbp->hi_rxon = t->c_cc[VSTART]; 1553 ccbp->hi_rxoff = t->c_cc[VSTOP]; 1554 1555 /* ========== send settings to the card ========== */ 1556 /* potential sleep here */ 1557 if (ccbp->hi_stat == IDLE_CLOSE) /* Not yet open */ 1558 si_command(pp, LOPEN, SI_WAIT); /* open it */ 1559 else 1560 si_command(pp, CONFIG, SI_WAIT); /* change params */ 1561 1562 /* ========== set DTR etc ========== */ 1563 /* Hangup if ospeed == 0 */ 1564 if (t->c_ospeed == 0) { 1565 (void) si_modem(pp, BIC, TIOCM_DTR|TIOCM_RTS); 1566 } else { 1567 /* 1568 * If the previous speed was 0, may need to re-enable 1569 * the modem signals 1570 */ 1571 (void) si_modem(pp, SET, TIOCM_DTR|TIOCM_RTS); 1572 } 1573 1574 DPRINT((pp, DBG_PARAM, "siparam, complete: MR1 %x MR2 %x HI_MASK %x PRTCL %x HI_BREAK %x\n", 1575 ccbp->hi_mr1, ccbp->hi_mr2, ccbp->hi_mask, ccbp->hi_prtcl, ccbp->hi_break)); 1576 1577 splx(oldspl); 1578 return(error); 1579} 1580 1581/* 1582 * Enable or Disable the writes to this channel... 1583 * "state" -> enabled = 1; disabled = 0; 1584 */ 1585static void 1586si_write_enable(pp, state) 1587 register struct si_port *pp; 1588 int state; 1589{ 1590 int oldspl; 1591 1592 oldspl = spltty(); 1593 1594 if (state) { 1595 pp->sp_state &= ~SS_BLOCKWRITE; 1596 if (pp->sp_state & SS_WAITWRITE) { 1597 pp->sp_state &= ~SS_WAITWRITE; 1598 /* thunder away! */ 1599 wakeup((caddr_t)pp); 1600 } 1601 } else { 1602 pp->sp_state |= SS_BLOCKWRITE; 1603 } 1604 1605 splx(oldspl); 1606} 1607 1608/* 1609 * Set/Get state of modem control lines. 1610 * Due to DCE-like behaviour of the adapter, some signals need translation: 1611 * TIOCM_DTR DSR 1612 * TIOCM_RTS CTS 1613 */ 1614static int 1615si_modem(pp, cmd, bits) 1616 struct si_port *pp; 1617 enum si_mctl cmd; 1618 int bits; 1619{ 1620 volatile struct si_channel *ccbp; 1621 int x; 1622 1623 DPRINT((pp, DBG_ENTRY|DBG_MODEM, "si_modem(%x,%s,%x)\n", pp, si_mctl2str(cmd), bits)); 1624 ccbp = pp->sp_ccb; /* Find channel address */ 1625 switch (cmd) { 1626 case GET: 1627 x = ccbp->hi_ip; 1628 bits = TIOCM_LE; 1629 if (x & IP_DCD) bits |= TIOCM_CAR; 1630 if (x & IP_DTR) bits |= TIOCM_DTR; 1631 if (x & IP_RTS) bits |= TIOCM_RTS; 1632 if (x & IP_RI) bits |= TIOCM_RI; 1633 return(bits); 1634 case SET: 1635 ccbp->hi_op &= ~(OP_DSR|OP_CTS); 1636 /* fall through */ 1637 case BIS: 1638 x = 0; 1639 if (bits & TIOCM_DTR) 1640 x |= OP_DSR; 1641 if (bits & TIOCM_RTS) 1642 x |= OP_CTS; 1643 ccbp->hi_op |= x; 1644 break; 1645 case BIC: 1646 if (bits & TIOCM_DTR) 1647 ccbp->hi_op &= ~OP_DSR; 1648 if (bits & TIOCM_RTS) 1649 ccbp->hi_op &= ~OP_CTS; 1650 } 1651 return 0; 1652} 1653 1654/* 1655 * Handle change of modem state 1656 */ 1657static void 1658si_modem_state(pp, tp, hi_ip) 1659 register struct si_port *pp; 1660 register struct tty *tp; 1661 register int hi_ip; 1662{ 1663 /* if a modem dev */ 1664 if (hi_ip & IP_DCD) { 1665 if ( !(pp->sp_last_hi_ip & IP_DCD)) { 1666 DPRINT((pp, DBG_INTR, "modem carr on t_line %d\n", 1667 tp->t_line)); 1668 (void)(*linesw[tp->t_line].l_modem)(tp, 1); 1669 } 1670 } else { 1671 if (pp->sp_last_hi_ip & IP_DCD) { 1672 DPRINT((pp, DBG_INTR, "modem carr off\n")); 1673 if ((*linesw[tp->t_line].l_modem)(tp, 0)) 1674 (void) si_modem(pp, SET, 0); 1675 } 1676 } 1677 pp->sp_last_hi_ip = hi_ip; 1678 1679} 1680 1681/* 1682 * Poller to catch missed interrupts. 1683 * 1684 * Note that the SYSV Specialix drivers poll at 100 times per second to get 1685 * better response. We could really use a "periodic" version timeout(). :-) 1686 */ 1687#ifdef POLL 1688static void 1689si_poll(void *nothing) 1690{ 1691 register struct si_softc *sc; 1692 register int i; 1693 volatile struct si_reg *regp; 1694 register struct si_port *pp; 1695 int lost, oldspl, port; 1696 1697 DPRINT((0, DBG_POLL, "si_poll()\n")); 1698 oldspl = spltty(); 1699 if (in_intr) 1700 goto out; 1701 lost = 0; 1702 for (i=0; i<NSI; i++) { 1703 sc = &si_softc[i]; 1704 if (sc->sc_type == SIEMPTY) 1705 continue; 1706 regp = (struct si_reg *)sc->sc_maddr; 1707 /* 1708 * See if there has been a pending interrupt for 2 seconds 1709 * or so. The test <int_scounter >= 200) won't correspond 1710 * to 2 seconds if int_count gets changed. 1711 */ 1712 if (regp->int_pending != 0) { 1713 if (regp->int_scounter >= 200 && 1714 regp->initstat == 1) { 1715 printf("si%d: lost intr\n", i); 1716 lost++; 1717 } 1718 } else { 1719 regp->int_scounter = 0; 1720 } 1721 1722 /* 1723 * gripe about no input flow control.. 1724 */ 1725 pp = sc->sc_ports; 1726 for (port = 0; port < sc->sc_nport; pp++, port++) { 1727 if (pp->sp_delta_overflows > 0) { 1728 printf("si%d: %d tty level buffer overflows\n", 1729 i, pp->sp_delta_overflows); 1730 pp->sp_delta_overflows = 0; 1731 } 1732 } 1733 } 1734 if (lost) 1735 siintr(-1); /* call intr with fake vector */ 1736out: 1737 splx(oldspl); 1738 1739 timeout(si_poll, (caddr_t)0L, si_pollrate); 1740} 1741#endif /* ifdef POLL */ 1742 1743/* 1744 * The interrupt handler polls ALL ports on ALL adapters each time 1745 * it is called. 1746 */ 1747 1748static BYTE si_rxbuf[SI_BUFFERSIZE]; /* input staging area */ 1749 1750void 1751siintr(int unit) 1752{ 1753 register struct si_softc *sc; 1754 1755 register struct si_port *pp; 1756 volatile struct si_channel *ccbp; 1757 register struct tty *tp; 1758 volatile caddr_t maddr; 1759 BYTE op, ip; 1760 int x, card, port, n, i, isopen; 1761 volatile BYTE *z; 1762 BYTE c; 1763 1764 DPRINT((0, (unit < 0) ? DBG_POLL:DBG_INTR, "siintr(%d)\n", unit)); 1765 if (in_intr) { 1766 if (unit < 0) /* should never happen */ 1767 return; 1768 printf("si%d: Warning interrupt handler re-entered\n", 1769 unit); 1770 return; 1771 } 1772 in_intr = 1; 1773 1774 /* 1775 * When we get an int we poll all the channels and do ALL pending 1776 * work, not just the first one we find. This allows all cards to 1777 * share the same vector. 1778 */ 1779 for (card=0; card < NSI; card++) { 1780 sc = &si_softc[card]; 1781 if (sc->sc_type == SIEMPTY) 1782 continue; 1783 1784 /* 1785 * First, clear the interrupt 1786 */ 1787 switch(sc->sc_type) { 1788 case SIHOST : 1789 maddr = sc->sc_maddr; 1790 ((volatile struct si_reg *)maddr)->int_pending = 0; 1791 /* flag nothing pending */ 1792 *(maddr+SIINTCL) = 0x00; /* Set IRQ clear */ 1793 *(maddr+SIINTCL_CL) = 0x00; /* Clear IRQ clear */ 1794 break; 1795 case SIHOST2: 1796 maddr = sc->sc_maddr; 1797 ((volatile struct si_reg *)maddr)->int_pending = 0; 1798 *(maddr+SIPLIRQCLR) = 0x00; 1799 *(maddr+SIPLIRQCLR) = 0x10; 1800 break; 1801 case SIEISA: 1802#if NEISA > 0 1803 maddr = sc->sc_maddr; 1804 ((volatile struct si_reg *)maddr)->int_pending = 0; 1805 (void)inb(sc->sc_eisa_iobase+3); 1806 break; 1807#endif /* fall through if not EISA kernel */ 1808 case SIEMPTY: 1809 default: 1810 continue; 1811 } 1812 ((volatile struct si_reg *)maddr)->int_scounter = 0; 1813 1814 /* 1815 * check each port 1816 */ 1817 for (pp=sc->sc_ports,port=0; port < sc->sc_nport; pp++,port++) { 1818 ccbp = pp->sp_ccb; 1819 tp = pp->sp_tty; 1820 1821 1822 /* 1823 * See if a command has completed ? 1824 */ 1825 if (ccbp->hi_stat != pp->sp_pend) { 1826 DPRINT((pp, DBG_INTR, 1827 "siintr hi_stat = 0x%x, pend = %d\n", 1828 ccbp->hi_stat, pp->sp_pend)); 1829 switch(pp->sp_pend) { 1830 case LOPEN: 1831 case MPEND: 1832 case MOPEN: 1833 case CONFIG: 1834 pp->sp_pend = ccbp->hi_stat; 1835 /* sleeping in si_command */ 1836 wakeup(&pp->sp_state); 1837 break; 1838 default: 1839 pp->sp_pend = ccbp->hi_stat; 1840 } 1841 } 1842 1843 /* 1844 * Continue on if it's closed 1845 */ 1846 if (ccbp->hi_stat == IDLE_CLOSE) { 1847 continue; 1848 } 1849 1850 /* 1851 * Do modem state change if not a local device 1852 */ 1853 si_modem_state(pp, tp, ccbp->hi_ip); 1854 1855 /* 1856 * Check to see if there's we should 'receive' 1857 * characters. 1858 */ 1859 if (tp->t_state & TS_CONNECTED && 1860 tp->t_state & TS_ISOPEN) 1861 isopen = 1; 1862 else 1863 isopen = 0; 1864 1865 /* 1866 * Do break processing 1867 */ 1868 if (ccbp->hi_state & ST_BREAK) { 1869 if (isopen) { 1870 (*linesw[tp->t_line].l_rint)(TTY_BI, tp); 1871 } 1872 ccbp->hi_state &= ~ST_BREAK; /* A Bit iffy this */ 1873 DPRINT((pp, DBG_INTR, "si_intr break\n")); 1874 } 1875 1876 /* 1877 * Do RX stuff - if not open then dump any characters. 1878 * XXX: This is VERY messy and needs to be cleaned up. 1879 * 1880 * XXX: can we leave data in the host adapter buffer 1881 * when the clists are full? That may be dangerous 1882 * if the user cannot get an interrupt signal through. 1883 */ 1884 1885 more_rx: /* XXX Sorry. the nesting was driving me bats! :-( */ 1886 1887 if (!isopen) { 1888 ccbp->hi_rxopos = ccbp->hi_rxipos; 1889 goto end_rx; 1890 } 1891 1892 /* 1893 * If the tty input buffers are blocked, stop emptying 1894 * the incoming buffers and let the auto flow control 1895 * assert.. 1896 */ 1897 if (tp->t_state & TS_TBLOCK) { 1898 goto end_rx; 1899 } 1900 1901 /* 1902 * Process read characters if not skipped above 1903 */ 1904 op = ccbp->hi_rxopos; 1905 ip = ccbp->hi_rxipos; 1906 c = ip - op; 1907 if (c == 0) { 1908 goto end_rx; 1909 } 1910 1911 n = c & 0xff; 1912 if (n > 250) 1913 n = 250; 1914 1915 DPRINT((pp, DBG_INTR, "n = %d, op = %d, ip = %d\n", 1916 n, op, ip)); 1917 1918 /* 1919 * Suck characters out of host card buffer into the 1920 * "input staging buffer" - so that we dont leave the 1921 * host card in limbo while we're possibly echoing 1922 * characters and possibly flushing input inside the 1923 * ldisc l_rint() routine. 1924 */ 1925 if (n <= SI_BUFFERSIZE - op) { 1926 1927 DPRINT((pp, DBG_INTR, "\tsingle copy\n")); 1928 z = ccbp->hi_rxbuf + op; 1929 bcopy((caddr_t)z, si_rxbuf, n); 1930 1931 op += n; 1932 } else { 1933 x = SI_BUFFERSIZE - op; 1934 1935 DPRINT((pp, DBG_INTR, "\tdouble part 1 %d\n", x)); 1936 z = ccbp->hi_rxbuf + op; 1937 bcopy((caddr_t)z, si_rxbuf, x); 1938 1939 DPRINT((pp, DBG_INTR, "\tdouble part 2 %d\n", n-x)); 1940 z = ccbp->hi_rxbuf; 1941 bcopy((caddr_t)z, si_rxbuf+x, n-x); 1942 1943 op += n; 1944 } 1945 1946 /* clear collected characters from buffer */ 1947 ccbp->hi_rxopos = op; 1948 1949 DPRINT((pp, DBG_INTR, "n = %d, op = %d, ip = %d\n", 1950 n, op, ip)); 1951 1952 /* 1953 * at this point... 1954 * n = number of chars placed in si_rxbuf 1955 */ 1956 1957 /* 1958 * Avoid the grotesquely inefficient lineswitch 1959 * routine (ttyinput) in "raw" mode. It usually 1960 * takes about 450 instructions (that's without 1961 * canonical processing or echo!). slinput is 1962 * reasonably fast (usually 40 instructions 1963 * plus call overhead). 1964 */ 1965 if (tp->t_state & TS_CAN_BYPASS_L_RINT) { 1966 1967 /* block if the driver supports it */ 1968 if (tp->t_rawq.c_cc + n >= SI_I_HIGH_WATER 1969 && (tp->t_cflag & CRTS_IFLOW 1970 || tp->t_iflag & IXOFF) 1971 && !(tp->t_state & TS_TBLOCK)) 1972 ttyblock(tp); 1973 1974 tk_nin += n; 1975 tk_rawcc += n; 1976 tp->t_rawcc += n; 1977 1978 pp->sp_delta_overflows += 1979 b_to_q((char *)si_rxbuf, n, &tp->t_rawq); 1980 1981 ttwakeup(tp); 1982 if (tp->t_state & TS_TTSTOP 1983 && (tp->t_iflag & IXANY 1984 || tp->t_cc[VSTART] == tp->t_cc[VSTOP])) { 1985 tp->t_state &= ~TS_TTSTOP; 1986 tp->t_lflag &= ~FLUSHO; 1987 si_start(tp); 1988 } 1989 } else { 1990 /* 1991 * It'd be nice to not have to go through the 1992 * function call overhead for each char here. 1993 * It'd be nice to block input it, saving a 1994 * loop here and the call/return overhead. 1995 */ 1996 for(x = 0; x < n; x++) { 1997 i = si_rxbuf[x]; 1998 if ((*linesw[tp->t_line].l_rint)(i, tp) 1999 == -1) { 2000 pp->sp_delta_overflows++; 2001 } 2002 /* 2003 * doesn't seem to be much point doing 2004 * this here.. this driver has no 2005 * softtty processing! ?? 2006 */ 2007 if (pp->sp_hotchar && i == pp->sp_hotchar) { 2008 setsofttty(); 2009 } 2010 } 2011 } 2012 goto more_rx; /* try for more until RXbuf is empty */ 2013 2014 end_rx: /* XXX: Again, sorry about the gotos.. :-) */ 2015 2016 /* 2017 * Do TX stuff 2018 */ 2019 (*linesw[tp->t_line].l_start)(tp); 2020 2021 } /* end of for (all ports on this controller) */ 2022 } /* end of for (all controllers) */ 2023 2024 in_intr = 0; 2025 DPRINT((0, (unit < 0) ? DBG_POLL:DBG_INTR, "end siintr(%d)\n", unit)); 2026} 2027 2028/* 2029 * Nudge the transmitter... 2030 * 2031 * XXX: I inherited some funny code here. It implies the host card only 2032 * interrupts when the transmit buffer reaches the low-water-mark, and does 2033 * not interrupt when it's actually hits empty. In some cases, we have 2034 * processes waiting for complete drain, and we need to simulate an interrupt 2035 * about when we think the buffer is going to be empty (and retry if not). 2036 * I really am not certain about this... I *need* the hardware manuals. 2037 */ 2038static void 2039si_start(tp) 2040 register struct tty *tp; 2041{ 2042 struct si_port *pp; 2043 volatile struct si_channel *ccbp; 2044 register struct clist *qp; 2045 register char *dptr; 2046 BYTE ipos; 2047 int nchar; 2048 int oldspl, count, n, amount, buffer_full; 2049 int do_exitproc; 2050 2051 oldspl = spltty(); 2052 2053 qp = &tp->t_outq; 2054 pp = TP2PP(tp); 2055 2056 DPRINT((pp, DBG_ENTRY|DBG_START, 2057 "si_start(%x) t_state %x sp_state %x t_outq.c_cc %d\n", 2058 tp, tp->t_state, pp->sp_state, qp->c_cc)); 2059 2060 if (tp->t_state & (TS_TIMEOUT|TS_TTSTOP)) 2061 goto out; 2062 2063 do_exitproc = 0; 2064 buffer_full = 0; 2065 ccbp = pp->sp_ccb; 2066 2067 /* 2068 * Handle the case where ttywait() is called on process exit 2069 * this may be BSDI specific, I dont know... 2070 */ 2071 if (tp->t_session != NULL && tp->t_session->s_leader != NULL && 2072 (tp->t_session->s_leader->p_flag & P_WEXIT)) { 2073 do_exitproc++; 2074 } 2075 2076 count = (int)ccbp->hi_txipos - (int)ccbp->hi_txopos; 2077 DPRINT((pp, DBG_START, "count %d\n", (BYTE)count)); 2078 2079 dptr = (char *)ccbp->hi_txbuf; /* data buffer */ 2080 2081 while ((nchar = qp->c_cc) > 0) { 2082 if ((BYTE)count >= 255) { 2083 buffer_full++; 2084 break; 2085 } 2086 amount = min(nchar, (255 - (BYTE)count)); 2087 ipos = (unsigned int)ccbp->hi_txipos; 2088 /* will it fit in one lump? */ 2089 if ((SI_BUFFERSIZE - ipos) >= amount) { 2090 n = q_to_b(&tp->t_outq, 2091 (char *)&ccbp->hi_txbuf[ipos], amount); 2092 } else { 2093 n = q_to_b(&tp->t_outq, 2094 (char *)&ccbp->hi_txbuf[ipos], 2095 SI_BUFFERSIZE-ipos); 2096 if (n == SI_BUFFERSIZE-ipos) { 2097 n += q_to_b(&tp->t_outq, 2098 (char *)&ccbp->hi_txbuf[0], 2099 amount - (SI_BUFFERSIZE-ipos)); 2100 } 2101 } 2102 ccbp->hi_txipos += n; 2103 count = (int)ccbp->hi_txipos - (int)ccbp->hi_txopos; 2104 } 2105 2106 if (count != 0 && nchar == 0) { 2107 tp->t_state |= TS_BUSY; 2108 } else { 2109 tp->t_state &= ~TS_BUSY; 2110 } 2111 2112 /* wakeup time? */ 2113 ttwwakeup(tp); 2114 2115 DPRINT((pp, DBG_START, "count %d, nchar %d, tp->t_state 0x%x\n", 2116 (BYTE)count, nchar, tp->t_state)); 2117 2118 if ((tp->t_state & TS_BUSY) || do_exitproc) 2119 { 2120 int time; 2121 2122 if (do_exitproc != 0) { 2123 time = hz / 10; 2124 } else { 2125 time = ttspeedtab(tp->t_ospeed, chartimes); 2126 2127 if (time > 0) { 2128 if (time < nchar) 2129 time = nchar / time; 2130 else 2131 time = 2; 2132 } else { 2133 DPRINT((pp, DBG_START, 2134 "bad char time value! %d\n", time)); 2135 time = hz/10; 2136 } 2137 } 2138 2139 if ((pp->sp_state & (SS_LSTART|SS_INLSTART)) == SS_LSTART) { 2140 untimeout((timeout_func_t)si_lstart, (caddr_t)pp); 2141 } else { 2142 pp->sp_state |= SS_LSTART; 2143 } 2144 DPRINT((pp, DBG_START, "arming lstart, time=%d\n", time)); 2145 timeout((timeout_func_t)si_lstart, (caddr_t)pp, time); 2146 } 2147 2148out: 2149 splx(oldspl); 2150 DPRINT((pp, DBG_EXIT|DBG_START, "leave si_start()\n")); 2151} 2152 2153/* 2154 * Note: called at splsoftclock from the timeout code 2155 * This has to deal with two things... cause wakeups while waiting for 2156 * tty drains on last process exit, and call l_start at about the right 2157 * time for protocols like ppp. 2158 */ 2159static void 2160si_lstart(pp) 2161 register struct si_port *pp; 2162{ 2163 register struct tty *tp; 2164 int oldspl; 2165 2166 DPRINT((pp, DBG_ENTRY|DBG_LSTART, "si_lstart(%x) sp_state %x\n", 2167 pp, pp->sp_state)); 2168 2169 oldspl = spltty(); 2170 2171 if ((pp->sp_state & SS_OPEN) == 0 || (pp->sp_state & SS_LSTART) == 0) { 2172 splx(oldspl); 2173 return; 2174 } 2175 pp->sp_state &= ~SS_LSTART; 2176 pp->sp_state |= SS_INLSTART; 2177 2178 tp = pp->sp_tty; 2179 2180 /* deal with the process exit case */ 2181 ttwwakeup(tp); 2182 2183 /* nudge protocols - eg: ppp */ 2184 (*linesw[tp->t_line].l_start)(tp); 2185 2186 pp->sp_state &= ~SS_INLSTART; 2187 splx(oldspl); 2188} 2189 2190/* 2191 * Stop output on a line. called at spltty(); 2192 */ 2193void 2194sistop(tp, rw) 2195 register struct tty *tp; 2196 int rw; 2197{ 2198 volatile struct si_channel *ccbp; 2199 struct si_port *pp; 2200 2201 pp = TP2PP(tp); 2202 ccbp = pp->sp_ccb; 2203 2204 DPRINT((TP2PP(tp), DBG_ENTRY|DBG_STOP, "sistop(%x,%x)\n", tp, rw)); 2205 2206 /* XXX: must check (rw & FWRITE | FREAD) etc flushing... */ 2207 if (rw & FWRITE) { 2208 /* what level are we meant to be flushing anyway? */ 2209 if (tp->t_state & TS_BUSY) { 2210 si_command(TP2PP(tp), WFLUSH, SI_NOWAIT); 2211 tp->t_state &= ~TS_BUSY; 2212 ttwwakeup(tp); /* Bruce???? */ 2213 } 2214 } 2215#if 1 /* XXX: this doesn't work right yet.. */ 2216 /* XXX: this may have been failing because we used to call l_rint() 2217 * while we were looping based on these two counters. Now, we collect 2218 * the data and then loop stuffing it into l_rint(), making this 2219 * useless. Should we cause this to blow away the staging buffer? 2220 */ 2221 if (rw & FREAD) { 2222 ccbp->hi_rxopos = ccbp->hi_rxipos; 2223 } 2224#endif 2225} 2226 2227/* 2228 * Issue a command to the Z280 host card CPU. 2229 */ 2230 2231static void 2232si_command(pp, cmd, waitflag) 2233 struct si_port *pp; /* port control block (local) */ 2234 int cmd; 2235 int waitflag; 2236{ 2237 int oldspl; 2238 volatile struct si_channel *ccbp = pp->sp_ccb; 2239 int x; 2240 2241 DPRINT((pp, DBG_ENTRY|DBG_PARAM, "si_command(%x,%x,%d): hi_stat 0x%x\n", 2242 pp, cmd, waitflag, ccbp->hi_stat)); 2243 2244 oldspl = spltty(); /* Keep others out */ 2245 2246 /* wait until it's finished what it was doing.. */ 2247 while((x = ccbp->hi_stat) != IDLE_OPEN && 2248 x != IDLE_CLOSE && 2249 x != cmd) { 2250 if (in_intr) { /* Prevent sleep in intr */ 2251 DPRINT((pp, DBG_PARAM, 2252 "cmd intr collision - completing %d\trequested %d\n", 2253 x, cmd)); 2254 splx(oldspl); 2255 return; 2256 } else if (ttysleep(pp->sp_tty, (caddr_t)&pp->sp_state, TTIPRI|PCATCH, 2257 "sicmd1", 1)) { 2258 splx(oldspl); 2259 return; 2260 } 2261 } 2262 /* it should now be in IDLE_OPEN, IDLE_CLOSE, or "cmd" */ 2263 2264 /* if there was a pending command, cause a state-change wakeup */ 2265 if (pp->sp_pend != IDLE_OPEN) { 2266 switch(pp->sp_pend) { 2267 case LOPEN: 2268 case MPEND: 2269 case MOPEN: 2270 case CONFIG: 2271 wakeup(&pp->sp_state); 2272 break; 2273 default: 2274 break; 2275 } 2276 } 2277 2278 pp->sp_pend = cmd; /* New command pending */ 2279 ccbp->hi_stat = cmd; /* Post it */ 2280 2281 if (waitflag) { 2282 if (in_intr) { /* If in interrupt handler */ 2283 DPRINT((pp, DBG_PARAM, 2284 "attempt to sleep in si_intr - cmd req %d\n", 2285 cmd)); 2286 splx(oldspl); 2287 return; 2288 } else while(ccbp->hi_stat != IDLE_OPEN) { 2289 if (ttysleep(pp->sp_tty, (caddr_t)&pp->sp_state, TTIPRI|PCATCH, 2290 "sicmd2", 0)) 2291 break; 2292 } 2293 } 2294 splx(oldspl); 2295} 2296 2297static void 2298si_disc_optim(tp, t, pp) 2299 struct tty *tp; 2300 struct termios *t; 2301 struct si_port *pp; 2302{ 2303 /* 2304 * XXX can skip a lot more cases if Smarts. Maybe 2305 * (IGNCR | ISTRIP | IXON) in c_iflag. But perhaps we 2306 * shouldn't skip if (TS_CNTTB | TS_LNCH) is set in t_state. 2307 */ 2308 if (!(t->c_iflag & (ICRNL | IGNCR | IMAXBEL | INLCR | ISTRIP | IXON)) 2309 && (!(t->c_iflag & BRKINT) || (t->c_iflag & IGNBRK)) 2310 && (!(t->c_iflag & PARMRK) 2311 || (t->c_iflag & (IGNPAR | IGNBRK)) == (IGNPAR | IGNBRK)) 2312 && !(t->c_lflag & (ECHO | ICANON | IEXTEN | ISIG | PENDIN)) 2313 && linesw[tp->t_line].l_rint == ttyinput) 2314 tp->t_state |= TS_CAN_BYPASS_L_RINT; 2315 else 2316 tp->t_state &= ~TS_CAN_BYPASS_L_RINT; 2317 2318 /* 2319 * Prepare to reduce input latency for packet 2320 * discplines with a end of packet character. 2321 */ 2322 if (tp->t_line == SLIPDISC) 2323 pp->sp_hotchar = 0xc0; 2324 else if (tp->t_line == PPPDISC) 2325 pp->sp_hotchar = 0x7e; 2326 else 2327 pp->sp_hotchar = 0; 2328 2329 DPRINT((pp, DBG_OPTIM, "bypass: %s, hotchar: %x\n", 2330 (tp->t_state & TS_CAN_BYPASS_L_RINT) ? "on" : "off", 2331 pp->sp_hotchar)); 2332} 2333 2334 2335#ifdef SI_DEBUG 2336 2337static void 2338#ifdef __STDC__ 2339si_dprintf(struct si_port *pp, int flags, const char *fmt, ...) 2340#else 2341si_dprintf(pp, flags, fmt, va_alist) 2342 struct si_port *pp; 2343 int flags; 2344 char *fmt; 2345#endif 2346{ 2347 va_list ap; 2348 2349 if ((pp == NULL && (si_debug&flags)) || 2350 (pp != NULL && ((pp->sp_debug&flags) || (si_debug&flags)))) { 2351 if (pp != NULL) 2352 printf("%ci%d(%d): ", 's', 2353 (int)SI_CARD(pp->sp_tty->t_dev), 2354 (int)SI_PORT(pp->sp_tty->t_dev)); 2355 va_start(ap, fmt); 2356 vprintf(fmt, ap); 2357 va_end(ap); 2358 } 2359} 2360 2361static char * 2362si_mctl2str(cmd) 2363 enum si_mctl cmd; 2364{ 2365 switch (cmd) { 2366 case GET: return("GET"); 2367 case SET: return("SET"); 2368 case BIS: return("BIS"); 2369 case BIC: return("BIC"); 2370 } 2371 return("BAD"); 2372} 2373 2374#endif /* DEBUG */ 2375 2376 2377 2378static si_devsw_installed = 0; 2379 2380static void si_drvinit(void *unused) 2381{ 2382 dev_t dev; 2383 2384 if( ! si_devsw_installed ) { 2385 dev = makedev(CDEV_MAJOR, 0); 2386 cdevsw_add(&dev,&si_cdevsw, NULL); 2387 si_devsw_installed = 1; 2388 } 2389} 2390 2391SYSINIT(sidev,SI_SUB_DRIVERS,SI_ORDER_MIDDLE+CDEV_MAJOR,si_drvinit,NULL) 2392 2393