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