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