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