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