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