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