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