xref: /netbsd-src/sys/arch/atari/dev/zs.c (revision b1c86f5f087524e68db12794ee9c3e3da1ab17a0)
1 /*	$NetBSD: zs.c,v 1.72 2010/04/09 17:38:43 tsutsui Exp $	*/
2 
3 /*
4  * Copyright (c) 1992, 1993
5  *	The Regents of the University of California.  All rights reserved.
6  *
7  * This software was developed by the Computer Systems Engineering group
8  * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
9  * contributed to Berkeley.
10  *
11  *
12  * All advertising materials mentioning features or use of this software
13  * must display the following acknowledgement:
14  *	This product includes software developed by the University of
15  *	California, Lawrence Berkeley Laboratory.
16  *
17  * Redistribution and use in source and binary forms, with or without
18  * modification, are permitted provided that the following conditions
19  * are met:
20  * 1. Redistributions of source code must retain the above copyright
21  *    notice, this list of conditions and the following disclaimer.
22  * 2. Redistributions in binary form must reproduce the above copyright
23  *    notice, this list of conditions and the following disclaimer in the
24  *    documentation and/or other materials provided with the distribution.
25  * 3. Neither the name of the University nor the names of its contributors
26  *    may be used to endorse or promote products derived from this software
27  *    without specific prior written permission.
28  *
29  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
30  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
31  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
32  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
33  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
34  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
35  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
36  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
37  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
38  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
39  * SUCH DAMAGE.
40  *
41  *	@(#)zs.c	8.1 (Berkeley) 7/19/93
42  */
43 
44 /*-
45  * Copyright (c) 1995 The NetBSD Foundation, Inc. (Atari modifications)
46  * All rights reserved.
47  *
48  * This code is derived from software contributed to The NetBSD Foundation
49  * by Leo Weppelman.
50  *
51  * Redistribution and use in source and binary forms, with or without
52  * modification, are permitted provided that the following conditions
53  * are met:
54  * 1. Redistributions of source code must retain the above copyright
55  *    notice, this list of conditions and the following disclaimer.
56  * 2. Redistributions in binary form must reproduce the above copyright
57  *    notice, this list of conditions and the following disclaimer in the
58  *    documentation and/or other materials provided with the distribution.
59  *
60  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
61  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
62  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
63  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
64  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
65  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
66  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
67  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
68  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
69  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
70  * POSSIBILITY OF SUCH DAMAGE.
71  */
72 
73 /*
74  * Zilog Z8530 (ZSCC) driver.
75  *
76  * Runs two tty ports (modem2 and serial2) on zs0.
77  *
78  * This driver knows far too much about chip to usage mappings.
79  */
80 
81 #include <sys/cdefs.h>
82 __KERNEL_RCSID(0, "$NetBSD: zs.c,v 1.72 2010/04/09 17:38:43 tsutsui Exp $");
83 
84 #include <sys/param.h>
85 #include <sys/systm.h>
86 #include <sys/proc.h>
87 #include <sys/device.h>
88 #include <sys/conf.h>
89 #include <sys/file.h>
90 #include <sys/ioctl.h>
91 #include <sys/malloc.h>
92 #include <sys/tty.h>
93 #include <sys/time.h>
94 #include <sys/kernel.h>
95 #include <sys/syslog.h>
96 #include <sys/kauth.h>
97 
98 #include <machine/cpu.h>
99 #include <machine/iomap.h>
100 #include <machine/scu.h>
101 #include <machine/mfp.h>
102 #include <atari/dev/ym2149reg.h>
103 
104 #include <dev/ic/z8530reg.h>
105 #include <atari/dev/zsvar.h>
106 
107 #include "ioconf.h"
108 
109 #include "zs.h"
110 #if NZS > 1
111 #error "This driver supports only 1 85C30!"
112 #endif
113 
114 #if NZS > 0
115 
116 #define PCLK	(8053976)	/* PCLK pin input clock rate */
117 #define PCLK_HD	(9600 * 1536)	/* PCLK on Hades pin input clock rate */
118 
119 #define splzs	spl5
120 
121 /*
122  * Software state per found chip.
123  */
124 struct zs_softc {
125 	device_t sc_dev;		/* base device */
126 	struct zs_chanstate *sc_cs[2];	/* chan A and B software state */
127 
128 	struct zs_chanstate sc_cs_store[2];
129 	void *sc_sicookie;		/* for callback */
130 };
131 
132 /*
133  * Define the registers for a closed port
134  */
135 static uint8_t zs_init_regs[16] = {
136 /*  0 */	0,
137 /*  1 */	0,
138 /*  2 */	0x60,
139 /*  3 */	0,
140 /*  4 */	0,
141 /*  5 */	0,
142 /*  6 */	0,
143 /*  7 */	0,
144 /*  8 */	0,
145 /*  9 */	ZSWR9_MASTER_IE | ZSWR9_VECTOR_INCL_STAT,
146 /* 10 */	ZSWR10_NRZ,
147 /* 11 */	ZSWR11_TXCLK_BAUD | ZSWR11_RXCLK_BAUD,
148 /* 12 */	0,
149 /* 13 */	0,
150 /* 14 */	ZSWR14_BAUD_FROM_PCLK | ZSWR14_BAUD_ENA,
151 /* 15 */	0
152 };
153 
154 /*
155  * Define the machine dependant clock frequencies
156  * If BRgen feeds sender/receiver we always use a
157  * divisor 16, therefor the division by 16 can as
158  * well be done here.
159  */
160 static const u_long zs_freqs_tt[] = {
161 	/*
162 	 * Atari TT, RTxCB is generated by TT-MFP timer C,
163 	 * which is set to 307.2 kHz during initialisation
164 	 * and never changed afterwards.
165 	 */
166 	PCLK/16,	/* BRgen, PCLK,  divisor 16	*/
167 	 229500,	/* BRgen, RTxCA, divisor 16	*/
168 	3672000,	/* RTxCA, from PCLK4		*/
169 	      0,	/* TRxCA, external		*/
170 
171 	PCLK/16,	/* BRgen, PCLK,  divisor 16	*/
172 	  19200,	/* BRgen, RTxCB, divisor 16	*/
173 	 307200,	/* RTxCB, from TT-MFP TCO	*/
174 	2457600		/* TRxCB, from BCLK		*/
175 };
176 
177 static const u_long zs_freqs_falcon[] = {
178 	/*
179 	 * Atari Falcon, XXX no specs available, this might be wrong
180 	 */
181 	PCLK/16,	/* BRgen, PCLK,  divisor 16	*/
182 	 229500,	/* BRgen, RTxCA, divisor 16	*/
183 	3672000,	/* RTxCA, ???			*/
184 	      0,	/* TRxCA, external		*/
185 
186 	PCLK/16,	/* BRgen, PCLK,  divisor 16	*/
187 	 229500,	/* BRgen, RTxCB, divisor 16	*/
188 	3672000,	/* RTxCB, ???			*/
189 	2457600		/* TRxCB, ???			*/
190 };
191 
192 static const u_long zs_freqs_hades[] = {
193 	/*
194 	 * XXX: Channel-A unchecked!!!!!
195 	 */
196      PCLK_HD/16,	/* BRgen, PCLK,  divisor 16	*/
197 	 229500,	/* BRgen, RTxCA, divisor 16	*/
198 	3672000,	/* RTxCA, from PCLK4		*/
199 	      0,	/* TRxCA, external		*/
200 
201      PCLK_HD/16,	/* BRgen, PCLK,  divisor 16	*/
202 	 235550,	/* BRgen, RTxCB, divisor 16	*/
203 	3768800,	/* RTxCB, 3.7688MHz		*/
204 	3768800		/* TRxCB, 3.7688MHz		*/
205 };
206 
207 static const u_long zs_freqs_generic[] = {
208 	/*
209 	 * other machines, assume only PCLK is available
210 	 */
211 	PCLK/16,	/* BRgen, PCLK,  divisor 16	*/
212 	      0,	/* BRgen, RTxCA, divisor 16	*/
213 	      0,	/* RTxCA, unknown		*/
214 	      0,	/* TRxCA, unknown		*/
215 
216 	PCLK/16,	/* BRgen, PCLK,  divisor 16	*/
217 	      0,	/* BRgen, RTxCB, divisor 16	*/
218 	      0,	/* RTxCB, unknown		*/
219 	      0		/* TRxCB, unknown		*/
220 };
221 static const u_long *zs_frequencies;
222 
223 /* Definition of the driver for autoconfig. */
224 static int	zsmatch(device_t, cfdata_t, void *);
225 static void	zsattach(device_t, device_t, void *);
226 
227 CFATTACH_DECL_NEW(zs, sizeof(struct zs_softc),
228     zsmatch, zsattach, NULL, NULL);
229 
230 /* {b,c}devsw[] function prototypes */
231 dev_type_open(zsopen);
232 dev_type_close(zsclose);
233 dev_type_read(zsread);
234 dev_type_write(zswrite);
235 dev_type_ioctl(zsioctl);
236 dev_type_stop(zsstop);
237 dev_type_tty(zstty);
238 dev_type_poll(zspoll);
239 
240 const struct cdevsw zs_cdevsw = {
241 	zsopen, zsclose, zsread, zswrite, zsioctl,
242 	zsstop, zstty, zspoll, nommap, ttykqfilter, D_TTY
243 };
244 
245 /* Interrupt handlers. */
246 static int	zshard(void *);
247 static int	zssoft(void *);
248 static int	zsrint(struct zs_chanstate *, struct zschan *);
249 static int	zsxint(struct zs_chanstate *, struct zschan *);
250 static int	zssint(struct zs_chanstate *, struct zschan *);
251 
252 /* Routines called from other code. */
253 static void	zsstart(struct tty *);
254 
255 /* Routines purely local to this driver. */
256 static void	zsoverrun(int, long *, const char *);
257 static int	zsparam(struct tty *, struct termios *);
258 static int	zsbaudrate(int, int, int *, int *, int *, int *);
259 static int	zs_modem(struct zs_chanstate *, int, int);
260 static void	zs_loadchannelregs(struct zschan *, uint8_t *);
261 static void	zs_shutdown(struct zs_chanstate *);
262 
263 static int
264 zsmatch(device_t parent, cfdata_t cf, void *aux)
265 {
266 	static int zs_matched = 0;
267 
268 	if (strcmp("zs", aux) || zs_matched)
269 		return 0;
270 	zs_matched = 1;
271 	return 1;
272 }
273 
274 /*
275  * Attach a found zs.
276  */
277 static void
278 zsattach(device_t parent, device_t self, void *aux)
279 {
280 	struct zs_softc *sc;
281 	struct zsdevice *zs;
282 	struct zschan *zc;
283 	struct zs_chanstate *cs;
284 	int channel;
285 
286 	sc = device_private(self);
287 	sc->sc_dev = self;
288 
289 	printf(": serial2 on channel a and modem2 on channel b\n");
290 
291 	zs = (struct zsdevice *)AD_SCC;
292 
293 	for (channel = 0; channel < 2; channel++) {
294 		cs = &sc->sc_cs_store[channel];
295 		sc->sc_cs[channel] = cs;
296 
297 		cs->cs_unit = channel;
298 		cs->cs_zc = zc =
299 		    (channel == 0) ?  &zs->zs_chan_a : &zs->zs_chan_b;
300 		/*
301 		 * Get the command register into a known state.
302 		 */
303 		(void)zc->zc_csr;
304 		(void)zc->zc_csr;
305 
306 		/*
307 		 * Do a hardware reset.
308 		 */
309 		if (channel == 0) {
310 			ZS_WRITE(zc, 9, ZSWR9_HARD_RESET);
311 			delay(50000);	/* enough ? */
312 			ZS_WRITE(zc, 9, 0);
313 		}
314 
315 		/*
316 		 * Initialize channel
317 		 */
318 		zs_loadchannelregs(zc, zs_init_regs);
319 	}
320 
321 	if (machineid & ATARI_TT) {
322 		/*
323 		 * ininitialise TT-MFP timer C: 307200Hz
324 		 * timer C and D share one control register:
325 		 *	bits 0-2 control timer D
326 		 *	bits 4-6 control timer C
327 		 */
328 		int cr = MFP2->mf_tcdcr & 7;
329 		MFP2->mf_tcdcr = cr;		/* stop timer C  */
330 		MFP2->mf_tcdr  = 1;		/* counter 1     */
331 		cr |= T_Q004 << 4;		/* divisor 4     */
332 		MFP2->mf_tcdcr = cr;		/* start timer C */
333 		/*
334 		 * enable scc related interrupts
335 		 */
336 		SCU->vme_mask |= SCU_SCC;
337 
338 		zs_frequencies = zs_freqs_tt;
339 	} else if (machineid & ATARI_FALCON) {
340 		zs_frequencies = zs_freqs_falcon;
341 	} else if (machineid & ATARI_HADES) {
342 		zs_frequencies = zs_freqs_hades;
343 	} else {
344 		zs_frequencies = zs_freqs_generic;
345 	}
346 
347 	if (intr_establish(36, USER_VEC, 0, (hw_ifun_t)zshard, sc) == NULL)
348 		aprint_error_dev(self,
349 		    "Can't establish interrupt (Rx chan B)\n");
350 	if (intr_establish(32, USER_VEC, 0, (hw_ifun_t)zshard, sc) == NULL)
351 		aprint_error_dev(self,
352 		    "Can't establish interrupt (Tx empty chan B)\n");
353 	if (intr_establish(34, USER_VEC, 0, (hw_ifun_t)zshard, sc) == NULL)
354 		aprint_error_dev(self,
355 		    "Can't establish interrupt (Ext./Status chan B)\n");
356 	if (intr_establish(38, USER_VEC, 0, (hw_ifun_t)zshard, sc) == NULL)
357 		aprint_error_dev(self,
358 		    "Can't establish interrupt (Special Rx cond. chan B)\n");
359 	if (intr_establish(44, USER_VEC, 0, (hw_ifun_t)zshard, sc) == NULL)
360 		aprint_error_dev(self,
361 		    "Can't establish interrupt (Rx chan A)\n");
362 	if (intr_establish(40, USER_VEC, 0, (hw_ifun_t)zshard, sc) == NULL)
363 		aprint_error_dev(self,
364 		    "Can't establish interrupt (Tx empty chan A)\n");
365 	if (intr_establish(42, USER_VEC, 0, (hw_ifun_t)zshard, sc) == NULL)
366 		aprint_error_dev(self,
367 		    "Can't establish interrupt (Ext./Status chan A)\n");
368 	if (intr_establish(46, USER_VEC, 0, (hw_ifun_t)zshard, sc) == NULL)
369 		aprint_error_dev(self,
370 		    "Can't establish interrupt (Special Rx cond. chan A)\n");
371 
372 	sc->sc_sicookie = softint_establish(SOFTINT_SERIAL,
373 	    (void (*)(void *))zssoft, sc);
374 }
375 
376 /*
377  * Open a zs serial port.
378  */
379 int
380 zsopen(dev_t dev, int flags, int mode, struct lwp *l)
381 {
382 	struct tty *tp;
383 	struct zs_chanstate *cs;
384 	struct zs_softc *sc;
385 	int unit = ZS_UNIT(dev);
386 	int zs = unit >> 1;
387 	int error, s;
388 
389 	sc = device_lookup_private(&zs_cd, zs);
390 	if (sc == NULL)
391 		return ENXIO;
392 	cs = sc->sc_cs[unit & 1];
393 
394 	/*
395 	 * When port A (ser02) is selected on the TT, make sure
396 	 * the port is enabled.
397 	 */
398 	if ((machineid & ATARI_TT) && !(unit & 1))
399 		ym2149_ser2(1);
400 
401 	if (cs->cs_rbuf == NULL) {
402 		cs->cs_rbuf = malloc(ZLRB_RING_SIZE * sizeof(int), M_DEVBUF,
403 		    M_WAITOK);
404 	}
405 
406 	tp = cs->cs_ttyp;
407 	if (tp == NULL) {
408 		cs->cs_ttyp = tp = ttymalloc();
409 		tty_attach(tp);
410 		tp->t_dev   = dev;
411 		tp->t_oproc = zsstart;
412 		tp->t_param = zsparam;
413 	}
414 
415 	if (kauth_authorize_device_tty(l->l_cred, KAUTH_DEVICE_TTY_OPEN, tp))
416 		return EBUSY;
417 
418 	s  = spltty();
419 
420 	/*
421 	 * Do the following iff this is a first open.
422 	 */
423 	if ((tp->t_state & TS_ISOPEN) == 0 && tp->t_wopen == 0) {
424 		if (tp->t_ispeed == 0) {
425 			tp->t_iflag = TTYDEF_IFLAG;
426 			tp->t_oflag = TTYDEF_OFLAG;
427 			tp->t_cflag = TTYDEF_CFLAG;
428 			tp->t_lflag = TTYDEF_LFLAG;
429 			tp->t_ispeed = tp->t_ospeed = TTYDEF_SPEED;
430 		}
431 		ttychars(tp);
432 		ttsetwater(tp);
433 
434 		(void)zsparam(tp, &tp->t_termios);
435 
436 		/*
437 		 * Turn on DTR.  We must always do this, even if carrier is not
438 		 * present, because otherwise we'd have to use TIOCSDTR
439 		 * immediately after setting CLOCAL, which applications do not
440 		 * expect.  We always assert DTR while the device is open
441 		 * unless explicitly requested to deassert it.
442 		 */
443 		zs_modem(cs, ZSWR5_RTS|ZSWR5_DTR, DMSET);
444 		/* May never get a status intr. if DCD already on. -gwr */
445 		if (((cs->cs_rr0 = cs->cs_zc->zc_csr) & ZSRR0_DCD) != 0)
446 			tp->t_state |= TS_CARR_ON;
447 		if (cs->cs_softcar)
448 			tp->t_state |= TS_CARR_ON;
449 	}
450 
451 	splx(s);
452 
453 	error = ttyopen(tp, ZS_DIALOUT(dev), (flags & O_NONBLOCK));
454 	if (error)
455 		goto bad;
456 
457 	error = tp->t_linesw->l_open(dev, tp);
458 	if (error)
459 		goto bad;
460 	return 0;
461 
462 bad:
463 	if ((tp->t_state & TS_ISOPEN) == 0 && tp->t_wopen == 0) {
464 		/*
465 		 * We failed to open the device, and nobody else had it opened.
466 		 * Clean up the state as appropriate.
467 		 */
468 		zs_shutdown(cs);
469 	}
470 	return error;
471 }
472 
473 /*
474  * Close a zs serial port.
475  */
476 int
477 zsclose(dev_t dev, int flags, int mode, struct lwp *l)
478 {
479 	struct zs_chanstate *cs;
480 	struct tty *tp;
481 	struct zs_softc *sc;
482 	int unit = ZS_UNIT(dev);
483 
484 	sc = device_lookup_private(&zs_cd, unit >> 1);
485 	cs = sc->sc_cs[unit & 1];
486 	tp = cs->cs_ttyp;
487 
488 	tp->t_linesw->l_close(tp, flags);
489 	ttyclose(tp);
490 
491 	if ((tp->t_state & TS_ISOPEN) == 0 && tp->t_wopen == 0) {
492 		/*
493 		 * Although we got a last close, the device may still be in
494 		 * use; e.g. if this was the dialout node, and there are still
495 		 * processes waiting for carrier on the non-dialout node.
496 		 */
497 		zs_shutdown(cs);
498 	}
499 	return 0;
500 }
501 
502 /*
503  * Read/write zs serial port.
504  */
505 int
506 zsread(dev_t dev, struct uio *uio, int flags)
507 {
508 	struct zs_chanstate *cs;
509 	struct zs_softc *sc;
510 	struct tty *tp;
511 	int unit;
512 
513 	unit = ZS_UNIT(dev);
514 	sc   = device_lookup_private(&zs_cd, unit >> 1);
515 	cs   = sc->sc_cs[unit & 1];
516 	tp   = cs->cs_ttyp;
517 
518 	return (*tp->t_linesw->l_read)(tp, uio, flags);
519 }
520 
521 int
522 zswrite(dev_t dev, struct uio *uio, int flags)
523 {
524 	struct zs_chanstate *cs;
525 	struct zs_softc *sc;
526 	struct tty *tp;
527 	int unit;
528 
529 	unit = ZS_UNIT(dev);
530 	sc   = device_lookup_private(&zs_cd, unit >> 1);
531 	cs   = sc->sc_cs[unit & 1];
532 	tp   = cs->cs_ttyp;
533 
534 	return (*tp->t_linesw->l_write)(tp, uio, flags);
535 }
536 
537 int
538 zspoll(dev_t dev, int events, struct lwp *l)
539 {
540 	struct zs_chanstate *cs;
541 	struct zs_softc *sc;
542 	struct tty *tp;
543 	int unit;
544 
545 	unit = ZS_UNIT(dev);
546 	sc   = device_lookup_private(&zs_cd, unit >> 1);
547 	cs   = sc->sc_cs[unit & 1];
548 	tp   = cs->cs_ttyp;
549 
550 	return (*tp->t_linesw->l_poll)(tp, events, l);
551 }
552 
553 struct tty *
554 zstty(dev_t dev)
555 {
556 	struct zs_chanstate *cs;
557 	struct zs_softc *sc;
558 	int unit;
559 
560 	unit = ZS_UNIT(dev);
561 	sc   = device_lookup_private(&zs_cd, unit >> 1);
562 	cs   = sc->sc_cs[unit & 1];
563 	return cs->cs_ttyp;
564 }
565 
566 /*
567  * ZS hardware interrupt.  Scan all ZS channels.  NB: we know here that
568  * channels are kept in (A,B) pairs.
569  *
570  * Do just a little, then get out; set a software interrupt if more
571  * work is needed.
572  *
573  * We deliberately ignore the vectoring Zilog gives us, and match up
574  * only the number of `reset interrupt under service' operations, not
575  * the order.
576  */
577 
578 int
579 zshard(void *arg)
580 {
581 	struct zs_softc *sc;
582 	struct zs_chanstate *cs0, *cs1;
583 	struct zschan *zc;
584 	int intflags, v, i;
585 	uint8_t rr3;
586 
587 	sc = arg;
588 	intflags = 0;
589 	cs0 = sc->sc_cs[0];
590 	cs1 = sc->sc_cs[1];
591 
592 	do {
593 		intflags &= ~4;
594 		rr3 = ZS_READ(cs0->cs_zc, 3);
595 		if (rr3 & (ZSRR3_IP_A_RX | ZSRR3_IP_A_TX | ZSRR3_IP_A_STAT)) {
596 			intflags |= 4 | 2;
597 			zc = cs0->cs_zc;
598 			i  = cs0->cs_rbput;
599 			if ((rr3 & ZSRR3_IP_A_RX) != 0 &&
600 			    (v = zsrint(cs0, zc)) != 0) {
601 				cs0->cs_rbuf[i++ & ZLRB_RING_MASK] = v;
602 				intflags |= 1;
603 			}
604 			if ((rr3 & ZSRR3_IP_A_TX) != 0 &&
605 			    (v = zsxint(cs0, zc)) != 0) {
606 				cs0->cs_rbuf[i++ & ZLRB_RING_MASK] = v;
607 				intflags |= 1;
608 			}
609 			if ((rr3 & ZSRR3_IP_A_STAT) != 0 &&
610 			    (v = zssint(cs0, zc)) != 0) {
611 				cs0->cs_rbuf[i++ & ZLRB_RING_MASK] = v;
612 				intflags |= 1;
613 			}
614 			cs0->cs_rbput = i;
615 		}
616 		if (rr3 & (ZSRR3_IP_B_RX | ZSRR3_IP_B_TX | ZSRR3_IP_B_STAT)) {
617 			intflags |= 4 | 2;
618 			zc = cs1->cs_zc;
619 			i  = cs1->cs_rbput;
620 			if ((rr3 & ZSRR3_IP_B_RX) != 0 &&
621 			    (v = zsrint(cs1, zc)) != 0) {
622 				cs1->cs_rbuf[i++ & ZLRB_RING_MASK] = v;
623 				intflags |= 1;
624 			}
625 			if ((rr3 & ZSRR3_IP_B_TX) != 0 &&
626 			    (v = zsxint(cs1, zc)) != 0) {
627 				cs1->cs_rbuf[i++ & ZLRB_RING_MASK] = v;
628 				intflags |= 1;
629 			}
630 			if ((rr3 & ZSRR3_IP_B_STAT) != 0 &&
631 			    (v = zssint(cs1, zc)) != 0) {
632 				cs1->cs_rbuf[i++ & ZLRB_RING_MASK] = v;
633 				intflags |= 1;
634 			}
635 			cs1->cs_rbput = i;
636 		}
637 	} while (intflags & 4);
638 
639 	if (intflags & 1)
640 		softint_schedule(sc->sc_sicookie);
641 
642 	return intflags & 2;
643 }
644 
645 static int
646 zsrint(struct zs_chanstate *cs, struct zschan *zc)
647 {
648 	int c;
649 
650 	/*
651 	 * First read the status, because read of the received char
652 	 * destroy the status of this char.
653 	 */
654 	c = ZS_READ(zc, 1);
655 	c |= (zc->zc_data << 8);
656 
657 	/* clear receive error & interrupt condition */
658 	zc->zc_csr = ZSWR0_RESET_ERRORS;
659 	zc->zc_csr = ZSWR0_CLR_INTR;
660 
661 	return ZRING_MAKE(ZRING_RINT, c);
662 }
663 
664 static int
665 zsxint(struct zs_chanstate *cs, struct zschan *zc)
666 {
667 	int i = cs->cs_tbc;
668 
669 	if (i == 0) {
670 		zc->zc_csr = ZSWR0_RESET_TXINT;
671 		zc->zc_csr = ZSWR0_CLR_INTR;
672 		return ZRING_MAKE(ZRING_XINT, 0);
673 	}
674 	cs->cs_tbc = i - 1;
675 	zc->zc_data = *cs->cs_tba++;
676 	zc->zc_csr = ZSWR0_CLR_INTR;
677 	return 0;
678 }
679 
680 static int
681 zssint(struct zs_chanstate *cs, struct zschan *zc)
682 {
683 	int rr0;
684 
685 	rr0 = zc->zc_csr;
686 	zc->zc_csr = ZSWR0_RESET_STATUS;
687 	zc->zc_csr = ZSWR0_CLR_INTR;
688 	/*
689 	 * The chip's hardware flow control is, as noted in zsreg.h,
690 	 * busted---if the DCD line goes low the chip shuts off the
691 	 * receiver (!).  If we want hardware CTS flow control but do
692 	 * not have it, and carrier is now on, turn HFC on; if we have
693 	 * HFC now but carrier has gone low, turn it off.
694 	 */
695 	if (rr0 & ZSRR0_DCD) {
696 		if (cs->cs_ttyp->t_cflag & CCTS_OFLOW &&
697 		    (cs->cs_creg[3] & ZSWR3_HFC) == 0) {
698 			cs->cs_creg[3] |= ZSWR3_HFC;
699 			ZS_WRITE(zc, 3, cs->cs_creg[3]);
700 		}
701 	} else {
702 		if (cs->cs_creg[3] & ZSWR3_HFC) {
703 			cs->cs_creg[3] &= ~ZSWR3_HFC;
704 			ZS_WRITE(zc, 3, cs->cs_creg[3]);
705 		}
706 	}
707 	return ZRING_MAKE(ZRING_SINT, rr0);
708 }
709 
710 /*
711  * Print out a ring or fifo overrun error message.
712  */
713 static void
714 zsoverrun(int unit, long *ptime, const char *what)
715 {
716 	time_t cur_sec = time_second;
717 
718 	if (*ptime != cur_sec) {
719 		*ptime = cur_sec;
720 		log(LOG_WARNING, "zs%d%c: %s overrun\n", unit >> 1,
721 		    (unit & 1) + 'a', what);
722 	}
723 }
724 
725 /*
726  * ZS software interrupt.  Scan all channels for deferred interrupts.
727  */
728 int
729 zssoft(void *arg)
730 {
731 	struct zs_softc *sc;
732 	struct zs_chanstate *cs;
733 	struct zschan *zc;
734 	struct linesw *line;
735 	struct tty *tp;
736 	int chan, get, n, c, cc, s;
737 	int retval = 0;
738 
739 	sc = arg;
740 	s = spltty();
741 	for (chan = 0; chan < 2; chan++) {
742 		cs = sc->sc_cs[chan];
743 		get = cs->cs_rbget;
744 again:
745 		n = cs->cs_rbput;	/* atomic			*/
746 		if (get == n)		/* nothing more on this line	*/
747 			continue;
748 		retval = 1;
749 		zc     = cs->cs_zc;
750 		tp     = cs->cs_ttyp;
751 		line   = tp->t_linesw;
752 		/*
753 		 * Compute the number of interrupts in the receive ring.
754 		 * If the count is overlarge, we lost some events, and
755 		 * must advance to the first valid one.  It may get
756 		 * overwritten if more data are arriving, but this is
757 		 * too expensive to check and gains nothing (we already
758 		 * lost out; all we can do at this point is trade one
759 		 * kind of loss for another).
760 		 */
761 		n -= get;
762 		if (n > ZLRB_RING_SIZE) {
763 			zsoverrun(chan, &cs->cs_rotime, "ring");
764 			get += n - ZLRB_RING_SIZE;
765 			n    = ZLRB_RING_SIZE;
766 		}
767 		while (--n >= 0) {
768 			/* race to keep ahead of incoming interrupts */
769 			c = cs->cs_rbuf[get++ & ZLRB_RING_MASK];
770 			switch (ZRING_TYPE(c)) {
771 
772 			case ZRING_RINT:
773 				c = ZRING_VALUE(c);
774 				if ((c & ZSRR1_DO) != 0)
775 					zsoverrun(chan, &cs->cs_fotime, "fifo");
776 				cc = c >> 8;
777 				if ((c & ZSRR1_FE) != 0)
778 					cc |= TTY_FE;
779 				if ((c & ZSRR1_PE) != 0)
780 					cc |= TTY_PE;
781 				line->l_rint(cc, tp);
782 				break;
783 
784 			case ZRING_XINT:
785 				/*
786 				 * Transmit done: change registers and resume,
787 				 * or clear BUSY.
788 				 */
789 				if (cs->cs_heldchange) {
790 					int sps;
791 
792 					sps = splzs();
793 					c = zc->zc_csr;
794 					if ((c & ZSRR0_DCD) == 0)
795 						cs->cs_preg[3] &= ~ZSWR3_HFC;
796 					memcpy((void *)cs->cs_creg,
797 					    (void *)cs->cs_preg, 16);
798 					zs_loadchannelregs(zc, cs->cs_creg);
799 					splx(sps);
800 					cs->cs_heldchange = 0;
801 					if (cs->cs_heldtbc &&
802 					    (tp->t_state & TS_TTSTOP) == 0) {
803 						cs->cs_tbc = cs->cs_heldtbc - 1;
804 						zc->zc_data = *cs->cs_tba++;
805 						goto again;
806 					}
807 				}
808 				tp->t_state &= ~TS_BUSY;
809 				if ((tp->t_state & TS_FLUSH) != 0)
810 					tp->t_state &= ~TS_FLUSH;
811 				else
812 					ndflush(&tp->t_outq,
813 					    cs->cs_tba - tp->t_outq.c_cf);
814 				line->l_start(tp);
815 				break;
816 
817 			case ZRING_SINT:
818 				/*
819 				 * Status line change.  HFC bit is run in
820 				 * hardware interrupt, to avoid locking
821 				 * at splzs here.
822 				 */
823 				c = ZRING_VALUE(c);
824 				if (((c ^ cs->cs_rr0) & ZSRR0_DCD) != 0) {
825 					cc = (c & ZSRR0_DCD) != 0;
826 					if (line->l_modem(tp, cc) == 0)
827 						zs_modem(cs,
828 						    ZSWR5_RTS | ZSWR5_DTR,
829 						    cc ? DMBIS : DMBIC);
830 				}
831 				cs->cs_rr0 = c;
832 				break;
833 
834 			default:
835 				log(LOG_ERR, "zs%d%c: bad ZRING_TYPE (%x)\n",
836 				    chan >> 1, (chan & 1) + 'a', c);
837 				break;
838 			}
839 		}
840 		cs->cs_rbget = get;
841 		goto again;
842 	}
843 	splx(s);
844 	return retval;
845 }
846 
847 int
848 zsioctl(dev_t dev, u_long cmd, void * data, int flag, struct lwp *l)
849 {
850 	int unit = ZS_UNIT(dev);
851 	struct zs_softc *sc = device_lookup_private(&zs_cd, unit >> 1);
852 	struct zs_chanstate *cs = sc->sc_cs[unit & 1];
853 	struct tty *tp = cs->cs_ttyp;
854 	int error, s;
855 
856 	error = tp->t_linesw->l_ioctl(tp, cmd, data, flag, l);
857 	if (error != EPASSTHROUGH)
858 		return error;
859 
860 	error = ttioctl(tp, cmd, data, flag, l);
861 	if (error !=EPASSTHROUGH)
862 		return error;
863 
864 	switch (cmd) {
865 	case TIOCSBRK:
866 		s = splzs();
867 		cs->cs_preg[5] |= ZSWR5_BREAK;
868 		cs->cs_creg[5] |= ZSWR5_BREAK;
869 		ZS_WRITE(cs->cs_zc, 5, cs->cs_creg[5]);
870 		splx(s);
871 		break;
872 	case TIOCCBRK:
873 		s = splzs();
874 		cs->cs_preg[5] &= ~ZSWR5_BREAK;
875 		cs->cs_creg[5] &= ~ZSWR5_BREAK;
876 		ZS_WRITE(cs->cs_zc, 5, cs->cs_creg[5]);
877 		splx(s);
878 		break;
879 	case TIOCGFLAGS: {
880 		int bits = 0;
881 
882 		if (cs->cs_softcar)
883 			bits |= TIOCFLAG_SOFTCAR;
884 		if ((cs->cs_creg[15] & ZSWR15_DCD_IE) != 0)
885 			bits |= TIOCFLAG_CLOCAL;
886 		if ((cs->cs_creg[3] & ZSWR3_HFC) != 0)
887 			bits |= TIOCFLAG_CRTSCTS;
888 		*(int *)data = bits;
889 		break;
890 	}
891 	case TIOCSFLAGS: {
892 		int userbits = 0;
893 
894 		error = kauth_authorize_device_tty(l->l_cred,
895 		    KAUTH_DEVICE_TTY_PRIVSET, tp);
896 		if (error != 0)
897 			return EPERM;
898 
899 		userbits = *(int *)data;
900 
901 		/*
902 		 * can have `local' or `softcar', and `rtscts' or `mdmbuf'
903 		 # defaulting to software flow control.
904 		 */
905 		if ((userbits & TIOCFLAG_SOFTCAR) != 0 &&
906 		    (userbits & TIOCFLAG_CLOCAL) != 0)
907 			return EINVAL;
908 		if ((userbits & TIOCFLAG_MDMBUF) != 0)
909 			/* don't support this (yet?) */
910 			return ENODEV;
911 
912 		s = splzs();
913 		if ((userbits & TIOCFLAG_SOFTCAR) != 0) {
914 			cs->cs_softcar = 1;	/* turn on softcar */
915 			cs->cs_preg[15] &= ~ZSWR15_DCD_IE; /* turn off dcd */
916 			cs->cs_creg[15] &= ~ZSWR15_DCD_IE;
917 			ZS_WRITE(cs->cs_zc, 15, cs->cs_creg[15]);
918 		} else if ((userbits & TIOCFLAG_CLOCAL) != 0) {
919 			cs->cs_softcar = 0; 	/* turn off softcar */
920 			cs->cs_preg[15] |= ZSWR15_DCD_IE; /* turn on dcd */
921 			cs->cs_creg[15] |= ZSWR15_DCD_IE;
922 			ZS_WRITE(cs->cs_zc, 15, cs->cs_creg[15]);
923 			tp->t_termios.c_cflag |= CLOCAL;
924 		}
925 		if ((userbits & TIOCFLAG_CRTSCTS) != 0) {
926 			cs->cs_preg[15] |= ZSWR15_CTS_IE;
927 			cs->cs_creg[15] |= ZSWR15_CTS_IE;
928 			ZS_WRITE(cs->cs_zc, 15, cs->cs_creg[15]);
929 			cs->cs_preg[3] |= ZSWR3_HFC;
930 			cs->cs_creg[3] |= ZSWR3_HFC;
931 			ZS_WRITE(cs->cs_zc, 3, cs->cs_creg[3]);
932 			tp->t_termios.c_cflag |= CRTSCTS;
933 		} else {
934 			/* no mdmbuf, so we must want software flow control */
935 			cs->cs_preg[15] &= ~ZSWR15_CTS_IE;
936 			cs->cs_creg[15] &= ~ZSWR15_CTS_IE;
937 			ZS_WRITE(cs->cs_zc, 15, cs->cs_creg[15]);
938 			cs->cs_preg[3] &= ~ZSWR3_HFC;
939 			cs->cs_creg[3] &= ~ZSWR3_HFC;
940 			ZS_WRITE(cs->cs_zc, 3, cs->cs_creg[3]);
941 			tp->t_termios.c_cflag &= ~CRTSCTS;
942 		}
943 		splx(s);
944 		break;
945 	}
946 	case TIOCSDTR:
947 		zs_modem(cs, ZSWR5_DTR, DMBIS);
948 		break;
949 	case TIOCCDTR:
950 		zs_modem(cs, ZSWR5_DTR, DMBIC);
951 		break;
952 	case TIOCMGET:
953 		zs_modem(cs, 0, DMGET);
954 		break;
955 	case TIOCMSET:
956 	case TIOCMBIS:
957 	case TIOCMBIC:
958 	default:
959 		return EPASSTHROUGH;
960 	}
961 	return 0;
962 }
963 
964 /*
965  * Start or restart transmission.
966  */
967 static void
968 zsstart(struct tty *tp)
969 {
970 	struct zs_chanstate *cs;
971 	int s, nch;
972 	int unit = ZS_UNIT(tp->t_dev);
973 	struct zs_softc *sc = device_lookup_private(&zs_cd, unit >> 1);
974 
975 	cs = sc->sc_cs[unit & 1];
976 	s  = spltty();
977 
978 	/*
979 	 * If currently active or delaying, no need to do anything.
980 	 */
981 	if ((tp->t_state & (TS_TIMEOUT | TS_BUSY | TS_TTSTOP)) != 0)
982 		goto out;
983 
984 	/*
985 	 * If there are sleepers, and output has drained below low
986 	 * water mark, awaken.
987 	 */
988 	ttypull(tp);
989 
990 	nch = ndqb(&tp->t_outq, 0);	/* XXX */
991 	if (nch) {
992 		char *p = tp->t_outq.c_cf;
993 
994 		/* mark busy, enable tx done interrupts, & send first byte */
995 		tp->t_state |= TS_BUSY;
996 		(void)splzs();
997 		cs->cs_preg[1] |= ZSWR1_TIE;
998 		cs->cs_creg[1] |= ZSWR1_TIE;
999 		ZS_WRITE(cs->cs_zc, 1, cs->cs_creg[1]);
1000 		cs->cs_zc->zc_data = *p;
1001 		cs->cs_tba = p + 1;
1002 		cs->cs_tbc = nch - 1;
1003 	} else {
1004 		/*
1005 		 * Nothing to send, turn off transmit done interrupts.
1006 		 * This is useful if something is doing polled output.
1007 		 */
1008 		(void)splzs();
1009 		cs->cs_preg[1] &= ~ZSWR1_TIE;
1010 		cs->cs_creg[1] &= ~ZSWR1_TIE;
1011 		ZS_WRITE(cs->cs_zc, 1, cs->cs_creg[1]);
1012 	}
1013 out:
1014 	splx(s);
1015 }
1016 
1017 /*
1018  * Stop output, e.g., for ^S or output flush.
1019  */
1020 void
1021 zsstop(struct tty *tp, int flag)
1022 {
1023 	struct zs_chanstate *cs;
1024 	int s, unit = ZS_UNIT(tp->t_dev);
1025 	struct zs_softc *sc = device_lookup_private(&zs_cd, unit >> 1);
1026 
1027 	cs = sc->sc_cs[unit & 1];
1028 	s  = splzs();
1029 	if ((tp->t_state & TS_BUSY) != 0) {
1030 		/*
1031 		 * Device is transmitting; must stop it.
1032 		 */
1033 		cs->cs_tbc = 0;
1034 		if ((tp->t_state & TS_TTSTOP) == 0)
1035 			tp->t_state |= TS_FLUSH;
1036 	}
1037 	splx(s);
1038 }
1039 
1040 static void
1041 zs_shutdown(struct zs_chanstate *cs)
1042 {
1043 	struct tty *tp = cs->cs_ttyp;
1044 	int s;
1045 
1046 	s = splzs();
1047 
1048 	/*
1049 	 * Hang up if necessary.  Wait a bit, so the other side has time to
1050 	 * notice even if we immediately open the port again.
1051 	 */
1052 	if ((tp->t_cflag & HUPCL) != 0) {
1053 		zs_modem(cs, 0, DMSET);
1054 		(void)tsleep((void *)cs, TTIPRI, ttclos, hz);
1055 	}
1056 
1057 	/* Clear any break condition set with TIOCSBRK. */
1058 	if ((cs->cs_creg[5] & ZSWR5_BREAK) != 0) {
1059 		cs->cs_preg[5] &= ~ZSWR5_BREAK;
1060 		cs->cs_creg[5] &= ~ZSWR5_BREAK;
1061 		ZS_WRITE(cs->cs_zc, 5, cs->cs_creg[5]);
1062 	}
1063 
1064 	/*
1065 	 * Drop all lines and cancel interrupts
1066 	 */
1067 	zs_loadchannelregs(cs->cs_zc, zs_init_regs);
1068 	splx(s);
1069 }
1070 
1071 /*
1072  * Set ZS tty parameters from termios.
1073  *
1074  * This routine makes use of the fact that only registers
1075  * 1, 3, 4, 5, 9, 10, 11, 12, 13, 14, and 15 are written.
1076  */
1077 static int
1078 zsparam(struct tty *tp, struct termios *t)
1079 {
1080 	int unit = ZS_UNIT(tp->t_dev);
1081 	struct zs_softc *sc = device_lookup_private(&zs_cd, unit >> 1);
1082 	struct zs_chanstate *cs = sc->sc_cs[unit & 1];
1083 	int cdiv = 0;	/* XXX gcc4 -Wuninitialized */
1084 	int clkm = 0;	/* XXX gcc4 -Wuninitialized */
1085 	int brgm = 0;	/* XXX gcc4 -Wuninitialized */
1086 	int tcon = 0;	/* XXX gcc4 -Wuninitialized */
1087 	int tmp, tmp5, cflag, s;
1088 
1089 	tmp  = t->c_ospeed;
1090 	tmp5 = t->c_ispeed;
1091 	if (tmp < 0 || (tmp5 && tmp5 != tmp))
1092 		return EINVAL;
1093 	if (tmp == 0) {
1094 		/* stty 0 => drop DTR and RTS */
1095 		zs_modem(cs, 0, DMSET);
1096 		return 0;
1097 	}
1098 	tmp = zsbaudrate(unit, tmp, &cdiv, &clkm, &brgm, &tcon);
1099 	if (tmp < 0)
1100 		return EINVAL;
1101 	tp->t_ispeed = tp->t_ospeed = tmp;
1102 
1103 	cflag = tp->t_cflag = t->c_cflag;
1104 	if ((cflag & CSTOPB) != 0)
1105 		cdiv |= ZSWR4_TWOSB;
1106 	else
1107 		cdiv |= ZSWR4_ONESB;
1108 	if ((cflag & PARODD) == 0)
1109 		cdiv |= ZSWR4_EVENP;
1110 	if ((cflag & PARENB) != 0)
1111 		cdiv |= ZSWR4_PARENB;
1112 
1113 	switch (cflag & CSIZE) {
1114 	case CS5:
1115 		tmp  = ZSWR3_RX_5;
1116 		tmp5 = ZSWR5_TX_5;
1117 		break;
1118 	case CS6:
1119 		tmp  = ZSWR3_RX_6;
1120 		tmp5 = ZSWR5_TX_6;
1121 		break;
1122 	case CS7:
1123 		tmp  = ZSWR3_RX_7;
1124 		tmp5 = ZSWR5_TX_7;
1125 		break;
1126 	case CS8:
1127 	default:
1128 		tmp  = ZSWR3_RX_8;
1129 		tmp5 = ZSWR5_TX_8;
1130 		break;
1131 	}
1132 	tmp  |= ZSWR3_RX_ENABLE;
1133 	tmp5 |= ZSWR5_TX_ENABLE | ZSWR5_DTR | ZSWR5_RTS;
1134 
1135 	/*
1136 	 * Block interrupts so that state will not
1137 	 * be altered until we are done setting it up.
1138 	 */
1139 	s = splzs();
1140 	cs->cs_preg[4]  = cdiv;
1141 	cs->cs_preg[11] = clkm;
1142 	cs->cs_preg[12] = tcon;
1143 	cs->cs_preg[13] = tcon >> 8;
1144 	cs->cs_preg[14] = brgm;
1145 	cs->cs_preg[1]  = ZSWR1_RIE | ZSWR1_TIE | ZSWR1_SIE;
1146 	cs->cs_preg[9]  = ZSWR9_MASTER_IE | ZSWR9_VECTOR_INCL_STAT;
1147 	cs->cs_preg[10] = ZSWR10_NRZ;
1148 	cs->cs_preg[15] = ZSWR15_BREAK_IE | ZSWR15_DCD_IE;
1149 
1150 	/*
1151 	 * Output hardware flow control on the chip is horrendous: if
1152 	 * carrier detect drops, the receiver is disabled.  Hence we
1153 	 * can only do this when the carrier is on.
1154 	 */
1155 	if ((cflag & CCTS_OFLOW) != 0 &&
1156 	    (cs->cs_zc->zc_csr & ZSRR0_DCD) != 0)
1157 		tmp |= ZSWR3_HFC;
1158 	cs->cs_preg[3] = tmp;
1159 	cs->cs_preg[5] = tmp5;
1160 
1161 	/*
1162 	 * If nothing is being transmitted, set up new current values,
1163 	 * else mark them as pending.
1164 	 */
1165 	if (cs->cs_heldchange == 0) {
1166 		if ((cs->cs_ttyp->t_state & TS_BUSY) != 0) {
1167 			cs->cs_heldtbc = cs->cs_tbc;
1168 			cs->cs_tbc = 0;
1169 			cs->cs_heldchange = 1;
1170 		} else {
1171 			memcpy((void *)cs->cs_creg, (void *)cs->cs_preg, 16);
1172 			zs_loadchannelregs(cs->cs_zc, cs->cs_creg);
1173 		}
1174 	}
1175 	splx(s);
1176 	return 0;
1177 }
1178 
1179 /*
1180  * search for the best matching baudrate
1181  */
1182 static int
1183 zsbaudrate(int unit, int wanted, int *divisor, int *clockmode, int *brgenmode,
1184     int *timeconst)
1185 {
1186 	int bestdiff, bestbps, source;
1187 
1188 	bestdiff = bestbps = 0;
1189 	unit = (unit & 1) << 2;
1190 	for (source = 0; source < 4; ++source) {
1191 		u_long freq = zs_frequencies[unit + source];
1192 		int diff, bps, div, clkm, brgm, tcon;
1193 
1194 		bps = div = clkm = brgm = tcon = 0;
1195 		switch (source) {
1196 		case 0:	/* BRgen, PCLK */
1197 			brgm = ZSWR14_BAUD_ENA|ZSWR14_BAUD_FROM_PCLK;
1198 			break;
1199 		case 1:	/* BRgen, RTxC */
1200 			brgm = ZSWR14_BAUD_ENA;
1201 			break;
1202 		case 2: /* RTxC */
1203 			clkm = ZSWR11_RXCLK_RTXC|ZSWR11_TXCLK_RTXC;
1204 			break;
1205 		case 3: /* TRxC */
1206 			clkm = ZSWR11_RXCLK_TRXC|ZSWR11_TXCLK_TRXC;
1207 			break;
1208 		}
1209 		switch (source) {
1210 		case 0:
1211 		case 1:
1212 			div  = ZSWR4_CLK_X16;
1213 			clkm = ZSWR11_RXCLK_BAUD|ZSWR11_TXCLK_BAUD;
1214 			tcon = BPS_TO_TCONST(freq, wanted);
1215 			if (tcon < 0)
1216 				tcon = 0;
1217 			bps  = TCONST_TO_BPS(freq, tcon);
1218 			break;
1219 		case 2:
1220 		case 3:
1221 		    {
1222 			int b1 = freq / 16, d1 = abs(b1 - wanted);
1223 			int b2 = freq / 32, d2 = abs(b2 - wanted);
1224 			int b3 = freq / 64, d3 = abs(b3 - wanted);
1225 
1226 			if (d1 < d2 && d1 < d3) {
1227 				div = ZSWR4_CLK_X16;
1228 				bps = b1;
1229 			} else if (d2 < d3 && d2 < d1) {
1230 				div = ZSWR4_CLK_X32;
1231 				bps = b2;
1232 			} else {
1233 				div = ZSWR4_CLK_X64;
1234 				bps = b3;
1235 			}
1236 			brgm = tcon = 0;
1237 			break;
1238 		    }
1239 		}
1240 		diff = abs(bps - wanted);
1241 		if (!source || diff < bestdiff) {
1242 			*divisor   = div;
1243 			*clockmode = clkm;
1244 			*brgenmode = brgm;
1245 			*timeconst = tcon;
1246 			bestbps    = bps;
1247 			bestdiff   = diff;
1248 			if (diff == 0)
1249 				break;
1250 		}
1251 	}
1252 	/* Allow deviations upto 5% */
1253 	if (20 * bestdiff > wanted)
1254 		return -1;
1255 	return bestbps;
1256 }
1257 
1258 /*
1259  * Raise or lower modem control (DTR/RTS) signals.  If a character is
1260  * in transmission, the change is deferred.
1261  */
1262 static int
1263 zs_modem(struct zs_chanstate *cs, int bits, int how)
1264 {
1265 	int s, mbits;
1266 
1267 	bits  &= ZSWR5_DTR | ZSWR5_RTS;
1268 
1269 	s = splzs();
1270 	mbits  = cs->cs_preg[5] &  (ZSWR5_DTR | ZSWR5_RTS);
1271 
1272 	switch (how) {
1273 	case DMSET:
1274 		mbits  = bits;
1275 		break;
1276 	case DMBIS:
1277 		mbits |= bits;
1278 		break;
1279 	case DMBIC:
1280 		mbits &= ~bits;
1281 		break;
1282 	case DMGET:
1283 		splx(s);
1284 		return mbits;
1285 	}
1286 
1287 	cs->cs_preg[5] = (cs->cs_preg[5] & ~(ZSWR5_DTR | ZSWR5_RTS)) | mbits;
1288 	if (cs->cs_heldchange == 0) {
1289 		if ((cs->cs_ttyp->t_state & TS_BUSY) != 0) {
1290 			cs->cs_heldtbc = cs->cs_tbc;
1291 			cs->cs_tbc = 0;
1292 			cs->cs_heldchange = 1;
1293 		} else {
1294 			ZS_WRITE(cs->cs_zc, 5, cs->cs_creg[5]);
1295 		}
1296 	}
1297 	splx(s);
1298 	return 0;
1299 }
1300 
1301 /*
1302  * Write the given register set to the given zs channel in the proper order.
1303  * The channel must not be transmitting at the time.  The receiver will
1304  * be disabled for the time it takes to write all the registers.
1305  */
1306 static void
1307 zs_loadchannelregs(struct zschan *zc, uint8_t *reg)
1308 {
1309 	int i;
1310 
1311 	zc->zc_csr = ZSM_RESET_ERR;	/* reset error condition */
1312 	i = zc->zc_data;		/* drain fifo */
1313 	i = zc->zc_data;
1314 	i = zc->zc_data;
1315 	ZS_WRITE(zc,  4, reg[4]);
1316 	ZS_WRITE(zc, 10, reg[10]);
1317 	ZS_WRITE(zc,  3, reg[3] & ~ZSWR3_RX_ENABLE);
1318 	ZS_WRITE(zc,  5, reg[5] & ~ZSWR5_TX_ENABLE);
1319 	ZS_WRITE(zc,  1, reg[1]);
1320 	ZS_WRITE(zc,  9, reg[9]);
1321 	ZS_WRITE(zc, 11, reg[11]);
1322 	ZS_WRITE(zc, 12, reg[12]);
1323 	ZS_WRITE(zc, 13, reg[13]);
1324 	ZS_WRITE(zc, 14, reg[14]);
1325 	ZS_WRITE(zc, 15, reg[15]);
1326 	ZS_WRITE(zc,  3, reg[3]);
1327 	ZS_WRITE(zc,  5, reg[5]);
1328 }
1329 #endif /* NZS > 1 */
1330