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