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