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