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