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