si.c revision 17290
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.47 1996/06/30 04:56:05 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", tp->t_timeout)) { 1063 if (error == ETIMEDOUT) 1064 error = EIO; 1065 goto out; 1066 } 1067 } 1068 1069 error = (*linesw[tp->t_line].l_write)(tp, uio, flag); 1070out: 1071 splx(oldspl); 1072 return (error); 1073} 1074 1075 1076static struct tty * 1077sidevtotty(dev_t dev) 1078{ 1079 struct si_port *pp; 1080 int mynor = minor(dev); 1081 struct si_softc *sc = &si_softc[SI_CARD(mynor)]; 1082 1083 if (IS_SPECIAL(mynor)) 1084 return(NULL); 1085 if (SI_PORT(mynor) >= sc->sc_nport) 1086 return(NULL); 1087 pp = MINOR2PP(mynor); 1088 return (pp->sp_tty); 1089} 1090 1091static int 1092siioctl(dev, cmd, data, flag, p) 1093 dev_t dev; 1094 int cmd; 1095 caddr_t data; 1096 int flag; 1097 struct proc *p; 1098{ 1099 struct si_port *pp; 1100 register struct tty *tp; 1101 int error; 1102 int mynor = minor(dev); 1103 int oldspl; 1104 int blocked = 0; 1105#if defined(COMPAT_43) 1106 int oldcmd; 1107 struct termios term; 1108#endif 1109 1110 if (IS_SI_IOCTL(cmd)) 1111 return(si_Sioctl(dev, cmd, data, flag, p)); 1112 1113 pp = MINOR2PP(mynor); 1114 tp = pp->sp_tty; 1115 1116 DPRINT((pp, DBG_ENTRY|DBG_IOCTL, "siioctl(%x,%x,%x,%x)\n", 1117 dev, cmd, data, flag)); 1118 if (IS_STATE(mynor)) { 1119 struct termios *ct; 1120 1121 switch (mynor & SI_STATE_MASK) { 1122 case SI_INIT_STATE_MASK: 1123 ct = IS_CALLOUT(mynor) ? &pp->sp_iout : &pp->sp_iin; 1124 break; 1125 case SI_LOCK_STATE_MASK: 1126 ct = IS_CALLOUT(mynor) ? &pp->sp_lout : &pp->sp_lin; 1127 break; 1128 default: 1129 return (ENODEV); 1130 } 1131 switch (cmd) { 1132 case TIOCSETA: 1133 error = suser(p->p_ucred, &p->p_acflag); 1134 if (error != 0) 1135 return (error); 1136 *ct = *(struct termios *)data; 1137 return (0); 1138 case TIOCGETA: 1139 *(struct termios *)data = *ct; 1140 return (0); 1141 case TIOCGETD: 1142 *(int *)data = TTYDISC; 1143 return (0); 1144 case TIOCGWINSZ: 1145 bzero(data, sizeof(struct winsize)); 1146 return (0); 1147 default: 1148 return (ENOTTY); 1149 } 1150 } 1151 /* 1152 * Do the old-style ioctl compat routines... 1153 */ 1154#if defined(COMPAT_43) 1155 term = tp->t_termios; 1156 oldcmd = cmd; 1157 error = ttsetcompat(tp, &cmd, data, &term); 1158 if (error != 0) 1159 return (error); 1160 if (cmd != oldcmd) 1161 data = (caddr_t)&term; 1162#endif 1163 /* 1164 * Do the initial / lock state business 1165 */ 1166 if (cmd == TIOCSETA || cmd == TIOCSETAW || cmd == TIOCSETAF) { 1167 int cc; 1168 struct termios *dt = (struct termios *)data; 1169 struct termios *lt = mynor & SI_CALLOUT_MASK 1170 ? &pp->sp_lout : &pp->sp_lin; 1171 1172 dt->c_iflag = (tp->t_iflag & lt->c_iflag) 1173 | (dt->c_iflag & ~lt->c_iflag); 1174 dt->c_oflag = (tp->t_oflag & lt->c_oflag) 1175 | (dt->c_oflag & ~lt->c_oflag); 1176 dt->c_cflag = (tp->t_cflag & lt->c_cflag) 1177 | (dt->c_cflag & ~lt->c_cflag); 1178 dt->c_lflag = (tp->t_lflag & lt->c_lflag) 1179 | (dt->c_lflag & ~lt->c_lflag); 1180 for (cc = 0; cc < NCCS; ++cc) 1181 if (lt->c_cc[cc] != 0) 1182 dt->c_cc[cc] = tp->t_cc[cc]; 1183 if (lt->c_ispeed != 0) 1184 dt->c_ispeed = tp->t_ispeed; 1185 if (lt->c_ospeed != 0) 1186 dt->c_ospeed = tp->t_ospeed; 1187 } 1188 1189 /* 1190 * Block user-level writes to give the ttywait() 1191 * a chance to completely drain for commands 1192 * that require the port to be in a quiescent state. 1193 */ 1194 switch (cmd) { 1195 case TIOCSETAW: case TIOCSETAF: 1196 case TIOCDRAIN: case TIOCSETP: 1197 blocked++; /* block writes for ttywait() and siparam() */ 1198 si_write_enable(pp, 0); 1199 } 1200 1201 error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag, p); 1202 if (error >= 0) 1203 goto out; 1204 1205 oldspl = spltty(); 1206 1207 error = ttioctl(tp, cmd, data, flag); 1208 si_disc_optim(tp, &tp->t_termios, pp); 1209 if (error >= 0) 1210 goto outspl; 1211 1212 switch (cmd) { 1213 case TIOCSBRK: 1214 si_command(pp, SBREAK, SI_WAIT); 1215 break; 1216 case TIOCCBRK: 1217 si_command(pp, EBREAK, SI_WAIT); 1218 break; 1219 case TIOCSDTR: 1220 (void) si_modem(pp, SET, TIOCM_DTR|TIOCM_RTS); 1221 break; 1222 case TIOCCDTR: 1223 (void) si_modem(pp, SET, 0); 1224 break; 1225 case TIOCMSET: 1226 (void) si_modem(pp, SET, *(int *)data); 1227 break; 1228 case TIOCMBIS: 1229 (void) si_modem(pp, BIS, *(int *)data); 1230 break; 1231 case TIOCMBIC: 1232 (void) si_modem(pp, BIC, *(int *)data); 1233 break; 1234 case TIOCMGET: 1235 *(int *)data = si_modem(pp, GET, 0); 1236 break; 1237 case TIOCMSDTRWAIT: 1238 /* must be root since the wait applies to following logins */ 1239 error = suser(p->p_ucred, &p->p_acflag); 1240 if (error != 0) { 1241 goto outspl; 1242 } 1243 pp->sp_dtr_wait = *(int *)data * hz / 100; 1244 break; 1245 case TIOCMGDTRWAIT: 1246 *(int *)data = pp->sp_dtr_wait * 100 / hz; 1247 break; 1248 1249 default: 1250 error = ENOTTY; 1251 } 1252 error = 0; 1253outspl: 1254 splx(oldspl); 1255out: 1256 DPRINT((pp, DBG_IOCTL|DBG_EXIT, "siioctl ret %d\n", error)); 1257 if (blocked) 1258 si_write_enable(pp, 1); 1259 return(error); 1260} 1261 1262/* 1263 * Handle the Specialix ioctls. All MUST be called via the CONTROL device 1264 */ 1265static int 1266si_Sioctl(dev_t dev, int cmd, caddr_t data, int flag, struct proc *p) 1267{ 1268 struct si_softc *xsc; 1269 register struct si_port *xpp; 1270 volatile struct si_reg *regp; 1271 struct si_tcsi *dp; 1272 struct si_pstat *sps; 1273 int *ip, error = 0; 1274 int oldspl; 1275 int card, port; 1276 int mynor = minor(dev); 1277 1278 DPRINT((0, DBG_ENTRY|DBG_IOCTL, "si_Sioctl(%x,%x,%x,%x)\n", 1279 dev, cmd, data, flag)); 1280 1281#if 1 1282 DPRINT((0, DBG_IOCTL, "TCSI_PORT=%x\n", TCSI_PORT)); 1283 DPRINT((0, DBG_IOCTL, "TCSI_CCB=%x\n", TCSI_CCB)); 1284 DPRINT((0, DBG_IOCTL, "TCSI_TTY=%x\n", TCSI_TTY)); 1285#endif 1286 1287 if (!IS_CONTROLDEV(mynor)) { 1288 DPRINT((0, DBG_IOCTL|DBG_FAIL, "not called from control device!\n")); 1289 return(ENODEV); 1290 } 1291 1292 oldspl = spltty(); /* better safe than sorry */ 1293 1294 ip = (int *)data; 1295 1296#define SUCHECK if (error = suser(p->p_ucred, &p->p_acflag)) goto out 1297 1298 switch (cmd) { 1299 case TCSIPORTS: 1300 *ip = si_Nports; 1301 goto out; 1302 case TCSIMODULES: 1303 *ip = si_Nmodules; 1304 goto out; 1305 case TCSISDBG_ALL: 1306 SUCHECK; 1307 si_debug = *ip; 1308 goto out; 1309 case TCSIGDBG_ALL: 1310 *ip = si_debug; 1311 goto out; 1312 default: 1313 /* 1314 * Check that a controller for this port exists 1315 */ 1316 1317 /* may also be a struct si_pstat, a superset of si_tcsi */ 1318 1319 dp = (struct si_tcsi *)data; 1320 sps = (struct si_pstat *)data; 1321 card = dp->tc_card; 1322 xsc = &si_softc[card]; /* check.. */ 1323 if (card < 0 || card >= NSI || xsc->sc_type == SIEMPTY) { 1324 error = ENOENT; 1325 goto out; 1326 } 1327 /* 1328 * And check that a port exists 1329 */ 1330 port = dp->tc_port; 1331 if (port < 0 || port >= xsc->sc_nport) { 1332 error = ENOENT; 1333 goto out; 1334 } 1335 xpp = xsc->sc_ports + port; 1336 regp = (struct si_reg *)xsc->sc_maddr; 1337 } 1338 1339 switch (cmd) { 1340 case TCSIDEBUG: 1341#ifdef SI_DEBUG 1342 SUCHECK; 1343 if (xpp->sp_debug) 1344 xpp->sp_debug = 0; 1345 else { 1346 xpp->sp_debug = DBG_ALL; 1347 DPRINT((xpp, DBG_IOCTL, "debug toggled %s\n", 1348 (xpp->sp_debug&DBG_ALL)?"ON":"OFF")); 1349 } 1350 break; 1351#else 1352 error = ENODEV; 1353 goto out; 1354#endif 1355 case TCSISDBG_LEVEL: 1356 case TCSIGDBG_LEVEL: 1357#ifdef SI_DEBUG 1358 if (cmd == TCSIGDBG_LEVEL) { 1359 dp->tc_dbglvl = xpp->sp_debug; 1360 } else { 1361 SUCHECK; 1362 xpp->sp_debug = dp->tc_dbglvl; 1363 } 1364 break; 1365#else 1366 error = ENODEV; 1367 goto out; 1368#endif 1369 case TCSIGRXIT: 1370 dp->tc_int = regp->rx_int_count; 1371 break; 1372 case TCSIRXIT: 1373 SUCHECK; 1374 regp->rx_int_count = dp->tc_int; 1375 break; 1376 case TCSIGIT: 1377 dp->tc_int = regp->int_count; 1378 break; 1379 case TCSIIT: 1380 SUCHECK; 1381 regp->int_count = dp->tc_int; 1382 break; 1383 case TCSISTATE: 1384 dp->tc_int = xpp->sp_ccb->hi_ip; 1385 break; 1386 /* these next three use a different structure */ 1387 case TCSI_PORT: 1388 SUCHECK; 1389 bcopy(xpp, &sps->tc_siport, sizeof(sps->tc_siport)); 1390 break; 1391 case TCSI_CCB: 1392 SUCHECK; 1393 bcopy((char *)xpp->sp_ccb, &sps->tc_ccb, sizeof(sps->tc_ccb)); 1394 break; 1395 case TCSI_TTY: 1396 SUCHECK; 1397 bcopy(xpp->sp_tty, &sps->tc_tty, sizeof(sps->tc_tty)); 1398 break; 1399 default: 1400 error = EINVAL; 1401 goto out; 1402 } 1403out: 1404 splx(oldspl); 1405 return(error); /* success */ 1406} 1407 1408/* 1409 * siparam() : Configure line params 1410 * called at spltty(); 1411 * this may sleep, does not flush, nor wait for drain, nor block writes 1412 * caller must arrange this if it's important.. 1413 */ 1414static int 1415siparam(tp, t) 1416 register struct tty *tp; 1417 register struct termios *t; 1418{ 1419 register struct si_port *pp = TP2PP(tp); 1420 volatile struct si_channel *ccbp; 1421 int oldspl, cflag, iflag, oflag, lflag; 1422 int error = 0; /* shutup gcc */ 1423 int ispeed = 0; /* shutup gcc */ 1424 int ospeed = 0; /* shutup gcc */ 1425 BYTE val; 1426 1427 DPRINT((pp, DBG_ENTRY|DBG_PARAM, "siparam(%x,%x)\n", tp, t)); 1428 cflag = t->c_cflag; 1429 iflag = t->c_iflag; 1430 oflag = t->c_oflag; 1431 lflag = t->c_lflag; 1432 DPRINT((pp, DBG_PARAM, "OFLAG 0x%x CFLAG 0x%x IFLAG 0x%x LFLAG 0x%x\n", 1433 oflag, cflag, iflag, lflag)); 1434 1435 1436 /* if not hung up.. */ 1437 if (t->c_ospeed != 0) { 1438 /* translate baud rate to firmware values */ 1439 ospeed = ttspeedtab(t->c_ospeed, bdrates); 1440 ispeed = t->c_ispeed ? 1441 ttspeedtab(t->c_ispeed, bdrates) : ospeed; 1442 1443 /* enforce legit baud rate */ 1444 if (ospeed < 0 || ispeed < 0) 1445 return (EINVAL); 1446 } 1447 1448 1449 oldspl = spltty(); 1450 1451 ccbp = pp->sp_ccb; 1452 1453 /* ========== set hi_break ========== */ 1454 val = 0; 1455 if (iflag & IGNBRK) /* Breaks */ 1456 val |= BR_IGN; 1457 if (iflag & BRKINT) /* Interrupt on break? */ 1458 val |= BR_INT; 1459 if (iflag & PARMRK) /* Parity mark? */ 1460 val |= BR_PARMRK; 1461 if (iflag & IGNPAR) /* Ignore chars with parity errors? */ 1462 val |= BR_PARIGN; 1463 ccbp->hi_break = val; 1464 1465 /* ========== set hi_csr ========== */ 1466 /* if not hung up.. */ 1467 if (t->c_ospeed != 0) { 1468 /* Set I/O speeds */ 1469 val = (ispeed << 4) | ospeed; 1470 } 1471 ccbp->hi_csr = val; 1472 1473 /* ========== set hi_mr2 ========== */ 1474 val = 0; 1475 if (cflag & CSTOPB) /* Stop bits */ 1476 val |= MR2_2_STOP; 1477 else 1478 val |= MR2_1_STOP; 1479 /* 1480 * Enable H/W RTS/CTS handshaking. The default TA/MTA is 1481 * a DCE, hence the reverse sense of RTS and CTS 1482 */ 1483 /* Output Flow - RTS must be raised before data can be sent */ 1484 if (cflag & CCTS_OFLOW) 1485 val |= MR2_RTSCONT; 1486 1487 ccbp->hi_mr2 = val; 1488 1489 /* ========== set hi_mr1 ========== */ 1490 val = 0; 1491 if (!(cflag & PARENB)) /* Parity */ 1492 val |= MR1_NONE; 1493 else 1494 val |= MR1_WITH; 1495 if (cflag & PARODD) 1496 val |= MR1_ODD; 1497 1498 if ((cflag & CS8) == CS8) { /* 8 data bits? */ 1499 val |= MR1_8_BITS; 1500 } else if ((cflag & CS7) == CS7) { /* 7 data bits? */ 1501 val |= MR1_7_BITS; 1502 } else if ((cflag & CS6) == CS6) { /* 6 data bits? */ 1503 val |= MR1_6_BITS; 1504 } else { /* Must be 5 */ 1505 val |= MR1_5_BITS; 1506 } 1507 /* 1508 * Enable H/W RTS/CTS handshaking. The default TA/MTA is 1509 * a DCE, hence the reverse sense of RTS and CTS 1510 */ 1511 /* Input Flow - CTS is raised when port is ready to receive data */ 1512 if (cflag & CRTS_IFLOW) 1513 val |= MR1_CTSCONT; 1514 1515 ccbp->hi_mr1 = val; 1516 1517 /* ========== set hi_mask ========== */ 1518 val = 0xff; 1519 if ((cflag & CS8) == CS8) { /* 8 data bits? */ 1520 val &= 0xFF; 1521 } else if ((cflag & CS7) == CS7) { /* 7 data bits? */ 1522 val &= 0x7F; 1523 } else if ((cflag & CS6) == CS6) { /* 6 data bits? */ 1524 val &= 0x3F; 1525 } else { /* Must be 5 */ 1526 val &= 0x1F; 1527 } 1528 if (iflag & ISTRIP) 1529 val &= 0x7F; 1530 1531 ccbp->hi_mask = val; 1532 1533 /* ========== set hi_prtcl ========== */ 1534 val = 0; 1535 /* Monitor DCD etc. if a modem */ 1536 if (!(cflag & CLOCAL)) 1537 val |= SP_DCEN; 1538 if (iflag & IXANY) 1539 val |= SP_TANY; 1540 if (iflag & IXON) 1541 val |= SP_TXEN; 1542 if (iflag & IXOFF) 1543 val |= SP_RXEN; 1544 if (iflag & INPCK) 1545 val |= SP_PAEN; 1546 1547 ccbp->hi_prtcl = val; 1548 1549 1550 /* ========== set hi_{rx|tx}{on|off} ========== */ 1551 /* XXX: the card TOTALLY shields us from the flow control... */ 1552 ccbp->hi_txon = t->c_cc[VSTART]; 1553 ccbp->hi_txoff = t->c_cc[VSTOP]; 1554 1555 ccbp->hi_rxon = t->c_cc[VSTART]; 1556 ccbp->hi_rxoff = t->c_cc[VSTOP]; 1557 1558 /* ========== send settings to the card ========== */ 1559 /* potential sleep here */ 1560 if (ccbp->hi_stat == IDLE_CLOSE) /* Not yet open */ 1561 si_command(pp, LOPEN, SI_WAIT); /* open it */ 1562 else 1563 si_command(pp, CONFIG, SI_WAIT); /* change params */ 1564 1565 /* ========== set DTR etc ========== */ 1566 /* Hangup if ospeed == 0 */ 1567 if (t->c_ospeed == 0) { 1568 (void) si_modem(pp, BIC, TIOCM_DTR|TIOCM_RTS); 1569 } else { 1570 /* 1571 * If the previous speed was 0, may need to re-enable 1572 * the modem signals 1573 */ 1574 (void) si_modem(pp, SET, TIOCM_DTR|TIOCM_RTS); 1575 } 1576 1577 DPRINT((pp, DBG_PARAM, "siparam, complete: MR1 %x MR2 %x HI_MASK %x PRTCL %x HI_BREAK %x\n", 1578 ccbp->hi_mr1, ccbp->hi_mr2, ccbp->hi_mask, ccbp->hi_prtcl, ccbp->hi_break)); 1579 1580 splx(oldspl); 1581 return(error); 1582} 1583 1584/* 1585 * Enable or Disable the writes to this channel... 1586 * "state" -> enabled = 1; disabled = 0; 1587 */ 1588static void 1589si_write_enable(pp, state) 1590 register struct si_port *pp; 1591 int state; 1592{ 1593 int oldspl; 1594 1595 oldspl = spltty(); 1596 1597 if (state) { 1598 pp->sp_state &= ~SS_BLOCKWRITE; 1599 if (pp->sp_state & SS_WAITWRITE) { 1600 pp->sp_state &= ~SS_WAITWRITE; 1601 /* thunder away! */ 1602 wakeup((caddr_t)pp); 1603 } 1604 } else { 1605 pp->sp_state |= SS_BLOCKWRITE; 1606 } 1607 1608 splx(oldspl); 1609} 1610 1611/* 1612 * Set/Get state of modem control lines. 1613 * Due to DCE-like behaviour of the adapter, some signals need translation: 1614 * TIOCM_DTR DSR 1615 * TIOCM_RTS CTS 1616 */ 1617static int 1618si_modem(pp, cmd, bits) 1619 struct si_port *pp; 1620 enum si_mctl cmd; 1621 int bits; 1622{ 1623 volatile struct si_channel *ccbp; 1624 int x; 1625 1626 DPRINT((pp, DBG_ENTRY|DBG_MODEM, "si_modem(%x,%s,%x)\n", pp, si_mctl2str(cmd), bits)); 1627 ccbp = pp->sp_ccb; /* Find channel address */ 1628 switch (cmd) { 1629 case GET: 1630 x = ccbp->hi_ip; 1631 bits = TIOCM_LE; 1632 if (x & IP_DCD) bits |= TIOCM_CAR; 1633 if (x & IP_DTR) bits |= TIOCM_DTR; 1634 if (x & IP_RTS) bits |= TIOCM_RTS; 1635 if (x & IP_RI) bits |= TIOCM_RI; 1636 return(bits); 1637 case SET: 1638 ccbp->hi_op &= ~(OP_DSR|OP_CTS); 1639 /* fall through */ 1640 case BIS: 1641 x = 0; 1642 if (bits & TIOCM_DTR) 1643 x |= OP_DSR; 1644 if (bits & TIOCM_RTS) 1645 x |= OP_CTS; 1646 ccbp->hi_op |= x; 1647 break; 1648 case BIC: 1649 if (bits & TIOCM_DTR) 1650 ccbp->hi_op &= ~OP_DSR; 1651 if (bits & TIOCM_RTS) 1652 ccbp->hi_op &= ~OP_CTS; 1653 } 1654 return 0; 1655} 1656 1657/* 1658 * Handle change of modem state 1659 */ 1660static void 1661si_modem_state(pp, tp, hi_ip) 1662 register struct si_port *pp; 1663 register struct tty *tp; 1664 register int hi_ip; 1665{ 1666 /* if a modem dev */ 1667 if (hi_ip & IP_DCD) { 1668 if ( !(pp->sp_last_hi_ip & IP_DCD)) { 1669 DPRINT((pp, DBG_INTR, "modem carr on t_line %d\n", 1670 tp->t_line)); 1671 (void)(*linesw[tp->t_line].l_modem)(tp, 1); 1672 } 1673 } else { 1674 if (pp->sp_last_hi_ip & IP_DCD) { 1675 DPRINT((pp, DBG_INTR, "modem carr off\n")); 1676 if ((*linesw[tp->t_line].l_modem)(tp, 0)) 1677 (void) si_modem(pp, SET, 0); 1678 } 1679 } 1680 pp->sp_last_hi_ip = hi_ip; 1681 1682} 1683 1684/* 1685 * Poller to catch missed interrupts. 1686 * 1687 * Note that the SYSV Specialix drivers poll at 100 times per second to get 1688 * better response. We could really use a "periodic" version timeout(). :-) 1689 */ 1690#ifdef POLL 1691static void 1692si_poll(void *nothing) 1693{ 1694 register struct si_softc *sc; 1695 register int i; 1696 volatile struct si_reg *regp; 1697 register struct si_port *pp; 1698 int lost, oldspl, port; 1699 1700 DPRINT((0, DBG_POLL, "si_poll()\n")); 1701 oldspl = spltty(); 1702 if (in_intr) 1703 goto out; 1704 lost = 0; 1705 for (i=0; i<NSI; i++) { 1706 sc = &si_softc[i]; 1707 if (sc->sc_type == SIEMPTY) 1708 continue; 1709 regp = (struct si_reg *)sc->sc_maddr; 1710 /* 1711 * See if there has been a pending interrupt for 2 seconds 1712 * or so. The test <int_scounter >= 200) won't correspond 1713 * to 2 seconds if int_count gets changed. 1714 */ 1715 if (regp->int_pending != 0) { 1716 if (regp->int_scounter >= 200 && 1717 regp->initstat == 1) { 1718 printf("si%d: lost intr\n", i); 1719 lost++; 1720 } 1721 } else { 1722 regp->int_scounter = 0; 1723 } 1724 1725 /* 1726 * gripe about no input flow control.. 1727 */ 1728 pp = sc->sc_ports; 1729 for (port = 0; port < sc->sc_nport; pp++, port++) { 1730 if (pp->sp_delta_overflows > 0) { 1731 printf("si%d: %d tty level buffer overflows\n", 1732 i, pp->sp_delta_overflows); 1733 pp->sp_delta_overflows = 0; 1734 } 1735 } 1736 } 1737 if (lost) 1738 siintr(-1); /* call intr with fake vector */ 1739out: 1740 splx(oldspl); 1741 1742 timeout(si_poll, (caddr_t)0L, si_pollrate); 1743} 1744#endif /* ifdef POLL */ 1745 1746/* 1747 * The interrupt handler polls ALL ports on ALL adapters each time 1748 * it is called. 1749 */ 1750 1751static BYTE si_rxbuf[SI_BUFFERSIZE]; /* input staging area */ 1752 1753void 1754siintr(int unit) 1755{ 1756 register struct si_softc *sc; 1757 1758 register struct si_port *pp; 1759 volatile struct si_channel *ccbp; 1760 register struct tty *tp; 1761 volatile caddr_t maddr; 1762 BYTE op, ip; 1763 int x, card, port, n, i, isopen; 1764 volatile BYTE *z; 1765 BYTE c; 1766 1767 DPRINT((0, (unit < 0) ? DBG_POLL:DBG_INTR, "siintr(%d)\n", unit)); 1768 if (in_intr) { 1769 if (unit < 0) /* should never happen */ 1770 return; 1771 printf("si%d: Warning interrupt handler re-entered\n", 1772 unit); 1773 return; 1774 } 1775 in_intr = 1; 1776 1777 /* 1778 * When we get an int we poll all the channels and do ALL pending 1779 * work, not just the first one we find. This allows all cards to 1780 * share the same vector. 1781 */ 1782 for (card=0; card < NSI; card++) { 1783 sc = &si_softc[card]; 1784 if (sc->sc_type == SIEMPTY) 1785 continue; 1786 1787 /* 1788 * First, clear the interrupt 1789 */ 1790 switch(sc->sc_type) { 1791 case SIHOST : 1792 maddr = sc->sc_maddr; 1793 ((volatile struct si_reg *)maddr)->int_pending = 0; 1794 /* flag nothing pending */ 1795 *(maddr+SIINTCL) = 0x00; /* Set IRQ clear */ 1796 *(maddr+SIINTCL_CL) = 0x00; /* Clear IRQ clear */ 1797 break; 1798 case SIHOST2: 1799 maddr = sc->sc_maddr; 1800 ((volatile struct si_reg *)maddr)->int_pending = 0; 1801 *(maddr+SIPLIRQCLR) = 0x00; 1802 *(maddr+SIPLIRQCLR) = 0x10; 1803 break; 1804 case SIEISA: 1805#if NEISA > 0 1806 maddr = sc->sc_maddr; 1807 ((volatile struct si_reg *)maddr)->int_pending = 0; 1808 (void)inb(sc->sc_eisa_iobase+3); 1809 break; 1810#endif /* fall through if not EISA kernel */ 1811 case SIEMPTY: 1812 default: 1813 continue; 1814 } 1815 ((volatile struct si_reg *)maddr)->int_scounter = 0; 1816 1817 /* 1818 * check each port 1819 */ 1820 for (pp=sc->sc_ports,port=0; port < sc->sc_nport; pp++,port++) { 1821 ccbp = pp->sp_ccb; 1822 tp = pp->sp_tty; 1823 1824 1825 /* 1826 * See if a command has completed ? 1827 */ 1828 if (ccbp->hi_stat != pp->sp_pend) { 1829 DPRINT((pp, DBG_INTR, 1830 "siintr hi_stat = 0x%x, pend = %d\n", 1831 ccbp->hi_stat, pp->sp_pend)); 1832 switch(pp->sp_pend) { 1833 case LOPEN: 1834 case MPEND: 1835 case MOPEN: 1836 case CONFIG: 1837 case SBREAK: 1838 case EBREAK: 1839 pp->sp_pend = ccbp->hi_stat; 1840 /* sleeping in si_command */ 1841 wakeup(&pp->sp_state); 1842 break; 1843 default: 1844 pp->sp_pend = ccbp->hi_stat; 1845 } 1846 } 1847 1848 /* 1849 * Continue on if it's closed 1850 */ 1851 if (ccbp->hi_stat == IDLE_CLOSE) { 1852 continue; 1853 } 1854 1855 /* 1856 * Do modem state change if not a local device 1857 */ 1858 si_modem_state(pp, tp, ccbp->hi_ip); 1859 1860 /* 1861 * Check to see if there's we should 'receive' 1862 * characters. 1863 */ 1864 if (tp->t_state & TS_CONNECTED && 1865 tp->t_state & TS_ISOPEN) 1866 isopen = 1; 1867 else 1868 isopen = 0; 1869 1870 /* 1871 * Do input break processing 1872 */ 1873 if (ccbp->hi_state & ST_BREAK) { 1874 if (isopen) { 1875 (*linesw[tp->t_line].l_rint)(TTY_BI, tp); 1876 } 1877 ccbp->hi_state &= ~ST_BREAK; /* A Bit iffy this */ 1878 DPRINT((pp, DBG_INTR, "si_intr break\n")); 1879 } 1880 1881 /* 1882 * Do RX stuff - if not open then dump any characters. 1883 * XXX: This is VERY messy and needs to be cleaned up. 1884 * 1885 * XXX: can we leave data in the host adapter buffer 1886 * when the clists are full? That may be dangerous 1887 * if the user cannot get an interrupt signal through. 1888 */ 1889 1890 more_rx: /* XXX Sorry. the nesting was driving me bats! :-( */ 1891 1892 if (!isopen) { 1893 ccbp->hi_rxopos = ccbp->hi_rxipos; 1894 goto end_rx; 1895 } 1896 1897 /* 1898 * If the tty input buffers are blocked, stop emptying 1899 * the incoming buffers and let the auto flow control 1900 * assert.. 1901 */ 1902 if (tp->t_state & TS_TBLOCK) { 1903 goto end_rx; 1904 } 1905 1906 /* 1907 * Process read characters if not skipped above 1908 */ 1909 op = ccbp->hi_rxopos; 1910 ip = ccbp->hi_rxipos; 1911 c = ip - op; 1912 if (c == 0) { 1913 goto end_rx; 1914 } 1915 1916 n = c & 0xff; 1917 if (n > 250) 1918 n = 250; 1919 1920 DPRINT((pp, DBG_INTR, "n = %d, op = %d, ip = %d\n", 1921 n, op, ip)); 1922 1923 /* 1924 * Suck characters out of host card buffer into the 1925 * "input staging buffer" - so that we dont leave the 1926 * host card in limbo while we're possibly echoing 1927 * characters and possibly flushing input inside the 1928 * ldisc l_rint() routine. 1929 */ 1930 if (n <= SI_BUFFERSIZE - op) { 1931 1932 DPRINT((pp, DBG_INTR, "\tsingle copy\n")); 1933 z = ccbp->hi_rxbuf + op; 1934 bcopy((caddr_t)z, si_rxbuf, n); 1935 1936 op += n; 1937 } else { 1938 x = SI_BUFFERSIZE - op; 1939 1940 DPRINT((pp, DBG_INTR, "\tdouble part 1 %d\n", x)); 1941 z = ccbp->hi_rxbuf + op; 1942 bcopy((caddr_t)z, si_rxbuf, x); 1943 1944 DPRINT((pp, DBG_INTR, "\tdouble part 2 %d\n", n-x)); 1945 z = ccbp->hi_rxbuf; 1946 bcopy((caddr_t)z, si_rxbuf+x, n-x); 1947 1948 op += n; 1949 } 1950 1951 /* clear collected characters from buffer */ 1952 ccbp->hi_rxopos = op; 1953 1954 DPRINT((pp, DBG_INTR, "n = %d, op = %d, ip = %d\n", 1955 n, op, ip)); 1956 1957 /* 1958 * at this point... 1959 * n = number of chars placed in si_rxbuf 1960 */ 1961 1962 /* 1963 * Avoid the grotesquely inefficient lineswitch 1964 * routine (ttyinput) in "raw" mode. It usually 1965 * takes about 450 instructions (that's without 1966 * canonical processing or echo!). slinput is 1967 * reasonably fast (usually 40 instructions 1968 * plus call overhead). 1969 */ 1970 if (tp->t_state & TS_CAN_BYPASS_L_RINT) { 1971 1972 /* block if the driver supports it */ 1973 if (tp->t_rawq.c_cc + n >= SI_I_HIGH_WATER 1974 && (tp->t_cflag & CRTS_IFLOW 1975 || tp->t_iflag & IXOFF) 1976 && !(tp->t_state & TS_TBLOCK)) 1977 ttyblock(tp); 1978 1979 tk_nin += n; 1980 tk_rawcc += n; 1981 tp->t_rawcc += n; 1982 1983 pp->sp_delta_overflows += 1984 b_to_q((char *)si_rxbuf, n, &tp->t_rawq); 1985 1986 ttwakeup(tp); 1987 if (tp->t_state & TS_TTSTOP 1988 && (tp->t_iflag & IXANY 1989 || tp->t_cc[VSTART] == tp->t_cc[VSTOP])) { 1990 tp->t_state &= ~TS_TTSTOP; 1991 tp->t_lflag &= ~FLUSHO; 1992 si_start(tp); 1993 } 1994 } else { 1995 /* 1996 * It'd be nice to not have to go through the 1997 * function call overhead for each char here. 1998 * It'd be nice to block input it, saving a 1999 * loop here and the call/return overhead. 2000 */ 2001 for(x = 0; x < n; x++) { 2002 i = si_rxbuf[x]; 2003 if ((*linesw[tp->t_line].l_rint)(i, tp) 2004 == -1) { 2005 pp->sp_delta_overflows++; 2006 } 2007 /* 2008 * doesn't seem to be much point doing 2009 * this here.. this driver has no 2010 * softtty processing! ?? 2011 */ 2012 if (pp->sp_hotchar && i == pp->sp_hotchar) { 2013 setsofttty(); 2014 } 2015 } 2016 } 2017 goto more_rx; /* try for more until RXbuf is empty */ 2018 2019 end_rx: /* XXX: Again, sorry about the gotos.. :-) */ 2020 2021 /* 2022 * Do TX stuff 2023 */ 2024 (*linesw[tp->t_line].l_start)(tp); 2025 2026 } /* end of for (all ports on this controller) */ 2027 } /* end of for (all controllers) */ 2028 2029 in_intr = 0; 2030 DPRINT((0, (unit < 0) ? DBG_POLL:DBG_INTR, "end siintr(%d)\n", unit)); 2031} 2032 2033/* 2034 * Nudge the transmitter... 2035 * 2036 * XXX: I inherited some funny code here. It implies the host card only 2037 * interrupts when the transmit buffer reaches the low-water-mark, and does 2038 * not interrupt when it's actually hits empty. In some cases, we have 2039 * processes waiting for complete drain, and we need to simulate an interrupt 2040 * about when we think the buffer is going to be empty (and retry if not). 2041 * I really am not certain about this... I *need* the hardware manuals. 2042 */ 2043static void 2044si_start(tp) 2045 register struct tty *tp; 2046{ 2047 struct si_port *pp; 2048 volatile struct si_channel *ccbp; 2049 register struct clist *qp; 2050 register char *dptr; 2051 BYTE ipos; 2052 int nchar; 2053 int oldspl, count, n, amount, buffer_full; 2054 int do_exitproc; 2055 2056 oldspl = spltty(); 2057 2058 qp = &tp->t_outq; 2059 pp = TP2PP(tp); 2060 2061 DPRINT((pp, DBG_ENTRY|DBG_START, 2062 "si_start(%x) t_state %x sp_state %x t_outq.c_cc %d\n", 2063 tp, tp->t_state, pp->sp_state, qp->c_cc)); 2064 2065 if (tp->t_state & (TS_TIMEOUT|TS_TTSTOP)) 2066 goto out; 2067 2068 do_exitproc = 0; 2069 buffer_full = 0; 2070 ccbp = pp->sp_ccb; 2071 2072 /* 2073 * Handle the case where ttywait() is called on process exit 2074 * this may be BSDI specific, I dont know... 2075 */ 2076 if (tp->t_session != NULL && tp->t_session->s_leader != NULL && 2077 (tp->t_session->s_leader->p_flag & P_WEXIT)) { 2078 do_exitproc++; 2079 } 2080 2081 count = (int)ccbp->hi_txipos - (int)ccbp->hi_txopos; 2082 DPRINT((pp, DBG_START, "count %d\n", (BYTE)count)); 2083 2084 dptr = (char *)ccbp->hi_txbuf; /* data buffer */ 2085 2086 while ((nchar = qp->c_cc) > 0) { 2087 if ((BYTE)count >= 255) { 2088 buffer_full++; 2089 break; 2090 } 2091 amount = min(nchar, (255 - (BYTE)count)); 2092 ipos = (unsigned int)ccbp->hi_txipos; 2093 /* will it fit in one lump? */ 2094 if ((SI_BUFFERSIZE - ipos) >= amount) { 2095 n = q_to_b(&tp->t_outq, 2096 (char *)&ccbp->hi_txbuf[ipos], amount); 2097 } else { 2098 n = q_to_b(&tp->t_outq, 2099 (char *)&ccbp->hi_txbuf[ipos], 2100 SI_BUFFERSIZE-ipos); 2101 if (n == SI_BUFFERSIZE-ipos) { 2102 n += q_to_b(&tp->t_outq, 2103 (char *)&ccbp->hi_txbuf[0], 2104 amount - (SI_BUFFERSIZE-ipos)); 2105 } 2106 } 2107 ccbp->hi_txipos += n; 2108 count = (int)ccbp->hi_txipos - (int)ccbp->hi_txopos; 2109 } 2110 2111 if (count != 0 && nchar == 0) { 2112 tp->t_state |= TS_BUSY; 2113 } else { 2114 tp->t_state &= ~TS_BUSY; 2115 } 2116 2117 /* wakeup time? */ 2118 ttwwakeup(tp); 2119 2120 DPRINT((pp, DBG_START, "count %d, nchar %d, tp->t_state 0x%x\n", 2121 (BYTE)count, nchar, tp->t_state)); 2122 2123 if ((tp->t_state & TS_BUSY) || do_exitproc) 2124 { 2125 int time; 2126 2127 if (do_exitproc != 0) { 2128 time = hz / 10; 2129 } else { 2130 time = ttspeedtab(tp->t_ospeed, chartimes); 2131 2132 if (time > 0) { 2133 if (time < nchar) 2134 time = nchar / time; 2135 else 2136 time = 2; 2137 } else { 2138 DPRINT((pp, DBG_START, 2139 "bad char time value! %d\n", time)); 2140 time = hz/10; 2141 } 2142 } 2143 2144 if ((pp->sp_state & (SS_LSTART|SS_INLSTART)) == SS_LSTART) { 2145 untimeout((timeout_func_t)si_lstart, (caddr_t)pp); 2146 } else { 2147 pp->sp_state |= SS_LSTART; 2148 } 2149 DPRINT((pp, DBG_START, "arming lstart, time=%d\n", time)); 2150 timeout((timeout_func_t)si_lstart, (caddr_t)pp, time); 2151 } 2152 2153out: 2154 splx(oldspl); 2155 DPRINT((pp, DBG_EXIT|DBG_START, "leave si_start()\n")); 2156} 2157 2158/* 2159 * Note: called at splsoftclock from the timeout code 2160 * This has to deal with two things... cause wakeups while waiting for 2161 * tty drains on last process exit, and call l_start at about the right 2162 * time for protocols like ppp. 2163 */ 2164static void 2165si_lstart(pp) 2166 register struct si_port *pp; 2167{ 2168 register struct tty *tp; 2169 int oldspl; 2170 2171 DPRINT((pp, DBG_ENTRY|DBG_LSTART, "si_lstart(%x) sp_state %x\n", 2172 pp, pp->sp_state)); 2173 2174 oldspl = spltty(); 2175 2176 if ((pp->sp_state & SS_OPEN) == 0 || (pp->sp_state & SS_LSTART) == 0) { 2177 splx(oldspl); 2178 return; 2179 } 2180 pp->sp_state &= ~SS_LSTART; 2181 pp->sp_state |= SS_INLSTART; 2182 2183 tp = pp->sp_tty; 2184 2185 /* deal with the process exit case */ 2186 ttwwakeup(tp); 2187 2188 /* nudge protocols - eg: ppp */ 2189 (*linesw[tp->t_line].l_start)(tp); 2190 2191 pp->sp_state &= ~SS_INLSTART; 2192 splx(oldspl); 2193} 2194 2195/* 2196 * Stop output on a line. called at spltty(); 2197 */ 2198void 2199sistop(tp, rw) 2200 register struct tty *tp; 2201 int rw; 2202{ 2203 volatile struct si_channel *ccbp; 2204 struct si_port *pp; 2205 2206 pp = TP2PP(tp); 2207 ccbp = pp->sp_ccb; 2208 2209 DPRINT((TP2PP(tp), DBG_ENTRY|DBG_STOP, "sistop(%x,%x)\n", tp, rw)); 2210 2211 /* XXX: must check (rw & FWRITE | FREAD) etc flushing... */ 2212 if (rw & FWRITE) { 2213 /* what level are we meant to be flushing anyway? */ 2214 if (tp->t_state & TS_BUSY) { 2215 si_command(TP2PP(tp), WFLUSH, SI_NOWAIT); 2216 tp->t_state &= ~TS_BUSY; 2217 ttwwakeup(tp); /* Bruce???? */ 2218 } 2219 } 2220#if 1 /* XXX: this doesn't work right yet.. */ 2221 /* XXX: this may have been failing because we used to call l_rint() 2222 * while we were looping based on these two counters. Now, we collect 2223 * the data and then loop stuffing it into l_rint(), making this 2224 * useless. Should we cause this to blow away the staging buffer? 2225 */ 2226 if (rw & FREAD) { 2227 ccbp->hi_rxopos = ccbp->hi_rxipos; 2228 } 2229#endif 2230} 2231 2232/* 2233 * Issue a command to the Z280 host card CPU. 2234 */ 2235 2236static void 2237si_command(pp, cmd, waitflag) 2238 struct si_port *pp; /* port control block (local) */ 2239 int cmd; 2240 int waitflag; 2241{ 2242 int oldspl; 2243 volatile struct si_channel *ccbp = pp->sp_ccb; 2244 int x; 2245 2246 DPRINT((pp, DBG_ENTRY|DBG_PARAM, "si_command(%x,%x,%d): hi_stat 0x%x\n", 2247 pp, cmd, waitflag, ccbp->hi_stat)); 2248 2249 oldspl = spltty(); /* Keep others out */ 2250 2251 /* wait until it's finished what it was doing.. */ 2252 /* XXX: sits in IDLE_BREAK until something disturbs it or break 2253 * is turned off. */ 2254 while((x = ccbp->hi_stat) != IDLE_OPEN && 2255 x != IDLE_CLOSE && 2256 x != IDLE_BREAK && 2257 x != cmd) { 2258 if (in_intr) { /* Prevent sleep in intr */ 2259 DPRINT((pp, DBG_PARAM, 2260 "cmd intr collision - completing %d\trequested %d\n", 2261 x, cmd)); 2262 splx(oldspl); 2263 return; 2264 } else if (ttysleep(pp->sp_tty, (caddr_t)&pp->sp_state, TTIPRI|PCATCH, 2265 "sicmd1", 1)) { 2266 splx(oldspl); 2267 return; 2268 } 2269 } 2270 /* it should now be in IDLE_{OPEN|CLOSE|BREAK}, or "cmd" */ 2271 2272 /* if there was a pending command, cause a state-change wakeup */ 2273 switch(pp->sp_pend) { 2274 case LOPEN: 2275 case MPEND: 2276 case MOPEN: 2277 case CONFIG: 2278 case SBREAK: 2279 case EBREAK: 2280 wakeup(&pp->sp_state); 2281 break; 2282 default: 2283 break; 2284 } 2285 2286 pp->sp_pend = cmd; /* New command pending */ 2287 ccbp->hi_stat = cmd; /* Post it */ 2288 2289 if (waitflag) { 2290 if (in_intr) { /* If in interrupt handler */ 2291 DPRINT((pp, DBG_PARAM, 2292 "attempt to sleep in si_intr - cmd req %d\n", 2293 cmd)); 2294 splx(oldspl); 2295 return; 2296 } else while(ccbp->hi_stat != IDLE_OPEN && 2297 ccbp->hi_stat != IDLE_BREAK) { 2298 if (ttysleep(pp->sp_tty, (caddr_t)&pp->sp_state, TTIPRI|PCATCH, 2299 "sicmd2", 0)) 2300 break; 2301 } 2302 } 2303 splx(oldspl); 2304} 2305 2306static void 2307si_disc_optim(tp, t, pp) 2308 struct tty *tp; 2309 struct termios *t; 2310 struct si_port *pp; 2311{ 2312 /* 2313 * XXX can skip a lot more cases if Smarts. Maybe 2314 * (IGNCR | ISTRIP | IXON) in c_iflag. But perhaps we 2315 * shouldn't skip if (TS_CNTTB | TS_LNCH) is set in t_state. 2316 */ 2317 if (!(t->c_iflag & (ICRNL | IGNCR | IMAXBEL | INLCR | ISTRIP | IXON)) 2318 && (!(t->c_iflag & BRKINT) || (t->c_iflag & IGNBRK)) 2319 && (!(t->c_iflag & PARMRK) 2320 || (t->c_iflag & (IGNPAR | IGNBRK)) == (IGNPAR | IGNBRK)) 2321 && !(t->c_lflag & (ECHO | ICANON | IEXTEN | ISIG | PENDIN)) 2322 && linesw[tp->t_line].l_rint == ttyinput) 2323 tp->t_state |= TS_CAN_BYPASS_L_RINT; 2324 else 2325 tp->t_state &= ~TS_CAN_BYPASS_L_RINT; 2326 2327 /* 2328 * Prepare to reduce input latency for packet 2329 * discplines with a end of packet character. 2330 */ 2331 if (tp->t_line == SLIPDISC) 2332 pp->sp_hotchar = 0xc0; 2333 else if (tp->t_line == PPPDISC) 2334 pp->sp_hotchar = 0x7e; 2335 else 2336 pp->sp_hotchar = 0; 2337 2338 DPRINT((pp, DBG_OPTIM, "bypass: %s, hotchar: %x\n", 2339 (tp->t_state & TS_CAN_BYPASS_L_RINT) ? "on" : "off", 2340 pp->sp_hotchar)); 2341} 2342 2343 2344#ifdef SI_DEBUG 2345 2346static void 2347#ifdef __STDC__ 2348si_dprintf(struct si_port *pp, int flags, const char *fmt, ...) 2349#else 2350si_dprintf(pp, flags, fmt, va_alist) 2351 struct si_port *pp; 2352 int flags; 2353 char *fmt; 2354#endif 2355{ 2356 va_list ap; 2357 2358 if ((pp == NULL && (si_debug&flags)) || 2359 (pp != NULL && ((pp->sp_debug&flags) || (si_debug&flags)))) { 2360 if (pp != NULL) 2361 printf("%ci%d(%d): ", 's', 2362 (int)SI_CARD(pp->sp_tty->t_dev), 2363 (int)SI_PORT(pp->sp_tty->t_dev)); 2364 va_start(ap, fmt); 2365 vprintf(fmt, ap); 2366 va_end(ap); 2367 } 2368} 2369 2370static char * 2371si_mctl2str(cmd) 2372 enum si_mctl cmd; 2373{ 2374 switch (cmd) { 2375 case GET: return("GET"); 2376 case SET: return("SET"); 2377 case BIS: return("BIS"); 2378 case BIC: return("BIC"); 2379 } 2380 return("BAD"); 2381} 2382 2383#endif /* DEBUG */ 2384 2385 2386 2387static si_devsw_installed = 0; 2388 2389static void si_drvinit(void *unused) 2390{ 2391 dev_t dev; 2392 2393 if( ! si_devsw_installed ) { 2394 dev = makedev(CDEV_MAJOR, 0); 2395 cdevsw_add(&dev,&si_cdevsw, NULL); 2396 si_devsw_installed = 1; 2397 } 2398} 2399 2400SYSINIT(sidev,SI_SUB_DRIVERS,SI_ORDER_MIDDLE+CDEV_MAJOR,si_drvinit,NULL) 2401 2402