xref: /illumos-gate/usr/src/uts/sun/io/zs_async.c (revision dd72704bd9e794056c558153663c739e2012d721)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21 /*
22  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
23  * Use is subject to license terms.
24  * Copyright (c) 2016 by Delphix. All rights reserved.
25  * Copyright (c) 2019 Peter Tribble.
26  */
27 
28 /*
29  *	Asynchronous protocol handler for Z8530 chips
30  *	Handles normal UNIX support for terminals & modems
31  */
32 
33 #include <sys/types.h>
34 #include <sys/param.h>
35 #include <sys/systm.h>
36 #include <sys/sysmacros.h>
37 #include <sys/signal.h>
38 #include <sys/kmem.h>
39 #include <sys/termios.h>
40 #include <sys/stropts.h>
41 #include <sys/stream.h>
42 #include <sys/strsun.h>
43 #include <sys/tty.h>
44 #include <sys/ptyvar.h>
45 #include <sys/cred.h>
46 #include <sys/user.h>
47 #include <sys/proc.h>
48 #include <sys/file.h>
49 #include <sys/uio.h>
50 #include <sys/buf.h>
51 #include <sys/mkdev.h>
52 #include <sys/cmn_err.h>
53 #include <sys/strtty.h>
54 #include <sys/consdev.h>
55 #include <sys/zsdev.h>
56 #include <sys/ser_async.h>
57 #include <sys/debug.h>
58 #include <sys/kbio.h>
59 #include <sys/conf.h>
60 #include <sys/ddi.h>
61 #include <sys/sunddi.h>
62 #include <sys/promif.h>
63 #include <sys/policy.h>
64 
65 /*
66  * PPS (Pulse Per Second) support.
67  */
68 extern void ddi_hardpps(struct timeval *, int);
69 static struct ppsclockev ppsclockev;
70 
71 #ifdef PPSCLOCKLED
72 /* XXX Use these to observe PPS latencies and jitter on a scope */
73 #define	LED_ON
74 #define	LED_OFF
75 #else
76 #define	LED_ON
77 #define	LED_OFF
78 #endif
79 
80 #define	ZSA_RCV_SIZE	64
81 #define	ZA_KICK_RCV_COUNT	3
82 #define	ZSA_GRACE_MIN_FLOW_CONTROL	5
83 #define	ZSA_GRACE_MAX_FLOW_CONTROL	20
84 
85 int zsasoftdtr = 0;	/* if nonzero, softcarrier raises dtr at attach */
86 int zsb134_weird = 0;	/* if set, old weird B134 behavior */
87 int g_zsticks = 0;	/* if set, becomes the global zsticks value */
88 int g_nocluster = 0;	/* if set, disables clustering of received data */
89 
90 unsigned int zsa_rstandby = ZSA_MIN_RSTANDBY;
91 unsigned int zsa_rdone = ZSA_RDONE_MIN;
92 unsigned int zsa_grace_flow_control = ZSA_GRACE_MIN_FLOW_CONTROL;
93 
94 
95 #define	NSPEED	18	/* max # of speeds */
96 ushort_t zs_speeds[NSPEED] = {
97 	0,
98 	ZSPEED(50),	/* 1 */
99 	ZSPEED(75),	/* 2 */
100 	ZSPEED(110),	/* 3 */
101 #ifdef lint
102 	ZSPEED(134),	/* 4 */
103 #else
104 	ZSPEED(269/2),			/* XXX - This is sleazy */
105 #endif
106 	ZSPEED(150),	/* 5 */
107 	ZSPEED(200),	/* 6 */
108 	ZSPEED(300),	/* 7 */
109 	ZSPEED(600),	/* 8 */
110 	ZSPEED(1200),	/* 9 */
111 	ZSPEED(1800),	/* 10 */
112 	ZSPEED(2400),	/* 11 */
113 	ZSPEED(4800),	/* 12 */
114 	ZSPEED(9600),	/* 13 */
115 	ZSPEED(19200),	/* 14 */
116 	ZSPEED(38400),	/* 15 */
117 	ZSPEED(57680),	/* 16 */
118 	ZSPEED(76800)	/* 17 */
119 };
120 
121 ushort_t zsticks[NSPEED] = {
122 	3,		/* 0 */
123 	3,		/* 1 */
124 	3,		/* 2 */
125 	3,		/* 3 */
126 	3,		/* 4 */
127 	3,		/* 5 */
128 	3,		/* 6 */
129 	3,		/* 7 */
130 	3,		/* 8 */
131 	3,		/* 9 */
132 	3,		/* 10 */
133 	3,		/* 11 */
134 	3,		/* 12 */
135 	3,		/* 13 */
136 	2,		/* 14 */
137 	1,		/* 15 */
138 	1,		/* 16 */
139 	1		/* 17 */
140 };
141 
142 #define	ztdelay(nsp)	(zsdelay[(nsp)]*(hz/100))
143 
144 ushort_t zsdelay[NSPEED] = {
145 	0,
146 	ZDELAY(50),	/* 1 */
147 	ZDELAY(75),	/* 2 */
148 	ZDELAY(110),    /* 3 */
149 #ifdef lint
150 	ZDELAY(134),    /* 4 */
151 #else
152 	ZDELAY(269/2),
153 #endif
154 	ZDELAY(150),    /* 5 */
155 	ZDELAY(200),    /* 6 */
156 	ZDELAY(300),    /* 7 */
157 	ZDELAY(600),    /* 8 */
158 	ZDELAY(1200),   /* 9 */
159 	ZDELAY(1800),   /* 10 */
160 	ZDELAY(2400),   /* 11 */
161 	ZDELAY(4800),   /* 12 */
162 	ZDELAY(9600),   /* 13 */
163 	ZDELAY(19200),  /* 14 */
164 	ZDELAY(38400),  /* 15 */
165 	ZDELAY(57600),  /* 16 */
166 	ZDELAY(76800)	/* 17 */
167 };
168 
169 ushort_t zslowat[NSPEED] = {
170 	3,		/* 0 */
171 	3,		/* 1 */
172 	3,		/* 2 */
173 	3,		/* 3 */
174 	3,		/* 4 */
175 	3,		/* 5 */
176 	3,		/* 6 */
177 	2,		/* 7 */
178 	2,		/* 8 */
179 	2,		/* 9 */
180 	2,		/* 10 */
181 	1,		/* 11 */
182 	1,		/* 12 */
183 	1,		/* 13 */
184 	1,		/* 14 */
185 	1,		/* 15 */
186 	1,		/* 16 */
187 	1		/* 17 */
188 };
189 
190 ushort_t zshiwat[NSPEED] = {
191 	0,		/* 0 */
192 	1,		/* 1 */
193 	1,		/* 2 */
194 	1,		/* 3 */
195 	1,		/* 4 */
196 	1,		/* 5 */
197 	1,		/* 6 */
198 	1,		/* 7 */
199 	1,		/* 8 */
200 	1,		/* 9 */
201 	1,		/* 10 */
202 	1,		/* 11 */
203 	1,		/* 12 */
204 	3,		/* 13 */
205 	3,		/* 14 */
206 	4,		/* 15 */
207 	4,		/* 16 */
208 	4		/* 17 */
209 };
210 
211 #define	SLAVIO_BUG	/* this workaround required to fix bug 1102778 */
212 
213 #define	SPEED(cflag) \
214 	((cflag) & CBAUDEXT) ? \
215 		(((cflag) & 0x1) + CBAUD + 1) : ((cflag) & CBAUD)
216 
217 /*
218  * Special macros to handle STREAMS operations.
219  * These are required to address memory leakage problems.
220  * WARNING : the macro do NOT call ZSSETSOFT
221  */
222 
223 /*
224  * Should be called holding only the adaptive (zs_excl) mutex.
225  */
226 #define	ZSA_GETBLOCK(zs, allocbcount) \
227 { \
228 	int n = zsa_rstandby; \
229 	while (--n >= 0 && allocbcount > 0) { \
230 		if (!za->za_rstandby[n]) { \
231 			if ((za->za_rstandby[n] = allocb(ZSA_RCV_SIZE, \
232 			    BPRI_MED)) == NULL) { \
233 				if (za->za_bufcid == 0) { \
234 					za->za_bufcid = bufcall(ZSA_RCV_SIZE, \
235 					    BPRI_MED, \
236 					    zsa_callback, zs); \
237 					break; \
238 				} \
239 			} \
240 			allocbcount--; \
241 		} \
242 	} \
243 	if (za->za_ttycommon.t_cflag & CRTSXOFF) { \
244 		mutex_enter(zs->zs_excl_hi); \
245 		if (!(zs->zs_wreg[5] & ZSWR5_RTS)) { \
246 			int usedcnt = 0; \
247 			for (n = 0; n < zsa_rstandby; n++) \
248 				if (!za->za_rstandby[n]) \
249 					usedcnt++; \
250 			if ((ushort_t)usedcnt <= \
251 			    zslowat[SPEED(za->za_ttycommon.t_cflag)]) \
252 				SCC_BIS(5, ZSWR5_RTS); \
253 		} \
254 		mutex_exit(zs->zs_excl_hi); \
255 	} \
256 }
257 
258 /*
259  * Should be called holding the spin (zs_excl_hi) mutex.
260  */
261 #define	ZSA_ALLOCB(mp) \
262 { \
263 	int n = zsa_rstandby; \
264 	while (--n >= 0) { \
265 		if ((mp = za->za_rstandby[n]) != NULL) { \
266 			za->za_rstandby[n] = NULL; \
267 			break; \
268 		} \
269 	} \
270 	if (za->za_ttycommon.t_cflag & CRTSXOFF) { \
271 		if (!mp) { \
272 			if (zs->zs_wreg[5] & ZSWR5_RTS) \
273 				SCC_BIC(5, ZSWR5_RTS); \
274 			cmn_err(CE_WARN, "zs%d: message lost\n", \
275 				UNIT(za->za_dev)); \
276 		} else if (zs->zs_wreg[5] & ZSWR5_RTS) { \
277 			int usedcnt = 0; \
278 			for (n = 0; n < zsa_rstandby; n++) \
279 				if (!za->za_rstandby[n]) \
280 					usedcnt++; \
281 			if ((ushort_t)usedcnt >= (zsa_rstandby - \
282 			    zshiwat[SPEED(za->za_ttycommon.t_cflag)])) \
283 				SCC_BIC(5, ZSWR5_RTS); \
284 		} \
285 	} \
286 }
287 
288 /*
289  * Should get the spin (zs_excl_hi) mutex.
290  */
291 #define	ZSA_QREPLY(q, mp) \
292 { \
293 	mutex_enter(zs->zs_excl_hi); \
294 	ZSA_PUTQ(mp); \
295 	ZSSETSOFT(zs); \
296 	mutex_exit(zs->zs_excl_hi); \
297 }
298 
299 /*
300  * Should be called holding the spin (zs_excl_hi) mutex.
301  */
302 #define	ZSA_PUTQ(mp) \
303 { \
304 	int wptr, rptr; \
305 	wptr = za->za_rdone_wptr; \
306 	rptr = za->za_rdone_rptr; \
307 	za->za_rdone[wptr] = mp; \
308 	if ((wptr)+1 == zsa_rdone) { \
309 		za->za_rdone_wptr = wptr = 0; \
310 	} else \
311 		za->za_rdone_wptr = ++wptr; \
312 	if (wptr == rptr) { \
313 		SCC_BIC(1, ZSWR1_INIT); \
314 		cmn_err(CE_WARN, "zs%d disabled: input buffer overflow", \
315 			UNIT(za->za_dev)); \
316 	} \
317 }
318 
319 /*
320  * Should be called holding the spin (zs_excl_hi) mutex.
321  */
322 #define	ZSA_KICK_RCV \
323 { \
324 	mblk_t *mp = za->za_rcvblk; \
325 	if (mp) { \
326 		if (zs->zs_rd_cur) {	/* M_DATA */ \
327 			mp->b_wptr = zs->zs_rd_cur; \
328 			zs->zs_rd_cur = NULL; \
329 			zs->zs_rd_lim = NULL; \
330 		} \
331 		za->za_rcvblk = NULL; \
332 		ZSA_PUTQ(mp); \
333 		ZSSETSOFT(zs); \
334 	} \
335 }
336 
337 #define	ZSA_SEEQ(mp) \
338 { \
339 		if (za->za_rdone_rptr != za->za_rdone_wptr) { \
340 			mp = za->za_rdone[za->za_rdone_rptr]; \
341 		} else { \
342 			mp = NULL; \
343 		} \
344 }
345 
346 
347 /*
348  * Should be called holding only the adaptive (zs_excl) mutex.
349  */
350 #define	ZSA_GETQ(mp) \
351 { \
352 	if (za->za_rdone_rptr != za->za_rdone_wptr) { \
353 		mp = za->za_rdone[za->za_rdone_rptr]; \
354 		za->za_rdone[za->za_rdone_rptr++] = NULL; \
355 		if (za->za_rdone_rptr == zsa_rdone) \
356 			za->za_rdone_rptr = 0; \
357 	} else { \
358 		mp = NULL; \
359 	} \
360 }
361 
362 /*
363  * Should be called holding only the adaptive (zs_excl) mutex.
364  */
365 #define	ZSA_FLUSHQ \
366 { \
367 	mblk_t *tmp; \
368 	for (;;) { \
369 		ZSA_GETQ(tmp); \
370 		if (!(tmp)) \
371 			break; \
372 		freemsg(tmp); \
373 	} \
374 }
375 
376 
377 /*
378  * Logging definitions
379  */
380 
381 #ifdef ZSA_DEBUG
382 
383 #ifdef ZS_DEBUG_ALL
384 
385 extern	char	zs_h_log[];
386 extern	int	zs_h_log_n;
387 
388 #define	zsa_h_log_clear
389 
390 #define	zsa_h_log_add(c) \
391 { \
392 	if (zs_h_log_n >= ZS_H_LOG_MAX) \
393 		zs_h_log_n = 0; \
394 	zs_h_log[zs_h_log_n++] = 'A' + zs->zs_unit; \
395 	zs_h_log[zs_h_log_n++] = c; \
396 	zs_h_log[zs_h_log_n] = '\0'; \
397 }
398 
399 #else /* ZS_DEBUG_ALL */
400 
401 #define	ZSA_H_LOG_MAX	0x4000
402 char zsa_h_log[40][ZSA_H_LOG_MAX +10];
403 int zsa_h_log_n[40];
404 
405 #define	zsa_h_log_add(c) \
406 { \
407 	if (zsa_h_log_n[zs->zs_unit] >= ZSA_H_LOG_MAX) \
408 		zsa_h_log_n[zs->zs_unit] = 0; \
409 	zsa_h_log[zs->zs_unit][zsa_h_log_n[zs->zs_unit]++] = c; \
410 	zsa_h_log[zs->zs_unit][zsa_h_log_n[zs->zs_unit]] = '\0'; \
411 }
412 
413 #define	zsa_h_log_clear \
414 { \
415 	char *p; \
416 	for (p = &zsa_h_log[zs->zs_unit][ZSA_H_LOG_MAX]; \
417 		p >= &zsa_h_log[zs->zs_unit][0]; /* null */) \
418 		*p-- = '\0'; \
419 	zsa_h_log_n[zs->zs_unit] = 0; \
420 }
421 
422 #endif /* ZS_DEBUG_ALL */
423 
424 #define	ZSA_R0_LOG(r0) \
425 { \
426 	if (r0 & ZSRR0_RX_READY) zsa_h_log_add('R'); \
427 	if (r0 & ZSRR0_TIMER) zsa_h_log_add('Z'); \
428 	if (r0 & ZSRR0_TX_READY) zsa_h_log_add('T'); \
429 	if (r0 & ZSRR0_CD) zsa_h_log_add('D'); \
430 	if (r0 & ZSRR0_SYNC) zsa_h_log_add('S'); \
431 	if (r0 & ZSRR0_CTS) zsa_h_log_add('C'); \
432 	if (r0 & ZSRR0_TXUNDER) zsa_h_log_add('U'); \
433 	if (r0 & ZSRR0_BREAK) zsa_h_log_add('B'); \
434 }
435 
436 #else /* ZSA_DEBUG */
437 
438 #define	zsa_h_log_clear
439 #define	zsa_h_log_add(c)
440 #define	 ZSA_R0_LOG(r0)
441 
442 #endif /* ZSA_DEBUG */
443 
444 
445 
446 static int zsa_open(queue_t *rq, dev_t *dev, int flag, int sflag, cred_t *cr);
447 static int zsa_close(queue_t *q, int flag, cred_t *cr);
448 static int zsa_wput(queue_t *q, mblk_t *mp);
449 static int zsa_rsrv(queue_t *q);
450 
451 static struct module_info asyncm_info = {
452 	0,
453 	"zs",
454 	0,
455 	INFPSZ,
456 	2048,
457 	128
458 };
459 
460 static struct qinit async_rinit = {
461 	putq,
462 	zsa_rsrv,
463 	zsa_open,
464 	zsa_close,
465 	NULL,
466 	&asyncm_info,
467 	NULL
468 };
469 
470 static struct qinit async_winit = {
471 	zsa_wput,
472 	NULL,
473 	NULL,
474 	NULL,
475 	NULL,
476 	&asyncm_info,
477 	NULL
478 };
479 
480 struct streamtab asynctab = {
481 	&async_rinit,
482 	&async_winit,
483 	NULL,
484 	NULL,
485 };
486 
487 /*
488  * The async interrupt entry points.
489  */
490 static void	zsa_txint(struct zscom *zs);
491 static void	zsa_xsint(struct zscom *zs);
492 static void	zsa_rxint(struct zscom *zs);
493 static void	zsa_srint(struct zscom *zs);
494 static int	zsa_softint(struct zscom *zs);
495 static int	zsa_suspend(struct zscom *zs);
496 static int	zsa_resume(struct zscom *zs);
497 
498 static void
499 zsa_null(struct zscom *zs)
500 {
501 	short	c;
502 
503 	SCC_WRITE0(ZSWR0_RESET_TXINT);
504 	SCC_WRITE0(ZSWR0_RESET_STATUS);
505 	c = SCC_READDATA();
506 	ZSDELAY();
507 	SCC_WRITE0(ZSWR0_RESET_ERRORS);
508 }
509 
510 /*ARGSUSED*/
511 static int
512 zsa_null_int(struct zscom *zs)
513 {
514 	return (0);
515 }
516 
517 struct zsops zsops_null_async = {
518 	zsa_null,
519 	zsa_null,
520 	zsa_null,
521 	zsa_null,
522 	zsa_null_int,
523 	zsa_null_int,
524 	zsa_null_int
525 };
526 
527 struct zsops zsops_async = {
528 	zsa_txint,
529 	zsa_xsint,
530 	zsa_rxint,
531 	zsa_srint,
532 	zsa_softint,
533 	zsa_suspend,
534 	zsa_resume
535 };
536 
537 static int	dmtozs(int bits);
538 static int	zstodm(int bits);
539 static void	zsa_restart(void *);
540 static void	zsa_reioctl(void *);
541 static void	zsa_ioctl(struct asyncline *za, queue_t *q, mblk_t *mp);
542 static void	zsa_program(struct asyncline *za, int setibaud);
543 static void	zsa_start(struct zscom *zs);
544 static void	zsa_kick_rcv(void *);
545 static void	zsa_callback(void *);
546 static void	zsa_set_za_rcv_flags_mask(struct asyncline *za);
547 int		zsgetspeed(dev_t dev);
548 
549 static boolean_t abort_charseq_recognize(uchar_t ch);
550 
551 /* ARGSUSED */
552 int
553 zsc_info(dev_info_t *dip, ddi_info_cmd_t infocmd, void *arg,
554     void **result)
555 {
556 	dev_t dev = (dev_t)arg;
557 	int unit, error;
558 	struct zscom *zs;
559 
560 	if ((unit = UNIT(dev)) >= nzs)
561 		return (DDI_FAILURE);
562 
563 	switch (infocmd) {
564 	case DDI_INFO_DEVT2DEVINFO:
565 		zs = &zscom[unit];
566 		*result = zs->zs_dip;
567 		error = DDI_SUCCESS;
568 		break;
569 	case DDI_INFO_DEVT2INSTANCE:
570 		*result = (void *)(uintptr_t)(unit / 2);
571 		error = DDI_SUCCESS;
572 		break;
573 	default:
574 		error = DDI_FAILURE;
575 	}
576 	return (error);
577 }
578 
579 /*
580  * The Asynchronous Driver.
581  */
582 
583 /*
584  * Determine if the zsminor device is in use as either a stdin or stdout
585  * device, so we can be careful about how we initialize the DUART, if
586  * it is, in fact, in use.
587  *
588  * Since this is expensive, we do it once and store away the answers,
589  * since this gets called a number of times per phyical zs device.
590  * Perhaps, this should be in a loadable module, so it can get thrown
591  * away after all the zs devices are attached?
592  */
593 
594 /*
595  * To determine if a given unit is being used by the PROM,
596  * we need to map stdin/stdout devices as known to the PROM
597  * to zs internal minor device numbers:
598  *
599  * PROM (real device)	zs minor	device
600  *
601  * "zs", 0, "a"		 0		ttya
602  * "zs", 0, "b"		 1		ttyb
603  * "zs", 1, "a"		 2		keyboard
604  * "zs", 1, "b"		 3		mouse
605  * "zs", 2, "a"		 4		ttyc
606  * "zs", 2, "b"		 5		ttyd
607  *
608  * The following value mapping lines assume that insource
609  * and outsink map as "screen, a, b, c, d, ...", and that
610  * zs minors are "a, b, kbd, mouse, c, d, ...".
611  */
612 
613 static int zsa_inuse;		/* Strictly for debugging */
614 
615 int
616 zsa_channel_is_active_in_rom(dev_info_t *dev, int zsminor)
617 {
618 	char pathname[OBP_MAXPATHLEN];
619 	char default_pathname[OBP_MAXPATHLEN];
620 	char *stdioname;
621 	char minordata[3];
622 
623 	/*
624 	 * Basically, get my name and compare it to stdio devnames
625 	 * and if we get a match, then the device is in use as either
626 	 * stdin or stdout device (console tip line or keyboard device).
627 	 *
628 	 * We get two forms of the pathname, one complete with the
629 	 * the channel number, and if the channel is 'a', then
630 	 * we also deal with the user's ability to default to
631 	 * channel 'a', by omitting the channel number option.
632 	 * We then compare these pathnames to both the stdin and
633 	 * stdout pathnames. If any of these match, then the channel
634 	 * is in use.
635 	 */
636 
637 	(void) ddi_pathname(dev, pathname);	/* device pathname */
638 	default_pathname[0] = (char)0;	/* default pathname if channel 'a' */
639 	if ((zsminor & 1) == 0)
640 		(void) strcpy(default_pathname, pathname);
641 	minordata[0] = ':';
642 	minordata[1] = (char)('a' + (zsminor & 1));
643 	minordata[2] = (char)0;
644 	(void) strcat(pathname, minordata);
645 
646 	stdioname = prom_stdinpath();
647 	if (strcmp(pathname, stdioname) == 0) {
648 		zsa_inuse |= (1 << zsminor);
649 		return (1);
650 	}
651 	if (strcmp(default_pathname, stdioname) == 0) {
652 		zsa_inuse |= (1 << zsminor);
653 		return (1);
654 	}
655 
656 	stdioname = prom_stdoutpath();
657 	if (strcmp(pathname, stdioname) == 0) {
658 		zsa_inuse |= (1 << zsminor);
659 		return (1);
660 	}
661 	if (strcmp(default_pathname, stdioname) == 0) {
662 		zsa_inuse |= (1 << zsminor);
663 		return (1);
664 	}
665 
666 	return (0);
667 }
668 
669 /*
670  * Initialize zs
671  */
672 void
673 zsa_init(struct zscom *zs)
674 {
675 	/*
676 	 * This routine is called near the end of the zs module's attach
677 	 * process. It initializes the TTY protocol-private data for this
678 	 * channel that needs to be in place before interrupts are enabled.
679 	 */
680 	mutex_enter(zs->zs_excl);
681 	mutex_enter(zs->zs_excl_hi);
682 
683 	/*
684 	 * Raise modem control lines on serial ports associated
685 	 * with the console and (optionally) softcarrier lines.
686 	 * Drop modem control lines on all others so that modems
687 	 * will not answer and portselectors will skip these
688 	 * lines until they are opened by a getty.
689 	 */
690 	if (zsa_channel_is_active_in_rom(zs->zs_dip, zs->zs_unit))
691 		(void) zsmctl(zs, ZS_ON, DMSET);	/* raise dtr */
692 	else if (zsasoftdtr && (zssoftCAR[zs->zs_unit]))
693 		(void) zsmctl(zs, ZS_ON, DMSET);	/* raise dtr */
694 	else
695 		(void) zsmctl(zs, ZS_OFF, DMSET);	/* drop dtr */
696 
697 	if (zsa_rstandby > ZSA_MAX_RSTANDBY)
698 		zsa_rstandby = ZSA_MAX_RSTANDBY;
699 
700 	if (zsa_rdone > ZSA_RDONE_MAX)
701 		zsa_rdone = ZSA_RDONE_MAX;
702 
703 	if (zsa_grace_flow_control > ZSA_GRACE_MAX_FLOW_CONTROL)
704 		zsa_grace_flow_control = ZSA_GRACE_MAX_FLOW_CONTROL;
705 
706 	mutex_exit(zs->zs_excl_hi);
707 	mutex_exit(zs->zs_excl);
708 }
709 
710 
711 /*
712  * Open routine.
713  */
714 /*ARGSUSED*/
715 static int
716 zsa_open(queue_t *rq, dev_t *dev, int flag, int sflag, cred_t *cr)
717 {
718 	struct zscom *zs;
719 	struct asyncline *za;
720 	int	speed, unit;
721 	struct termios *termiosp;
722 	int len;
723 	int allocbcount = zsa_rstandby;
724 	boolean_t set_zsoptinit = B_FALSE;
725 
726 	unit = UNIT(*dev);
727 	if (unit >= nzs)
728 		return (ENXIO);		/* unit not configured */
729 
730 	/* zscom is allocated by zsattach, and thus cannot be NULL here */
731 	zs = &zscom[unit];
732 	if (zs->zs_ops == NULL) {
733 		return (ENXIO);	 /* device not found by autoconfig */
734 	}
735 
736 	mutex_enter(zs->zs_ocexcl);
737 	mutex_enter(zs->zs_excl);
738 again:
739 	if ((zs->zs_ops != &zsops_null) &&
740 	    (zs->zs_ops != &zsops_async)) {
741 		mutex_exit(zs->zs_excl);
742 		mutex_exit(zs->zs_ocexcl);
743 		return (EBUSY);	 /* another protocol got here first */
744 	}
745 
746 	za = (struct asyncline *)&zs->zs_priv_str;
747 
748 	if (zs->zs_suspended) {
749 		mutex_exit(zs->zs_excl);
750 		mutex_exit(zs->zs_ocexcl);
751 		(void) ddi_dev_is_needed(zs->zs_dip, 0, 1);
752 		mutex_enter(zs->zs_ocexcl);
753 		mutex_enter(zs->zs_excl);
754 	}
755 
756 	/* Mark device as busy (for power management) */
757 	(void) pm_busy_component(zs->zs_dip, unit%2+1);
758 
759 	if (zs->zs_ops == &zsops_null) {
760 		bzero(za, sizeof (zs->zs_priv_str));
761 		za->za_common = zs;
762 		if (zssoftCAR[zs->zs_unit])
763 			za->za_ttycommon.t_flags |= TS_SOFTCAR;
764 		zsopinit(zs, &zsops_async);
765 		set_zsoptinit = B_TRUE;
766 		za->za_rdone_wptr = 0;
767 		za->za_rdone_rptr = 0;
768 	}
769 
770 	zs->zs_priv = (caddr_t)za;
771 
772 	/*
773 	 * Block waiting for carrier to come up,
774 	 * unless this is a no-delay open.
775 	 */
776 	mutex_enter(zs->zs_excl_hi);
777 	if (!(za->za_flags & ZAS_ISOPEN)) {
778 		/*
779 		 * Get the default termios settings (cflag).
780 		 * These are stored as a property in the
781 		 * "options" node.
782 		 */
783 		mutex_exit(zs->zs_excl_hi);
784 		if (ddi_getlongprop(DDI_DEV_T_ANY,
785 		    ddi_root_node(), 0, "ttymodes",
786 		    (caddr_t)&termiosp, &len) == DDI_PROP_SUCCESS &&
787 		    len == sizeof (struct termios)) {
788 
789 			za->za_ttycommon.t_cflag = termiosp->c_cflag;
790 			kmem_free(termiosp, len);
791 		} else {
792 			/*
793 			 * Gack! Whine about it.
794 			 */
795 			cmn_err(CE_WARN,
796 			    "zs: Couldn't get ttymodes property!");
797 		}
798 		mutex_enter(zs->zs_excl_hi);
799 		if ((*dev == rconsdev) || (*dev == kbddev) ||
800 		    (*dev == stdindev)) {
801 			speed = zsgetspeed(*dev);
802 			za->za_ttycommon.t_cflag &= ~(CBAUD);
803 			if (speed > CBAUD) {
804 				za->za_ttycommon.t_cflag |= CBAUDEXT;
805 				za->za_ttycommon.t_cflag |=
806 				    ((speed - CBAUD - 1) & CBAUD);
807 			} else {
808 				za->za_ttycommon.t_cflag &= ~CBAUDEXT;
809 				za->za_ttycommon.t_cflag |= (speed & CBAUD);
810 			}
811 		}
812 		za->za_overrun = 0;
813 		za->za_ttycommon.t_iflag = 0;
814 		za->za_ttycommon.t_iocpending = NULL;
815 		za->za_ttycommon.t_size.ws_row = 0;
816 		za->za_ttycommon.t_size.ws_col = 0;
817 		za->za_ttycommon.t_size.ws_xpixel = 0;
818 		za->za_ttycommon.t_size.ws_ypixel = 0;
819 		za->za_dev = *dev;
820 		za->za_wbufcid = 0;
821 		zsa_program(za, za->za_ttycommon.t_cflag & (CIBAUDEXT|CIBAUD));
822 		zsa_set_za_rcv_flags_mask(za);
823 	} else if ((za->za_ttycommon.t_flags & TS_XCLUDE) &&
824 	    secpolicy_excl_open(cr) != 0) {
825 		mutex_exit(zs->zs_excl_hi);
826 		if (set_zsoptinit && !(za->za_flags & ISOPEN))
827 			zsopinit(zs, &zsops_null);
828 		mutex_exit(zs->zs_excl);
829 		mutex_exit(zs->zs_ocexcl);
830 		return (EBUSY);
831 	} else if ((*dev & OUTLINE) && !(za->za_flags & ZAS_OUT)) {
832 		mutex_exit(zs->zs_excl_hi);
833 		if (set_zsoptinit && !(za->za_flags & ISOPEN))
834 			zsopinit(zs, &zsops_null);
835 		mutex_exit(zs->zs_excl);
836 		mutex_exit(zs->zs_ocexcl);
837 		return (EBUSY);
838 	}
839 
840 	if (*dev & OUTLINE)
841 		za->za_flags |= ZAS_OUT;
842 	(void) zsmctl(zs, ZS_ON, DMSET);
843 
844 	/*
845 	 * Check carrier.
846 	 */
847 	if ((za->za_ttycommon.t_flags & TS_SOFTCAR) ||
848 	    (zsmctl(zs, 0, DMGET) & ZSRR0_CD))
849 		za->za_flags |= ZAS_CARR_ON;
850 	mutex_exit(zs->zs_excl_hi);
851 
852 	/*
853 	 * If FNDELAY and FNONBLOCK are clear, block until carrier up.
854 	 * Quit on interrupt.
855 	 */
856 	if (!(flag & (FNDELAY|FNONBLOCK)) &&
857 	    !(za->za_ttycommon.t_cflag & CLOCAL)) {
858 		if (!(za->za_flags & (ZAS_CARR_ON|ZAS_OUT)) ||
859 		    ((za->za_flags & ZAS_OUT) && !(*dev & OUTLINE))) {
860 			za->za_flags |= ZAS_WOPEN;
861 			mutex_exit(zs->zs_excl);
862 			if (cv_wait_sig(&zs->zs_flags_cv, zs->zs_ocexcl) == 0) {
863 				mutex_enter(zs->zs_excl);
864 				if (zs->zs_suspended) {
865 					mutex_exit(zs->zs_excl);
866 					mutex_exit(zs->zs_ocexcl);
867 					(void) ddi_dev_is_needed(zs->zs_dip,
868 					    0, 1);
869 					mutex_enter(zs->zs_ocexcl);
870 					mutex_enter(zs->zs_excl);
871 				}
872 				za->za_flags &= ~ZAS_WOPEN;
873 				if (set_zsoptinit && !(za->za_flags & ISOPEN))
874 					zsopinit(zs, &zsops_null);
875 				mutex_exit(zs->zs_excl);
876 				mutex_exit(zs->zs_ocexcl);
877 				return (EINTR);
878 			}
879 			mutex_enter(zs->zs_excl);
880 			za->za_flags &= ~ZAS_WOPEN;
881 			if ((zs->zs_ops == &zsops_null) ||
882 			    (zs->zs_ops == &zsops_async))
883 				goto again;
884 			else {
885 				if (set_zsoptinit && !(za->za_flags & ISOPEN))
886 					zsopinit(zs, &zsops_null);
887 				mutex_exit(zs->zs_excl);
888 				mutex_exit(zs->zs_ocexcl);
889 				return (EBUSY);
890 			}
891 		}
892 	} else if ((za->za_flags & ZAS_OUT) && !(*dev & OUTLINE)) {
893 		if (set_zsoptinit && !(za->za_flags & ISOPEN))
894 			zsopinit(zs, &zsops_null);
895 		mutex_exit(zs->zs_excl);
896 		mutex_exit(zs->zs_ocexcl);
897 		return (EBUSY);
898 	}
899 
900 	za->za_ttycommon.t_readq = rq;
901 	za->za_ttycommon.t_writeq = WR(rq);
902 	rq->q_ptr = WR(rq)->q_ptr = (caddr_t)za;
903 
904 	za->za_flags |= ZAS_ISOPEN;
905 	ZSA_GETBLOCK(zs, allocbcount);
906 	qprocson(rq);
907 	mutex_exit(zs->zs_excl);
908 	mutex_exit(zs->zs_ocexcl);
909 	return (0);
910 }
911 
912 static void
913 zs_progress_check(void *arg)
914 {
915 	struct asyncline *za = arg;
916 	struct zscom *zs = za->za_common;
917 	mblk_t *bp;
918 
919 	/*
920 	 * We define "progress" as either waiting on a timed break or delay, or
921 	 * having had at least one transmitter interrupt.  If none of these are
922 	 * true, then just terminate the output and wake up that close thread.
923 	 */
924 	mutex_enter(zs->zs_excl);
925 	if (!(zs->zs_flags & ZS_PROGRESS) &&
926 	    !(za->za_flags & (ZAS_BREAK|ZAS_DELAY))) {
927 		za->za_flags &= ~ZAS_BUSY;
928 		mutex_enter(zs->zs_excl_hi);
929 		za->za_rcv_flags_mask &= ~DO_RETRANSMIT;
930 		zs->zs_wr_cur = NULL;
931 		zs->zs_wr_lim = NULL;
932 		bp = za->za_xmitblk;
933 		za->za_xmitblk = NULL;
934 		mutex_exit(zs->zs_excl_hi);
935 		zs->zs_timer = 0;
936 		mutex_exit(zs->zs_excl);
937 		if (bp != NULL)
938 			freeb(bp);
939 		/*
940 		 * Since this timer is running, we know that we're in exit(2).
941 		 * That means that the user can't possibly be waiting on any
942 		 * valid ioctl(2) completion anymore, and we should just flush
943 		 * everything.
944 		 */
945 		flushq(za->za_ttycommon.t_writeq, FLUSHALL);
946 		cv_broadcast(&zs->zs_flags_cv);
947 	} else {
948 		zs->zs_flags &= ~ZS_PROGRESS;
949 		zs->zs_timer = timeout(zs_progress_check, za,
950 		    drv_usectohz(zs_drain_check));
951 		mutex_exit(zs->zs_excl);
952 	}
953 }
954 
955 /*
956  * Close routine.
957  *
958  * Important locking note: the zs_ocexcl lock is not held at all in this
959  * routine.  This is intentional.  That lock is used to coordinate multiple
960  * simultaneous opens on a stream, and there's no such thing as multiple
961  * simultaneous closes on a stream.
962  */
963 
964 /*ARGSUSED*/
965 static int
966 zsa_close(queue_t *q, int flag, cred_t *cr __unused)
967 {
968 	struct asyncline *za;
969 	struct zscom *zs;
970 	int i;
971 	mblk_t *bp;
972 	timeout_id_t za_zsa_restart_id, za_kick_rcv_id;
973 	bufcall_id_t za_bufcid, za_wbufcid;
974 	int	 tmp;
975 
976 	za = q->q_ptr;
977 	ASSERT(za != NULL);
978 
979 	zs = za->za_common;
980 
981 	mutex_enter(zs->zs_excl);
982 	zs->zs_flags |= ZS_CLOSING;
983 
984 	/*
985 	 * There are two flavors of break -- timed (M_BREAK or TCSBRK) and
986 	 * untimed (TIOCSBRK).  For the timed case, these are enqueued on our
987 	 * write queue and there's a timer running, so we don't have to worry
988 	 * about them.  For the untimed case, though, the user obviously made a
989 	 * mistake, because these are handled immediately.  We'll terminate the
990 	 * break now and honor their implicit request by discarding the rest of
991 	 * the data.
992 	 */
993 	if (!(za->za_flags & ZAS_BREAK) && (zs->zs_wreg[5] & ZSWR5_BREAK))
994 		goto nodrain;
995 
996 	/*
997 	 * If the user told us not to delay the close ("non-blocking"), then
998 	 * don't bother trying to drain.
999 	 *
1000 	 * If the user did M_STOP (ASYNC_STOPPED), there's no hope of ever
1001 	 * getting an M_START (since these messages aren't enqueued), and the
1002 	 * only other way to clear the stop condition is by loss of DCD, which
1003 	 * would discard the queue data.  Thus, we drop the output data if
1004 	 * ASYNC_STOPPED is set.
1005 	 */
1006 	if ((flag & (FNDELAY|FNONBLOCK)) || (za->za_flags & ZAS_STOPPED))
1007 		goto nodrain;
1008 
1009 	/*
1010 	 * If there's any pending output, then we have to try to drain it.
1011 	 * There are two main cases to be handled:
1012 	 *	- called by close(2): need to drain until done or until
1013 	 *	  a signal is received.  No timeout.
1014 	 *	- called by exit(2): need to drain while making progress
1015 	 *	  or until a timeout occurs.  No signals.
1016 	 *
1017 	 * If we can't rely on receiving a signal to get us out of a hung
1018 	 * session, then we have to use a timer.  In this case, we set a timer
1019 	 * to check for progress in sending the output data -- all that we ask
1020 	 * (at each interval) is that there's been some progress made.  Since
1021 	 * the interrupt routine grabs buffers from the write queue, we can't
1022 	 * trust changes in zs_wr_cur.  Instead, we use a progress flag.
1023 	 *
1024 	 * Note that loss of carrier will cause the output queue to be flushed,
1025 	 * and we'll wake up again and finish normally.
1026 	 */
1027 	if (!ddi_can_receive_sig() && zs_drain_check != 0) {
1028 		zs->zs_flags &= ~ZS_PROGRESS;
1029 		zs->zs_timer = timeout(zs_progress_check, za,
1030 		    drv_usectohz(zs_drain_check));
1031 	}
1032 
1033 	while (zs->zs_wr_cur != NULL ||
1034 	    za->za_ttycommon.t_writeq->q_first != NULL ||
1035 	    (za->za_flags & (ZAS_BUSY|ZAS_DELAY|ZAS_BREAK))) {
1036 		if (cv_wait_sig(&zs->zs_flags_cv, zs->zs_excl) == 0)
1037 			break;
1038 	}
1039 
1040 	if (zs->zs_timer != 0) {
1041 		(void) untimeout(zs->zs_timer);
1042 		zs->zs_timer = 0;
1043 	}
1044 
1045 nodrain:
1046 	/*
1047 	 * If break is in progress, stop it.
1048 	 */
1049 	mutex_enter(zs->zs_excl_hi);
1050 	if (zs->zs_wreg[5] & ZSWR5_BREAK) {
1051 		SCC_BIC(5, ZSWR5_BREAK);
1052 		za->za_flags &= ~ZAS_BREAK;
1053 	}
1054 
1055 	za_wbufcid = za->za_wbufcid;
1056 	za_bufcid = za->za_bufcid;
1057 	za_zsa_restart_id = za->za_zsa_restart_id;
1058 	za_kick_rcv_id = za->za_kick_rcv_id;
1059 
1060 	za->za_wbufcid = za->za_bufcid = 0;
1061 	za->za_zsa_restart_id = za->za_kick_rcv_id = 0;
1062 
1063 	/*
1064 	 * If line has HUPCL set or is incompletely opened,
1065 	 * and it is not the console or the keyboard,
1066 	 * fix up the modem lines.
1067 	 */
1068 
1069 	zsopinit(zs, &zsops_null_async);
1070 
1071 	/*
1072 	 * Nobody, zsh or zs can now open this port until
1073 	 * zsopinit(zs, &zsops_null);
1074 	 *
1075 	 */
1076 
1077 	if ((za->za_dev != rconsdev) && (za->za_dev != kbddev) &&
1078 	    (za->za_dev != stdindev) &&
1079 	    (((za->za_flags & (ZAS_WOPEN|ZAS_ISOPEN)) != ZAS_ISOPEN) ||
1080 	    (za->za_ttycommon.t_cflag & HUPCL))) {
1081 		/*
1082 		 * If DTR is being held high by softcarrier,
1083 		 * set up the ZS_ON set; if not, hang up.
1084 		 */
1085 		if (zsasoftdtr && (za->za_ttycommon.t_flags & TS_SOFTCAR))
1086 			(void) zsmctl(zs, ZS_ON, DMSET);
1087 		else
1088 			(void) zsmctl(zs, ZS_OFF, DMSET);
1089 		mutex_exit(zs->zs_excl_hi);
1090 		/*
1091 		 * Don't let an interrupt in the middle of close
1092 		 * bounce us back to the top; just continue
1093 		 * closing as if nothing had happened.
1094 		 */
1095 		tmp = cv_reltimedwait_sig(&zs->zs_flags_cv, zs->zs_excl,
1096 		    drv_usectohz(10000), TR_CLOCK_TICK);
1097 		if (zs->zs_suspended) {
1098 			mutex_exit(zs->zs_excl);
1099 			(void) ddi_dev_is_needed(zs->zs_dip, 0, 1);
1100 			mutex_enter(zs->zs_excl);
1101 		}
1102 		if (tmp == 0)
1103 			goto out;
1104 		mutex_enter(zs->zs_excl_hi);
1105 	}
1106 
1107 	/*
1108 	 * If nobody's now using it, turn off receiver interrupts.
1109 	 */
1110 	if ((za->za_flags & (ZAS_ISOPEN|ZAS_WOPEN)) == 0)
1111 		SCC_BIC(1, ZSWR1_RIE);
1112 	mutex_exit(zs->zs_excl_hi);
1113 
1114 out:
1115 	/*
1116 	 * Clear out device state.
1117 	 */
1118 	ttycommon_close(&za->za_ttycommon);
1119 
1120 	za->za_ttycommon.t_readq = NULL;
1121 	za->za_ttycommon.t_writeq = NULL;
1122 
1123 	mutex_enter(zs->zs_excl_hi);
1124 	za->za_rcv_flags_mask &= ~DO_RETRANSMIT;
1125 	zs->zs_wr_cur = NULL;
1126 	zs->zs_wr_lim = NULL;
1127 	bp = za->za_xmitblk;
1128 	za->za_xmitblk = NULL;
1129 	mutex_exit(zs->zs_excl_hi);
1130 	if (bp)
1131 		freemsg(bp);
1132 
1133 	mutex_enter(zs->zs_excl_hi);
1134 	zs->zs_rd_cur = NULL;
1135 	zs->zs_rd_lim = NULL;
1136 	bp = za->za_rcvblk;
1137 	za->za_rcvblk = NULL;
1138 	mutex_exit(zs->zs_excl_hi);
1139 	if (bp)
1140 		freemsg(bp);
1141 
1142 	for (i = 0; i < zsa_rstandby; i++) {
1143 		mutex_enter(zs->zs_excl_hi);
1144 		bp = za->za_rstandby[i];
1145 		za->za_rstandby[i] = NULL;
1146 		mutex_exit(zs->zs_excl_hi);
1147 		if (bp)
1148 			freemsg(bp);
1149 	}
1150 
1151 	if (za->za_soft_active || za->za_kick_active) {
1152 		zs->zs_flags |= ZS_CLOSED;
1153 		while (za->za_soft_active || za->za_kick_active)
1154 			cv_wait(&zs->zs_flags_cv, zs->zs_excl);
1155 	}
1156 	if (zs->zs_suspended) {
1157 		mutex_exit(zs->zs_excl);
1158 		(void) ddi_dev_is_needed(zs->zs_dip, 0, 1);
1159 		mutex_enter(zs->zs_excl);
1160 	}
1161 
1162 	ZSA_FLUSHQ;
1163 	bzero(za, sizeof (struct asyncline));
1164 	qprocsoff(q);
1165 	mutex_exit(zs->zs_excl);
1166 
1167 	/*
1168 	 * Cancel outstanding "bufcall" request.
1169 	 */
1170 	if (za_wbufcid)
1171 		unbufcall(za_wbufcid);
1172 	if (za_bufcid)
1173 		unbufcall(za_bufcid);
1174 
1175 	/*
1176 	 * Cancel outstanding timeout.
1177 	 */
1178 	if (za_zsa_restart_id)
1179 		(void) untimeout(za_zsa_restart_id);
1180 
1181 	if (za_kick_rcv_id)
1182 		(void) untimeout(za_kick_rcv_id);
1183 
1184 	q->q_ptr = WR(q)->q_ptr = NULL;
1185 	zsopinit(zs, &zsops_null);
1186 	cv_broadcast(&zs->zs_flags_cv);
1187 
1188 	/* Mark device as available for power management */
1189 	(void) pm_idle_component(zs->zs_dip, zs->zs_unit%2+1);
1190 	return (0);
1191 }
1192 
1193 /*
1194  * Put procedure for write queue.
1195  * Respond to M_STOP, M_START, M_IOCTL, and M_FLUSH messages here;
1196  * set the flow control character for M_STOPI and M_STARTI messages;
1197  * queue up M_BREAK, M_DELAY, and M_DATA messages for processing
1198  * by the start routine, and then call the start routine; discard
1199  * everything else. Note that this driver does not incorporate any
1200  * mechanism to negotiate to handle the canonicalization process.
1201  * It expects that these functions are handled in upper module(s),
1202  * as we do in ldterm.
1203  */
1204 static int
1205 zsa_wput(queue_t *q, mblk_t *mp)
1206 {
1207 	struct asyncline	*za;
1208 	struct zscom		*zs;
1209 	struct copyresp	*resp;
1210 	mblk_t			*bp = NULL;
1211 	int				error;
1212 	struct iocblk			*iocp;
1213 
1214 	za = (struct asyncline *)q->q_ptr;
1215 	zs = za->za_common;
1216 	if (zs->zs_flags & ZS_NEEDSOFT) {
1217 		zs->zs_flags &= ~ZS_NEEDSOFT;
1218 		(void) zsa_softint(zs);
1219 	}
1220 
1221 	switch (mp->b_datap->db_type) {
1222 
1223 	case M_STOP:
1224 		/*
1225 		 * Since we don't do real DMA, we can just let the
1226 		 * chip coast to a stop after applying the brakes.
1227 		 */
1228 		mutex_enter(zs->zs_excl);
1229 		mutex_enter(zs->zs_excl_hi);
1230 		za->za_flags |= ZAS_STOPPED;
1231 		if ((zs->zs_wr_cur) != NULL) {
1232 			za->za_flags &= ~ZAS_BUSY;
1233 			za->za_rcv_flags_mask &= ~DO_RETRANSMIT;
1234 			bp = za->za_xmitblk;
1235 			bp->b_rptr = zs->zs_wr_cur;
1236 			zs->zs_wr_cur = NULL;
1237 			zs->zs_wr_lim = NULL;
1238 			za->za_xmitblk = NULL;
1239 		}
1240 		mutex_exit(zs->zs_excl_hi);
1241 		if (bp)
1242 			(void) putbq(q, bp);
1243 		freemsg(mp);
1244 		mutex_exit(zs->zs_excl);
1245 		break;
1246 
1247 	case M_START:
1248 		mutex_enter(zs->zs_excl);
1249 		if (za->za_flags & ZAS_STOPPED) {
1250 			za->za_flags &= ~ZAS_STOPPED;
1251 			/*
1252 			 * If an output operation is in progress,
1253 			 * resume it. Otherwise, prod the start
1254 			 * routine.
1255 			 */
1256 			zsa_start(zs);
1257 		}
1258 		freemsg(mp);
1259 		mutex_exit(zs->zs_excl);
1260 		break;
1261 
1262 	case M_IOCTL:
1263 		mutex_enter(zs->zs_excl);
1264 		iocp = (struct iocblk *)mp->b_rptr;
1265 
1266 		switch (iocp->ioc_cmd) {
1267 
1268 		case TIOCGPPS:
1269 			/*
1270 			 * Get PPS state.
1271 			 */
1272 			if (mp->b_cont != NULL)
1273 				freemsg(mp->b_cont);
1274 
1275 			mp->b_cont = allocb(sizeof (int), BPRI_HI);
1276 			if (mp->b_cont == NULL) {
1277 				mp->b_datap->db_type = M_IOCNAK;
1278 				iocp->ioc_error = ENOMEM;
1279 				ZSA_QREPLY(q, mp);
1280 				break;
1281 			}
1282 			if (za->za_pps)
1283 				*(int *)mp->b_cont->b_wptr = 1;
1284 			else
1285 				*(int *)mp->b_cont->b_wptr = 0;
1286 			mp->b_cont->b_wptr += sizeof (int);
1287 			mp->b_datap->db_type = M_IOCACK;
1288 			iocp->ioc_count = sizeof (int);
1289 			ZSA_QREPLY(q, mp);
1290 			break;
1291 
1292 		case TIOCSPPS:
1293 			/*
1294 			 * Set PPS state.
1295 			 */
1296 			error = miocpullup(mp, sizeof (int));
1297 			if (error != 0) {
1298 				mp->b_datap->db_type = M_IOCNAK;
1299 				iocp->ioc_error = error;
1300 				ZSA_QREPLY(q, mp);
1301 				break;
1302 			}
1303 
1304 			za->za_pps = (*(int *)mp->b_cont->b_rptr != 0);
1305 			mp->b_datap->db_type = M_IOCACK;
1306 			ZSA_QREPLY(q, mp);
1307 			break;
1308 
1309 		case TIOCGPPSEV:
1310 		{
1311 			/*
1312 			 * Get PPS event data.
1313 			 */
1314 			void *buf;
1315 #ifdef _SYSCALL32_IMPL
1316 			struct ppsclockev32 p32;
1317 #endif
1318 
1319 			if (mp->b_cont != NULL) {
1320 				freemsg(mp->b_cont);
1321 				mp->b_cont = NULL;
1322 			}
1323 			if (za->za_pps == 0) {
1324 				mp->b_datap->db_type = M_IOCNAK;
1325 				iocp->ioc_error = ENXIO;
1326 				ZSA_QREPLY(q, mp);
1327 				break;
1328 			}
1329 
1330 #ifdef _SYSCALL32_IMPL
1331 			if ((iocp->ioc_flag & IOC_MODELS) != IOC_NATIVE) {
1332 				TIMEVAL_TO_TIMEVAL32(&p32.tv, &ppsclockev.tv);
1333 				p32.serial = ppsclockev.serial;
1334 				buf = &p32;
1335 				iocp->ioc_count = sizeof (struct ppsclockev32);
1336 			} else
1337 #endif
1338 			{
1339 				buf = &ppsclockev;
1340 				iocp->ioc_count = sizeof (struct ppsclockev);
1341 			}
1342 
1343 			if ((bp = allocb(iocp->ioc_count, BPRI_HI)) == NULL) {
1344 				mp->b_datap->db_type = M_IOCNAK;
1345 				iocp->ioc_error = ENOMEM;
1346 				ZSA_QREPLY(q, mp);
1347 				break;
1348 			}
1349 			mp->b_cont = bp;
1350 
1351 			bcopy(buf, bp->b_wptr, iocp->ioc_count);
1352 			bp->b_wptr += iocp->ioc_count;
1353 			mp->b_datap->db_type = M_IOCACK;
1354 			ZSA_QREPLY(q, mp);
1355 			break;
1356 		}
1357 
1358 		case TCSETSW:
1359 		case TCSETSF:
1360 		case TCSETAW:
1361 		case TCSETAF:
1362 		case TCSBRK:
1363 			/*
1364 			 * The changes do not take effect until all
1365 			 * output queued before them is drained.
1366 			 * Put this message on the queue, so that
1367 			 * "zsa_start" will see it when it's done
1368 			 * with the output before it. Poke the
1369 			 * start routine, just in case.
1370 			 */
1371 			(void) putq(q, mp);
1372 			zsa_start(zs);
1373 			break;
1374 
1375 		default:
1376 			/*
1377 			 * Do it now.
1378 			 */
1379 			zsa_ioctl(za, q, mp);
1380 			break;
1381 		}
1382 		mutex_exit(zs->zs_excl);
1383 		break;
1384 
1385 
1386 	case M_IOCDATA:
1387 
1388 		mutex_enter(zs->zs_excl);
1389 		resp = (struct copyresp *)mp->b_rptr;
1390 		if (resp->cp_rval) {
1391 			/*
1392 			 * Just free message on failure.
1393 			 */
1394 			freemsg(mp);
1395 			mutex_exit(zs->zs_excl);
1396 			break;
1397 		}
1398 		switch (resp->cp_cmd) {
1399 
1400 		case TIOCMSET:
1401 			mutex_enter(zs->zs_excl_hi);
1402 			(void) zsmctl(zs, dmtozs(*(int *)mp->b_cont->b_rptr),
1403 			    DMSET);
1404 			mutex_exit(zs->zs_excl_hi);
1405 			mioc2ack(mp, NULL, 0, 0);
1406 			ZSA_QREPLY(q, mp);
1407 			break;
1408 
1409 		case TIOCMBIS:
1410 			mutex_enter(zs->zs_excl_hi);
1411 			(void) zsmctl(zs, dmtozs(*(int *)mp->b_cont->b_rptr),
1412 			    DMBIS);
1413 			mutex_exit(zs->zs_excl_hi);
1414 			mioc2ack(mp, NULL, 0, 0);
1415 			ZSA_QREPLY(q, mp);
1416 			break;
1417 
1418 		case TIOCMBIC:
1419 			mutex_enter(zs->zs_excl_hi);
1420 			(void) zsmctl(zs, dmtozs(*(int *)mp->b_cont->b_rptr),
1421 			    DMBIC);
1422 			mutex_exit(zs->zs_excl_hi);
1423 			mioc2ack(mp, NULL, 0, 0);
1424 			ZSA_QREPLY(q, mp);
1425 			break;
1426 
1427 		case TIOCMGET:
1428 			mioc2ack(mp, NULL, 0, 0);
1429 			ZSA_QREPLY(q, mp);
1430 			break;
1431 
1432 		default:
1433 			freemsg(mp);
1434 
1435 		}
1436 		mutex_exit(zs->zs_excl);
1437 		break;
1438 
1439 
1440 	case M_FLUSH:
1441 		mutex_enter(zs->zs_excl);
1442 		if (*mp->b_rptr & FLUSHW) {
1443 
1444 			/*
1445 			 * Abort any output in progress.
1446 			 */
1447 			if (za->za_flags & ZAS_BUSY) {
1448 				za->za_flags &= ~ZAS_BUSY;
1449 				mutex_enter(zs->zs_excl_hi);
1450 				za->za_rcv_flags_mask &= ~DO_RETRANSMIT;
1451 				zs->zs_wr_cur = NULL;
1452 				zs->zs_wr_lim = NULL;
1453 				bp = za->za_xmitblk;
1454 				za->za_xmitblk = NULL;
1455 				mutex_exit(zs->zs_excl_hi);
1456 				if (bp)
1457 					freemsg(bp);
1458 			}
1459 			/*
1460 			 * Flush our write queue.
1461 			 */
1462 			flushq(q, FLUSHDATA);	/* XXX doesn't flush M_DELAY */
1463 			*mp->b_rptr &= ~FLUSHW;	/* it has been flushed */
1464 		}
1465 		if (*mp->b_rptr & FLUSHR) {
1466 			/*
1467 			 * Flush any data in the temporary receive buffer
1468 			 */
1469 			mutex_enter(zs->zs_excl_hi);
1470 			if ((za->za_ttycommon.t_flags & TS_SOFTCAR) ||
1471 			    (SCC_READ0() & ZSRR0_CD)) {
1472 				ZSA_KICK_RCV;
1473 			} else {
1474 				ZSA_KICK_RCV;
1475 				if (!(SCC_READ0() & ZSRR0_RX_READY)) {
1476 					/*
1477 					 * settle time for 1 character shift
1478 					 */
1479 					mutex_exit(zs->zs_excl_hi);
1480 					mutex_exit(zs->zs_excl);
1481 					delay(ztdelay(SPEED(
1482 					    za->za_ttycommon.t_cflag))/3 + 1);
1483 					mutex_enter(zs->zs_excl);
1484 					mutex_enter(zs->zs_excl_hi);
1485 					if (!(SCC_READ0() & ZSRR0_CD))
1486 						ZSA_KICK_RCV;
1487 				}
1488 				while ((SCC_READ0() &
1489 				    (ZSRR0_CD | ZSRR0_RX_READY)) ==
1490 				    ZSRR0_RX_READY) {
1491 					/*
1492 					 * Empty Receiver
1493 					 */
1494 					(void) SCC_READDATA();
1495 				}
1496 			}
1497 			mutex_exit(zs->zs_excl_hi);
1498 			flushq(RD(q), FLUSHDATA);
1499 			ZSA_QREPLY(q, mp);
1500 			/*
1501 			 * give the read queues a crack at it
1502 			 */
1503 		} else
1504 			freemsg(mp);
1505 
1506 		/*
1507 		 * We must make sure we process messages that survive the
1508 		 * write-side flush. Without this call, the close protocol
1509 		 * with ldterm can hang forever.  (ldterm will have sent us a
1510 		 * TCSBRK ioctl that it expects a response to.)
1511 		 */
1512 		zsa_start(zs);
1513 		mutex_exit(zs->zs_excl);
1514 		break;
1515 
1516 	case M_BREAK:
1517 	case M_DELAY:
1518 	case M_DATA:
1519 		mutex_enter(zs->zs_excl);
1520 		/*
1521 		 * Queue the message up to be transmitted,
1522 		 * and poke the start routine.
1523 		 */
1524 		(void) putq(q, mp);
1525 		zsa_start(zs);
1526 		mutex_exit(zs->zs_excl);
1527 		break;
1528 
1529 	case M_STOPI:
1530 		mutex_enter(zs->zs_excl);
1531 		mutex_enter(zs->zs_excl_hi);
1532 		za->za_flowc = za->za_ttycommon.t_stopc;
1533 		if ((zs->zs_wr_cur) != NULL) {
1534 			za->za_rcv_flags_mask &= ~DO_RETRANSMIT;
1535 			bp = za->za_xmitblk;
1536 			bp->b_rptr = zs->zs_wr_cur;
1537 			zs->zs_wr_cur = NULL;
1538 			zs->zs_wr_lim = NULL;
1539 			za->za_xmitblk = NULL;
1540 		}
1541 		mutex_exit(zs->zs_excl_hi);
1542 		if (bp)
1543 			(void) putbq(q, bp);
1544 		else
1545 			zsa_start(zs);		/* poke the start routine */
1546 		freemsg(mp);
1547 		mutex_exit(zs->zs_excl);
1548 		break;
1549 
1550 	case M_STARTI:
1551 		mutex_enter(zs->zs_excl);
1552 		mutex_enter(zs->zs_excl_hi);
1553 		za->za_flowc = za->za_ttycommon.t_startc;
1554 		if ((zs->zs_wr_cur) != NULL) {
1555 			za->za_rcv_flags_mask &= ~DO_RETRANSMIT;
1556 			bp = za->za_xmitblk;
1557 			bp->b_rptr = zs->zs_wr_cur;
1558 			zs->zs_wr_cur = NULL;
1559 			zs->zs_wr_lim = NULL;
1560 			za->za_xmitblk = NULL;
1561 		}
1562 		mutex_exit(zs->zs_excl_hi);
1563 		if (bp)
1564 			(void) putbq(q, bp);
1565 		else
1566 			zsa_start(zs);		/* poke the start routine */
1567 		freemsg(mp);
1568 		mutex_exit(zs->zs_excl);
1569 		break;
1570 
1571 	case M_CTL:
1572 		if (MBLKL(mp) >= sizeof (struct iocblk) &&
1573 		    ((struct iocblk *)mp->b_rptr)->ioc_cmd == MC_POSIXQUERY) {
1574 			((struct iocblk *)mp->b_rptr)->ioc_cmd = MC_HAS_POSIX;
1575 			qreply(q, mp);
1576 		} else {
1577 			/*
1578 			 * These MC_SERVICE type messages are used by upper
1579 			 * modules to tell this driver to send input up
1580 			 * immediately, or that it can wait for normal
1581 			 * processing that may or may not be done. Sun
1582 			 * requires these for the mouse module.
1583 			 */
1584 			mutex_enter(zs->zs_excl);
1585 			switch (*mp->b_rptr) {
1586 
1587 			case MC_SERVICEIMM:
1588 				mutex_enter(zs->zs_excl_hi);
1589 				za->za_flags |= ZAS_SERVICEIMM;
1590 				mutex_exit(zs->zs_excl_hi);
1591 				break;
1592 
1593 			case MC_SERVICEDEF:
1594 				mutex_enter(zs->zs_excl_hi);
1595 				za->za_flags &= ~ZAS_SERVICEIMM;
1596 				mutex_exit(zs->zs_excl_hi);
1597 				break;
1598 			}
1599 			freemsg(mp);
1600 			mutex_exit(zs->zs_excl);
1601 		}
1602 		break;
1603 
1604 	default:
1605 		/*
1606 		 * "No, I don't want a subscription to Chain Store Age,
1607 		 * thank you anyway."
1608 		 */
1609 		freemsg(mp);
1610 		break;
1611 	}
1612 	return (0);
1613 }
1614 
1615 /*
1616  * zs read service procedure
1617  */
1618 static int
1619 zsa_rsrv(queue_t *q)
1620 {
1621 	struct asyncline	*za;
1622 	struct zscom		*zs;
1623 
1624 	if (((za = (struct asyncline *)q->q_ptr) != NULL) &&
1625 	    (za->za_ttycommon.t_cflag & CRTSXOFF)) {
1626 		zs = za->za_common;
1627 		mutex_enter(zs->zs_excl_hi);
1628 		ZSSETSOFT(zs);
1629 		mutex_exit(zs->zs_excl_hi);
1630 	}
1631 	return (0);
1632 }
1633 
1634 /*
1635  * Transmitter interrupt service routine.
1636  * If there's more data to transmit in the current pseudo-DMA block,
1637  * and the transmitter is ready, send the next character if output
1638  * is not stopped or draining.
1639  * Otherwise, queue up a soft interrupt.
1640  */
1641 static void
1642 zsa_txint(struct zscom *zs)
1643 {
1644 	struct asyncline *za = (struct asyncline *)&zs->zs_priv_str;
1645 	uchar_t *wr_cur;
1646 	uchar_t s0;
1647 
1648 	s0 = SCC_READ0();
1649 
1650 	if ((wr_cur = zs->zs_wr_cur) != NULL) {
1651 		if (wr_cur < zs->zs_wr_lim) {
1652 			if ((za->za_ttycommon.t_cflag & CRTSCTS) &&
1653 			    !(s0 & ZSRR0_CTS)) {
1654 				SCC_WRITE0(ZSWR0_RESET_TXINT);
1655 				za->za_rcv_flags_mask |= DO_RETRANSMIT;
1656 				return;
1657 			}
1658 			SCC_WRITEDATA(*wr_cur++);
1659 #ifdef ZSA_DEBUG
1660 			za->za_wr++;
1661 #endif
1662 			zs->zs_wr_cur = wr_cur;
1663 			zs->zs_flags |= ZS_PROGRESS;
1664 			return;
1665 		} else {
1666 			zs->zs_wr_cur = NULL;
1667 			zs->zs_wr_lim = NULL;
1668 			/*
1669 			 * Use the rcv_flags_mask as it is set and
1670 			 * test while holding the zs_excl_hi mutex
1671 			 */
1672 			za->za_rcv_flags_mask |= DO_TRANSMIT;
1673 			SCC_WRITE0(ZSWR0_RESET_TXINT);
1674 			ZSSETSOFT(zs);
1675 			return;
1676 		}
1677 	}
1678 
1679 	if (za->za_flowc != '\0' && (!(za->za_flags & ZAS_DRAINING))) {
1680 		if ((za->za_ttycommon.t_cflag & CRTSCTS) &&
1681 		    !(s0 & ZSRR0_CTS)) {
1682 			SCC_WRITE0(ZSWR0_RESET_TXINT);
1683 			return;
1684 		}
1685 		SCC_WRITEDATA(za->za_flowc);
1686 		za->za_flowc = '\0';
1687 		return;
1688 	}
1689 	SCC_WRITE0(ZSWR0_RESET_TXINT);
1690 	/*
1691 	 * Set DO_TRANSMIT bit so that the soft interrupt can
1692 	 * test it and unset the ZAS_BUSY in za_flags while holding
1693 	 * the mutex zs_excl and zs_excl_hi
1694 	 */
1695 	za->za_rcv_flags_mask |= DO_TRANSMIT;
1696 	ZSSETSOFT(zs);
1697 }
1698 
1699 /*
1700  * External/Status interrupt.
1701  */
1702 static void
1703 zsa_xsint(struct zscom *zs)
1704 {
1705 	struct asyncline *za = (struct asyncline *)&zs->zs_priv_str;
1706 	uchar_t s0, x0;
1707 
1708 	s0 = SCC_READ0();
1709 	ZSA_R0_LOG(s0);
1710 	x0 = s0 ^ za->za_rr0;
1711 	za->za_rr0 = s0;
1712 	SCC_WRITE0(ZSWR0_RESET_STATUS);
1713 
1714 	/*
1715 	 * PPS (Pulse Per Second) support.
1716 	 */
1717 	if (za->za_pps && (x0 & ZSRR0_CD) && (s0 & ZSRR0_CD)) {
1718 		/*
1719 		 * This code captures a timestamp at the designated
1720 		 * transition of the PPS signal (CD asserted).  The
1721 		 * code provides a pointer to the timestamp, as well
1722 		 * as the hardware counter value at the capture.
1723 		 *
1724 		 * Note: the kernel has nano based time values while
1725 		 * NTP requires micro based, an in-line fast algorithm
1726 		 * to convert nsec to usec is used here -- see hrt2ts()
1727 		 * in common/os/timers.c for a full description.
1728 		 */
1729 		struct timeval *tvp = &ppsclockev.tv;
1730 		timespec_t ts;
1731 		int nsec, usec;
1732 
1733 		LED_OFF;
1734 		gethrestime(&ts);
1735 		LED_ON;
1736 		nsec = ts.tv_nsec;
1737 		usec = nsec + (nsec >> 2);
1738 		usec = nsec + (usec >> 1);
1739 		usec = nsec + (usec >> 2);
1740 		usec = nsec + (usec >> 4);
1741 		usec = nsec - (usec >> 3);
1742 		usec = nsec + (usec >> 2);
1743 		usec = nsec + (usec >> 3);
1744 		usec = nsec + (usec >> 4);
1745 		usec = nsec + (usec >> 1);
1746 		usec = nsec + (usec >> 6);
1747 		tvp->tv_usec = usec >> 10;
1748 		tvp->tv_sec = ts.tv_sec;
1749 
1750 		++ppsclockev.serial;
1751 
1752 		/*
1753 		 * Because the kernel keeps a high-resolution time, pass the
1754 		 * current highres timestamp in tvp and zero in usec.
1755 		 */
1756 		ddi_hardpps(tvp, 0);
1757 	}
1758 
1759 	ZSA_KICK_RCV;
1760 
1761 	if ((x0 & ZSRR0_BREAK) && (s0 & ZSRR0_BREAK) == 0) {
1762 #ifdef SLAVIO_BUG
1763 		/*
1764 		 * ZSRR0_BREAK turned off.  This means that the break sequence
1765 		 * has completed (i.e., the stop bit finally arrived).
1766 		 */
1767 		if ((s0 & ZSRR0_RX_READY) == 0) {
1768 			/*
1769 			 * SLAVIO will generate a separate STATUS change
1770 			 * interrupt when the break sequence completes.
1771 			 * SCC will combine both, taking the higher priority
1772 			 * one, the receive.  Should still see the ext/stat.
1773 			 * bit in REG3 on SCC.  If no ext/stat, it must be
1774 			 * a SLAVIO.
1775 			 */
1776 			za->za_breakoff = 1;
1777 		} else {
1778 			/*
1779 			 * The NUL character in the receiver is part of the
1780 			 * break sequence; it is discarded.
1781 			 */
1782 			(void) SCC_READDATA(); /* swallow null */
1783 		}
1784 #else /* SLAVIO_BUG */
1785 		/*
1786 		 * ZSRR0_BREAK turned off.  This means that the break sequence
1787 		 * has completed (i.e., the stop bit finally arrived).  The NUL
1788 		 * character in the receiver is part of the break sequence;
1789 		 * it is discarded.
1790 		 */
1791 		(void) SCC_READDATA(); /* swallow null */
1792 #endif /* SLAVIO_BUG */
1793 		SCC_WRITE0(ZSWR0_RESET_ERRORS);
1794 
1795 		/*
1796 		 * Note: this will cause an abort if a break occurs on
1797 		 * the "keyboard device", regardless of whether the
1798 		 * "keyboard device" is a real keyboard or just a
1799 		 * terminal on a serial line. This permits you to
1800 		 * abort a workstation by unplugging the keyboard,
1801 		 * even if the normal abort key sequence isn't working.
1802 		 */
1803 		if ((za->za_dev == kbddev) ||
1804 		    ((za->za_dev == rconsdev) || (za->za_dev == stdindev)) &&
1805 		    (abort_enable != KIOCABORTALTERNATE)) {
1806 			abort_sequence_enter((char *)NULL);
1807 			/*
1808 			 * We just broke into the monitor or debugger,
1809 			 * ignore the break in this case so whatever
1810 			 * random program that was running doesn't get
1811 			 * a SIGINT.
1812 			 */
1813 			return;
1814 		}
1815 		za->za_break = 1;
1816 	}
1817 
1818 	/*
1819 	 * If hardware flow control is enabled, (re)start output
1820 	 * when CTS is reasserted.
1821 	 */
1822 	if ((za->za_ttycommon.t_cflag & CRTSCTS) &&
1823 	    (x0 & ZSRR0_CTS) && (s0 & ZSRR0_CTS) &&
1824 	    (za->za_rcv_flags_mask & DO_RETRANSMIT))
1825 			za->za_rcv_flags_mask |= DO_TRANSMIT;
1826 
1827 	za->za_ext = 1;
1828 	ZSSETSOFT(zs);
1829 }
1830 
1831 /*
1832  * Receive Interrupt
1833  */
1834 static void
1835 zsa_rxint(struct zscom *zs)
1836 {
1837 	struct asyncline *za = (struct asyncline *)&zs->zs_priv_str;
1838 	uchar_t c;
1839 	uchar_t *rd_cur = zs->zs_rd_cur;
1840 	uchar_t *rd_lim = zs->zs_rd_lim;
1841 	mblk_t	*bp;
1842 	uint_t	fm = za->za_rcv_flags_mask;
1843 
1844 
1845 #ifdef ZSA_DEBUG
1846 	za->za_rd++;
1847 #endif
1848 	c = (fm >> 16) & (SCC_READDATA());
1849 
1850 	/*
1851 	 * Check for character break sequence
1852 	 */
1853 	if ((abort_enable == KIOCABORTALTERNATE) && (za->za_dev == rconsdev)) {
1854 		if (abort_charseq_recognize(c))
1855 			abort_sequence_enter((char *)NULL);
1856 	}
1857 
1858 	if (!rd_cur) {
1859 #ifdef SLAVIO_BUG
1860 		/*
1861 		 * SLAVIO generates FE for the start of break and
1862 		 * during break when parity is set.  End of break is
1863 		 * detected when the first character is received.
1864 		 * This character is always garbage and is thrown away.
1865 		 */
1866 		if (za->za_slav_break) {
1867 			za->za_slav_break = 0;
1868 			za->za_rr0 |= ZSRR0_BREAK;
1869 			zsa_xsint(zs);
1870 			return;
1871 		}
1872 #endif /* SLAVIO_BUG */
1873 
1874 		if (c == 0 && (za->za_rr0 & ZSRR0_BREAK)) {
1875 			/*
1876 			 * A break sequence was under way, and a NUL character
1877 			 * was received. Discard the NUL character, as it is
1878 			 * part of the break sequence; if ZSRR0_BREAK turned
1879 			 * off, indicating that the break sequence has com-
1880 			 * pleted, call "zsa_xsint" to properly handle the
1881 			 * error. It would appear that External/Status
1882 			 * interrupts get lost occasionally, so this ensures
1883 			 * that one is delivered.
1884 			 */
1885 			c = SCC_READ0();
1886 			if (!(c & ZSRR0_BREAK))
1887 				zsa_xsint(zs);
1888 			return;
1889 		}
1890 
1891 #ifdef SLAVIO_BUG
1892 		if (c == 0 && za->za_breakoff) {
1893 			/*
1894 			 * A break sequence completed, but SLAVIO generates
1895 			 * the NULL character interrupt late, so we throw the
1896 			 * NULL away now.
1897 			 */
1898 			return;
1899 		}
1900 
1901 		/*
1902 		 * make sure it gets cleared.
1903 		 */
1904 		za->za_breakoff = 0;
1905 #endif /* SLAVIO_BUG */
1906 
1907 		ZSA_KICK_RCV;	/* We can have M_BREAK msg */
1908 		ZSA_ALLOCB(bp);
1909 		if (!bp) {
1910 			za->za_sw_overrun++;
1911 			ZSSETSOFT(zs);
1912 			return;
1913 		}
1914 		za->za_rcvblk = bp;
1915 		zs->zs_rd_cur = rd_cur = bp->b_wptr;
1916 		zs->zs_rd_lim = rd_lim = bp->b_datap->db_lim;
1917 		if (za->za_kick_rcv_id == 0)
1918 			ZSSETSOFT(zs);
1919 	}
1920 	if (c == 0377 && (fm & DO_ESC)) {
1921 		if (rd_lim < rd_cur + 2) {
1922 			ZSA_ALLOCB(bp);
1923 			ZSA_KICK_RCV;
1924 			if (!bp) {
1925 				za->za_sw_overrun++;
1926 				return;
1927 			}
1928 			za->za_rcvblk = bp;
1929 			zs->zs_rd_cur = rd_cur = bp->b_wptr;
1930 			zs->zs_rd_lim = rd_lim = bp->b_datap->db_lim;
1931 		}
1932 		*rd_cur++ = c;
1933 	}
1934 
1935 
1936 	*rd_cur++ = c;
1937 	zs->zs_rd_cur = rd_cur;
1938 
1939 	if (rd_cur == rd_lim) {
1940 		ZSA_KICK_RCV;
1941 	} else if ((fm & DO_STOPC) && (c == (fm & 0xff))) {
1942 		za->za_do_kick_rcv_in_softint = 1;
1943 		ZSSETSOFT(zs);
1944 	}
1945 
1946 	if ((za->za_flags & ZAS_SERVICEIMM) || g_nocluster) {
1947 		/*
1948 		 * Send the data up immediately
1949 		 */
1950 		ZSA_KICK_RCV;
1951 	}
1952 }
1953 
1954 /*
1955  * Special receive condition interrupt handler.
1956  */
1957 static void
1958 zsa_srint(struct zscom *zs)
1959 {
1960 	struct asyncline *za = (struct asyncline *)&zs->zs_priv_str;
1961 	short s1;
1962 	uchar_t c;
1963 	uchar_t c1;
1964 	mblk_t *bp = za->za_rcvblk;
1965 	uchar_t *rd_cur = zs->zs_rd_cur;
1966 
1967 	SCC_READ(1, s1);
1968 	if (s1 & (ZSRR1_FE | ZSRR1_PE | ZSRR1_DO)) {
1969 		c = SCC_READDATA();	/* swallow bad character */
1970 	}
1971 #ifdef SLAVIO_BUG
1972 	/*
1973 	 * SLAVIO does not handle breaks properly when parity is enabled.
1974 	 *
1975 	 * In general, if a null character is received when a framing
1976 	 * error occurs then it is a break condition and not a real
1977 	 * framing error. The null character must be limited to the
1978 	 * number of bits including the parity bit. For example, a 6
1979 	 * bit character with parity would be null if the lower 7 bits
1980 	 * read from the receive fifo were 0. (The higher order bits are
1981 	 * padded with 1 and/or the stop bits.) The only exception to this
1982 	 * general rule would be an 8 bit null character with parity being
1983 	 * a 1 in the parity bit and a framing error. This exception
1984 	 * can be determined by examining the parity error bit in RREG 1.
1985 	 *
1986 	 * A null character, even parity, 8 bits, no parity error,
1987 	 * (0 0000 0000) with framing error is a break condition.
1988 	 *
1989 	 * A null character, even parity, 8 bits, parity error,
1990 	 * (1 0000 0000) with framing error is a framing error.
1991 	 *
1992 	 * A null character, odd parity, 8 bits, parity error
1993 	 * (0 0000 0000) with framing error is a break condition.
1994 	 *
1995 	 * A null character, odd parity, 8 bits, no parity error,
1996 	 * (1 0000 0000) with framing error is a framing error.
1997 	 */
1998 	if (za->za_ttycommon.t_cflag & PARENB) {
1999 		switch (za->za_ttycommon.t_cflag & CSIZE) {
2000 
2001 		case CS5:
2002 			c1 = c & 0x3f;
2003 			break;
2004 
2005 		case CS6:
2006 			c1 = c & 0x7f;
2007 			break;
2008 
2009 		case CS7:
2010 			c1 = c & 0xff;
2011 			break;
2012 
2013 		case CS8:
2014 			if ((za->za_ttycommon.t_cflag & PARODD) &&
2015 			    !(s1 & ZSRR1_PE))
2016 				c1 = 0xff;
2017 			else if (!(za->za_ttycommon.t_cflag & PARODD) &&
2018 			    (s1 & ZSRR1_PE))
2019 				c1 = 0xff;
2020 			else
2021 				c1 = c;
2022 			break;
2023 		}
2024 
2025 		/*
2026 		 * We fake start of break condition.
2027 		 */
2028 		if ((s1 & ZSRR1_FE) && c1 == 0) {
2029 			za->za_slav_break = 1;
2030 			return;
2031 		}
2032 	}
2033 #endif /* SLAVIO_BUG */
2034 
2035 	if (s1 & ZSRR1_PE) {
2036 
2037 		/*
2038 		 * Mark the parity error so zsa_process will
2039 		 * notice it and send it up in an M_BREAK
2040 		 * message; ldterm will do the actual parity error
2041 		 * processing
2042 		 */
2043 
2044 		if (bp && zs->zs_rd_cur) {	/* M_DATA msg */
2045 			ZSA_KICK_RCV;
2046 			bp = NULL;
2047 		}
2048 		if (!bp)
2049 			ZSA_ALLOCB(bp);
2050 		if (!bp) {
2051 			za->za_sw_overrun++;
2052 			ZSSETSOFT(zs);
2053 		} else {
2054 			za->za_rcvblk = bp;
2055 			zs->zs_rd_cur = rd_cur = bp->b_wptr;
2056 			zs->zs_rd_lim = bp->b_datap->db_lim;
2057 			*rd_cur++ = c;
2058 			zs->zs_rd_cur = rd_cur;
2059 			bp->b_datap->db_type = M_BREAK;
2060 			if (bp->b_datap->db_lim <= rd_cur)
2061 				ZSA_KICK_RCV;
2062 			za->za_do_kick_rcv_in_softint = 1;
2063 			ZSSETSOFT(zs);
2064 
2065 		}
2066 	}
2067 	SCC_WRITE0(ZSWR0_RESET_ERRORS);
2068 	if (s1 & ZSRR1_DO) {
2069 		za->za_hw_overrun++;
2070 		ZSSETSOFT(zs);
2071 	}
2072 }
2073 
2074 /*
2075  * Process software interrupts (or poll)
2076  * Crucial points:
2077  * 3.	BUG - breaks are handled "out-of-band" - their relative position
2078  *	among input events is lost, as well as multiple breaks together.
2079  *	This is probably not a problem in practice.
2080  */
2081 static int
2082 zsa_softint(struct zscom *zs)
2083 {
2084 	struct asyncline *za = (struct asyncline *)&zs->zs_priv_str;
2085 	uchar_t r0;
2086 	uchar_t za_kick_active;
2087 	int	m_error;
2088 	int	allocbcount = 0;
2089 	int	do_ttycommon_qfull = 0;
2090 	boolean_t	hangup = B_FALSE, unhangup = B_FALSE;
2091 	boolean_t	m_break = B_FALSE, wakeup = B_FALSE;
2092 	queue_t *q;
2093 	mblk_t	*bp;
2094 	mblk_t *head = NULL, *tail = NULL;
2095 
2096 	mutex_enter(zs->zs_excl);
2097 	if (zs->zs_suspended || (zs->zs_flags & ZS_CLOSED)) {
2098 		mutex_exit(zs->zs_excl);
2099 		return (0);
2100 	}
2101 	q = za->za_ttycommon.t_readq;
2102 	if (za->za_flags & ZAS_WOPEN && !q) {
2103 		if (za->za_ext) {
2104 			mutex_enter(zs->zs_excl_hi);
2105 			r0 = SCC_READ0();
2106 			za->za_ext = 0;
2107 			mutex_exit(zs->zs_excl_hi);
2108 			/*
2109 			 * carrier up?
2110 			 */
2111 			if ((r0 & ZSRR0_CD) ||
2112 			    (za->za_ttycommon.t_flags & TS_SOFTCAR)) {
2113 				/*
2114 				 * carrier present
2115 				 */
2116 				if ((za->za_flags & ZAS_CARR_ON) == 0) {
2117 					za->za_flags |= ZAS_CARR_ON;
2118 					mutex_exit(zs->zs_excl);
2119 					cv_broadcast(&zs->zs_flags_cv);
2120 					return (0);
2121 				}
2122 			}
2123 		}
2124 		mutex_exit(zs->zs_excl);
2125 		return (0);
2126 	}
2127 	q = za->za_ttycommon.t_readq;
2128 	if (!q) {
2129 		mutex_exit(zs->zs_excl);
2130 		return (0);
2131 	}
2132 
2133 	m_error = za->za_m_error;
2134 	za->za_m_error = 0;
2135 
2136 	if (za->za_do_kick_rcv_in_softint) {
2137 		mutex_enter(zs->zs_excl_hi);
2138 		ZSA_KICK_RCV;
2139 		za->za_do_kick_rcv_in_softint = 0;
2140 		mutex_exit(zs->zs_excl_hi);
2141 	}
2142 
2143 	za_kick_active = za->za_kick_active;
2144 
2145 	while (!za_kick_active) {
2146 		ZSA_SEEQ(bp);
2147 		if (!bp)
2148 			break;
2149 
2150 		allocbcount++;
2151 
2152 		if (bp->b_datap->db_type <= QPCTL) {
2153 			if (!(canputnext(q))) {
2154 				if (za->za_grace_flow_control >=
2155 				    zsa_grace_flow_control) {
2156 					if (za->za_ttycommon.t_cflag &
2157 					    CRTSXOFF) {
2158 						allocbcount--;
2159 						break;
2160 					}
2161 					ZSA_GETQ(bp);
2162 					freemsg(bp);
2163 					do_ttycommon_qfull = 1;
2164 					continue;
2165 				} else
2166 					za->za_grace_flow_control++;
2167 			} else
2168 				za->za_grace_flow_control = 0;
2169 		}
2170 		ZSA_GETQ(bp);
2171 		if (!head) {
2172 			head = bp;
2173 		} else {
2174 			if (!tail)
2175 				tail = head;
2176 			tail->b_next = bp;
2177 			tail = bp;
2178 		}
2179 	}
2180 
2181 	if (allocbcount)
2182 		ZSA_GETBLOCK(zs, allocbcount);
2183 
2184 	if (za->za_ext) {
2185 		mutex_enter(zs->zs_excl_hi);
2186 		r0 = SCC_READ0();
2187 		za->za_ext = 0;
2188 		/*
2189 		 * carrier up?
2190 		 */
2191 		if ((r0 & ZSRR0_CD) ||
2192 		    (za->za_ttycommon.t_flags & TS_SOFTCAR)) {
2193 			/*
2194 			 * carrier present
2195 			 */
2196 			if ((za->za_flags & ZAS_CARR_ON) == 0) {
2197 				za->za_flags |= ZAS_CARR_ON;
2198 				unhangup = B_TRUE;
2199 				wakeup = B_TRUE;
2200 			}
2201 		} else {
2202 			if ((za->za_flags & ZAS_CARR_ON) &&
2203 			    !(za->za_ttycommon.t_cflag & CLOCAL)) {
2204 				/*
2205 				 * Carrier went away.
2206 				 * Drop DTR, abort any output in progress,
2207 				 * indicate that output is not stopped, and
2208 				 * send a hangup notification upstream.
2209 				 */
2210 				(void) zsmctl(zs, ZSWR5_DTR, DMBIC);
2211 				if ((za->za_flags & ZAS_BUSY) &&
2212 				    (zs->zs_wr_cur != NULL)) {
2213 					zs->zs_wr_cur = NULL;
2214 					zs->zs_wr_lim = NULL;
2215 				}
2216 				hangup = B_TRUE;
2217 				wakeup = B_TRUE;
2218 				za->za_flags &= ~(ZAS_STOPPED | ZAS_CARR_ON |
2219 				    ZAS_BUSY);
2220 				za->za_rcv_flags_mask &= ~(DO_TRANSMIT |
2221 				    DO_RETRANSMIT);
2222 			}
2223 		}
2224 		mutex_exit(zs->zs_excl_hi);
2225 		if (hangup && (bp = za->za_xmitblk) != NULL) {
2226 			za->za_xmitblk = NULL;
2227 			freeb(bp);
2228 		}
2229 	}
2230 
2231 	if (za->za_break != 0) {
2232 		mutex_enter(zs->zs_excl_hi);
2233 		r0 = SCC_READ0();
2234 		mutex_exit(zs->zs_excl_hi);
2235 		if ((r0 & ZSRR0_BREAK) == 0) {
2236 			za->za_break = 0;
2237 			m_break = B_TRUE;
2238 		}
2239 	}
2240 
2241 	/*
2242 	 * If a transmission has finished, indicate that it's
2243 	 * finished, and start that line up again.
2244 	 */
2245 
2246 	mutex_enter(zs->zs_excl_hi);
2247 	if (za->za_rcv_flags_mask & DO_TRANSMIT) {
2248 		za->za_rcv_flags_mask &= ~DO_TRANSMIT;
2249 		za->za_flags &= ~ZAS_BUSY;
2250 
2251 		if ((za->za_ttycommon.t_cflag & CRTSCTS) &&
2252 		    (za->za_rcv_flags_mask & DO_RETRANSMIT) &&
2253 		    zs->zs_wr_cur)
2254 			bp = NULL;
2255 		else {
2256 			za->za_rcv_flags_mask &= ~DO_RETRANSMIT;
2257 			bp = za->za_xmitblk;
2258 			za->za_xmitblk = 0;
2259 		}
2260 		mutex_exit(zs->zs_excl_hi);
2261 		if (bp)
2262 			freemsg(bp);
2263 		zsa_start(zs);
2264 		/* if we didn't start anything, then notify waiters */
2265 		if (!(za->za_flags & ZAS_BUSY))
2266 			wakeup = B_TRUE;
2267 	} else {
2268 		mutex_exit(zs->zs_excl_hi);
2269 	}
2270 
2271 
2272 	/*
2273 	 * A note about these overrun bits: all they do is *tell* someone
2274 	 * about an error- They do not track multiple errors. In fact,
2275 	 * you could consider them latched register bits if you like.
2276 	 * We are only interested in printing the error message once for
2277 	 * any cluster of overrun errors.
2278 	 */
2279 	if ((!za->za_kick_rcv_id) && (zs->zs_rd_cur || za_kick_active)) {
2280 		if (g_zsticks)
2281 			za->za_kick_rcv_id = timeout(zsa_kick_rcv, zs,
2282 			    g_zsticks);
2283 		else
2284 			za->za_kick_rcv_id = timeout(zsa_kick_rcv, zs,
2285 			    zsticks[SPEED(za->za_ttycommon.t_cflag)]);
2286 		za->za_kick_rcv_count = ZA_KICK_RCV_COUNT;
2287 	}
2288 	za->za_soft_active = 1;
2289 	mutex_exit(zs->zs_excl);
2290 
2291 	if (!hangup && do_ttycommon_qfull) {
2292 		ttycommon_qfull(&za->za_ttycommon, q);
2293 		mutex_enter(zs->zs_excl);
2294 		zsa_start(zs);
2295 		mutex_exit(zs->zs_excl);
2296 	}
2297 
2298 	if (za->za_hw_overrun > 10) {
2299 		cmn_err(CE_NOTE, "zs%d: silo overflow\n", UNIT(za->za_dev));
2300 		za->za_hw_overrun = 0;
2301 	}
2302 
2303 	if (za->za_sw_overrun > 10) {
2304 		cmn_err(CE_NOTE, "zs%d:ring buffer overflow\n",
2305 		    UNIT(za->za_dev));
2306 		za->za_sw_overrun = 0;
2307 	}
2308 
2309 	if (unhangup)
2310 		(void) putnextctl(q, M_UNHANGUP);
2311 
2312 	if (m_break)
2313 		(void) putnextctl(q, M_BREAK);
2314 
2315 	while (head) {
2316 		if (!tail) {
2317 			putnext(q, head);
2318 			break;
2319 		}
2320 		bp = head;
2321 		head = head->b_next;
2322 		bp->b_next = NULL;
2323 		putnext(q, bp);
2324 	}
2325 
2326 	if (hangup) {
2327 		int flushflag;
2328 
2329 		/*
2330 		 * If we're in the midst of close, then flush everything.  Don't
2331 		 * leave stale ioctls lying about.
2332 		 */
2333 		flushflag = (zs->zs_flags & ZS_CLOSING) ? FLUSHALL : FLUSHDATA;
2334 		flushq(za->za_ttycommon.t_writeq, flushflag);
2335 		(void) putnextctl(q, M_HANGUP);
2336 	}
2337 
2338 	if (m_error)
2339 		(void) putnextctl1(q, M_ERROR, m_error);
2340 
2341 	za->za_soft_active = 0;
2342 
2343 	if (wakeup || (zs->zs_flags & ZS_CLOSED))
2344 		cv_broadcast(&zs->zs_flags_cv);
2345 
2346 	return (0);
2347 }
2348 
2349 /*
2350  * Start output on a line, unless it's busy, frozen, or otherwise.
2351  */
2352 static void
2353 zsa_start(struct zscom *zs)
2354 {
2355 	struct asyncline *za = (struct asyncline *)&zs->zs_priv_str;
2356 	int cc;
2357 	queue_t *q;
2358 	mblk_t *bp;
2359 	uchar_t *rptr, *wptr;
2360 
2361 	/*
2362 	 * If the chip is busy (i.e., we're waiting for a break timeout
2363 	 * to expire, or for the current transmission to finish, or for
2364 	 * output to finish draining from chip), don't grab anything new.
2365 	 */
2366 	if ((za->za_flags & (ZAS_BREAK|ZAS_BUSY|ZAS_DRAINING)) ||
2367 	    zs->zs_suspended)
2368 		return;
2369 
2370 	if (za->za_ttycommon.t_cflag & CRTSCTS) {
2371 		mutex_enter(zs->zs_excl_hi);
2372 		if (za->za_rcv_flags_mask & DO_RETRANSMIT) {
2373 			rptr = zs->zs_wr_cur;
2374 			wptr = zs->zs_wr_lim;
2375 			goto zsa_start_retransmit;
2376 
2377 		}
2378 		mutex_exit(zs->zs_excl_hi);
2379 	}
2380 
2381 	/*
2382 	 * If we have a flow-control character to transmit, do it now.
2383 	 */
2384 	if (za->za_flowc != '\0') {
2385 		mutex_enter(zs->zs_excl_hi);
2386 		if (za->za_ttycommon.t_cflag & CRTSCTS) {
2387 			if ((SCC_READ0() & (ZSRR0_CTS|ZSRR0_TX_READY)) !=
2388 			    (ZSRR0_CTS|ZSRR0_TX_READY)) {
2389 				mutex_exit(zs->zs_excl_hi);
2390 				return;
2391 			}
2392 		} else if (!(SCC_READ0() & ZSRR0_TX_READY)) {
2393 			mutex_exit(zs->zs_excl_hi);
2394 			return;
2395 		}
2396 
2397 		ZSDELAY();
2398 		SCC_WRITEDATA(za->za_flowc);
2399 		za->za_flowc = '\0';
2400 		mutex_exit(zs->zs_excl_hi);
2401 		return;
2402 	}
2403 
2404 	/*
2405 	 * If we're waiting for a delay timeout to expire, don't grab
2406 	 * anything new.
2407 	 */
2408 	if (za->za_flags & ZAS_DELAY)
2409 		return;
2410 
2411 	if ((q = za->za_ttycommon.t_writeq) == NULL)
2412 		return;	/* not attached to a stream */
2413 
2414 zsa_start_again:
2415 	for (;;) {
2416 		if ((bp = getq(q)) == NULL)
2417 			return;	/* no data to transmit */
2418 
2419 		/*
2420 		 * We have a message block to work on.
2421 		 * Check whether it's a break, a delay, or an ioctl (the latter
2422 		 * occurs if the ioctl in question was waiting for the output
2423 		 * to drain). If it's one of those, process it immediately.
2424 		 */
2425 		switch (bp->b_datap->db_type) {
2426 
2427 		case M_BREAK:
2428 			/*
2429 			 * Set the break bit, and arrange for "zsa_restart"
2430 			 * to be called in 1/4 second; it will turn the
2431 			 * break bit off, and call "zsa_start" to grab
2432 			 * the next message.
2433 			 */
2434 			mutex_enter(zs->zs_excl_hi);
2435 			SCC_BIS(5, ZSWR5_BREAK);
2436 			mutex_exit(zs->zs_excl_hi);
2437 			if (!za->za_zsa_restart_id) {
2438 				za->za_zsa_restart_id =
2439 				    timeout(zsa_restart, zs, hz/4);
2440 			}
2441 			za->za_flags |= ZAS_BREAK;
2442 			freemsg(bp);
2443 			return;	/* wait for this to finish */
2444 
2445 		case M_DELAY:
2446 			/*
2447 			 * Arrange for "zsa_restart" to be called when the
2448 			 * delay expires; it will turn MTS_DELAY off,
2449 			 * and call "zsa_start" to grab the next message.
2450 			 */
2451 			if (! za->za_zsa_restart_id) {
2452 				za->za_zsa_restart_id = timeout(zsa_restart,
2453 				    zs,
2454 				    (int)(*(unsigned char *)bp->b_rptr + 6));
2455 			}
2456 			za->za_flags |= ZAS_DELAY;
2457 			freemsg(bp);
2458 			return;	/* wait for this to finish */
2459 
2460 		case M_IOCTL:
2461 			/*
2462 			 * This ioctl was waiting for the output ahead of
2463 			 * it to drain; obviously, it has. Do it, and
2464 			 * then grab the next message after it.
2465 			 */
2466 			zsa_ioctl(za, q, bp);
2467 			continue;
2468 		default: /* M_DATA */
2469 			goto zsa_start_transmit;
2470 		}
2471 
2472 	}
2473 zsa_start_transmit:
2474 	/*
2475 	 * We have data to transmit. If output is stopped, put
2476 	 * it back and try again later.
2477 	 */
2478 	if (za->za_flags & ZAS_STOPPED) {
2479 		(void) putbq(q, bp);
2480 		return;
2481 	}
2482 
2483 	za->za_xmitblk = bp;
2484 	rptr = bp->b_rptr;
2485 	wptr = bp->b_wptr;
2486 	cc = wptr - rptr;
2487 	bp = bp->b_cont;
2488 	if (bp != NULL) {
2489 		za->za_xmitblk->b_cont = NULL;
2490 		(void) putbq(q, bp);	/* not done with this message yet */
2491 	}
2492 
2493 	if (rptr >= wptr) {
2494 		freeb(za->za_xmitblk);
2495 		za->za_xmitblk = NULL;
2496 		goto zsa_start_again;
2497 	}
2498 
2499 	/*
2500 	 * In 5-bit mode, the high order bits are used
2501 	 * to indicate character sizes less than five,
2502 	 * so we need to explicitly mask before transmitting
2503 	 */
2504 	if ((za->za_ttycommon.t_cflag & CSIZE) == CS5) {
2505 		unsigned char *p = rptr;
2506 		int cnt = cc;
2507 
2508 		while (cnt--)
2509 			*p++ &= (unsigned char) 0x1f;
2510 	}
2511 
2512 	/*
2513 	 * Set up this block for pseudo-DMA.
2514 	 */
2515 
2516 	mutex_enter(zs->zs_excl_hi);
2517 	zs->zs_wr_cur = rptr;
2518 	zs->zs_wr_lim = wptr;
2519 
2520 zsa_start_retransmit:
2521 	za->za_rcv_flags_mask &= ~DO_TRANSMIT;
2522 	if (za->za_ttycommon.t_cflag & CRTSCTS) {
2523 		if ((SCC_READ0() & (ZSRR0_CTS|ZSRR0_TX_READY)) !=
2524 		    (ZSRR0_CTS|ZSRR0_TX_READY)) {
2525 			za->za_rcv_flags_mask |= DO_RETRANSMIT;
2526 			za->za_flags |= ZAS_BUSY;
2527 			mutex_exit(zs->zs_excl_hi);
2528 			return;
2529 		}
2530 		za->za_rcv_flags_mask &= ~DO_RETRANSMIT;
2531 	} else {
2532 		if (!(SCC_READ0() & ZSRR0_TX_READY)) {
2533 			za->za_flags |= ZAS_BUSY;
2534 			mutex_exit(zs->zs_excl_hi);
2535 			return;
2536 		}
2537 	}
2538 	/*
2539 	 * If the transmitter is ready, shove the first
2540 	 * character out.
2541 	 */
2542 	ZSDELAY();
2543 	SCC_WRITEDATA(*rptr++);
2544 #ifdef ZSA_DEBUG
2545 	za->za_wr++;
2546 #endif
2547 	zs->zs_wr_cur = rptr;
2548 	za->za_flags |= ZAS_BUSY;
2549 	zs->zs_flags |= ZS_PROGRESS;
2550 	mutex_exit(zs->zs_excl_hi);
2551 }
2552 
2553 /*
2554  * Restart output on a line after a delay or break timer expired.
2555  */
2556 static void
2557 zsa_restart(void *arg)
2558 {
2559 	struct zscom *zs = arg;
2560 	struct asyncline *za = (struct asyncline *)&zs->zs_priv_str;
2561 
2562 	/*
2563 	 * If break timer expired, turn off the break bit.
2564 	 */
2565 	mutex_enter(zs->zs_excl);
2566 	if (!za->za_zsa_restart_id) {
2567 		mutex_exit(zs->zs_excl);
2568 		return;
2569 	}
2570 	za->za_zsa_restart_id = 0;
2571 	if (za->za_flags & ZAS_BREAK) {
2572 		mutex_enter(zs->zs_excl_hi);
2573 		SCC_BIC(5, ZSWR5_BREAK);
2574 		mutex_exit(zs->zs_excl_hi);
2575 	}
2576 	za->za_flags &= ~(ZAS_DELAY|ZAS_BREAK);
2577 	if (za->za_ttycommon.t_writeq != NULL)
2578 		zsa_start(zs);
2579 	mutex_exit(zs->zs_excl);
2580 	cv_broadcast(&zs->zs_flags_cv);
2581 }
2582 
2583 /*
2584  * See if the receiver has any data after zs_tick delay
2585  */
2586 static void
2587 zsa_kick_rcv(void *arg)
2588 {
2589 	struct zscom *zs = arg;
2590 	struct asyncline *za = (struct asyncline *)&zs->zs_priv_str;
2591 	queue_t *q;
2592 	int	tmp;
2593 	mblk_t	*mp;
2594 	uchar_t za_soft_active, za_kick_active;
2595 	int	allocbcount = 0;
2596 	int do_ttycommon_qfull = 0;
2597 	mblk_t *head = NULL, *tail = NULL;
2598 
2599 	mutex_enter(zs->zs_excl);
2600 	if (za->za_kick_rcv_id == 0 || (zs->zs_flags & ZS_CLOSED)) {
2601 		mutex_exit(zs->zs_excl);
2602 		return;
2603 	}
2604 	za_soft_active = za->za_soft_active;
2605 	za_kick_active = za->za_kick_active;
2606 	q = za->za_ttycommon.t_readq;
2607 	if (!q) {
2608 		mutex_exit(zs->zs_excl);
2609 		return;
2610 	}
2611 	mutex_enter(zs->zs_excl_hi);
2612 	if (zs->zs_rd_cur) {
2613 		ZSA_KICK_RCV;
2614 		za->za_kick_rcv_count = tmp = ZA_KICK_RCV_COUNT;
2615 	} else
2616 		tmp = --za->za_kick_rcv_count;
2617 	if (tmp > 0 || za_soft_active || za_kick_active) {
2618 		mutex_exit(zs->zs_excl_hi);
2619 		if (g_zsticks)
2620 			za->za_kick_rcv_id = timeout(zsa_kick_rcv,
2621 			    zs, g_zsticks);
2622 		else
2623 			za->za_kick_rcv_id = timeout(zsa_kick_rcv,
2624 			    zs, zsticks[SPEED(za->za_ttycommon.t_cflag)]);
2625 		if (za_soft_active || za_kick_active) {
2626 			mutex_exit(zs->zs_excl);
2627 			return;
2628 		}
2629 	} else {
2630 		za->za_kick_rcv_id = 0;
2631 		mutex_exit(zs->zs_excl_hi);
2632 	}
2633 
2634 
2635 	for (;;) {
2636 		ZSA_SEEQ(mp);
2637 		if (!mp)
2638 			break;
2639 
2640 		allocbcount++;
2641 
2642 		if (mp->b_datap->db_type <= QPCTL) {
2643 			if (!(canputnext(q))) {
2644 				if (za->za_grace_flow_control >=
2645 				    zsa_grace_flow_control) {
2646 					if (za->za_ttycommon.t_cflag &
2647 					    CRTSXOFF) {
2648 						allocbcount--;
2649 						break;
2650 					}
2651 					ZSA_GETQ(mp);
2652 					freemsg(mp);
2653 					do_ttycommon_qfull = 1;
2654 					continue;
2655 				} else
2656 					za->za_grace_flow_control++;
2657 			} else
2658 				za->za_grace_flow_control = 0;
2659 		}
2660 		ZSA_GETQ(mp);
2661 		if (!head) {
2662 			head = mp;
2663 		} else {
2664 			if (!tail)
2665 				tail = head;
2666 			tail->b_next = mp;
2667 			tail = mp;
2668 		}
2669 	}
2670 
2671 	if (allocbcount)
2672 		ZSA_GETBLOCK(zs, allocbcount);
2673 
2674 	za->za_kick_active = 1;
2675 	mutex_exit(zs->zs_excl);
2676 
2677 	if (do_ttycommon_qfull) {
2678 		ttycommon_qfull(&za->za_ttycommon, q);
2679 		mutex_enter(zs->zs_excl);
2680 		zsa_start(zs);
2681 		mutex_exit(zs->zs_excl);
2682 	}
2683 
2684 	while (head) {
2685 		if (!tail) {
2686 			putnext(q, head);
2687 			break;
2688 		}
2689 		mp = head;
2690 		head = head->b_next;
2691 		mp->b_next = NULL;
2692 		putnext(q, mp);
2693 
2694 	}
2695 	za->za_kick_active = 0;
2696 
2697 	if (zs->zs_flags & ZS_CLOSED)
2698 		cv_broadcast(&zs->zs_flags_cv);
2699 }
2700 
2701 /*
2702  * Retry an "ioctl", now that "bufcall" claims we may be able to allocate
2703  * the buffer we need.
2704  */
2705 static void
2706 zsa_reioctl(void *arg)
2707 {
2708 	struct asyncline *za = arg;
2709 	struct zscom *zs = za->za_common;
2710 	queue_t *q;
2711 	mblk_t	 *mp;
2712 
2713 	/*
2714 	 * The bufcall is no longer pending.
2715 	 */
2716 	mutex_enter(zs->zs_excl);
2717 	if (!za->za_wbufcid) {
2718 		mutex_exit(zs->zs_excl);
2719 		return;
2720 	}
2721 	za->za_wbufcid = 0;
2722 	if ((q = za->za_ttycommon.t_writeq) == NULL) {
2723 		mutex_exit(zs->zs_excl);
2724 		return;
2725 	}
2726 	if ((mp = za->za_ttycommon.t_iocpending) != NULL) {
2727 		/*
2728 		 * not pending any more
2729 		 */
2730 		za->za_ttycommon.t_iocpending = NULL;
2731 		zsa_ioctl(za, q, mp);
2732 	}
2733 	mutex_exit(zs->zs_excl);
2734 }
2735 
2736 /*
2737  * Process an "ioctl" message sent down to us.
2738  * Note that we don't need to get any locks until we are ready to access
2739  * the hardware. Nothing we access until then is going to be altered
2740  * outside of the STREAMS framework, so we should be safe.
2741  */
2742 static void
2743 zsa_ioctl(struct asyncline *za, queue_t *wq, mblk_t *mp)
2744 {
2745 	struct zscom *zs = za->za_common;
2746 	struct iocblk *iocp;
2747 	unsigned datasize;
2748 	int error;
2749 	mblk_t *tmp;
2750 
2751 	if (za->za_ttycommon.t_iocpending != NULL) {
2752 		/*
2753 		 * We were holding an "ioctl" response pending the
2754 		 * availability of an "mblk" to hold data to be passed up;
2755 		 * another "ioctl" came through, which means that "ioctl"
2756 		 * must have timed out or been aborted.
2757 		 */
2758 		freemsg(za->za_ttycommon.t_iocpending);
2759 		za->za_ttycommon.t_iocpending = NULL;
2760 	}
2761 
2762 	iocp = (struct iocblk *)mp->b_rptr;
2763 
2764 	/*
2765 	 * The only way in which "ttycommon_ioctl" can fail is if the "ioctl"
2766 	 * requires a response containing data to be returned to the user,
2767 	 * and no mblk could be allocated for the data.
2768 	 * No such "ioctl" alters our state. Thus, we always go ahead and
2769 	 * do any state-changes the "ioctl" calls for. If we couldn't allocate
2770 	 * the data, "ttycommon_ioctl" has stashed the "ioctl" away safely, so
2771 	 * we just call "bufcall" to request that we be called back when we
2772 	 * stand a better chance of allocating the data.
2773 	 */
2774 	mutex_exit(zs->zs_excl);
2775 	datasize = ttycommon_ioctl(&za->za_ttycommon, wq, mp, &error);
2776 	mutex_enter(zs->zs_excl);
2777 	if (za->za_ttycommon.t_flags & TS_SOFTCAR)
2778 		zssoftCAR[zs->zs_unit] = 1;
2779 	else
2780 		zssoftCAR[zs->zs_unit] = 0;
2781 	if (datasize != 0) {
2782 		if (za->za_wbufcid)
2783 			unbufcall(za->za_wbufcid);
2784 		za->za_wbufcid = bufcall(datasize, BPRI_HI, zsa_reioctl, za);
2785 		return;
2786 	}
2787 
2788 
2789 	if (error == 0) {
2790 		/*
2791 		 * "ttycommon_ioctl" did most of the work; we just use the
2792 		 * data it set up.
2793 		 */
2794 		switch (iocp->ioc_cmd) {
2795 
2796 		case TCSETS:
2797 		case TCSETSW:
2798 		case TCSETSF:
2799 		case TCSETA:
2800 		case TCSETAW:
2801 		case TCSETAF:
2802 			mutex_enter(zs->zs_excl_hi);
2803 			zsa_program(za, 1);
2804 			zsa_set_za_rcv_flags_mask(za);
2805 			mutex_exit(zs->zs_excl_hi);
2806 			break;
2807 		}
2808 	} else if (error < 0) {
2809 		/*
2810 		 * "ttycommon_ioctl" didn't do anything; we process it here.
2811 		 */
2812 		error = 0;
2813 
2814 		switch (iocp->ioc_cmd) {
2815 
2816 		case TCSBRK:
2817 			error = miocpullup(mp, sizeof (int));
2818 			if (error != 0)
2819 				break;
2820 
2821 			if (*(int *)mp->b_cont->b_rptr == 0) {
2822 				/*
2823 				 * The delay ensures that a 3 byte transmit
2824 				 * fifo is empty.
2825 				 */
2826 				mutex_exit(zs->zs_excl);
2827 				delay(ztdelay(SPEED(za->za_ttycommon.t_cflag)));
2828 				mutex_enter(zs->zs_excl);
2829 
2830 				/*
2831 				 * Set the break bit, and arrange for
2832 				 * "zsa_restart" to be called in 1/4 second;
2833 				 * it will turn the break bit off, and call
2834 				 * "zsa_start" to grab the next message.
2835 				 */
2836 				mutex_enter(zs->zs_excl_hi);
2837 				SCC_BIS(5, ZSWR5_BREAK);
2838 				if (!za->za_zsa_restart_id) {
2839 					mutex_exit(zs->zs_excl_hi);
2840 					za->za_zsa_restart_id =
2841 					    timeout(zsa_restart, zs, hz / 4);
2842 					mutex_enter(zs->zs_excl_hi);
2843 				}
2844 				za->za_flags |= ZAS_BREAK;
2845 				mutex_exit(zs->zs_excl_hi);
2846 			}
2847 			break;
2848 
2849 		case TIOCSBRK:
2850 			mutex_enter(zs->zs_excl_hi);
2851 			SCC_BIS(5, ZSWR5_BREAK);
2852 			mutex_exit(zs->zs_excl_hi);
2853 			mioc2ack(mp, NULL, 0, 0);
2854 			break;
2855 
2856 		case TIOCCBRK:
2857 			mutex_enter(zs->zs_excl_hi);
2858 			SCC_BIC(5, ZSWR5_BREAK);
2859 			mutex_exit(zs->zs_excl_hi);
2860 			mioc2ack(mp, NULL, 0, 0);
2861 			break;
2862 
2863 		case TIOCMSET:
2864 		case TIOCMBIS:
2865 		case TIOCMBIC: {
2866 			int mlines;
2867 
2868 			if (iocp->ioc_count == TRANSPARENT) {
2869 				mcopyin(mp, NULL, sizeof (int), NULL);
2870 				break;
2871 			}
2872 
2873 			error = miocpullup(mp, sizeof (int));
2874 			if (error != 0)
2875 				break;
2876 
2877 			mlines = *(int *)mp->b_cont->b_rptr;
2878 
2879 			mutex_enter(zs->zs_excl_hi);
2880 			switch (iocp->ioc_cmd) {
2881 			case TIOCMSET:
2882 				(void) zsmctl(zs, dmtozs(mlines), DMSET);
2883 				break;
2884 			case TIOCMBIS:
2885 				(void) zsmctl(zs, dmtozs(mlines), DMBIS);
2886 				break;
2887 			case TIOCMBIC:
2888 				(void) zsmctl(zs, dmtozs(mlines), DMBIC);
2889 				break;
2890 			}
2891 			mutex_exit(zs->zs_excl_hi);
2892 
2893 			mioc2ack(mp, NULL, 0, 0);
2894 			break;
2895 		}
2896 
2897 		case TIOCMGET:
2898 			tmp = allocb(sizeof (int), BPRI_MED);
2899 			if (tmp == NULL) {
2900 				error = EAGAIN;
2901 				break;
2902 			}
2903 			if (iocp->ioc_count != TRANSPARENT)
2904 				mioc2ack(mp, tmp, sizeof (int), 0);
2905 			else
2906 				mcopyout(mp, NULL, sizeof (int), NULL, tmp);
2907 
2908 			mutex_enter(zs->zs_excl_hi);
2909 			*(int *)mp->b_cont->b_rptr =
2910 			    zstodm(zsmctl(zs, 0, DMGET));
2911 			mutex_exit(zs->zs_excl_hi);
2912 			/*
2913 			 * qreply done below
2914 			 */
2915 			break;
2916 
2917 		default:
2918 			/*
2919 			 * If we don't understand it, it's an error. NAK it.
2920 			 */
2921 			error = EINVAL;
2922 			break;
2923 		}
2924 	}
2925 
2926 	if (error != 0) {
2927 		iocp->ioc_error = error;
2928 		mp->b_datap->db_type = M_IOCNAK;
2929 	}
2930 
2931 	ZSA_QREPLY(wq, mp);
2932 }
2933 
2934 
2935 static int
2936 dmtozs(int bits)
2937 {
2938 	int b = 0;
2939 
2940 	if (bits & TIOCM_CAR)
2941 		b |= ZSRR0_CD;
2942 	if (bits & TIOCM_CTS)
2943 		b |= ZSRR0_CTS;
2944 	if (bits & TIOCM_RTS)
2945 		b |= ZSWR5_RTS;
2946 	if (bits & TIOCM_DTR)
2947 		b |= ZSWR5_DTR;
2948 	return (b);
2949 }
2950 
2951 static int
2952 zstodm(int bits)
2953 {
2954 	int b;
2955 
2956 	b = 0;
2957 	if (bits & ZSRR0_CD)
2958 		b |= TIOCM_CAR;
2959 	if (bits & ZSRR0_CTS)
2960 		b |= TIOCM_CTS;
2961 	if (bits & ZSWR5_RTS)
2962 		b |= TIOCM_RTS;
2963 	if (bits & ZSWR5_DTR)
2964 		b |= TIOCM_DTR;
2965 	return (b);
2966 }
2967 
2968 /*
2969  * Assemble registers and flags necessary to program the port to our liking.
2970  * For async operation, most of this is based on the values of
2971  * the "c_iflag" and "c_cflag" fields supplied to us.
2972  */
2973 static void
2974 zsa_program(struct asyncline *za, int setibaud)
2975 {
2976 	struct zscom *zs = za->za_common;
2977 	struct zs_prog *zspp;
2978 	int wr3, wr4, wr5, wr15, speed, baudrate, flags = 0;
2979 
2980 	if ((baudrate = SPEED(za->za_ttycommon.t_cflag)) == 0) {
2981 		/*
2982 		 * Hang up line.
2983 		 */
2984 		(void) zsmctl(zs, ZS_OFF, DMSET);
2985 		return;
2986 	}
2987 
2988 	/*
2989 	 * set input speed same as output, as split speed not supported
2990 	 */
2991 	if (setibaud) {
2992 		za->za_ttycommon.t_cflag &= ~(CIBAUD);
2993 		if (baudrate > CBAUD) {
2994 			za->za_ttycommon.t_cflag |= CIBAUDEXT;
2995 			za->za_ttycommon.t_cflag |=
2996 			    (((baudrate - CBAUD - 1) << IBSHIFT) & CIBAUD);
2997 		} else {
2998 			za->za_ttycommon.t_cflag &= ~CIBAUDEXT;
2999 			za->za_ttycommon.t_cflag |=
3000 			    ((baudrate << IBSHIFT) & CIBAUD);
3001 		}
3002 	}
3003 
3004 	/*
3005 	 * Do not allow the console/keyboard device to have its receiver
3006 	 * disabled; doing that would mean you couldn't type an abort
3007 	 * sequence.
3008 	 */
3009 	if ((za->za_dev == rconsdev) || (za->za_dev == kbddev) ||
3010 	    (za->za_dev == stdindev) || (za->za_ttycommon.t_cflag & CREAD))
3011 		wr3 = ZSWR3_RX_ENABLE;
3012 	else
3013 		wr3 = 0;
3014 	wr4 = ZSWR4_X16_CLK;
3015 	wr5 = (zs->zs_wreg[5] & (ZSWR5_RTS|ZSWR5_DTR)) | ZSWR5_TX_ENABLE;
3016 
3017 	if (zsb134_weird && baudrate == B134) {	/* what a joke! */
3018 		/*
3019 		 * XXX - should B134 set all this crap in the compatibility
3020 		 * module, leaving this stuff fairly clean?
3021 		 */
3022 		flags |= ZSP_PARITY_SPECIAL;
3023 		wr3 |= ZSWR3_RX_6;
3024 		wr4 |= ZSWR4_PARITY_ENABLE | ZSWR4_PARITY_EVEN;
3025 		wr4 |= ZSWR4_1_5_STOP;
3026 		wr5 |= ZSWR5_TX_6;
3027 	} else {
3028 
3029 		switch (za->za_ttycommon.t_cflag & CSIZE) {
3030 
3031 		case CS5:
3032 			wr3 |= ZSWR3_RX_5;
3033 			wr5 |= ZSWR5_TX_5;
3034 			break;
3035 
3036 		case CS6:
3037 			wr3 |= ZSWR3_RX_6;
3038 			wr5 |= ZSWR5_TX_6;
3039 			break;
3040 
3041 		case CS7:
3042 			wr3 |= ZSWR3_RX_7;
3043 			wr5 |= ZSWR5_TX_7;
3044 			break;
3045 
3046 		case CS8:
3047 			wr3 |= ZSWR3_RX_8;
3048 			wr5 |= ZSWR5_TX_8;
3049 			break;
3050 		}
3051 
3052 		if (za->za_ttycommon.t_cflag & PARENB) {
3053 			/*
3054 			 * The PARITY_SPECIAL bit causes a special rx
3055 			 * interrupt on parity errors. Turn it on if
3056 			 * we're checking the parity of characters.
3057 			 */
3058 			if (za->za_ttycommon.t_iflag & INPCK)
3059 				flags |= ZSP_PARITY_SPECIAL;
3060 			wr4 |= ZSWR4_PARITY_ENABLE;
3061 			if (!(za->za_ttycommon.t_cflag & PARODD))
3062 				wr4 |= ZSWR4_PARITY_EVEN;
3063 		}
3064 		wr4 |= (za->za_ttycommon.t_cflag & CSTOPB) ?
3065 		    ZSWR4_2_STOP : ZSWR4_1_STOP;
3066 	}
3067 
3068 #if 0
3069 	/*
3070 	 * The AUTO_CD_CTS flag enables the hardware flow control feature of
3071 	 * the 8530, which allows the state of CTS and DCD to control the
3072 	 * enabling of the transmitter and receiver, respectively. The
3073 	 * receiver and transmitter still must have their enable bits set in
3074 	 * WR3 and WR5, respectively, for CTS and DCD to be monitored this way.
3075 	 * Hardware flow control can thus be implemented with no help from
3076 	 * software.
3077 	 */
3078 	if (za->za_ttycommon.t_cflag & CRTSCTS)
3079 		wr3 |= ZSWR3_AUTO_CD_CTS;
3080 #endif
3081 	if (za->za_ttycommon.t_cflag & CRTSCTS)
3082 		wr15 = ZSR15_BREAK | ZSR15_TX_UNDER | ZSR15_CD | ZSR15_CTS;
3083 	else
3084 		wr15 = ZSR15_BREAK | ZSR15_TX_UNDER | ZSR15_CD;
3085 
3086 	speed = zs->zs_wreg[12] + (zs->zs_wreg[13] << 8);
3087 
3088 	/*
3089 	 * Here we assemble a set of changes to be passed to zs_program.
3090 	 * Note: Write Register 15 must be set to enable BREAK and UNDERrun
3091 	 * interrupts.  It must also enable CD interrupts which, although
3092 	 * not processed by the hardware interrupt handler, will be processed
3093 	 * by zsa_process, indirectly resulting in a SIGHUP being delivered
3094 	 * to the controlling process if CD drops.  CTS interrupts must NOT
3095 	 * be enabled.  We don't use them at all, and they will hang IPC/IPX
3096 	 * systems at boot time if synchronous modems that supply transmit
3097 	 * clock are attached to any of their serial ports.
3098 	 */
3099 	if (((zs->zs_wreg[1] & ZSWR1_PARITY_SPECIAL) &&
3100 	    !(flags & ZSP_PARITY_SPECIAL)) ||
3101 	    (!(zs->zs_wreg[1] & ZSWR1_PARITY_SPECIAL) &&
3102 	    (flags & ZSP_PARITY_SPECIAL)) ||
3103 	    wr3 != zs->zs_wreg[3] || wr4 != zs->zs_wreg[4] ||
3104 	    wr5 != zs->zs_wreg[5] || wr15 != zs->zs_wreg[15] ||
3105 	    speed != zs_speeds[baudrate]) {
3106 
3107 		za->za_flags |= ZAS_DRAINING;
3108 		zspp = &zs_prog[zs->zs_unit];
3109 		zspp->zs = zs;
3110 		zspp->flags = (uchar_t)flags;
3111 		zspp->wr4 = (uchar_t)wr4;
3112 		zspp->wr11 = (uchar_t)(ZSWR11_TXCLK_BAUD | ZSWR11_RXCLK_BAUD);
3113 
3114 		speed = zs_speeds[baudrate];
3115 		zspp->wr12 = (uchar_t)(speed & 0xff);
3116 		zspp->wr13 = (uchar_t)((speed >> 8) & 0xff);
3117 		zspp->wr3 = (uchar_t)wr3;
3118 		zspp->wr5 = (uchar_t)wr5;
3119 		zspp->wr15 = (uchar_t)wr15;
3120 
3121 		zs_program(zspp);
3122 		za->za_flags &= ~ZAS_DRAINING;
3123 	}
3124 }
3125 
3126 /*
3127  * Get the current speed of the console and turn it into something
3128  * UNIX knows about - used to preserve console speed when UNIX comes up.
3129  */
3130 int
3131 zsgetspeed(dev_t dev)
3132 {
3133 	struct zscom *zs;
3134 	int uspeed, zspeed;
3135 	uchar_t rr;
3136 
3137 	zs = &zscom[UNIT(dev)];
3138 	SCC_READ(12, zspeed);
3139 	SCC_READ(13, rr);
3140 	zspeed |= rr << 8;
3141 	for (uspeed = 0; uspeed < NSPEED; uspeed++)
3142 		if (zs_speeds[uspeed] == zspeed)
3143 			return (uspeed);
3144 	/*
3145 	 * 9600 baud if we can't figure it out
3146 	 */
3147 	return (ISPEED);
3148 }
3149 
3150 /*
3151  * callback routine when enough memory is available.
3152  */
3153 static void
3154 zsa_callback(void *arg)
3155 {
3156 	struct zscom *zs = arg;
3157 	struct asyncline *za = (struct asyncline *)&zs->zs_priv_str;
3158 	int allocbcount = zsa_rstandby;
3159 
3160 	mutex_enter(zs->zs_excl);
3161 	if (za->za_bufcid) {
3162 		za->za_bufcid = 0;
3163 		ZSA_GETBLOCK(zs, allocbcount);
3164 	}
3165 	mutex_exit(zs->zs_excl);
3166 }
3167 
3168 /*
3169  * Set the receiver flags
3170  */
3171 static void
3172 zsa_set_za_rcv_flags_mask(struct asyncline *za)
3173 {
3174 	uint_t mask;
3175 
3176 	za->za_rcv_flags_mask &= ~0xFF;
3177 	switch (za->za_ttycommon.t_cflag & CSIZE) {
3178 	case CS5:
3179 		mask = 0x1f;
3180 		break;
3181 	case CS6:
3182 		mask = 0x3f;
3183 		break;
3184 	case CS7:
3185 		mask = 0x7f;
3186 		break;
3187 	default:
3188 		mask = 0xff;
3189 	}
3190 
3191 	za->za_rcv_flags_mask &= ~(0xFF << 16);
3192 	za->za_rcv_flags_mask |=  mask << 16;
3193 
3194 	if ((za->za_ttycommon.t_iflag & PARMRK) &&
3195 	    !(za->za_ttycommon.t_iflag & (IGNPAR|ISTRIP))) {
3196 		za->za_rcv_flags_mask |= DO_ESC;
3197 	} else
3198 		za->za_rcv_flags_mask &= ~DO_ESC;
3199 	if (za->za_ttycommon.t_iflag & IXON) {
3200 		za->za_rcv_flags_mask |= DO_STOPC;
3201 		za->za_rcv_flags_mask &= ~0xFF;
3202 		za->za_rcv_flags_mask |= za->za_ttycommon.t_stopc;
3203 	} else
3204 		za->za_rcv_flags_mask &= ~DO_STOPC;
3205 }
3206 
3207 static int
3208 zsa_suspend(struct zscom *zs)
3209 {
3210 	struct asyncline	*za;
3211 	queue_t			*q;
3212 	mblk_t			*bp = NULL;
3213 	timeout_id_t		restart_id, kick_rcv_id;
3214 	struct zs_prog		*zspp;
3215 
3216 	za = (struct asyncline *)&zs->zs_priv_str;
3217 	mutex_enter(zs->zs_excl);
3218 	if (zs->zs_suspended) {
3219 		mutex_exit(zs->zs_excl);
3220 		return (DDI_SUCCESS);
3221 	}
3222 	zs->zs_suspended = 1;
3223 
3224 	/*
3225 	 * Turn off interrupts and get any bytes in receiver
3226 	 */
3227 	mutex_enter(zs->zs_excl_hi);
3228 	SCC_BIC(1, ZSWR1_INIT);
3229 	ZSA_KICK_RCV;
3230 	restart_id = za->za_zsa_restart_id;
3231 	za->za_zsa_restart_id = 0;
3232 	kick_rcv_id = za->za_kick_rcv_id;
3233 	za->za_kick_rcv_id = 0;
3234 	mutex_exit(zs->zs_excl_hi);
3235 	mutex_exit(zs->zs_excl);
3236 
3237 	/*
3238 	 * Cancel any timeouts
3239 	 */
3240 	if (restart_id)
3241 		(void) untimeout(restart_id);
3242 	if (kick_rcv_id)
3243 		(void) untimeout(kick_rcv_id);
3244 
3245 	/*
3246 	 * Since we have turned off interrupts, zsa_txint will not be called
3247 	 * and no new chars will given to the chip. We just wait for the
3248 	 * current character(s) to drain.
3249 	 */
3250 	delay(ztdelay(za->za_ttycommon.t_cflag & CBAUD));
3251 
3252 	/*
3253 	 * Return remains of partially sent message to queue
3254 	 */
3255 	mutex_enter(zs->zs_excl);
3256 	if ((q = za->za_ttycommon.t_writeq) != NULL) {
3257 		mutex_enter(zs->zs_excl_hi);
3258 		if ((zs->zs_wr_cur) != NULL) {
3259 			za->za_flags &= ~ZAS_BUSY;
3260 			za->za_rcv_flags_mask &= ~DO_RETRANSMIT;
3261 			bp = za->za_xmitblk;
3262 			bp->b_rptr = zs->zs_wr_cur;
3263 			zs->zs_wr_cur = NULL;
3264 			zs->zs_wr_lim = NULL;
3265 			za->za_xmitblk = NULL;
3266 		}
3267 		mutex_exit(zs->zs_excl_hi);
3268 		if (bp)
3269 			(void) putbq(q, bp);
3270 	}
3271 
3272 	/*
3273 	 * Stop any breaks in progress.
3274 	 */
3275 	mutex_enter(zs->zs_excl_hi);
3276 	if (zs->zs_wreg[5] & ZSWR5_BREAK) {
3277 		SCC_BIC(5, ZSWR5_BREAK);
3278 		za->za_flags &= ~ZAS_BREAK;
3279 	}
3280 
3281 	/*
3282 	 * Now get a copy of current registers setting.
3283 	 */
3284 	zspp = &zs_prog[zs->zs_unit];
3285 	zspp->zs = zs;
3286 	zspp->flags = 0;
3287 	zspp->wr3 = zs->zs_wreg[3];
3288 	zspp->wr4 = zs->zs_wreg[4];
3289 	zspp->wr5 = zs->zs_wreg[5];
3290 	zspp->wr11 = zs->zs_wreg[11];
3291 	zspp->wr12 = zs->zs_wreg[12];
3292 	zspp->wr13 = zs->zs_wreg[13];
3293 	zspp->wr15 = zs->zs_wreg[15];
3294 	mutex_exit(zs->zs_excl_hi);
3295 	mutex_exit(zs->zs_excl);
3296 	/*
3297 	 * We do this on the off chance that zsa_close is waiting on a timed
3298 	 * break to complete and nothing else.
3299 	 */
3300 	cv_broadcast(&zs->zs_flags_cv);
3301 	return (DDI_SUCCESS);
3302 }
3303 
3304 static int
3305 zsa_resume(struct zscom *zs)
3306 {
3307 	struct asyncline *za;
3308 	struct zs_prog	*zspp;
3309 
3310 	za = (struct asyncline *)&zs->zs_priv_str;
3311 	mutex_enter(zs->zs_excl);
3312 	if (!(zs->zs_suspended)) {
3313 		mutex_exit(zs->zs_excl);
3314 		return (DDI_SUCCESS);
3315 	}
3316 
3317 	/*
3318 	 * Restore H/W state
3319 	 */
3320 	mutex_enter(zs->zs_excl_hi);
3321 	zspp = &zs_prog[zs->zs_unit];
3322 	zs_program(zspp);
3323 
3324 	/*
3325 	 * Enable all interrupts for this chip and delay to let chip settle
3326 	 */
3327 	SCC_WRITE(9, ZSWR9_MASTER_IE | ZSWR9_VECTOR_INCL_STAT);
3328 	DELAY(4000);
3329 
3330 	/*
3331 	 * Restart receiving and transmitting
3332 	 */
3333 	zs->zs_suspended = 0;
3334 	za->za_rcv_flags_mask |= DO_TRANSMIT;
3335 	za->za_ext = 1;
3336 	ZSSETSOFT(zs);
3337 	mutex_exit(zs->zs_excl_hi);
3338 	mutex_exit(zs->zs_excl);
3339 
3340 	return (DDI_SUCCESS);
3341 }
3342 
3343 #ifdef ZSA_DEBUG
3344 static void
3345 zsa_print_info(struct zscom *zs)
3346 {
3347 	struct asyncline *za = (struct asyncline *)&zs->zs_priv_str;
3348 	queue_t *q = za->za_ttycommon.t_writeq;
3349 
3350 	printf(" next q=%s\n", (RD(q))->q_next->q_qinfo->qi_minfo->mi_idname);
3351 	printf("unit=%d\n", zs->zs_unit);
3352 	printf("tflag:\n");
3353 	if (za->za_ttycommon.t_flags & TS_SOFTCAR) printf(" t_fl:TS_SOFTCAR");
3354 	if (za->za_ttycommon.t_flags & TS_XCLUDE) printf(" t_fl:TS_XCLUDE");
3355 	if (za->za_ttycommon.t_iflag & IGNBRK) printf(" t_ifl:IGNBRK");
3356 	if (za->za_ttycommon.t_iflag & BRKINT) printf(" t_ifl:BRKINT");
3357 	if (za->za_ttycommon.t_iflag & IGNPAR) printf(" t_ifl:IGNPAR");
3358 	if (za->za_ttycommon.t_iflag & PARMRK) printf(" t_ifl:PARMRK");
3359 	if (za->za_ttycommon.t_iflag & INPCK) printf(" t_ifl:INPCK");
3360 	if (za->za_ttycommon.t_iflag & ISTRIP) printf(" t_ifl:ISTRIP");
3361 	if (za->za_ttycommon.t_iflag & INLCR) printf(" t_ifl:INLCR");
3362 	if (za->za_ttycommon.t_iflag & IGNCR) printf(" t_ifl:IGNCR");
3363 	if (za->za_ttycommon.t_iflag & ICRNL) printf(" t_ifl:ICRNL");
3364 	if (za->za_ttycommon.t_iflag & IUCLC) printf(" t_ifl:IUCLC");
3365 	if (za->za_ttycommon.t_iflag & IXON) printf(" t_ifl:IXON");
3366 	if (za->za_ttycommon.t_iflag & IXOFF) printf(" t_ifl:IXOFF");
3367 
3368 	printf("\n");
3369 
3370 
3371 	if (za->za_ttycommon.t_cflag & CSIZE == CS5) printf(" t_cfl:CS5");
3372 	if (za->za_ttycommon.t_cflag & CSIZE == CS6) printf(" t_cfl:CS6");
3373 	if (za->za_ttycommon.t_cflag & CSIZE == CS7) printf(" t_cfl:CS7");
3374 	if (za->za_ttycommon.t_cflag & CSIZE == CS8) printf(" t_cfl:CS8");
3375 	if (za->za_ttycommon.t_cflag & CSTOPB) printf(" t_cfl:CSTOPB");
3376 	if (za->za_ttycommon.t_cflag & CREAD) printf(" t_cfl:CREAD");
3377 	if (za->za_ttycommon.t_cflag & PARENB) printf(" t_cfl:PARENB");
3378 	if (za->za_ttycommon.t_cflag & PARODD) printf(" t_cfl:PARODD");
3379 	if (za->za_ttycommon.t_cflag & HUPCL) printf(" t_cfl:HUPCL");
3380 	if (za->za_ttycommon.t_cflag & CLOCAL) printf(" t_cfl:CLOCAL");
3381 	printf(" t_stopc=%x", za->za_ttycommon.t_stopc);
3382 	printf("\n");
3383 }
3384 #endif
3385 
3386 /*
3387  * Check for abort character sequence
3388  */
3389 static boolean_t
3390 abort_charseq_recognize(uchar_t ch)
3391 {
3392 	static int state = 0;
3393 #define	CNTRL(c) ((c)&037)
3394 	static char sequence[] = { '\r', '~', CNTRL('b') };
3395 
3396 	if (ch == sequence[state]) {
3397 		if (++state >= sizeof (sequence)) {
3398 			state = 0;
3399 			return (B_TRUE);
3400 		}
3401 	} else {
3402 		state = (ch == sequence[0]) ? 1 : 0;
3403 	}
3404 	return (B_FALSE);
3405 }
3406