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