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