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