si.c revision 16575
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.45 1996/06/17 18:52:53 peter 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_WAIT); 1212 break; 1213 case TIOCCBRK: 1214 si_command(pp, EBREAK, SI_WAIT); 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 bcopy(xpp, &sps->tc_siport, sizeof(sps->tc_siport)); 1387 break; 1388 case TCSI_CCB: 1389 SUCHECK; 1390 bcopy((char *)xpp->sp_ccb, &sps->tc_ccb, sizeof(sps->tc_ccb)); 1391 break; 1392 case TCSI_TTY: 1393 SUCHECK; 1394 bcopy(xpp->sp_tty, &sps->tc_tty, sizeof(sps->tc_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_mr2 = 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 case SBREAK: 1835 case EBREAK: 1836 pp->sp_pend = ccbp->hi_stat; 1837 /* sleeping in si_command */ 1838 wakeup(&pp->sp_state); 1839 break; 1840 default: 1841 pp->sp_pend = ccbp->hi_stat; 1842 } 1843 } 1844 1845 /* 1846 * Continue on if it's closed 1847 */ 1848 if (ccbp->hi_stat == IDLE_CLOSE) { 1849 continue; 1850 } 1851 1852 /* 1853 * Do modem state change if not a local device 1854 */ 1855 si_modem_state(pp, tp, ccbp->hi_ip); 1856 1857 /* 1858 * Check to see if there's we should 'receive' 1859 * characters. 1860 */ 1861 if (tp->t_state & TS_CONNECTED && 1862 tp->t_state & TS_ISOPEN) 1863 isopen = 1; 1864 else 1865 isopen = 0; 1866 1867 /* 1868 * Do input break processing 1869 */ 1870 if (ccbp->hi_state & ST_BREAK) { 1871 if (isopen) { 1872 (*linesw[tp->t_line].l_rint)(TTY_BI, tp); 1873 } 1874 ccbp->hi_state &= ~ST_BREAK; /* A Bit iffy this */ 1875 DPRINT((pp, DBG_INTR, "si_intr break\n")); 1876 } 1877 1878 /* 1879 * Do RX stuff - if not open then dump any characters. 1880 * XXX: This is VERY messy and needs to be cleaned up. 1881 * 1882 * XXX: can we leave data in the host adapter buffer 1883 * when the clists are full? That may be dangerous 1884 * if the user cannot get an interrupt signal through. 1885 */ 1886 1887 more_rx: /* XXX Sorry. the nesting was driving me bats! :-( */ 1888 1889 if (!isopen) { 1890 ccbp->hi_rxopos = ccbp->hi_rxipos; 1891 goto end_rx; 1892 } 1893 1894 /* 1895 * If the tty input buffers are blocked, stop emptying 1896 * the incoming buffers and let the auto flow control 1897 * assert.. 1898 */ 1899 if (tp->t_state & TS_TBLOCK) { 1900 goto end_rx; 1901 } 1902 1903 /* 1904 * Process read characters if not skipped above 1905 */ 1906 op = ccbp->hi_rxopos; 1907 ip = ccbp->hi_rxipos; 1908 c = ip - op; 1909 if (c == 0) { 1910 goto end_rx; 1911 } 1912 1913 n = c & 0xff; 1914 if (n > 250) 1915 n = 250; 1916 1917 DPRINT((pp, DBG_INTR, "n = %d, op = %d, ip = %d\n", 1918 n, op, ip)); 1919 1920 /* 1921 * Suck characters out of host card buffer into the 1922 * "input staging buffer" - so that we dont leave the 1923 * host card in limbo while we're possibly echoing 1924 * characters and possibly flushing input inside the 1925 * ldisc l_rint() routine. 1926 */ 1927 if (n <= SI_BUFFERSIZE - op) { 1928 1929 DPRINT((pp, DBG_INTR, "\tsingle copy\n")); 1930 z = ccbp->hi_rxbuf + op; 1931 bcopy((caddr_t)z, si_rxbuf, n); 1932 1933 op += n; 1934 } else { 1935 x = SI_BUFFERSIZE - op; 1936 1937 DPRINT((pp, DBG_INTR, "\tdouble part 1 %d\n", x)); 1938 z = ccbp->hi_rxbuf + op; 1939 bcopy((caddr_t)z, si_rxbuf, x); 1940 1941 DPRINT((pp, DBG_INTR, "\tdouble part 2 %d\n", n-x)); 1942 z = ccbp->hi_rxbuf; 1943 bcopy((caddr_t)z, si_rxbuf+x, n-x); 1944 1945 op += n; 1946 } 1947 1948 /* clear collected characters from buffer */ 1949 ccbp->hi_rxopos = op; 1950 1951 DPRINT((pp, DBG_INTR, "n = %d, op = %d, ip = %d\n", 1952 n, op, ip)); 1953 1954 /* 1955 * at this point... 1956 * n = number of chars placed in si_rxbuf 1957 */ 1958 1959 /* 1960 * Avoid the grotesquely inefficient lineswitch 1961 * routine (ttyinput) in "raw" mode. It usually 1962 * takes about 450 instructions (that's without 1963 * canonical processing or echo!). slinput is 1964 * reasonably fast (usually 40 instructions 1965 * plus call overhead). 1966 */ 1967 if (tp->t_state & TS_CAN_BYPASS_L_RINT) { 1968 1969 /* block if the driver supports it */ 1970 if (tp->t_rawq.c_cc + n >= SI_I_HIGH_WATER 1971 && (tp->t_cflag & CRTS_IFLOW 1972 || tp->t_iflag & IXOFF) 1973 && !(tp->t_state & TS_TBLOCK)) 1974 ttyblock(tp); 1975 1976 tk_nin += n; 1977 tk_rawcc += n; 1978 tp->t_rawcc += n; 1979 1980 pp->sp_delta_overflows += 1981 b_to_q((char *)si_rxbuf, n, &tp->t_rawq); 1982 1983 ttwakeup(tp); 1984 if (tp->t_state & TS_TTSTOP 1985 && (tp->t_iflag & IXANY 1986 || tp->t_cc[VSTART] == tp->t_cc[VSTOP])) { 1987 tp->t_state &= ~TS_TTSTOP; 1988 tp->t_lflag &= ~FLUSHO; 1989 si_start(tp); 1990 } 1991 } else { 1992 /* 1993 * It'd be nice to not have to go through the 1994 * function call overhead for each char here. 1995 * It'd be nice to block input it, saving a 1996 * loop here and the call/return overhead. 1997 */ 1998 for(x = 0; x < n; x++) { 1999 i = si_rxbuf[x]; 2000 if ((*linesw[tp->t_line].l_rint)(i, tp) 2001 == -1) { 2002 pp->sp_delta_overflows++; 2003 } 2004 /* 2005 * doesn't seem to be much point doing 2006 * this here.. this driver has no 2007 * softtty processing! ?? 2008 */ 2009 if (pp->sp_hotchar && i == pp->sp_hotchar) { 2010 setsofttty(); 2011 } 2012 } 2013 } 2014 goto more_rx; /* try for more until RXbuf is empty */ 2015 2016 end_rx: /* XXX: Again, sorry about the gotos.. :-) */ 2017 2018 /* 2019 * Do TX stuff 2020 */ 2021 (*linesw[tp->t_line].l_start)(tp); 2022 2023 } /* end of for (all ports on this controller) */ 2024 } /* end of for (all controllers) */ 2025 2026 in_intr = 0; 2027 DPRINT((0, (unit < 0) ? DBG_POLL:DBG_INTR, "end siintr(%d)\n", unit)); 2028} 2029 2030/* 2031 * Nudge the transmitter... 2032 * 2033 * XXX: I inherited some funny code here. It implies the host card only 2034 * interrupts when the transmit buffer reaches the low-water-mark, and does 2035 * not interrupt when it's actually hits empty. In some cases, we have 2036 * processes waiting for complete drain, and we need to simulate an interrupt 2037 * about when we think the buffer is going to be empty (and retry if not). 2038 * I really am not certain about this... I *need* the hardware manuals. 2039 */ 2040static void 2041si_start(tp) 2042 register struct tty *tp; 2043{ 2044 struct si_port *pp; 2045 volatile struct si_channel *ccbp; 2046 register struct clist *qp; 2047 register char *dptr; 2048 BYTE ipos; 2049 int nchar; 2050 int oldspl, count, n, amount, buffer_full; 2051 int do_exitproc; 2052 2053 oldspl = spltty(); 2054 2055 qp = &tp->t_outq; 2056 pp = TP2PP(tp); 2057 2058 DPRINT((pp, DBG_ENTRY|DBG_START, 2059 "si_start(%x) t_state %x sp_state %x t_outq.c_cc %d\n", 2060 tp, tp->t_state, pp->sp_state, qp->c_cc)); 2061 2062 if (tp->t_state & (TS_TIMEOUT|TS_TTSTOP)) 2063 goto out; 2064 2065 do_exitproc = 0; 2066 buffer_full = 0; 2067 ccbp = pp->sp_ccb; 2068 2069 /* 2070 * Handle the case where ttywait() is called on process exit 2071 * this may be BSDI specific, I dont know... 2072 */ 2073 if (tp->t_session != NULL && tp->t_session->s_leader != NULL && 2074 (tp->t_session->s_leader->p_flag & P_WEXIT)) { 2075 do_exitproc++; 2076 } 2077 2078 count = (int)ccbp->hi_txipos - (int)ccbp->hi_txopos; 2079 DPRINT((pp, DBG_START, "count %d\n", (BYTE)count)); 2080 2081 dptr = (char *)ccbp->hi_txbuf; /* data buffer */ 2082 2083 while ((nchar = qp->c_cc) > 0) { 2084 if ((BYTE)count >= 255) { 2085 buffer_full++; 2086 break; 2087 } 2088 amount = min(nchar, (255 - (BYTE)count)); 2089 ipos = (unsigned int)ccbp->hi_txipos; 2090 /* will it fit in one lump? */ 2091 if ((SI_BUFFERSIZE - ipos) >= amount) { 2092 n = q_to_b(&tp->t_outq, 2093 (char *)&ccbp->hi_txbuf[ipos], amount); 2094 } else { 2095 n = q_to_b(&tp->t_outq, 2096 (char *)&ccbp->hi_txbuf[ipos], 2097 SI_BUFFERSIZE-ipos); 2098 if (n == SI_BUFFERSIZE-ipos) { 2099 n += q_to_b(&tp->t_outq, 2100 (char *)&ccbp->hi_txbuf[0], 2101 amount - (SI_BUFFERSIZE-ipos)); 2102 } 2103 } 2104 ccbp->hi_txipos += n; 2105 count = (int)ccbp->hi_txipos - (int)ccbp->hi_txopos; 2106 } 2107 2108 if (count != 0 && nchar == 0) { 2109 tp->t_state |= TS_BUSY; 2110 } else { 2111 tp->t_state &= ~TS_BUSY; 2112 } 2113 2114 /* wakeup time? */ 2115 ttwwakeup(tp); 2116 2117 DPRINT((pp, DBG_START, "count %d, nchar %d, tp->t_state 0x%x\n", 2118 (BYTE)count, nchar, tp->t_state)); 2119 2120 if ((tp->t_state & TS_BUSY) || do_exitproc) 2121 { 2122 int time; 2123 2124 if (do_exitproc != 0) { 2125 time = hz / 10; 2126 } else { 2127 time = ttspeedtab(tp->t_ospeed, chartimes); 2128 2129 if (time > 0) { 2130 if (time < nchar) 2131 time = nchar / time; 2132 else 2133 time = 2; 2134 } else { 2135 DPRINT((pp, DBG_START, 2136 "bad char time value! %d\n", time)); 2137 time = hz/10; 2138 } 2139 } 2140 2141 if ((pp->sp_state & (SS_LSTART|SS_INLSTART)) == SS_LSTART) { 2142 untimeout((timeout_func_t)si_lstart, (caddr_t)pp); 2143 } else { 2144 pp->sp_state |= SS_LSTART; 2145 } 2146 DPRINT((pp, DBG_START, "arming lstart, time=%d\n", time)); 2147 timeout((timeout_func_t)si_lstart, (caddr_t)pp, time); 2148 } 2149 2150out: 2151 splx(oldspl); 2152 DPRINT((pp, DBG_EXIT|DBG_START, "leave si_start()\n")); 2153} 2154 2155/* 2156 * Note: called at splsoftclock from the timeout code 2157 * This has to deal with two things... cause wakeups while waiting for 2158 * tty drains on last process exit, and call l_start at about the right 2159 * time for protocols like ppp. 2160 */ 2161static void 2162si_lstart(pp) 2163 register struct si_port *pp; 2164{ 2165 register struct tty *tp; 2166 int oldspl; 2167 2168 DPRINT((pp, DBG_ENTRY|DBG_LSTART, "si_lstart(%x) sp_state %x\n", 2169 pp, pp->sp_state)); 2170 2171 oldspl = spltty(); 2172 2173 if ((pp->sp_state & SS_OPEN) == 0 || (pp->sp_state & SS_LSTART) == 0) { 2174 splx(oldspl); 2175 return; 2176 } 2177 pp->sp_state &= ~SS_LSTART; 2178 pp->sp_state |= SS_INLSTART; 2179 2180 tp = pp->sp_tty; 2181 2182 /* deal with the process exit case */ 2183 ttwwakeup(tp); 2184 2185 /* nudge protocols - eg: ppp */ 2186 (*linesw[tp->t_line].l_start)(tp); 2187 2188 pp->sp_state &= ~SS_INLSTART; 2189 splx(oldspl); 2190} 2191 2192/* 2193 * Stop output on a line. called at spltty(); 2194 */ 2195void 2196sistop(tp, rw) 2197 register struct tty *tp; 2198 int rw; 2199{ 2200 volatile struct si_channel *ccbp; 2201 struct si_port *pp; 2202 2203 pp = TP2PP(tp); 2204 ccbp = pp->sp_ccb; 2205 2206 DPRINT((TP2PP(tp), DBG_ENTRY|DBG_STOP, "sistop(%x,%x)\n", tp, rw)); 2207 2208 /* XXX: must check (rw & FWRITE | FREAD) etc flushing... */ 2209 if (rw & FWRITE) { 2210 /* what level are we meant to be flushing anyway? */ 2211 if (tp->t_state & TS_BUSY) { 2212 si_command(TP2PP(tp), WFLUSH, SI_NOWAIT); 2213 tp->t_state &= ~TS_BUSY; 2214 ttwwakeup(tp); /* Bruce???? */ 2215 } 2216 } 2217#if 1 /* XXX: this doesn't work right yet.. */ 2218 /* XXX: this may have been failing because we used to call l_rint() 2219 * while we were looping based on these two counters. Now, we collect 2220 * the data and then loop stuffing it into l_rint(), making this 2221 * useless. Should we cause this to blow away the staging buffer? 2222 */ 2223 if (rw & FREAD) { 2224 ccbp->hi_rxopos = ccbp->hi_rxipos; 2225 } 2226#endif 2227} 2228 2229/* 2230 * Issue a command to the Z280 host card CPU. 2231 */ 2232 2233static void 2234si_command(pp, cmd, waitflag) 2235 struct si_port *pp; /* port control block (local) */ 2236 int cmd; 2237 int waitflag; 2238{ 2239 int oldspl; 2240 volatile struct si_channel *ccbp = pp->sp_ccb; 2241 int x; 2242 2243 DPRINT((pp, DBG_ENTRY|DBG_PARAM, "si_command(%x,%x,%d): hi_stat 0x%x\n", 2244 pp, cmd, waitflag, ccbp->hi_stat)); 2245 2246 oldspl = spltty(); /* Keep others out */ 2247 2248 /* wait until it's finished what it was doing.. */ 2249 /* XXX: sits in IDLE_BREAK until something disturbs it or break 2250 * is turned off. */ 2251 while((x = ccbp->hi_stat) != IDLE_OPEN && 2252 x != IDLE_CLOSE && 2253 x != IDLE_BREAK && 2254 x != cmd) { 2255 if (in_intr) { /* Prevent sleep in intr */ 2256 DPRINT((pp, DBG_PARAM, 2257 "cmd intr collision - completing %d\trequested %d\n", 2258 x, cmd)); 2259 splx(oldspl); 2260 return; 2261 } else if (ttysleep(pp->sp_tty, (caddr_t)&pp->sp_state, TTIPRI|PCATCH, 2262 "sicmd1", 1)) { 2263 splx(oldspl); 2264 return; 2265 } 2266 } 2267 /* it should now be in IDLE_{OPEN|CLOSE|BREAK}, or "cmd" */ 2268 2269 /* if there was a pending command, cause a state-change wakeup */ 2270 switch(pp->sp_pend) { 2271 case LOPEN: 2272 case MPEND: 2273 case MOPEN: 2274 case CONFIG: 2275 case SBREAK: 2276 case EBREAK: 2277 wakeup(&pp->sp_state); 2278 break; 2279 default: 2280 break; 2281 } 2282 2283 pp->sp_pend = cmd; /* New command pending */ 2284 ccbp->hi_stat = cmd; /* Post it */ 2285 2286 if (waitflag) { 2287 if (in_intr) { /* If in interrupt handler */ 2288 DPRINT((pp, DBG_PARAM, 2289 "attempt to sleep in si_intr - cmd req %d\n", 2290 cmd)); 2291 splx(oldspl); 2292 return; 2293 } else while(ccbp->hi_stat != IDLE_OPEN && 2294 ccbp->hi_stat != IDLE_BREAK) { 2295 if (ttysleep(pp->sp_tty, (caddr_t)&pp->sp_state, TTIPRI|PCATCH, 2296 "sicmd2", 0)) 2297 break; 2298 } 2299 } 2300 splx(oldspl); 2301} 2302 2303static void 2304si_disc_optim(tp, t, pp) 2305 struct tty *tp; 2306 struct termios *t; 2307 struct si_port *pp; 2308{ 2309 /* 2310 * XXX can skip a lot more cases if Smarts. Maybe 2311 * (IGNCR | ISTRIP | IXON) in c_iflag. But perhaps we 2312 * shouldn't skip if (TS_CNTTB | TS_LNCH) is set in t_state. 2313 */ 2314 if (!(t->c_iflag & (ICRNL | IGNCR | IMAXBEL | INLCR | ISTRIP | IXON)) 2315 && (!(t->c_iflag & BRKINT) || (t->c_iflag & IGNBRK)) 2316 && (!(t->c_iflag & PARMRK) 2317 || (t->c_iflag & (IGNPAR | IGNBRK)) == (IGNPAR | IGNBRK)) 2318 && !(t->c_lflag & (ECHO | ICANON | IEXTEN | ISIG | PENDIN)) 2319 && linesw[tp->t_line].l_rint == ttyinput) 2320 tp->t_state |= TS_CAN_BYPASS_L_RINT; 2321 else 2322 tp->t_state &= ~TS_CAN_BYPASS_L_RINT; 2323 2324 /* 2325 * Prepare to reduce input latency for packet 2326 * discplines with a end of packet character. 2327 */ 2328 if (tp->t_line == SLIPDISC) 2329 pp->sp_hotchar = 0xc0; 2330 else if (tp->t_line == PPPDISC) 2331 pp->sp_hotchar = 0x7e; 2332 else 2333 pp->sp_hotchar = 0; 2334 2335 DPRINT((pp, DBG_OPTIM, "bypass: %s, hotchar: %x\n", 2336 (tp->t_state & TS_CAN_BYPASS_L_RINT) ? "on" : "off", 2337 pp->sp_hotchar)); 2338} 2339 2340 2341#ifdef SI_DEBUG 2342 2343static void 2344#ifdef __STDC__ 2345si_dprintf(struct si_port *pp, int flags, const char *fmt, ...) 2346#else 2347si_dprintf(pp, flags, fmt, va_alist) 2348 struct si_port *pp; 2349 int flags; 2350 char *fmt; 2351#endif 2352{ 2353 va_list ap; 2354 2355 if ((pp == NULL && (si_debug&flags)) || 2356 (pp != NULL && ((pp->sp_debug&flags) || (si_debug&flags)))) { 2357 if (pp != NULL) 2358 printf("%ci%d(%d): ", 's', 2359 (int)SI_CARD(pp->sp_tty->t_dev), 2360 (int)SI_PORT(pp->sp_tty->t_dev)); 2361 va_start(ap, fmt); 2362 vprintf(fmt, ap); 2363 va_end(ap); 2364 } 2365} 2366 2367static char * 2368si_mctl2str(cmd) 2369 enum si_mctl cmd; 2370{ 2371 switch (cmd) { 2372 case GET: return("GET"); 2373 case SET: return("SET"); 2374 case BIS: return("BIS"); 2375 case BIC: return("BIC"); 2376 } 2377 return("BAD"); 2378} 2379 2380#endif /* DEBUG */ 2381 2382 2383 2384static si_devsw_installed = 0; 2385 2386static void si_drvinit(void *unused) 2387{ 2388 dev_t dev; 2389 2390 if( ! si_devsw_installed ) { 2391 dev = makedev(CDEV_MAJOR, 0); 2392 cdevsw_add(&dev,&si_cdevsw, NULL); 2393 si_devsw_installed = 1; 2394 } 2395} 2396 2397SYSINIT(sidev,SI_SUB_DRIVERS,SI_ORDER_MIDDLE+CDEV_MAJOR,si_drvinit,NULL) 2398 2399