zs.c revision 1.1
1/*	$NetBSD: zs.c,v 1.1 1995/03/26 07:12:14 leo Exp $	*/
2
3/*
4 * Copyright (c) 1995 L. Weppelman (Atari modifications)
5 * Copyright (c) 1992, 1993
6 *	The Regents of the University of California.  All rights reserved.
7 *
8 * This software was developed by the Computer Systems Engineering group
9 * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
10 * contributed to Berkeley.
11 *
12 *
13 * All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 *	This product includes software developed by the University of
16 *	California, Lawrence Berkeley Laboratory.
17 *
18 * Redistribution and use in source and binary forms, with or without
19 * modification, are permitted provided that the following conditions
20 * are met:
21 * 1. Redistributions of source code must retain the above copyright
22 *    notice, this list of conditions and the following disclaimer.
23 * 2. Redistributions in binary form must reproduce the above copyright
24 *    notice, this list of conditions and the following disclaimer in the
25 *    documentation and/or other materials provided with the distribution.
26 * 3. All advertising materials mentioning features or use of this software
27 *    must display the following acknowledgement:
28 *	This product includes software developed by the University of
29 *	California, Berkeley and its contributors.
30 * 4. Neither the name of the University nor the names of its contributors
31 *    may be used to endorse or promote products derived from this software
32 *    without specific prior written permission.
33 *
34 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
35 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
36 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
37 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
38 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
39 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
40 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
41 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
42 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
43 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
44 * SUCH DAMAGE.
45 *
46 *	@(#)zs.c	8.1 (Berkeley) 7/19/93
47 */
48
49/*
50 * Zilog Z8530 (ZSCC) driver.
51 *
52 * Runs two tty ports (modem2 and serial2) on zs0.
53 *
54 * This driver knows far too much about chip to usage mappings.
55 */
56#include <sys/param.h>
57#include <sys/proc.h>
58#include <sys/device.h>
59#include <sys/conf.h>
60#include <sys/file.h>
61#include <sys/ioctl.h>
62#include <sys/tty.h>
63#include <sys/time.h>
64#include <sys/kernel.h>
65#include <sys/syslog.h>
66
67#include <machine/cpu.h>
68#include <machine/iomap.h>
69#include <machine/scu.h>
70#include <machine/mfp.h>
71
72#include <atari/dev/zsreg.h>
73#include <atari/dev/zsvar.h>
74#include "zs.h"
75#if NZS > 1
76#error "This driver supports only 1 85C30!"
77#endif
78
79#if NZS > 0
80
81#define PCLK	(8000000)	/* PCLK pin input clock rate */
82
83#define splzs	spl5
84
85/*
86 * Software state per found chip.
87 */
88struct zs_softc {
89    struct	device		zi_dev;    /* base device		  */
90    volatile struct zsdevice	*zi_zs;    /* chip registers		  */
91    struct	zs_chanstate	zi_cs[2];  /* chan A and B software state */
92};
93
94/*
95 * Define the registers for a closed port
96 */
97u_char zs_init_regs[16] = {
98/*  0 */	0,
99/*  1 */	0,
100/*  2 */	0x60,
101/*  3 */	0,
102/*  4 */	0,
103/*  5 */	0,
104/*  6 */	0,
105/*  7 */	0,
106/*  8 */	0,
107/*  9 */	ZSWR9_VECTOR_INCL_STAT,
108/* 10 */	ZSWR10_NRZ,
109/* 11 */	ZSWR11_TXCLK_BAUD | ZSWR11_RXCLK_BAUD,
110/* 12 */	0,
111/* 13 */	0,
112/* 14 */	ZSWR14_BAUD_FROM_PCLK | ZSWR14_BAUD_ENA,
113/* 15 */	0
114};
115
116struct tty *zs_tty[NZS * 2];		/* XXX should be dynamic */
117
118/* Definition of the driver for autoconfig. */
119static int	zsmatch __P((struct device *, struct cfdata *, void *));
120static void	zsattach __P((struct device *, struct device *, void *));
121struct cfdriver zscd = {
122	NULL, "zs", (cfmatch_t)zsmatch, zsattach, DV_TTY,
123	sizeof(struct zs_softc), NULL, 0 };
124
125/* Interrupt handlers. */
126int		zshard __P((long));
127static int	zssoft __P((long));
128static int	zsrint __P((struct zs_chanstate *, volatile struct zschan *));
129static int	zsxint __P((struct zs_chanstate *, volatile struct zschan *));
130static int	zssint __P((struct zs_chanstate *, volatile struct zschan *));
131
132struct zs_chanstate *zslist;
133
134/* Routines called from other code. */
135static void	zsstart __P((struct tty *));
136void		zsstop __P((struct tty *, int));
137static int	zsparam __P((struct tty *, struct termios *));
138
139/* Routines purely local to this driver. */
140static void	zs_reset __P((volatile struct zschan *, int, int));
141static int	zs_modem __P((struct zs_chanstate *, int, int));
142static void	zs_loadchannelregs __P((volatile struct zschan *, u_char *));
143
144int zsshortcuts;	/* number of "shortcut" software interrupts */
145
146static int zsmatch(pdp, cfp, auxp)
147struct device	*pdp;
148struct cfdata	*cfp;
149void		*auxp;
150{
151	if(strcmp("zs", auxp) || cfp->cf_unit != 0)
152		return(0);
153	return(1);
154}
155
156/*
157 * Attach a found zs.
158 */
159static void
160zsattach(parent, dev, aux)
161struct device	*parent;
162struct device	*dev;
163void		*aux;
164{
165	register struct zs_softc		*zi;
166	register struct zs_chanstate		*cs;
167	register volatile struct zsdevice	*addr;
168	register struct tty			*tp;
169		 char				tmp;
170
171	addr      = (struct zsdevice *)AD_SCC;
172	zi        = (struct zs_softc *)dev;
173	zi->zi_zs = addr;
174	cs        = zi->zi_cs;
175
176	/*
177	 * Get the command register into a known state.
178	 */
179	tmp = addr->zs_chan[CHAN_A].zc_csr;
180	tmp = addr->zs_chan[CHAN_A].zc_csr;
181	tmp = addr->zs_chan[CHAN_B].zc_csr;
182	tmp = addr->zs_chan[CHAN_B].zc_csr;
183
184	/*
185	 * Do a hardware reset.
186	 */
187	ZS_WRITE(&addr->zs_chan[CHAN_A], 9, ZSWR9_HARD_RESET);
188	delay(50000);	/*enough ? */
189	ZS_WRITE(&addr->zs_chan[CHAN_A], 9, 0);
190
191	/*
192	 * Initialize both channels
193	 */
194	zs_loadchannelregs(&addr->zs_chan[CHAN_A], zs_init_regs);
195	zs_loadchannelregs(&addr->zs_chan[CHAN_B], zs_init_regs);
196
197	/*
198	 * enable scc related interrupts
199	 */
200	SCU->sys_mask |= SCU_SCC;
201
202	/* link into interrupt list with order (A,B) (B=A+1) */
203	cs[0].cs_next = &cs[1];
204	cs[1].cs_next = zslist;
205	zslist        = cs;
206
207	cs->cs_unit  = 0;
208	cs->cs_zc    = &addr->zs_chan[CHAN_A];
209	cs++;
210	cs->cs_unit  = 1;
211	cs->cs_zc    = &addr->zs_chan[CHAN_B];
212
213	printf(": serial2 on channel a and modem2 on channel b\n");
214}
215
216/*
217 * Open a zs serial port.
218 */
219int
220zsopen(dev, flags, mode, p)
221dev_t		dev;
222int		flags;
223int		mode;
224struct proc	*p;
225{
226	register struct tty		*tp;
227	register struct zs_chanstate	*cs;
228		 struct zs_softc	*zi;
229		 int			unit = ZS_UNIT(dev);
230		 int			zs = unit >> 1;
231		 int			error, s;
232
233	if(zs >= zscd.cd_ndevs || (zi = zscd.cd_devs[zs]) == NULL)
234		return (ENXIO);
235	cs = &zi->zi_cs[unit & 1];
236	tp = cs->cs_ttyp;
237	if(tp == NULL) {
238		cs->cs_ttyp  = tp = zs_tty[unit] = ttymalloc();
239		tp->t_dev    = dev;
240		tp->t_oproc  = zsstart;
241		tp->t_param  = zsparam;
242	}
243
244	s  = spltty();
245	if((tp->t_state & TS_ISOPEN) == 0) {
246		ttychars(tp);
247		if(tp->t_ispeed == 0) {
248			tp->t_iflag = TTYDEF_IFLAG;
249			tp->t_oflag = TTYDEF_OFLAG;
250			tp->t_cflag = TTYDEF_CFLAG;
251			tp->t_lflag = TTYDEF_LFLAG;
252			tp->t_ispeed = tp->t_ospeed = TTYDEF_SPEED;
253		}
254		(void)zsparam(tp, &tp->t_termios);
255		ttsetwater(tp);
256	}
257	else if(tp->t_state & TS_XCLUDE && p->p_ucred->cr_uid != 0) {
258			splx(s);
259			return (EBUSY);
260	}
261	error = 0;
262	for(;;) {
263		/* loop, turning on the device, until carrier present */
264		zs_modem(cs, ZSWR5_RTS|ZSWR5_DTR, DMSET);
265		if(cs->cs_softcar)
266			tp->t_state |= TS_CARR_ON;
267		if(flags & O_NONBLOCK || tp->t_cflag & CLOCAL ||
268		    tp->t_state & TS_CARR_ON)
269			break;
270		tp->t_state |= TS_WOPEN;
271		if(error = ttysleep(tp, (caddr_t)&tp->t_rawq, TTIPRI | PCATCH,
272		    ttopen, 0)) {
273			if(!(tp->t_state & TS_ISOPEN)) {
274				zs_modem(cs, 0, DMSET);
275				tp->t_state &= ~TS_WOPEN;
276				ttwakeup(tp);
277			}
278			splx(s);
279			return error;
280		}
281	}
282	splx(s);
283	if(error == 0)
284		error = linesw[tp->t_line].l_open(dev, tp);
285	if(error)
286		zs_modem(cs, 0, DMSET);
287	return(error);
288}
289
290/*
291 * Close a zs serial port.
292 */
293int
294zsclose(dev, flags, mode, p)
295dev_t		dev;
296int		flags;
297int		mode;
298struct proc	*p;
299{
300	register struct zs_chanstate	*cs;
301	register struct tty		*tp;
302		 struct zs_softc	*zi;
303		 int			unit = ZS_UNIT(dev);
304		 int			s;
305
306	zi = zscd.cd_devs[unit >> 1];
307	cs = &zi->zi_cs[unit & 1];
308	tp = cs->cs_ttyp;
309	linesw[tp->t_line].l_close(tp, flags);
310	if(tp->t_cflag & HUPCL || tp->t_state & TS_WOPEN ||
311	    (tp->t_state & TS_ISOPEN) == 0) {
312		zs_modem(cs, 0, DMSET);
313		/* hold low for 1 second */
314		(void)tsleep((caddr_t)cs, TTIPRI, ttclos, hz);
315	}
316	if(cs->cs_creg[5] & ZSWR5_BREAK) {
317		s = splzs();
318		cs->cs_preg[5] &= ~ZSWR5_BREAK;
319		cs->cs_creg[5] &= ~ZSWR5_BREAK;
320		ZS_WRITE(cs->cs_zc, 5, cs->cs_creg[5]);
321		splx(s);
322	}
323	ttyclose(tp);
324
325	/*
326	 * Drop all lines and cancel interrupts
327	 */
328	zs_loadchannelregs(&zi->zi_zs->zs_chan[unit & 1], zs_init_regs);
329	return (0);
330}
331
332/*
333 * Read/write zs serial port.
334 */
335int
336zsread(dev, uio, flags)
337dev_t		dev;
338struct uio	*uio;
339int		flags;
340{
341	register struct tty *tp = zs_tty[ZS_UNIT(dev)];
342
343	return(linesw[tp->t_line].l_read(tp, uio, flags));
344}
345
346int zswrite(dev, uio, flags)
347dev_t		dev;
348struct uio	*uio;
349int		flags;
350{
351	register struct tty *tp = zs_tty[ZS_UNIT(dev)];
352
353	return(linesw[tp->t_line].l_write(tp, uio, flags));
354}
355
356/*
357 * ZS hardware interrupt.  Scan all ZS channels.  NB: we know here that
358 * channels are kept in (A,B) pairs.
359 *
360 * Do just a little, then get out; set a software interrupt if more
361 * work is needed.
362 *
363 * We deliberately ignore the vectoring Zilog gives us, and match up
364 * only the number of `reset interrupt under service' operations, not
365 * the order.
366 */
367int
368zshard(sr)
369long sr;
370{
371	register struct zs_chanstate	*a;
372#define	b (a + 1)
373	register volatile struct zschan *zc;
374	register int			rr3, intflags = 0, v, i;
375
376	for(a = zslist; a != NULL; a = b->cs_next) {
377		rr3 = ZS_READ(a->cs_zc, 3);
378		if(rr3 & (ZSRR3_IP_A_RX|ZSRR3_IP_A_TX|ZSRR3_IP_A_STAT)) {
379			intflags |= 2;
380			zc = a->cs_zc;
381			i  = a->cs_rbput;
382			if(rr3 & ZSRR3_IP_A_RX && (v = zsrint(a, zc)) != 0) {
383				a->cs_rbuf[i++ & ZLRB_RING_MASK] = v;
384				intflags |= 1;
385			}
386			if(rr3 & ZSRR3_IP_A_TX && (v = zsxint(a, zc)) != 0) {
387				a->cs_rbuf[i++ & ZLRB_RING_MASK] = v;
388				intflags |= 1;
389			}
390			if(rr3 & ZSRR3_IP_A_STAT && (v = zssint(a, zc)) != 0) {
391				a->cs_rbuf[i++ & ZLRB_RING_MASK] = v;
392				intflags |= 1;
393			}
394			a->cs_rbput = i;
395		}
396		if(rr3 & (ZSRR3_IP_B_RX|ZSRR3_IP_B_TX|ZSRR3_IP_B_STAT)) {
397			intflags |= 2;
398			zc = b->cs_zc;
399			i  = b->cs_rbput;
400			if(rr3 & ZSRR3_IP_B_RX && (v = zsrint(b, zc)) != 0) {
401				b->cs_rbuf[i++ & ZLRB_RING_MASK] = v;
402				intflags |= 1;
403			}
404			if(rr3 & ZSRR3_IP_B_TX && (v = zsxint(b, zc)) != 0) {
405				b->cs_rbuf[i++ & ZLRB_RING_MASK] = v;
406				intflags |= 1;
407			}
408			if(rr3 & ZSRR3_IP_B_STAT && (v = zssint(b, zc)) != 0) {
409				b->cs_rbuf[i++ & ZLRB_RING_MASK] = v;
410				intflags |= 1;
411			}
412			b->cs_rbput = i;
413		}
414	}
415#undef b
416
417	if(intflags & 1) {
418		if(BASEPRI(sr)) {
419			spl1();
420			zsshortcuts++;
421			return(zssoft(sr));
422		}
423		else add_sicallback(zssoft, 0, 0);
424	}
425	return(intflags & 2);
426}
427
428static int
429zsrint(cs, zc)
430register struct zs_chanstate	*cs;
431register volatile struct zschan	*zc;
432{
433	register int c = zc->zc_data;
434
435	/* compose receive character and status */
436	c <<= 8;
437	c |= ZS_READ(zc, 1);
438
439	/* clear receive error & interrupt condition */
440	zc->zc_csr = ZSWR0_RESET_ERRORS;
441	zc->zc_csr = ZSWR0_CLR_INTR;
442
443	return(ZRING_MAKE(ZRING_RINT, c));
444}
445
446static int
447zsxint(cs, zc)
448register struct zs_chanstate	*cs;
449register volatile struct zschan	*zc;
450{
451	register int i = cs->cs_tbc;
452
453	if(i == 0) {
454		zc->zc_csr = ZSWR0_RESET_TXINT;
455		zc->zc_csr = ZSWR0_CLR_INTR;
456		return(ZRING_MAKE(ZRING_XINT, 0));
457	}
458	cs->cs_tbc = i - 1;
459	zc->zc_data = *cs->cs_tba++;
460	zc->zc_csr = ZSWR0_CLR_INTR;
461	return (0);
462}
463
464static int
465zssint(cs, zc)
466register struct zs_chanstate	*cs;
467register volatile struct zschan	*zc;
468{
469	register int rr0;
470
471	rr0 = zc->zc_csr;
472	zc->zc_csr = ZSWR0_RESET_STATUS;
473	zc->zc_csr = ZSWR0_CLR_INTR;
474	/*
475	 * The chip's hardware flow control is, as noted in zsreg.h,
476	 * busted---if the DCD line goes low the chip shuts off the
477	 * receiver (!).  If we want hardware CTS flow control but do
478	 * not have it, and carrier is now on, turn HFC on; if we have
479	 * HFC now but carrier has gone low, turn it off.
480	 */
481	if(rr0 & ZSRR0_DCD) {
482		if(cs->cs_ttyp->t_cflag & CCTS_OFLOW &&
483		    (cs->cs_creg[3] & ZSWR3_HFC) == 0) {
484			cs->cs_creg[3] |= ZSWR3_HFC;
485			ZS_WRITE(zc, 3, cs->cs_creg[3]);
486		}
487	}
488	else {
489		if (cs->cs_creg[3] & ZSWR3_HFC) {
490			cs->cs_creg[3] &= ~ZSWR3_HFC;
491			ZS_WRITE(zc, 3, cs->cs_creg[3]);
492		}
493	}
494	return(ZRING_MAKE(ZRING_SINT, rr0));
495}
496
497/*
498 * Print out a ring or fifo overrun error message.
499 */
500static void
501zsoverrun(unit, ptime, what)
502int	unit;
503long	*ptime;
504char	*what;
505{
506
507	if(*ptime != time.tv_sec) {
508		*ptime = time.tv_sec;
509		log(LOG_WARNING, "zs%d%c: %s overrun\n", unit >> 1,
510		    (unit & 1) + 'a', what);
511	}
512}
513
514/*
515 * ZS software interrupt.  Scan all channels for deferred interrupts.
516 */
517int
518zssoft(sr)
519long sr;
520{
521    register struct zs_chanstate	*cs;
522    register volatile struct zschan	*zc;
523    register struct linesw		*line;
524    register struct tty			*tp;
525    register int			get, n, c, cc, unit, s;
526 	     int			retval = 0;
527
528    s = spltty();
529    for(cs = zslist; cs != NULL; cs = cs->cs_next) {
530	get = cs->cs_rbget;
531again:
532	n = cs->cs_rbput;	/* atomic			*/
533	if(get == n)		/* nothing more on this line	*/
534		continue;
535	retval = 1;
536	unit   = cs->cs_unit;	/* set up to handle interrupts	*/
537	zc     = cs->cs_zc;
538	tp     = cs->cs_ttyp;
539	line   = &linesw[tp->t_line];
540	/*
541	 * Compute the number of interrupts in the receive ring.
542	 * If the count is overlarge, we lost some events, and
543	 * must advance to the first valid one.  It may get
544	 * overwritten if more data are arriving, but this is
545	 * too expensive to check and gains nothing (we already
546	 * lost out; all we can do at this point is trade one
547	 * kind of loss for another).
548	 */
549	n -= get;
550	if(n > ZLRB_RING_SIZE) {
551		zsoverrun(unit, &cs->cs_rotime, "ring");
552		get += n - ZLRB_RING_SIZE;
553		n    = ZLRB_RING_SIZE;
554	}
555	while(--n >= 0) {
556		/* race to keep ahead of incoming interrupts */
557		c = cs->cs_rbuf[get++ & ZLRB_RING_MASK];
558		switch (ZRING_TYPE(c)) {
559
560		case ZRING_RINT:
561			c = ZRING_VALUE(c);
562			if(c & ZSRR1_DO)
563				zsoverrun(unit, &cs->cs_fotime, "fifo");
564			cc = c >> 8;
565			if(c & ZSRR1_FE)
566				cc |= TTY_FE;
567			if(c & ZSRR1_PE)
568				cc |= TTY_PE;
569			line->l_rint(cc, tp);
570			break;
571
572		case ZRING_XINT:
573			/*
574			 * Transmit done: change registers and resume,
575			 * or clear BUSY.
576			 */
577			if(cs->cs_heldchange) {
578				int sps;
579
580				sps = splzs();
581				c = zc->zc_csr;
582				if((c & ZSRR0_DCD) == 0)
583					cs->cs_preg[3] &= ~ZSWR3_HFC;
584				bcopy((caddr_t)cs->cs_preg,
585				    (caddr_t)cs->cs_creg, 16);
586				zs_loadchannelregs(zc, cs->cs_creg);
587				splx(sps);
588				cs->cs_heldchange = 0;
589				if(cs->cs_heldtbc
590					&& (tp->t_state & TS_TTSTOP) == 0) {
591					cs->cs_tbc = cs->cs_heldtbc - 1;
592					zc->zc_data = *cs->cs_tba++;
593					goto again;
594				}
595			}
596			tp->t_state &= ~TS_BUSY;
597			if(tp->t_state & TS_FLUSH)
598				tp->t_state &= ~TS_FLUSH;
599			else ndflush(&tp->t_outq,cs->cs_tba
600						- (caddr_t)tp->t_outq.c_cf);
601			line->l_start(tp);
602			break;
603
604		case ZRING_SINT:
605			/*
606			 * Status line change.  HFC bit is run in
607			 * hardware interrupt, to avoid locking
608			 * at splzs here.
609			 */
610			c = ZRING_VALUE(c);
611			if((c ^ cs->cs_rr0) & ZSRR0_DCD) {
612				cc = (c & ZSRR0_DCD) != 0;
613				if(line->l_modem(tp, cc) == 0)
614					zs_modem(cs, ZSWR5_RTS|ZSWR5_DTR,
615							cc ? DMBIS : DMBIC);
616			}
617			cs->cs_rr0 = c;
618			break;
619
620		default:
621			log(LOG_ERR, "zs%d%c: bad ZRING_TYPE (%x)\n",
622			    unit >> 1, (unit & 1) + 'a', c);
623			break;
624		}
625	}
626	cs->cs_rbget = get;
627	goto again;
628    }
629    splx(s);
630    return (retval);
631}
632
633int
634zsioctl(dev, cmd, data, flag, p)
635dev_t		dev;
636u_long		cmd;
637caddr_t		data;
638int		flag;
639struct proc	*p;
640{
641		 int			unit = ZS_UNIT(dev);
642		 struct zs_softc	*zi = zscd.cd_devs[unit >> 1];
643	register struct tty		*tp = zi->zi_cs[unit & 1].cs_ttyp;
644	register int			error, s;
645	register struct zs_chanstate	*cs = &zi->zi_cs[unit & 1];
646
647	error = linesw[tp->t_line].l_ioctl(tp, cmd, data, flag, p);
648	if(error >= 0)
649		return(error);
650	error = ttioctl(tp, cmd, data, flag, p);
651	if(error >= 0)
652		return (error);
653
654	switch (cmd) {
655	case TIOCSBRK:
656		s = splzs();
657		cs->cs_preg[5] |= ZSWR5_BREAK;
658		cs->cs_creg[5] |= ZSWR5_BREAK;
659		ZS_WRITE(cs->cs_zc, 5, cs->cs_creg[5]);
660		splx(s);
661		break;
662	case TIOCCBRK:
663		s = splzs();
664		cs->cs_preg[5] &= ~ZSWR5_BREAK;
665		cs->cs_creg[5] &= ~ZSWR5_BREAK;
666		ZS_WRITE(cs->cs_zc, 5, cs->cs_creg[5]);
667		splx(s);
668		break;
669	case TIOCGFLAGS: {
670		int bits = 0;
671
672		if(cs->cs_softcar)
673			bits |= TIOCFLAG_SOFTCAR;
674		if(cs->cs_creg[15] & ZSWR15_DCD_IE)
675			bits |= TIOCFLAG_CLOCAL;
676		if(cs->cs_creg[3] & ZSWR3_HFC)
677			bits |= TIOCFLAG_CRTSCTS;
678		*(int *)data = bits;
679		break;
680	}
681	case TIOCSFLAGS: {
682		int userbits, driverbits = 0;
683
684		error = suser(p->p_ucred, &p->p_acflag);
685		if(error != 0)
686			return (EPERM);
687
688		userbits = *(int *)data;
689
690		/*
691		 * can have `local' or `softcar', and `rtscts' or `mdmbuf'
692		 # defaulting to software flow control.
693		 */
694		if(userbits & TIOCFLAG_SOFTCAR && userbits & TIOCFLAG_CLOCAL)
695			return(EINVAL);
696		if(userbits & TIOCFLAG_MDMBUF)	/* don't support this (yet?) */
697			return(ENXIO);
698
699		s = splzs();
700		if((userbits & TIOCFLAG_SOFTCAR)) {
701			cs->cs_softcar = 1;	/* turn on softcar */
702			cs->cs_preg[15] &= ~ZSWR15_DCD_IE; /* turn off dcd */
703			cs->cs_creg[15] &= ~ZSWR15_DCD_IE;
704			ZS_WRITE(cs->cs_zc, 15, cs->cs_creg[15]);
705		}
706		else if(userbits & TIOCFLAG_CLOCAL) {
707			cs->cs_softcar = 0; 	/* turn off softcar */
708			cs->cs_preg[15] |= ZSWR15_DCD_IE; /* turn on dcd */
709			cs->cs_creg[15] |= ZSWR15_DCD_IE;
710			ZS_WRITE(cs->cs_zc, 15, cs->cs_creg[15]);
711			tp->t_termios.c_cflag |= CLOCAL;
712		}
713		if(userbits & TIOCFLAG_CRTSCTS) {
714			cs->cs_preg[15] |= ZSWR15_CTS_IE;
715			cs->cs_creg[15] |= ZSWR15_CTS_IE;
716			ZS_WRITE(cs->cs_zc, 15, cs->cs_creg[15]);
717			cs->cs_preg[3] |= ZSWR3_HFC;
718			cs->cs_creg[3] |= ZSWR3_HFC;
719			ZS_WRITE(cs->cs_zc, 3, cs->cs_creg[3]);
720			tp->t_termios.c_cflag |= CRTSCTS;
721		}
722		else {
723			/* no mdmbuf, so we must want software flow control */
724			cs->cs_preg[15] &= ~ZSWR15_CTS_IE;
725			cs->cs_creg[15] &= ~ZSWR15_CTS_IE;
726			ZS_WRITE(cs->cs_zc, 15, cs->cs_creg[15]);
727			cs->cs_preg[3] &= ~ZSWR3_HFC;
728			cs->cs_creg[3] &= ~ZSWR3_HFC;
729			ZS_WRITE(cs->cs_zc, 3, cs->cs_creg[3]);
730			tp->t_termios.c_cflag &= ~CRTSCTS;
731		}
732		splx(s);
733		break;
734	}
735	case TIOCSDTR:
736		zs_modem(cs, ZSWR5_DTR, DMBIS);
737		break;
738	case TIOCCDTR:
739		zs_modem(cs, ZSWR5_DTR, DMBIC);
740		break;
741	case TIOCMGET:
742		zs_modem(cs, 0, DMGET);
743		break;
744	case TIOCMSET:
745	case TIOCMBIS:
746	case TIOCMBIC:
747	default:
748		return (ENOTTY);
749	}
750	return (0);
751}
752
753/*
754 * Start or restart transmission.
755 */
756static void
757zsstart(tp)
758register struct tty *tp;
759{
760	register struct zs_chanstate	*cs;
761	register int			s, nch;
762		 int			unit = ZS_UNIT(tp->t_dev);
763		 struct zs_softc	*zi = zscd.cd_devs[unit >> 1];
764
765	cs = &zi->zi_cs[unit & 1];
766	s  = spltty();
767
768	/*
769	 * If currently active or delaying, no need to do anything.
770	 */
771	if(tp->t_state & (TS_TIMEOUT | TS_BUSY | TS_TTSTOP))
772		goto out;
773
774	/*
775	 * If there are sleepers, and output has drained below low
776	 * water mark, awaken.
777	 */
778	if(tp->t_outq.c_cc <= tp->t_lowat) {
779		if(tp->t_state & TS_ASLEEP) {
780			tp->t_state &= ~TS_ASLEEP;
781			wakeup((caddr_t)&tp->t_outq);
782		}
783		selwakeup(&tp->t_wsel);
784	}
785
786	nch = ndqb(&tp->t_outq, 0);	/* XXX */
787	if(nch) {
788		register char *p = tp->t_outq.c_cf;
789
790		/* mark busy, enable tx done interrupts, & send first byte */
791		tp->t_state |= TS_BUSY;
792		(void) splzs();
793		cs->cs_preg[1] |= ZSWR1_TIE;
794		cs->cs_creg[1] |= ZSWR1_TIE;
795		ZS_WRITE(cs->cs_zc, 1, cs->cs_creg[1]);
796		cs->cs_zc->zc_data = *p;
797		cs->cs_tba = p + 1;
798		cs->cs_tbc = nch - 1;
799	} else {
800		/*
801		 * Nothing to send, turn off transmit done interrupts.
802		 * This is useful if something is doing polled output.
803		 */
804		(void) splzs();
805		cs->cs_preg[1] &= ~ZSWR1_TIE;
806		cs->cs_creg[1] &= ~ZSWR1_TIE;
807		ZS_WRITE(cs->cs_zc, 1, cs->cs_creg[1]);
808	}
809out:
810	splx(s);
811}
812
813/*
814 * Stop output, e.g., for ^S or output flush.
815 */
816void
817zsstop(tp, flag)
818register struct tty	*tp;
819	 int		flag;
820{
821	register struct zs_chanstate	*cs;
822	register int			s, unit = ZS_UNIT(tp->t_dev);
823		 struct zs_softc	*zi = zscd.cd_devs[unit >> 1];
824
825	cs = &zi->zi_cs[unit & 1];
826	s  = splzs();
827	if(tp->t_state & TS_BUSY) {
828		/*
829		 * Device is transmitting; must stop it.
830		 */
831		cs->cs_tbc = 0;
832		if ((tp->t_state & TS_TTSTOP) == 0)
833			tp->t_state |= TS_FLUSH;
834	}
835	splx(s);
836}
837
838/*
839 * Set ZS tty parameters from termios.
840 *
841 * This routine makes use of the fact that only registers
842 * 1, 3, 4, 5, 9, 10, 11, 12, 13, 14, and 15 are written.
843 */
844static int
845zsparam(tp, t)
846register struct tty	*tp;
847register struct termios	*t;
848{
849		 int			unit = ZS_UNIT(tp->t_dev);
850		 struct zs_softc	*zi = zscd.cd_devs[unit >> 1];
851	register struct zs_chanstate	*cs = &zi->zi_cs[unit & 1];
852	register int			tmp, tmp5, cflag, s;
853
854	tmp = t->c_ospeed;
855	if(tmp < 0 || (t->c_ispeed && t->c_ispeed != tmp))
856		return(EINVAL);
857	if(tmp == 0) {
858		/* stty 0 => drop DTR and RTS */
859		zs_modem(cs, 0, DMSET);
860		return(0);
861	}
862	tmp = BPS_TO_TCONST(PCLK / 16, tmp);
863	if(tmp < 2)
864		return(EINVAL);
865
866	cflag = t->c_cflag;
867	tp->t_ispeed = tp->t_ospeed = TCONST_TO_BPS(PCLK / 16, tmp);
868	tp->t_cflag = cflag;
869
870	/*
871	 * Block interrupts so that state will not
872	 * be altered until we are done setting it up.
873	 */
874	s = splzs();
875	cs->cs_preg[12] = tmp;
876	cs->cs_preg[13] = tmp >> 8;
877	cs->cs_preg[1]  = ZSWR1_RIE | ZSWR1_TIE | ZSWR1_SIE;
878	switch(cflag & CSIZE) {
879	case CS5:
880		tmp  = ZSWR3_RX_5;
881		tmp5 = ZSWR5_TX_5;
882		break;
883	case CS6:
884		tmp  = ZSWR3_RX_6;
885		tmp5 = ZSWR5_TX_6;
886		break;
887	case CS7:
888		tmp  = ZSWR3_RX_7;
889		tmp5 = ZSWR5_TX_7;
890		break;
891	case CS8:
892	default:
893		tmp  = ZSWR3_RX_8;
894		tmp5 = ZSWR5_TX_8;
895		break;
896	}
897
898	/*
899	 * Output hardware flow control on the chip is horrendous: if
900	 * carrier detect drops, the receiver is disabled.  Hence we
901	 * can only do this when the carrier is on.
902	 */
903	if(cflag & CCTS_OFLOW && cs->cs_zc->zc_csr & ZSRR0_DCD)
904		tmp |= ZSWR3_HFC | ZSWR3_RX_ENABLE;
905	else tmp |= ZSWR3_RX_ENABLE;
906	cs->cs_preg[3] = tmp;
907	cs->cs_preg[5] = tmp5 | ZSWR5_TX_ENABLE | ZSWR5_DTR | ZSWR5_RTS;
908
909	tmp = ZSWR4_CLK_X16 | (cflag & CSTOPB ? ZSWR4_TWOSB : ZSWR4_ONESB);
910	if((cflag & PARODD) == 0)
911		tmp |= ZSWR4_EVENP;
912	if (cflag & PARENB)
913		tmp |= ZSWR4_PARENB;
914	cs->cs_preg[4]  = tmp;
915	cs->cs_preg[9]  = ZSWR9_MASTER_IE | ZSWR9_VECTOR_INCL_STAT;
916	cs->cs_preg[10] = ZSWR10_NRZ;
917	cs->cs_preg[11] = ZSWR11_TXCLK_BAUD | ZSWR11_RXCLK_BAUD;
918	cs->cs_preg[14] = ZSWR14_BAUD_FROM_PCLK | ZSWR14_BAUD_ENA;
919	cs->cs_preg[15] = ZSWR15_BREAK_IE | ZSWR15_DCD_IE;
920
921	/*
922	 * If nothing is being transmitted, set up new current values,
923	 * else mark them as pending.
924	 */
925	if(cs->cs_heldchange == 0) {
926		if (cs->cs_ttyp->t_state & TS_BUSY) {
927			cs->cs_heldtbc = cs->cs_tbc;
928			cs->cs_tbc = 0;
929			cs->cs_heldchange = 1;
930		}
931		else {
932			bcopy((caddr_t)cs->cs_preg, (caddr_t)cs->cs_creg, 16);
933			zs_loadchannelregs(cs->cs_zc, cs->cs_creg);
934		}
935	}
936	splx(s);
937	return (0);
938}
939
940/*
941 * Raise or lower modem control (DTR/RTS) signals.  If a character is
942 * in transmission, the change is deferred.
943 */
944static int
945zs_modem(cs, bits, how)
946struct zs_chanstate	*cs;
947int			bits, how;
948{
949	int s, mbits;
950
951	bits  &= ZSWR5_DTR | ZSWR5_RTS;
952
953	s = splzs();
954	mbits  = cs->cs_preg[5] &  (ZSWR5_DTR | ZSWR5_RTS);
955
956	switch(how) {
957		case DMSET:
958				mbits  = bits;
959				break;
960		case DMBIS:
961				mbits |= bits;
962				break;
963		case DMBIC:
964				mbits &= ~bits;
965				break;
966		case DMGET:
967				splx(s);
968				return(mbits);
969	}
970
971	cs->cs_preg[5] = (cs->cs_preg[5] & ~(ZSWR5_DTR | ZSWR5_RTS)) | mbits;
972	if(cs->cs_heldchange == 0) {
973		if(cs->cs_ttyp->t_state & TS_BUSY) {
974			cs->cs_heldtbc = cs->cs_tbc;
975			cs->cs_tbc = 0;
976			cs->cs_heldchange = 1;
977		}
978		else {
979			ZS_WRITE(cs->cs_zc, 5, cs->cs_creg[5]);
980		}
981	}
982	splx(s);
983	return(0);
984}
985
986/*
987 * Write the given register set to the given zs channel in the proper order.
988 * The channel must not be transmitting at the time.  The receiver will
989 * be disabled for the time it takes to write all the registers.
990 */
991static void
992zs_loadchannelregs(zc, reg)
993volatile struct zschan	*zc;
994u_char			*reg;
995{
996	int i;
997
998	zc->zc_csr = ZSM_RESET_ERR;	/* reset error condition */
999	i = zc->zc_data;		/* drain fifo */
1000	i = zc->zc_data;
1001	i = zc->zc_data;
1002	ZS_WRITE(zc,  4, reg[4]);
1003	ZS_WRITE(zc, 10, reg[10]);
1004	ZS_WRITE(zc,  3, reg[3] & ~ZSWR3_RX_ENABLE);
1005	ZS_WRITE(zc,  5, reg[5] & ~ZSWR5_TX_ENABLE);
1006	ZS_WRITE(zc,  1, reg[1]);
1007	ZS_WRITE(zc,  9, reg[9]);
1008	ZS_WRITE(zc, 11, reg[11]);
1009	ZS_WRITE(zc, 12, reg[12]);
1010	ZS_WRITE(zc, 13, reg[13]);
1011	ZS_WRITE(zc, 14, reg[14]);
1012	ZS_WRITE(zc, 15, reg[15]);
1013	ZS_WRITE(zc,  3, reg[3]);
1014	ZS_WRITE(zc,  5, reg[5]);
1015}
1016#endif /* NZS > 1 */
1017