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