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