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