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