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