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