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