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