zs.c revision 1.14
1/*	$NetBSD: zs.c,v 1.14 1996/01/23 09:35:15 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/systm.h>
58#include <sys/proc.h>
59#include <sys/device.h>
60#include <sys/conf.h>
61#include <sys/file.h>
62#include <sys/ioctl.h>
63#include <sys/malloc.h>
64#include <sys/tty.h>
65#include <sys/time.h>
66#include <sys/kernel.h>
67#include <sys/syslog.h>
68
69#include <machine/cpu.h>
70#include <machine/iomap.h>
71#include <machine/scu.h>
72#include <machine/mfp.h>
73#include <machine/video.h>
74
75#include <dev/ic/z8530reg.h>
76#include <atari/dev/zsvar.h>
77#include "zs.h"
78#if NZS > 1
79#error "This driver supports only 1 85C30!"
80#endif
81
82#if NZS > 0
83
84#define PCLK	(8053976)	/* PCLK pin input clock rate */
85
86#define splzs	spl5
87
88/*
89 * Software state per found chip.
90 */
91struct zs_softc {
92    struct	device		zi_dev;    /* base device		  */
93    volatile struct zsdevice	*zi_zs;    /* chip registers		  */
94    struct	zs_chanstate	zi_cs[2];  /* chan A and B software state */
95};
96
97static u_char	cb_scheduled = 0;	/* Already asked for callback? */
98/*
99 * Define the registers for a closed port
100 */
101static u_char zs_init_regs[16] = {
102/*  0 */	0,
103/*  1 */	0,
104/*  2 */	0x60,
105/*  3 */	0,
106/*  4 */	0,
107/*  5 */	0,
108/*  6 */	0,
109/*  7 */	0,
110/*  8 */	0,
111/*  9 */	ZSWR9_MASTER_IE | ZSWR9_VECTOR_INCL_STAT,
112/* 10 */	ZSWR10_NRZ,
113/* 11 */	ZSWR11_TXCLK_BAUD | ZSWR11_RXCLK_BAUD,
114/* 12 */	0,
115/* 13 */	0,
116/* 14 */	ZSWR14_BAUD_FROM_PCLK | ZSWR14_BAUD_ENA,
117/* 15 */	0
118};
119
120/*
121 * Define the machine dependant clock frequencies
122 * If BRgen feeds sender/receiver we always use a
123 * divisor 16, therefor the division by 16 can as
124 * well be done here.
125 */
126static u_long zs_freqs_tt[] = {
127	/*
128	 * Atari TT, RTxCB is generated by TT-MFP timer C,
129	 * which is set to 307.2KHz during initialisation
130	 * and never changed afterwards.
131	 */
132	PCLK/16,	/* BRgen, PCLK,  divisor 16	*/
133	 229500,	/* BRgen, RTxCA, divisor 16	*/
134	3672000,	/* RTxCA, from PCLK4		*/
135	      0,	/* TRxCA, external		*/
136
137	PCLK/16,	/* BRgen, PCLK,  divisor 16	*/
138	  19200,	/* BRgen, RTxCB, divisor 16	*/
139	 307200,	/* RTxCB, from TT-MFP TCO	*/
140	2457600		/* TRxCB, from BCLK		*/
141};
142static u_long zs_freqs_falcon[] = {
143	/*
144	 * Atari Falcon, XXX no specs available, this might be wrong
145	 */
146	PCLK/16,	/* BRgen, PCLK,  divisor 16	*/
147	 229500,	/* BRgen, RTxCA, divisor 16	*/
148	3672000,	/* RTxCA, ???			*/
149	      0,	/* TRxCA, external		*/
150
151	PCLK/16,	/* BRgen, PCLK,  divisor 16	*/
152	 229500,	/* BRgen, RTxCB, divisor 16	*/
153	3672000,	/* RTxCB, ???			*/
154	2457600		/* TRxCB, ???			*/
155};
156static u_long zs_freqs_generic[] = {
157	/*
158	 * other machines, assume only PCLK is available
159	 */
160	PCLK/16,	/* BRgen, PCLK,  divisor 16	*/
161	      0,	/* BRgen, RTxCA, divisor 16	*/
162	      0,	/* RTxCA, unknown		*/
163	      0,	/* TRxCA, unknown		*/
164
165	PCLK/16,	/* BRgen, PCLK,  divisor 16	*/
166	      0,	/* BRgen, RTxCB, divisor 16	*/
167	      0,	/* RTxCB, unknown		*/
168	      0		/* TRxCB, unknown		*/
169};
170static u_long *zs_frequencies;
171
172/* Definition of the driver for autoconfig. */
173static int	zsmatch __P((struct device *, struct cfdata *, void *));
174static void	zsattach __P((struct device *, struct device *, void *));
175struct cfdriver zscd = {
176	NULL, "zs", (cfmatch_t)zsmatch, zsattach, DV_TTY,
177	sizeof(struct zs_softc), NULL, 0 };
178
179/* Interrupt handlers. */
180int		zshard __P((long));
181static int	zssoft __P((long));
182static int	zsrint __P((struct zs_chanstate *, volatile struct zschan *));
183static int	zsxint __P((struct zs_chanstate *, volatile struct zschan *));
184static int	zssint __P((struct zs_chanstate *, volatile struct zschan *));
185
186static struct zs_chanstate *zslist;
187
188/* Routines called from other code. */
189static void	zsstart __P((struct tty *));
190void		zsstop __P((struct tty *, int));
191static int	zsparam __P((struct tty *, struct termios *));
192static int	zsbaudrate __P((int, int, int *, int *, int *, int *));
193
194/* Routines purely local to this driver. */
195static void	zs_reset __P((volatile struct zschan *, int, int));
196static int	zs_modem __P((struct zs_chanstate *, int, int));
197static void	zs_loadchannelregs __P((volatile struct zschan *, u_char *));
198
199static int zsshortcuts;	/* number of "shortcut" software interrupts */
200
201static int
202zsmatch(pdp, cfp, auxp)
203struct device	*pdp;
204struct cfdata	*cfp;
205void		*auxp;
206{
207	if(strcmp("zs", auxp) || cfp->cf_unit != 0)
208		return(0);
209	return(1);
210}
211
212/*
213 * Attach a found zs.
214 */
215static void
216zsattach(parent, dev, aux)
217struct device	*parent;
218struct device	*dev;
219void		*aux;
220{
221	register struct zs_softc		*zi;
222	register struct zs_chanstate		*cs;
223	register volatile struct zsdevice	*addr;
224	register struct tty			*tp;
225		 char				tmp;
226
227	addr      = (struct zsdevice *)AD_SCC;
228	zi        = (struct zs_softc *)dev;
229	zi->zi_zs = addr;
230	cs        = zi->zi_cs;
231
232	/*
233	 * Get the command register into a known state.
234	 */
235	tmp = addr->zs_chan[ZS_CHAN_A].zc_csr;
236	tmp = addr->zs_chan[ZS_CHAN_A].zc_csr;
237	tmp = addr->zs_chan[ZS_CHAN_B].zc_csr;
238	tmp = addr->zs_chan[ZS_CHAN_B].zc_csr;
239
240	/*
241	 * Do a hardware reset.
242	 */
243	ZS_WRITE(&addr->zs_chan[ZS_CHAN_A], 9, ZSWR9_HARD_RESET);
244	delay(50000);	/*enough ? */
245	ZS_WRITE(&addr->zs_chan[ZS_CHAN_A], 9, 0);
246
247	/*
248	 * Initialize both channels
249	 */
250	zs_loadchannelregs(&addr->zs_chan[ZS_CHAN_A], zs_init_regs);
251	zs_loadchannelregs(&addr->zs_chan[ZS_CHAN_B], zs_init_regs);
252
253	if(machineid & ATARI_TT) {
254		/*
255		 * ininitialise TT-MFP timer C: 307200Hz
256		 * timer C and D share one control register:
257		 *	bits 0-2 control timer D
258		 *	bits 4-6 control timer C
259		 */
260		int cr = MFP2->mf_tcdcr & 7;
261		MFP2->mf_tcdcr = cr;		/* stop timer C  */
262		MFP2->mf_tcdr  = 1;		/* counter 1     */
263		cr |= T_Q004 << 4;		/* divisor 4     */
264		MFP2->mf_tcdcr = cr;		/* start timer C */
265		/*
266		 * enable scc related interrupts
267		 */
268		SCU->sys_mask |= SCU_SCC;
269
270		zs_frequencies = zs_freqs_tt;
271	} else if (machineid & ATARI_FALCON) {
272		zs_frequencies = zs_freqs_falcon;
273	} else {
274		zs_frequencies = zs_freqs_generic;
275	}
276
277	/* link into interrupt list with order (A,B) (B=A+1) */
278	cs[0].cs_next = &cs[1];
279	cs[1].cs_next = zslist;
280	zslist        = cs;
281
282	cs->cs_unit  = 0;
283	cs->cs_zc    = &addr->zs_chan[ZS_CHAN_A];
284	cs++;
285	cs->cs_unit  = 1;
286	cs->cs_zc    = &addr->zs_chan[ZS_CHAN_B];
287
288	printf(": serial2 on channel a and modem2 on channel b\n");
289}
290
291/*
292 * Open a zs serial port.
293 */
294int
295zsopen(dev, flags, mode, p)
296dev_t		dev;
297int		flags;
298int		mode;
299struct proc	*p;
300{
301	register struct tty		*tp;
302	register struct zs_chanstate	*cs;
303		 struct zs_softc	*zi;
304		 int			unit = ZS_UNIT(dev);
305		 int			zs = unit >> 1;
306		 int			error, s;
307
308	if(zs >= zscd.cd_ndevs || (zi = zscd.cd_devs[zs]) == NULL)
309		return (ENXIO);
310	cs = &zi->zi_cs[unit & 1];
311
312	/*
313	 * When port A (ser02) is selected on the TT, make sure
314	 * the port is enabled.
315	 */
316	if((machineid & ATARI_TT) && !(unit & 1)) {
317		SOUND->sd_selr = YM_IOA;
318		SOUND->sd_wdat = SOUND->sd_rdat | PA_SER2;
319	}
320
321	if (cs->cs_rbuf == NULL) {
322		cs->cs_rbuf = malloc(ZLRB_RING_SIZE * sizeof(int), M_DEVBUF,
323								   M_WAITOK);
324	}
325
326	tp = cs->cs_ttyp;
327	if(tp == NULL) {
328		cs->cs_ttyp  = tp = ttymalloc();
329		tp->t_dev    = dev;
330		tp->t_oproc  = zsstart;
331		tp->t_param  = zsparam;
332	}
333
334	s  = spltty();
335	if((tp->t_state & TS_ISOPEN) == 0) {
336		ttychars(tp);
337		if(tp->t_ispeed == 0) {
338			tp->t_iflag = TTYDEF_IFLAG;
339			tp->t_oflag = TTYDEF_OFLAG;
340			tp->t_cflag = TTYDEF_CFLAG;
341			tp->t_lflag = TTYDEF_LFLAG;
342			tp->t_ispeed = tp->t_ospeed = TTYDEF_SPEED;
343		}
344		(void)zsparam(tp, &tp->t_termios);
345		ttsetwater(tp);
346	}
347	else if(tp->t_state & TS_XCLUDE && p->p_ucred->cr_uid != 0) {
348			splx(s);
349			return (EBUSY);
350	}
351	error = 0;
352	for(;;) {
353		/* loop, turning on the device, until carrier present */
354		zs_modem(cs, ZSWR5_RTS|ZSWR5_DTR, DMSET);
355
356		/* May never get a status intr. if DCD already on. -gwr */
357		if(cs->cs_zc->zc_csr & ZSRR0_DCD)
358			tp->t_state |= TS_CARR_ON;
359		if(cs->cs_softcar)
360			tp->t_state |= TS_CARR_ON;
361		if(flags & O_NONBLOCK || tp->t_cflag & CLOCAL ||
362		    tp->t_state & TS_CARR_ON)
363			break;
364		tp->t_state |= TS_WOPEN;
365		if(error = ttysleep(tp, (caddr_t)&tp->t_rawq, TTIPRI | PCATCH,
366		    ttopen, 0)) {
367			if(!(tp->t_state & TS_ISOPEN)) {
368				zs_modem(cs, 0, DMSET);
369				tp->t_state &= ~TS_WOPEN;
370				ttwakeup(tp);
371			}
372			splx(s);
373			return error;
374		}
375	}
376	splx(s);
377	if(error == 0)
378		error = linesw[tp->t_line].l_open(dev, tp);
379	if(error)
380		zs_modem(cs, 0, DMSET);
381	return(error);
382}
383
384/*
385 * Close a zs serial port.
386 */
387int
388zsclose(dev, flags, mode, p)
389dev_t		dev;
390int		flags;
391int		mode;
392struct proc	*p;
393{
394	register struct zs_chanstate	*cs;
395	register struct tty		*tp;
396		 struct zs_softc	*zi;
397		 int			unit = ZS_UNIT(dev);
398		 int			s;
399
400	zi = zscd.cd_devs[unit >> 1];
401	cs = &zi->zi_cs[unit & 1];
402	tp = cs->cs_ttyp;
403	linesw[tp->t_line].l_close(tp, flags);
404	if(tp->t_cflag & HUPCL || tp->t_state & TS_WOPEN ||
405	    (tp->t_state & TS_ISOPEN) == 0) {
406		zs_modem(cs, 0, DMSET);
407		/* hold low for 1 second */
408		(void)tsleep((caddr_t)cs, TTIPRI, ttclos, hz);
409	}
410	if(cs->cs_creg[5] & ZSWR5_BREAK) {
411		s = splzs();
412		cs->cs_preg[5] &= ~ZSWR5_BREAK;
413		cs->cs_creg[5] &= ~ZSWR5_BREAK;
414		ZS_WRITE(cs->cs_zc, 5, cs->cs_creg[5]);
415		splx(s);
416	}
417	ttyclose(tp);
418
419	/*
420	 * Drop all lines and cancel interrupts
421	 */
422	s = splzs();
423	zs_loadchannelregs(cs->cs_zc, zs_init_regs);
424	splx(s);
425	return (0);
426}
427
428/*
429 * Read/write zs serial port.
430 */
431int
432zsread(dev, uio, flags)
433dev_t		dev;
434struct uio	*uio;
435int		flags;
436{
437	register struct zs_chanstate	*cs;
438	register struct zs_softc	*zi;
439	register struct tty		*tp;
440		 int			unit;
441
442	unit = ZS_UNIT(dev);
443	zi   = zscd.cd_devs[unit >> 1];
444	cs   = &zi->zi_cs[unit & 1];
445	tp   = cs->cs_ttyp;
446
447	return(linesw[tp->t_line].l_read(tp, uio, flags));
448}
449
450int
451zswrite(dev, uio, flags)
452dev_t		dev;
453struct uio	*uio;
454int		flags;
455{
456	register struct zs_chanstate	*cs;
457	register struct zs_softc	*zi;
458	register struct tty		*tp;
459		 int			unit;
460
461	unit = ZS_UNIT(dev);
462	zi   = zscd.cd_devs[unit >> 1];
463	cs   = &zi->zi_cs[unit & 1];
464	tp   = cs->cs_ttyp;
465
466	return(linesw[tp->t_line].l_write(tp, uio, flags));
467}
468
469struct tty *
470zstty(dev)
471dev_t	dev;
472{
473	register struct zs_chanstate	*cs;
474	register struct zs_softc	*zi;
475		 int			unit;
476
477	unit = ZS_UNIT(dev);
478	zi   = zscd.cd_devs[unit >> 1];
479	cs   = &zi->zi_cs[unit & 1];
480	return(cs->cs_ttyp);
481}
482
483/*
484 * ZS hardware interrupt.  Scan all ZS channels.  NB: we know here that
485 * channels are kept in (A,B) pairs.
486 *
487 * Do just a little, then get out; set a software interrupt if more
488 * work is needed.
489 *
490 * We deliberately ignore the vectoring Zilog gives us, and match up
491 * only the number of `reset interrupt under service' operations, not
492 * the order.
493 */
494
495int
496zshard(sr)
497long sr;
498{
499	register struct zs_chanstate	*a;
500#define	b (a + 1)
501	register volatile struct zschan *zc;
502	register int			rr3, intflags = 0, v, i;
503
504	do {
505	    intflags &= ~4;
506	    for(a = zslist; a != NULL; a = b->cs_next) {
507		rr3 = ZS_READ(a->cs_zc, 3);
508		if(rr3 & (ZSRR3_IP_A_RX|ZSRR3_IP_A_TX|ZSRR3_IP_A_STAT)) {
509			intflags |= 4|2;
510			zc = a->cs_zc;
511			i  = a->cs_rbput;
512			if(rr3 & ZSRR3_IP_A_RX && (v = zsrint(a, zc)) != 0) {
513				a->cs_rbuf[i++ & ZLRB_RING_MASK] = v;
514				intflags |= 1;
515			}
516			if(rr3 & ZSRR3_IP_A_TX && (v = zsxint(a, zc)) != 0) {
517				a->cs_rbuf[i++ & ZLRB_RING_MASK] = v;
518				intflags |= 1;
519			}
520			if(rr3 & ZSRR3_IP_A_STAT && (v = zssint(a, zc)) != 0) {
521				a->cs_rbuf[i++ & ZLRB_RING_MASK] = v;
522				intflags |= 1;
523			}
524			a->cs_rbput = i;
525		}
526		if(rr3 & (ZSRR3_IP_B_RX|ZSRR3_IP_B_TX|ZSRR3_IP_B_STAT)) {
527			intflags |= 4|2;
528			zc = b->cs_zc;
529			i  = b->cs_rbput;
530			if(rr3 & ZSRR3_IP_B_RX && (v = zsrint(b, zc)) != 0) {
531				b->cs_rbuf[i++ & ZLRB_RING_MASK] = v;
532				intflags |= 1;
533			}
534			if(rr3 & ZSRR3_IP_B_TX && (v = zsxint(b, zc)) != 0) {
535				b->cs_rbuf[i++ & ZLRB_RING_MASK] = v;
536				intflags |= 1;
537			}
538			if(rr3 & ZSRR3_IP_B_STAT && (v = zssint(b, zc)) != 0) {
539				b->cs_rbuf[i++ & ZLRB_RING_MASK] = v;
540				intflags |= 1;
541			}
542			b->cs_rbput = i;
543		}
544	    }
545	} while(intflags & 4);
546#undef b
547
548	if(intflags & 1) {
549		if(BASEPRI(sr)) {
550			spl1();
551			zsshortcuts++;
552			return(zssoft(sr));
553		}
554		else if(!cb_scheduled) {
555			cb_scheduled++;
556			add_sicallback(zssoft, 0, 0);
557		}
558	}
559	return(intflags & 2);
560}
561
562static int
563zsrint(cs, zc)
564register struct zs_chanstate	*cs;
565register volatile struct zschan	*zc;
566{
567	register int c;
568
569	/*
570	 * First read the status, because read of the received char
571	 * destroy the status of this char.
572	 */
573	c = ZS_READ(zc, 1);
574	c |= (zc->zc_data << 8);
575
576	/* clear receive error & interrupt condition */
577	zc->zc_csr = ZSWR0_RESET_ERRORS;
578	zc->zc_csr = ZSWR0_CLR_INTR;
579
580	return(ZRING_MAKE(ZRING_RINT, c));
581}
582
583static int
584zsxint(cs, zc)
585register struct zs_chanstate	*cs;
586register volatile struct zschan	*zc;
587{
588	register int i = cs->cs_tbc;
589
590	if(i == 0) {
591		zc->zc_csr = ZSWR0_RESET_TXINT;
592		zc->zc_csr = ZSWR0_CLR_INTR;
593		return(ZRING_MAKE(ZRING_XINT, 0));
594	}
595	cs->cs_tbc = i - 1;
596	zc->zc_data = *cs->cs_tba++;
597	zc->zc_csr = ZSWR0_CLR_INTR;
598	return (0);
599}
600
601static int
602zssint(cs, zc)
603register struct zs_chanstate	*cs;
604register volatile struct zschan	*zc;
605{
606	register int rr0;
607
608	rr0 = zc->zc_csr;
609	zc->zc_csr = ZSWR0_RESET_STATUS;
610	zc->zc_csr = ZSWR0_CLR_INTR;
611	/*
612	 * The chip's hardware flow control is, as noted in zsreg.h,
613	 * busted---if the DCD line goes low the chip shuts off the
614	 * receiver (!).  If we want hardware CTS flow control but do
615	 * not have it, and carrier is now on, turn HFC on; if we have
616	 * HFC now but carrier has gone low, turn it off.
617	 */
618	if(rr0 & ZSRR0_DCD) {
619		if(cs->cs_ttyp->t_cflag & CCTS_OFLOW &&
620		    (cs->cs_creg[3] & ZSWR3_HFC) == 0) {
621			cs->cs_creg[3] |= ZSWR3_HFC;
622			ZS_WRITE(zc, 3, cs->cs_creg[3]);
623		}
624	}
625	else {
626		if (cs->cs_creg[3] & ZSWR3_HFC) {
627			cs->cs_creg[3] &= ~ZSWR3_HFC;
628			ZS_WRITE(zc, 3, cs->cs_creg[3]);
629		}
630	}
631	return(ZRING_MAKE(ZRING_SINT, rr0));
632}
633
634/*
635 * Print out a ring or fifo overrun error message.
636 */
637static void
638zsoverrun(unit, ptime, what)
639int	unit;
640long	*ptime;
641char	*what;
642{
643
644	if(*ptime != time.tv_sec) {
645		*ptime = time.tv_sec;
646		log(LOG_WARNING, "zs%d%c: %s overrun\n", unit >> 1,
647		    (unit & 1) + 'a', what);
648	}
649}
650
651/*
652 * ZS software interrupt.  Scan all channels for deferred interrupts.
653 */
654int
655zssoft(sr)
656long sr;
657{
658    register struct zs_chanstate	*cs;
659    register volatile struct zschan	*zc;
660    register struct linesw		*line;
661    register struct tty			*tp;
662    register int			get, n, c, cc, unit, s;
663 	     int			retval = 0;
664
665    cb_scheduled = 0;
666    s = spltty();
667    for(cs = zslist; cs != NULL; cs = cs->cs_next) {
668	get = cs->cs_rbget;
669again:
670	n = cs->cs_rbput;	/* atomic			*/
671	if(get == n)		/* nothing more on this line	*/
672		continue;
673	retval = 1;
674	unit   = cs->cs_unit;	/* set up to handle interrupts	*/
675	zc     = cs->cs_zc;
676	tp     = cs->cs_ttyp;
677	line   = &linesw[tp->t_line];
678	/*
679	 * Compute the number of interrupts in the receive ring.
680	 * If the count is overlarge, we lost some events, and
681	 * must advance to the first valid one.  It may get
682	 * overwritten if more data are arriving, but this is
683	 * too expensive to check and gains nothing (we already
684	 * lost out; all we can do at this point is trade one
685	 * kind of loss for another).
686	 */
687	n -= get;
688	if(n > ZLRB_RING_SIZE) {
689		zsoverrun(unit, &cs->cs_rotime, "ring");
690		get += n - ZLRB_RING_SIZE;
691		n    = ZLRB_RING_SIZE;
692	}
693	while(--n >= 0) {
694		/* race to keep ahead of incoming interrupts */
695		c = cs->cs_rbuf[get++ & ZLRB_RING_MASK];
696		switch (ZRING_TYPE(c)) {
697
698		case ZRING_RINT:
699			c = ZRING_VALUE(c);
700			if(c & ZSRR1_DO)
701				zsoverrun(unit, &cs->cs_fotime, "fifo");
702			cc = c >> 8;
703			if(c & ZSRR1_FE)
704				cc |= TTY_FE;
705			if(c & ZSRR1_PE)
706				cc |= TTY_PE;
707			line->l_rint(cc, tp);
708			break;
709
710		case ZRING_XINT:
711			/*
712			 * Transmit done: change registers and resume,
713			 * or clear BUSY.
714			 */
715			if(cs->cs_heldchange) {
716				int sps;
717
718				sps = splzs();
719				c = zc->zc_csr;
720				if((c & ZSRR0_DCD) == 0)
721					cs->cs_preg[3] &= ~ZSWR3_HFC;
722				bcopy((caddr_t)cs->cs_preg,
723				    (caddr_t)cs->cs_creg, 16);
724				zs_loadchannelregs(zc, cs->cs_creg);
725				splx(sps);
726				cs->cs_heldchange = 0;
727				if(cs->cs_heldtbc
728					&& (tp->t_state & TS_TTSTOP) == 0) {
729					cs->cs_tbc = cs->cs_heldtbc - 1;
730					zc->zc_data = *cs->cs_tba++;
731					goto again;
732				}
733			}
734			tp->t_state &= ~TS_BUSY;
735			if(tp->t_state & TS_FLUSH)
736				tp->t_state &= ~TS_FLUSH;
737			else ndflush(&tp->t_outq,cs->cs_tba
738						- (caddr_t)tp->t_outq.c_cf);
739			line->l_start(tp);
740			break;
741
742		case ZRING_SINT:
743			/*
744			 * Status line change.  HFC bit is run in
745			 * hardware interrupt, to avoid locking
746			 * at splzs here.
747			 */
748			c = ZRING_VALUE(c);
749			if((c ^ cs->cs_rr0) & ZSRR0_DCD) {
750				cc = (c & ZSRR0_DCD) != 0;
751				if(line->l_modem(tp, cc) == 0)
752					zs_modem(cs, ZSWR5_RTS|ZSWR5_DTR,
753							cc ? DMBIS : DMBIC);
754			}
755			cs->cs_rr0 = c;
756			break;
757
758		default:
759			log(LOG_ERR, "zs%d%c: bad ZRING_TYPE (%x)\n",
760			    unit >> 1, (unit & 1) + 'a', c);
761			break;
762		}
763	}
764	cs->cs_rbget = get;
765	goto again;
766    }
767    splx(s);
768    return (retval);
769}
770
771int
772zsioctl(dev, cmd, data, flag, p)
773dev_t		dev;
774u_long		cmd;
775caddr_t		data;
776int		flag;
777struct proc	*p;
778{
779		 int			unit = ZS_UNIT(dev);
780		 struct zs_softc	*zi = zscd.cd_devs[unit >> 1];
781	register struct tty		*tp = zi->zi_cs[unit & 1].cs_ttyp;
782	register int			error, s;
783	register struct zs_chanstate	*cs = &zi->zi_cs[unit & 1];
784
785	error = linesw[tp->t_line].l_ioctl(tp, cmd, data, flag, p);
786	if(error >= 0)
787		return(error);
788	error = ttioctl(tp, cmd, data, flag, p);
789	if(error >= 0)
790		return (error);
791
792	switch (cmd) {
793	case TIOCSBRK:
794		s = splzs();
795		cs->cs_preg[5] |= ZSWR5_BREAK;
796		cs->cs_creg[5] |= ZSWR5_BREAK;
797		ZS_WRITE(cs->cs_zc, 5, cs->cs_creg[5]);
798		splx(s);
799		break;
800	case TIOCCBRK:
801		s = splzs();
802		cs->cs_preg[5] &= ~ZSWR5_BREAK;
803		cs->cs_creg[5] &= ~ZSWR5_BREAK;
804		ZS_WRITE(cs->cs_zc, 5, cs->cs_creg[5]);
805		splx(s);
806		break;
807	case TIOCGFLAGS: {
808		int bits = 0;
809
810		if(cs->cs_softcar)
811			bits |= TIOCFLAG_SOFTCAR;
812		if(cs->cs_creg[15] & ZSWR15_DCD_IE)
813			bits |= TIOCFLAG_CLOCAL;
814		if(cs->cs_creg[3] & ZSWR3_HFC)
815			bits |= TIOCFLAG_CRTSCTS;
816		*(int *)data = bits;
817		break;
818	}
819	case TIOCSFLAGS: {
820		int userbits, driverbits = 0;
821
822		error = suser(p->p_ucred, &p->p_acflag);
823		if(error != 0)
824			return (EPERM);
825
826		userbits = *(int *)data;
827
828		/*
829		 * can have `local' or `softcar', and `rtscts' or `mdmbuf'
830		 # defaulting to software flow control.
831		 */
832		if(userbits & TIOCFLAG_SOFTCAR && userbits & TIOCFLAG_CLOCAL)
833			return(EINVAL);
834		if(userbits & TIOCFLAG_MDMBUF)	/* don't support this (yet?) */
835			return(ENODEV);
836
837		s = splzs();
838		if((userbits & TIOCFLAG_SOFTCAR)) {
839			cs->cs_softcar = 1;	/* turn on softcar */
840			cs->cs_preg[15] &= ~ZSWR15_DCD_IE; /* turn off dcd */
841			cs->cs_creg[15] &= ~ZSWR15_DCD_IE;
842			ZS_WRITE(cs->cs_zc, 15, cs->cs_creg[15]);
843		}
844		else if(userbits & TIOCFLAG_CLOCAL) {
845			cs->cs_softcar = 0; 	/* turn off softcar */
846			cs->cs_preg[15] |= ZSWR15_DCD_IE; /* turn on dcd */
847			cs->cs_creg[15] |= ZSWR15_DCD_IE;
848			ZS_WRITE(cs->cs_zc, 15, cs->cs_creg[15]);
849			tp->t_termios.c_cflag |= CLOCAL;
850		}
851		if(userbits & TIOCFLAG_CRTSCTS) {
852			cs->cs_preg[15] |= ZSWR15_CTS_IE;
853			cs->cs_creg[15] |= ZSWR15_CTS_IE;
854			ZS_WRITE(cs->cs_zc, 15, cs->cs_creg[15]);
855			cs->cs_preg[3] |= ZSWR3_HFC;
856			cs->cs_creg[3] |= ZSWR3_HFC;
857			ZS_WRITE(cs->cs_zc, 3, cs->cs_creg[3]);
858			tp->t_termios.c_cflag |= CRTSCTS;
859		}
860		else {
861			/* no mdmbuf, so we must want software flow control */
862			cs->cs_preg[15] &= ~ZSWR15_CTS_IE;
863			cs->cs_creg[15] &= ~ZSWR15_CTS_IE;
864			ZS_WRITE(cs->cs_zc, 15, cs->cs_creg[15]);
865			cs->cs_preg[3] &= ~ZSWR3_HFC;
866			cs->cs_creg[3] &= ~ZSWR3_HFC;
867			ZS_WRITE(cs->cs_zc, 3, cs->cs_creg[3]);
868			tp->t_termios.c_cflag &= ~CRTSCTS;
869		}
870		splx(s);
871		break;
872	}
873	case TIOCSDTR:
874		zs_modem(cs, ZSWR5_DTR, DMBIS);
875		break;
876	case TIOCCDTR:
877		zs_modem(cs, ZSWR5_DTR, DMBIC);
878		break;
879	case TIOCMGET:
880		zs_modem(cs, 0, DMGET);
881		break;
882	case TIOCMSET:
883	case TIOCMBIS:
884	case TIOCMBIC:
885	default:
886		return (ENOTTY);
887	}
888	return (0);
889}
890
891/*
892 * Start or restart transmission.
893 */
894static void
895zsstart(tp)
896register struct tty *tp;
897{
898	register struct zs_chanstate	*cs;
899	register int			s, nch;
900		 int			unit = ZS_UNIT(tp->t_dev);
901		 struct zs_softc	*zi = zscd.cd_devs[unit >> 1];
902
903	cs = &zi->zi_cs[unit & 1];
904	s  = spltty();
905
906	/*
907	 * If currently active or delaying, no need to do anything.
908	 */
909	if(tp->t_state & (TS_TIMEOUT | TS_BUSY | TS_TTSTOP))
910		goto out;
911
912	/*
913	 * If there are sleepers, and output has drained below low
914	 * water mark, awaken.
915	 */
916	if(tp->t_outq.c_cc <= tp->t_lowat) {
917		if(tp->t_state & TS_ASLEEP) {
918			tp->t_state &= ~TS_ASLEEP;
919			wakeup((caddr_t)&tp->t_outq);
920		}
921		selwakeup(&tp->t_wsel);
922	}
923
924	nch = ndqb(&tp->t_outq, 0);	/* XXX */
925	if(nch) {
926		register char *p = tp->t_outq.c_cf;
927
928		/* mark busy, enable tx done interrupts, & send first byte */
929		tp->t_state |= TS_BUSY;
930		(void) splzs();
931		cs->cs_preg[1] |= ZSWR1_TIE;
932		cs->cs_creg[1] |= ZSWR1_TIE;
933		ZS_WRITE(cs->cs_zc, 1, cs->cs_creg[1]);
934		cs->cs_zc->zc_data = *p;
935		cs->cs_tba = p + 1;
936		cs->cs_tbc = nch - 1;
937	} else {
938		/*
939		 * Nothing to send, turn off transmit done interrupts.
940		 * This is useful if something is doing polled output.
941		 */
942		(void) splzs();
943		cs->cs_preg[1] &= ~ZSWR1_TIE;
944		cs->cs_creg[1] &= ~ZSWR1_TIE;
945		ZS_WRITE(cs->cs_zc, 1, cs->cs_creg[1]);
946	}
947out:
948	splx(s);
949}
950
951/*
952 * Stop output, e.g., for ^S or output flush.
953 */
954void
955zsstop(tp, flag)
956register struct tty	*tp;
957	 int		flag;
958{
959	register struct zs_chanstate	*cs;
960	register int			s, unit = ZS_UNIT(tp->t_dev);
961		 struct zs_softc	*zi = zscd.cd_devs[unit >> 1];
962
963	cs = &zi->zi_cs[unit & 1];
964	s  = splzs();
965	if(tp->t_state & TS_BUSY) {
966		/*
967		 * Device is transmitting; must stop it.
968		 */
969		cs->cs_tbc = 0;
970		if ((tp->t_state & TS_TTSTOP) == 0)
971			tp->t_state |= TS_FLUSH;
972	}
973	splx(s);
974}
975
976/*
977 * Set ZS tty parameters from termios.
978 *
979 * This routine makes use of the fact that only registers
980 * 1, 3, 4, 5, 9, 10, 11, 12, 13, 14, and 15 are written.
981 */
982static int
983zsparam(tp, t)
984register struct tty	*tp;
985register struct termios	*t;
986{
987		 int			unit = ZS_UNIT(tp->t_dev);
988		 struct zs_softc	*zi = zscd.cd_devs[unit >> 1];
989	register struct zs_chanstate	*cs = &zi->zi_cs[unit & 1];
990		 int			cdiv, clkm, brgm, tcon;
991	register int			tmp, tmp5, cflag, s;
992
993	tmp  = t->c_ospeed;
994	tmp5 = t->c_ispeed;
995	if(tmp < 0 || (tmp5 && tmp5 != tmp))
996		return(EINVAL);
997	if(tmp == 0) {
998		/* stty 0 => drop DTR and RTS */
999		zs_modem(cs, 0, DMSET);
1000		return(0);
1001	}
1002	tmp = zsbaudrate(unit, tmp, &cdiv, &clkm, &brgm, &tcon);
1003	if (tmp < 0)
1004		return(EINVAL);
1005	tp->t_ispeed = tp->t_ospeed = tmp;
1006
1007	cflag = tp->t_cflag = t->c_cflag;
1008	if (cflag & CSTOPB)
1009		cdiv |= ZSWR4_TWOSB;
1010	else
1011		cdiv |= ZSWR4_ONESB;
1012	if (!(cflag & PARODD))
1013		cdiv |= ZSWR4_EVENP;
1014	if (cflag & PARENB)
1015		cdiv |= ZSWR4_PARENB;
1016
1017	switch(cflag & CSIZE) {
1018	case CS5:
1019		tmp  = ZSWR3_RX_5;
1020		tmp5 = ZSWR5_TX_5;
1021		break;
1022	case CS6:
1023		tmp  = ZSWR3_RX_6;
1024		tmp5 = ZSWR5_TX_6;
1025		break;
1026	case CS7:
1027		tmp  = ZSWR3_RX_7;
1028		tmp5 = ZSWR5_TX_7;
1029		break;
1030	case CS8:
1031	default:
1032		tmp  = ZSWR3_RX_8;
1033		tmp5 = ZSWR5_TX_8;
1034		break;
1035	}
1036	tmp  |= ZSWR3_RX_ENABLE;
1037	tmp5 |= ZSWR5_TX_ENABLE | ZSWR5_DTR | ZSWR5_RTS;
1038
1039	/*
1040	 * Block interrupts so that state will not
1041	 * be altered until we are done setting it up.
1042	 */
1043	s = splzs();
1044	cs->cs_preg[4]  = cdiv;
1045	cs->cs_preg[11] = clkm;
1046	cs->cs_preg[12] = tcon;
1047	cs->cs_preg[13] = tcon >> 8;
1048	cs->cs_preg[14] = brgm;
1049	cs->cs_preg[1]  = ZSWR1_RIE | ZSWR1_TIE | ZSWR1_SIE;
1050	cs->cs_preg[9]  = ZSWR9_MASTER_IE | ZSWR9_VECTOR_INCL_STAT;
1051	cs->cs_preg[10] = ZSWR10_NRZ;
1052	cs->cs_preg[15] = ZSWR15_BREAK_IE | ZSWR15_DCD_IE;
1053
1054	/*
1055	 * Output hardware flow control on the chip is horrendous: if
1056	 * carrier detect drops, the receiver is disabled.  Hence we
1057	 * can only do this when the carrier is on.
1058	 */
1059	if(cflag & CCTS_OFLOW && cs->cs_zc->zc_csr & ZSRR0_DCD)
1060		tmp |= ZSWR3_HFC;
1061	cs->cs_preg[3] = tmp;
1062	cs->cs_preg[5] = tmp5;
1063
1064	/*
1065	 * If nothing is being transmitted, set up new current values,
1066	 * else mark them as pending.
1067	 */
1068	if(cs->cs_heldchange == 0) {
1069		if (cs->cs_ttyp->t_state & TS_BUSY) {
1070			cs->cs_heldtbc = cs->cs_tbc;
1071			cs->cs_tbc = 0;
1072			cs->cs_heldchange = 1;
1073		} else {
1074			bcopy((caddr_t)cs->cs_preg, (caddr_t)cs->cs_creg, 16);
1075			zs_loadchannelregs(cs->cs_zc, cs->cs_creg);
1076		}
1077	}
1078	splx(s);
1079	return (0);
1080}
1081
1082/*
1083 * search for the best matching baudrate
1084 */
1085static int
1086zsbaudrate(unit, wanted, divisor, clockmode, brgenmode, timeconst)
1087int	unit, wanted, *divisor, *clockmode, *brgenmode, *timeconst;
1088{
1089	int	bestdiff, bestbps, source;
1090
1091	unit = (unit & 1) << 2;
1092	for (source = 0; source < 4; ++source) {
1093		long	freq = zs_frequencies[unit + source];
1094		int	diff, bps, div, clkm, brgm, tcon;
1095		switch (source) {
1096			case 0:	/* BRgen, PCLK */
1097				brgm = ZSWR14_BAUD_ENA|ZSWR14_BAUD_FROM_PCLK;
1098				break;
1099			case 1:	/* BRgen, RTxC */
1100				brgm = ZSWR14_BAUD_ENA;
1101				break;
1102			case 2: /* RTxC */
1103				clkm = ZSWR11_RXCLK_RTXC|ZSWR11_TXCLK_RTXC;
1104				break;
1105			case 3: /* TRxC */
1106				clkm = ZSWR11_RXCLK_TRXC|ZSWR11_TXCLK_TRXC;
1107				break;
1108		}
1109		switch (source) {
1110			case 0:
1111			case 1:
1112				div  = ZSWR4_CLK_X16;
1113				clkm = ZSWR11_RXCLK_BAUD|ZSWR11_TXCLK_BAUD;
1114				tcon = BPS_TO_TCONST(freq, wanted);
1115				if (tcon < 0)
1116					tcon = 0;
1117				bps  = TCONST_TO_BPS(freq, tcon);
1118				break;
1119			case 2:
1120			case 3:
1121			{	int	b1 = freq / 16, d1 = abs(b1 - wanted);
1122				int	b2 = freq / 32, d2 = abs(b2 - wanted);
1123				int	b3 = freq / 64, d3 = abs(b3 - wanted);
1124
1125				if (d1 < d2 && d1 < d3) {
1126					div = ZSWR4_CLK_X16;
1127					bps = b1;
1128				} else if (d2 < d3 && d2 < d1) {
1129					div = ZSWR4_CLK_X32;
1130					bps = b2;
1131				} else {
1132					div = ZSWR4_CLK_X64;
1133					bps = b3;
1134				}
1135				brgm = tcon = 0;
1136				break;
1137			}
1138		}
1139		diff = abs(bps - wanted);
1140		if (!source || diff < bestdiff) {
1141			*divisor   = div;
1142			*clockmode = clkm;
1143			*brgenmode = brgm;
1144			*timeconst = tcon;
1145			bestbps    = bps;
1146			bestdiff   = diff;
1147			if (diff == 0)
1148				break;
1149		}
1150	}
1151	/* Allow deviations upto 5% */
1152	if (20 * bestdiff > wanted)
1153		return -1;
1154	return bestbps;
1155}
1156
1157/*
1158 * Raise or lower modem control (DTR/RTS) signals.  If a character is
1159 * in transmission, the change is deferred.
1160 */
1161static int
1162zs_modem(cs, bits, how)
1163struct zs_chanstate	*cs;
1164int			bits, how;
1165{
1166	int s, mbits;
1167
1168	bits  &= ZSWR5_DTR | ZSWR5_RTS;
1169
1170	s = splzs();
1171	mbits  = cs->cs_preg[5] &  (ZSWR5_DTR | ZSWR5_RTS);
1172
1173	switch(how) {
1174		case DMSET:
1175				mbits  = bits;
1176				break;
1177		case DMBIS:
1178				mbits |= bits;
1179				break;
1180		case DMBIC:
1181				mbits &= ~bits;
1182				break;
1183		case DMGET:
1184				splx(s);
1185				return(mbits);
1186	}
1187
1188	cs->cs_preg[5] = (cs->cs_preg[5] & ~(ZSWR5_DTR | ZSWR5_RTS)) | mbits;
1189	if(cs->cs_heldchange == 0) {
1190		if(cs->cs_ttyp->t_state & TS_BUSY) {
1191			cs->cs_heldtbc = cs->cs_tbc;
1192			cs->cs_tbc = 0;
1193			cs->cs_heldchange = 1;
1194		}
1195		else {
1196			ZS_WRITE(cs->cs_zc, 5, cs->cs_creg[5]);
1197		}
1198	}
1199	splx(s);
1200	return(0);
1201}
1202
1203/*
1204 * Write the given register set to the given zs channel in the proper order.
1205 * The channel must not be transmitting at the time.  The receiver will
1206 * be disabled for the time it takes to write all the registers.
1207 */
1208static void
1209zs_loadchannelregs(zc, reg)
1210volatile struct zschan	*zc;
1211u_char			*reg;
1212{
1213	int i;
1214
1215	zc->zc_csr = ZSM_RESET_ERR;	/* reset error condition */
1216	i = zc->zc_data;		/* drain fifo */
1217	i = zc->zc_data;
1218	i = zc->zc_data;
1219	ZS_WRITE(zc,  4, reg[4]);
1220	ZS_WRITE(zc, 10, reg[10]);
1221	ZS_WRITE(zc,  3, reg[3] & ~ZSWR3_RX_ENABLE);
1222	ZS_WRITE(zc,  5, reg[5] & ~ZSWR5_TX_ENABLE);
1223	ZS_WRITE(zc,  1, reg[1]);
1224	ZS_WRITE(zc,  9, reg[9]);
1225	ZS_WRITE(zc, 11, reg[11]);
1226	ZS_WRITE(zc, 12, reg[12]);
1227	ZS_WRITE(zc, 13, reg[13]);
1228	ZS_WRITE(zc, 14, reg[14]);
1229	ZS_WRITE(zc, 15, reg[15]);
1230	ZS_WRITE(zc,  3, reg[3]);
1231	ZS_WRITE(zc,  5, reg[5]);
1232}
1233#endif /* NZS > 1 */
1234