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