xref: /illumos-gate/usr/src/uts/sun/io/zs_async.c (revision dec98d2aa2912b1fbd0abd2574307a695b566692)
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  */
26 
27 /*
28  *	Asynchronous protocol handler for Z8530 chips
29  *	Handles normal UNIX support for terminals & modems
30  */
31 
32 #include <sys/types.h>
33 #include <sys/param.h>
34 #include <sys/systm.h>
35 #include <sys/sysmacros.h>
36 #include <sys/signal.h>
37 #include <sys/kmem.h>
38 #include <sys/termios.h>
39 #include <sys/stropts.h>
40 #include <sys/stream.h>
41 #include <sys/strsun.h>
42 #include <sys/tty.h>
43 #include <sys/ptyvar.h>
44 #include <sys/cred.h>
45 #include <sys/user.h>
46 #include <sys/proc.h>
47 #include <sys/file.h>
48 #include <sys/uio.h>
49 #include <sys/buf.h>
50 #include <sys/mkdev.h>
51 #include <sys/cmn_err.h>
52 #include <sys/strtty.h>
53 #include <sys/consdev.h>
54 #include <sys/zsdev.h>
55 #include <sys/ser_async.h>
56 #include <sys/debug.h>
57 #include <sys/kbio.h>
58 #include <sys/conf.h>
59 #include <sys/ddi.h>
60 #include <sys/sunddi.h>
61 #include <sys/promif.h>
62 #include <sys/policy.h>
63 
64 /*
65  * PPS (Pulse Per Second) support.
66  */
67 extern void ddi_hardpps(struct timeval *, int);
68 static struct ppsclockev ppsclockev;
69 
70 #ifdef PPSCLOCKLED
71 /* XXX Use these to observe PPS latencies and jitter on a scope */
72 #define	LED_ON
73 #define	LED_OFF
74 #else
75 #define	LED_ON
76 #define	LED_OFF
77 #endif
78 
79 #define	ZSA_RCV_SIZE	64
80 #define	ZA_KICK_RCV_COUNT	3
81 #define	ZSA_GRACE_MIN_FLOW_CONTROL	5
82 #define	ZSA_GRACE_MAX_FLOW_CONTROL	20
83 
84 int zsasoftdtr = 0;	/* if nonzero, softcarrier raises dtr at attach */
85 int zsb134_weird = 0;	/* if set, old weird B134 behavior */
86 int g_zsticks = 0;	/* if set, becomes the global zsticks value */
87 int g_nocluster = 0;	/* if set, disables clustering of received data */
88 
89 unsigned int zsa_rstandby = ZSA_MIN_RSTANDBY;
90 unsigned int zsa_rdone = ZSA_RDONE_MIN;
91 unsigned int zsa_grace_flow_control = ZSA_GRACE_MIN_FLOW_CONTROL;
92 
93 
94 #define	NSPEED	18	/* max # of speeds */
95 ushort_t zs_speeds[NSPEED] = {
96 	0,
97 	ZSPEED(50),	/* 1 */
98 	ZSPEED(75),	/* 2 */
99 	ZSPEED(110),	/* 3 */
100 #ifdef lint
101 	ZSPEED(134),	/* 4 */
102 #else
103 	ZSPEED(269/2),			/* XXX - This is sleazy */
104 #endif
105 	ZSPEED(150),	/* 5 */
106 	ZSPEED(200),	/* 6 */
107 	ZSPEED(300),	/* 7 */
108 	ZSPEED(600),	/* 8 */
109 	ZSPEED(1200),	/* 9 */
110 	ZSPEED(1800),	/* 10 */
111 	ZSPEED(2400),	/* 11 */
112 	ZSPEED(4800),	/* 12 */
113 	ZSPEED(9600),	/* 13 */
114 	ZSPEED(19200),	/* 14 */
115 	ZSPEED(38400),	/* 15 */
116 	ZSPEED(57680),	/* 16 */
117 	ZSPEED(76800)	/* 17 */
118 };
119 
120 ushort_t zsticks[NSPEED] = {
121 	3,		/* 0 */
122 	3,		/* 1 */
123 	3,		/* 2 */
124 	3,		/* 3 */
125 	3,		/* 4 */
126 	3,		/* 5 */
127 	3,		/* 6 */
128 	3,		/* 7 */
129 	3,		/* 8 */
130 	3,		/* 9 */
131 	3,		/* 10 */
132 	3,		/* 11 */
133 	3,		/* 12 */
134 	3,		/* 13 */
135 	2,		/* 14 */
136 	1,		/* 15 */
137 	1,		/* 16 */
138 	1		/* 17 */
139 };
140 
141 #define	ztdelay(nsp)	(zsdelay[(nsp)]*(hz/100))
142 
143 ushort_t zsdelay[NSPEED] = {
144 	0,
145 	ZDELAY(50),	/* 1 */
146 	ZDELAY(75),	/* 2 */
147 	ZDELAY(110),    /* 3 */
148 #ifdef lint
149 	ZDELAY(134),    /* 4 */
150 #else
151 	ZDELAY(269/2),
152 #endif
153 	ZDELAY(150),    /* 5 */
154 	ZDELAY(200),    /* 6 */
155 	ZDELAY(300),    /* 7 */
156 	ZDELAY(600),    /* 8 */
157 	ZDELAY(1200),   /* 9 */
158 	ZDELAY(1800),   /* 10 */
159 	ZDELAY(2400),   /* 11 */
160 	ZDELAY(4800),   /* 12 */
161 	ZDELAY(9600),   /* 13 */
162 	ZDELAY(19200),  /* 14 */
163 	ZDELAY(38400),  /* 15 */
164 	ZDELAY(57600),  /* 16 */
165 	ZDELAY(76800)	/* 17 */
166 };
167 
168 ushort_t zslowat[NSPEED] = {
169 	3,		/* 0 */
170 	3,		/* 1 */
171 	3,		/* 2 */
172 	3,		/* 3 */
173 	3,		/* 4 */
174 	3,		/* 5 */
175 	3,		/* 6 */
176 	2,		/* 7 */
177 	2,		/* 8 */
178 	2,		/* 9 */
179 	2,		/* 10 */
180 	1,		/* 11 */
181 	1,		/* 12 */
182 	1,		/* 13 */
183 	1,		/* 14 */
184 	1,		/* 15 */
185 	1,		/* 16 */
186 	1		/* 17 */
187 };
188 
189 ushort_t zshiwat[NSPEED] = {
190 	0,		/* 0 */
191 	1,		/* 1 */
192 	1,		/* 2 */
193 	1,		/* 3 */
194 	1,		/* 4 */
195 	1,		/* 5 */
196 	1,		/* 6 */
197 	1,		/* 7 */
198 	1,		/* 8 */
199 	1,		/* 9 */
200 	1,		/* 10 */
201 	1,		/* 11 */
202 	1,		/* 12 */
203 	3,		/* 13 */
204 	3,		/* 14 */
205 	4,		/* 15 */
206 	4,		/* 16 */
207 	4		/* 17 */
208 };
209 
210 #define	SLAVIO_BUG	/* this workaround required to fix bug 1102778 */
211 
212 #define	SPEED(cflag) \
213 	((cflag) & CBAUDEXT) ? \
214 		(((cflag) & 0x1) + CBAUD + 1) : ((cflag) & CBAUD)
215 
216 /*
217  * Special macros to handle STREAMS operations.
218  * These are required to address memory leakage problems.
219  * WARNING : the macro do NOT call ZSSETSOFT
220  */
221 
222 /*
223  * Should be called holding only the adaptive (zs_excl) mutex.
224  */
225 #define	ZSA_GETBLOCK(zs, allocbcount) \
226 { \
227 	register int n = zsa_rstandby; \
228 	while (--n >= 0 && allocbcount > 0) { \
229 		if (!za->za_rstandby[n]) { \
230 			if ((za->za_rstandby[n] = allocb(ZSA_RCV_SIZE, \
231 			    BPRI_MED)) == NULL) { \
232 				if (za->za_bufcid == 0) { \
233 					za->za_bufcid = bufcall(ZSA_RCV_SIZE, \
234 					    BPRI_MED, \
235 					    zsa_callback, zs); \
236 					break; \
237 				} \
238 			} \
239 			allocbcount--; \
240 		} \
241 	} \
242 	if (za->za_ttycommon.t_cflag & CRTSXOFF) { \
243 		mutex_enter(zs->zs_excl_hi); \
244 		if (!(zs->zs_wreg[5] & ZSWR5_RTS)) { \
245 			register int usedcnt = 0; \
246 			for (n = 0; n < zsa_rstandby; n++) \
247 				if (!za->za_rstandby[n]) \
248 					usedcnt++; \
249 			if ((ushort_t)usedcnt <= \
250 			    zslowat[SPEED(za->za_ttycommon.t_cflag)]) \
251 				SCC_BIS(5, ZSWR5_RTS); \
252 		} \
253 		mutex_exit(zs->zs_excl_hi); \
254 	} \
255 }
256 
257 /*
258  * Should be called holding the spin (zs_excl_hi) mutex.
259  */
260 #define	ZSA_ALLOCB(mp) \
261 { \
262 	register int n = zsa_rstandby; \
263 	while (--n >= 0) { \
264 		if ((mp = za->za_rstandby[n]) != NULL) { \
265 			za->za_rstandby[n] = NULL; \
266 			break; \
267 		} \
268 	} \
269 	if (za->za_ttycommon.t_cflag & CRTSXOFF) { \
270 		if (!mp) { \
271 			if (zs->zs_wreg[5] & ZSWR5_RTS) \
272 				SCC_BIC(5, ZSWR5_RTS); \
273 			cmn_err(CE_WARN, "zs%d: message lost\n", \
274 				UNIT(za->za_dev)); \
275 		} else if (zs->zs_wreg[5] & ZSWR5_RTS) { \
276 			register int usedcnt = 0; \
277 			for (n = 0; n < zsa_rstandby; n++) \
278 				if (!za->za_rstandby[n]) \
279 					usedcnt++; \
280 			if ((ushort_t)usedcnt >= (zsa_rstandby - \
281 			    zshiwat[SPEED(za->za_ttycommon.t_cflag)])) \
282 				SCC_BIC(5, ZSWR5_RTS); \
283 		} \
284 	} \
285 }
286 
287 /*
288  * Should get the spin (zs_excl_hi) mutex.
289  */
290 #define	ZSA_QREPLY(q, mp) \
291 { \
292 	mutex_enter(zs->zs_excl_hi); \
293 	ZSA_PUTQ(mp); \
294 	ZSSETSOFT(zs); \
295 	mutex_exit(zs->zs_excl_hi); \
296 }
297 
298 /*
299  * Should be called holding the spin (zs_excl_hi) mutex.
300  */
301 #define	ZSA_PUTQ(mp) \
302 { \
303 	register int wptr, rptr; \
304 	wptr = za->za_rdone_wptr; \
305 	rptr = za->za_rdone_rptr; \
306 	za->za_rdone[wptr] = mp; \
307 	if ((wptr)+1 == zsa_rdone) { \
308 		za->za_rdone_wptr = wptr = 0; \
309 	} else \
310 		za->za_rdone_wptr = ++wptr; \
311 	if (wptr == rptr) { \
312 		SCC_BIC(1, ZSWR1_INIT); \
313 		cmn_err(CE_WARN, "zs%d disabled: input buffer overflow", \
314 			UNIT(za->za_dev)); \
315 	} \
316 }
317 
318 /*
319  * Should be called holding the spin (zs_excl_hi) mutex.
320  */
321 #define	ZSA_KICK_RCV \
322 { \
323 	register mblk_t *mp = za->za_rcvblk; \
324 	if (mp) { \
325 		if (zs->zs_rd_cur) {	/* M_DATA */ \
326 			mp->b_wptr = zs->zs_rd_cur; \
327 			zs->zs_rd_cur = NULL; \
328 			zs->zs_rd_lim = NULL; \
329 		} \
330 		za->za_rcvblk = NULL; \
331 		ZSA_PUTQ(mp); \
332 		ZSSETSOFT(zs); \
333 	} \
334 }
335 
336 #define	ZSA_SEEQ(mp) \
337 { \
338 		if (za->za_rdone_rptr != za->za_rdone_wptr) { \
339 			mp = za->za_rdone[za->za_rdone_rptr]; \
340 		} else { \
341 			mp = NULL; \
342 		} \
343 }
344 
345 
346 /*
347  * Should be called holding only the adaptive (zs_excl) mutex.
348  */
349 #define	ZSA_GETQ(mp) \
350 { \
351 	if (za->za_rdone_rptr != za->za_rdone_wptr) { \
352 		mp = za->za_rdone[za->za_rdone_rptr]; \
353 		za->za_rdone[za->za_rdone_rptr++] = NULL; \
354 		if (za->za_rdone_rptr == zsa_rdone) \
355 			za->za_rdone_rptr = 0; \
356 	} else { \
357 		mp = NULL; \
358 	} \
359 }
360 
361 /*
362  * Should be called holding only the adaptive (zs_excl) mutex.
363  */
364 #define	ZSA_FLUSHQ \
365 { \
366 	register mblk_t *tmp; \
367 	for (;;) { \
368 		ZSA_GETQ(tmp); \
369 		if (!(tmp)) \
370 			break; \
371 		freemsg(tmp); \
372 	} \
373 }
374 
375 
376 /*
377  * Logging definitions
378  */
379 
380 #ifdef ZSA_DEBUG
381 
382 #ifdef ZS_DEBUG_ALL
383 
384 extern	char	zs_h_log[];
385 extern	int	zs_h_log_n;
386 
387 #define	zsa_h_log_clear
388 
389 #define	zsa_h_log_add(c) \
390 { \
391 	if (zs_h_log_n >= ZS_H_LOG_MAX) \
392 		zs_h_log_n = 0; \
393 	zs_h_log[zs_h_log_n++] = 'A' + zs->zs_unit; \
394 	zs_h_log[zs_h_log_n++] = c; \
395 	zs_h_log[zs_h_log_n] = '\0'; \
396 }
397 
398 #else /* ZS_DEBUG_ALL */
399 
400 #define	ZSA_H_LOG_MAX	0x4000
401 char zsa_h_log[40][ZSA_H_LOG_MAX +10];
402 int zsa_h_log_n[40];
403 
404 #define	zsa_h_log_add(c) \
405 { \
406 	if (zsa_h_log_n[zs->zs_unit] >= ZSA_H_LOG_MAX) \
407 		zsa_h_log_n[zs->zs_unit] = 0; \
408 	zsa_h_log[zs->zs_unit][zsa_h_log_n[zs->zs_unit]++] = c; \
409 	zsa_h_log[zs->zs_unit][zsa_h_log_n[zs->zs_unit]] = '\0'; \
410 }
411 
412 #define	zsa_h_log_clear \
413 { \
414 	register char *p; \
415 	for (p = &zsa_h_log[zs->zs_unit][ZSA_H_LOG_MAX]; \
416 		p >= &zsa_h_log[zs->zs_unit][0]; /* null */) \
417 		*p-- = '\0'; \
418 	zsa_h_log_n[zs->zs_unit] = 0; \
419 }
420 
421 #endif /* ZS_DEBUG_ALL */
422 
423 #define	ZSA_R0_LOG(r0) \
424 { \
425 	if (r0 & ZSRR0_RX_READY) zsa_h_log_add('R'); \
426 	if (r0 & ZSRR0_TIMER) zsa_h_log_add('Z'); \
427 	if (r0 & ZSRR0_TX_READY) zsa_h_log_add('T'); \
428 	if (r0 & ZSRR0_CD) zsa_h_log_add('D'); \
429 	if (r0 & ZSRR0_SYNC) zsa_h_log_add('S'); \
430 	if (r0 & ZSRR0_CTS) zsa_h_log_add('C'); \
431 	if (r0 & ZSRR0_TXUNDER) zsa_h_log_add('U'); \
432 	if (r0 & ZSRR0_BREAK) zsa_h_log_add('B'); \
433 }
434 
435 #else /* ZSA_DEBUG */
436 
437 #define	zsa_h_log_clear
438 #define	zsa_h_log_add(c)
439 #define	 ZSA_R0_LOG(r0)
440 
441 #endif /* ZSA_DEBUG */
442 
443 
444 
445 static int zsa_open(queue_t *rq, dev_t *dev, int flag, int sflag, cred_t *cr);
446 static int zsa_close(queue_t *q, int flag);
447 static void zsa_wput(queue_t *q, mblk_t *mp);
448 static void zsa_rsrv(queue_t *q);
449 
450 static struct module_info asyncm_info = {
451 	0,
452 	"zs",
453 	0,
454 	INFPSZ,
455 	2048,
456 	128
457 };
458 
459 static struct qinit async_rinit = {
460 	putq,
461 	(int (*)())zsa_rsrv,
462 	zsa_open,
463 	zsa_close,
464 	NULL,
465 	&asyncm_info,
466 	NULL
467 };
468 
469 static struct qinit async_winit = {
470 	(int (*)())zsa_wput,
471 	NULL,
472 	NULL,
473 	NULL,
474 	NULL,
475 	&asyncm_info,
476 	NULL
477 };
478 
479 struct streamtab asynctab = {
480 	&async_rinit,
481 	&async_winit,
482 	NULL,
483 	NULL,
484 };
485 
486 /*
487  * The async interrupt entry points.
488  */
489 static void	zsa_txint(struct zscom *zs);
490 static void	zsa_xsint(struct zscom *zs);
491 static void	zsa_rxint(struct zscom *zs);
492 static void	zsa_srint(struct zscom *zs);
493 static int	zsa_softint(struct zscom *zs);
494 static int	zsa_suspend(struct zscom *zs);
495 static int	zsa_resume(struct zscom *zs);
496 
497 static void
498 zsa_null(struct zscom *zs)
499 {
500 	/* LINTED */
501 	register 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 	register dev_t dev = (dev_t)arg;
557 	register int unit, error;
558 	register 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 	register struct zscom *zs;
719 	register struct asyncline *za;
720 	register int	speed, unit;
721 	struct termios *termiosp;
722 	int len;
723 	register 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)
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 void
1205 zsa_wput(queue_t *q, mblk_t *mp)
1206 {
1207 	register struct asyncline	*za;
1208 	register struct zscom		*zs;
1209 	register struct copyresp	*resp;
1210 	register 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 == NULL) {
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 }
1613 
1614 /*
1615  * zs read service procedure
1616  */
1617 static void
1618 zsa_rsrv(queue_t *q)
1619 {
1620 	struct asyncline	*za;
1621 	struct zscom		*zs;
1622 
1623 	if (((za = (struct asyncline *)q->q_ptr) != NULL) &&
1624 	    (za->za_ttycommon.t_cflag & CRTSXOFF)) {
1625 		zs = za->za_common;
1626 		mutex_enter(zs->zs_excl_hi);
1627 		ZSSETSOFT(zs);
1628 		mutex_exit(zs->zs_excl_hi);
1629 	}
1630 }
1631 
1632 /*
1633  * Transmitter interrupt service routine.
1634  * If there's more data to transmit in the current pseudo-DMA block,
1635  * and the transmitter is ready, send the next character if output
1636  * is not stopped or draining.
1637  * Otherwise, queue up a soft interrupt.
1638  */
1639 static void
1640 zsa_txint(struct zscom *zs)
1641 {
1642 	register struct asyncline *za = (struct asyncline *)&zs->zs_priv_str;
1643 	register uchar_t *wr_cur;
1644 	register uchar_t s0;
1645 
1646 	s0 = SCC_READ0();
1647 
1648 	if ((wr_cur = zs->zs_wr_cur) != NULL) {
1649 		if (wr_cur < zs->zs_wr_lim) {
1650 			if ((za->za_ttycommon.t_cflag & CRTSCTS) &&
1651 			    !(s0 & ZSRR0_CTS)) {
1652 				SCC_WRITE0(ZSWR0_RESET_TXINT);
1653 				za->za_rcv_flags_mask |= DO_RETRANSMIT;
1654 				return;
1655 			}
1656 			SCC_WRITEDATA(*wr_cur++);
1657 #ifdef ZSA_DEBUG
1658 			za->za_wr++;
1659 #endif
1660 			zs->zs_wr_cur = wr_cur;
1661 			zs->zs_flags |= ZS_PROGRESS;
1662 			return;
1663 		} else {
1664 			zs->zs_wr_cur = NULL;
1665 			zs->zs_wr_lim = NULL;
1666 			/*
1667 			 * Use the rcv_flags_mask as it is set and
1668 			 * test while holding the zs_excl_hi mutex
1669 			 */
1670 			za->za_rcv_flags_mask |= DO_TRANSMIT;
1671 			SCC_WRITE0(ZSWR0_RESET_TXINT);
1672 			ZSSETSOFT(zs);
1673 			return;
1674 		}
1675 	}
1676 
1677 	if (za->za_flowc != '\0' && (!(za->za_flags & ZAS_DRAINING))) {
1678 		if ((za->za_ttycommon.t_cflag & CRTSCTS) &&
1679 		    !(s0 & ZSRR0_CTS)) {
1680 			SCC_WRITE0(ZSWR0_RESET_TXINT);
1681 			return;
1682 		}
1683 		SCC_WRITEDATA(za->za_flowc);
1684 		za->za_flowc = '\0';
1685 		return;
1686 	}
1687 	SCC_WRITE0(ZSWR0_RESET_TXINT);
1688 	/*
1689 	 * Set DO_TRANSMIT bit so that the soft interrupt can
1690 	 * test it and unset the ZAS_BUSY in za_flags while holding
1691 	 * the mutex zs_excl and zs_excl_hi
1692 	 */
1693 	za->za_rcv_flags_mask |= DO_TRANSMIT;
1694 	ZSSETSOFT(zs);
1695 }
1696 
1697 /*
1698  * External/Status interrupt.
1699  */
1700 static void
1701 zsa_xsint(struct zscom *zs)
1702 {
1703 	register struct asyncline *za = (struct asyncline *)&zs->zs_priv_str;
1704 	register uchar_t s0, x0;
1705 
1706 	s0 = SCC_READ0();
1707 	ZSA_R0_LOG(s0);
1708 	x0 = s0 ^ za->za_rr0;
1709 	za->za_rr0 = s0;
1710 	SCC_WRITE0(ZSWR0_RESET_STATUS);
1711 
1712 	/*
1713 	 * PPS (Pulse Per Second) support.
1714 	 */
1715 	if (za->za_pps && (x0 & ZSRR0_CD) && (s0 & ZSRR0_CD)) {
1716 		/*
1717 		 * This code captures a timestamp at the designated
1718 		 * transition of the PPS signal (CD asserted).  The
1719 		 * code provides a pointer to the timestamp, as well
1720 		 * as the hardware counter value at the capture.
1721 		 *
1722 		 * Note: the kernel has nano based time values while
1723 		 * NTP requires micro based, an in-line fast algorithm
1724 		 * to convert nsec to usec is used here -- see hrt2ts()
1725 		 * in common/os/timers.c for a full description.
1726 		 */
1727 		struct timeval *tvp = &ppsclockev.tv;
1728 		timespec_t ts;
1729 		int nsec, usec;
1730 
1731 		LED_OFF;
1732 		gethrestime(&ts);
1733 		LED_ON;
1734 		nsec = ts.tv_nsec;
1735 		usec = nsec + (nsec >> 2);
1736 		usec = nsec + (usec >> 1);
1737 		usec = nsec + (usec >> 2);
1738 		usec = nsec + (usec >> 4);
1739 		usec = nsec - (usec >> 3);
1740 		usec = nsec + (usec >> 2);
1741 		usec = nsec + (usec >> 3);
1742 		usec = nsec + (usec >> 4);
1743 		usec = nsec + (usec >> 1);
1744 		usec = nsec + (usec >> 6);
1745 		tvp->tv_usec = usec >> 10;
1746 		tvp->tv_sec = ts.tv_sec;
1747 
1748 		++ppsclockev.serial;
1749 
1750 		/*
1751 		 * Because the kernel keeps a high-resolution time, pass the
1752 		 * current highres timestamp in tvp and zero in usec.
1753 		 */
1754 		ddi_hardpps(tvp, 0);
1755 	}
1756 
1757 	ZSA_KICK_RCV;
1758 
1759 	if ((x0 & ZSRR0_BREAK) && (s0 & ZSRR0_BREAK) == 0) {
1760 #ifdef SLAVIO_BUG
1761 		/*
1762 		 * ZSRR0_BREAK turned off.  This means that the break sequence
1763 		 * has completed (i.e., the stop bit finally arrived).
1764 		 */
1765 		if ((s0 & ZSRR0_RX_READY) == 0) {
1766 			/*
1767 			 * SLAVIO will generate a separate STATUS change
1768 			 * interrupt when the break sequence completes.
1769 			 * SCC will combine both, taking the higher priority
1770 			 * one, the receive.  Should still see the ext/stat.
1771 			 * bit in REG3 on SCC.  If no ext/stat, it must be
1772 			 * a SLAVIO.
1773 			 */
1774 			za->za_breakoff = 1;
1775 		} else {
1776 			/*
1777 			 * The NUL character in the receiver is part of the
1778 			 * break sequence; it is discarded.
1779 			 */
1780 			(void) SCC_READDATA(); /* swallow null */
1781 		}
1782 #else /* SLAVIO_BUG */
1783 		/*
1784 		 * ZSRR0_BREAK turned off.  This means that the break sequence
1785 		 * has completed (i.e., the stop bit finally arrived).  The NUL
1786 		 * character in the receiver is part of the break sequence;
1787 		 * it is discarded.
1788 		 */
1789 		(void) SCC_READDATA(); /* swallow null */
1790 #endif /* SLAVIO_BUG */
1791 		SCC_WRITE0(ZSWR0_RESET_ERRORS);
1792 
1793 		/*
1794 		 * Note: this will cause an abort if a break occurs on
1795 		 * the "keyboard device", regardless of whether the
1796 		 * "keyboard device" is a real keyboard or just a
1797 		 * terminal on a serial line. This permits you to
1798 		 * abort a workstation by unplugging the keyboard,
1799 		 * even if the normal abort key sequence isn't working.
1800 		 */
1801 		if ((za->za_dev == kbddev) ||
1802 		    ((za->za_dev == rconsdev) || (za->za_dev == stdindev)) &&
1803 		    (abort_enable != KIOCABORTALTERNATE)) {
1804 			abort_sequence_enter((char *)NULL);
1805 			/*
1806 			 * We just broke into the monitor or debugger,
1807 			 * ignore the break in this case so whatever
1808 			 * random program that was running doesn't get
1809 			 * a SIGINT.
1810 			 */
1811 			return;
1812 		}
1813 		za->za_break = 1;
1814 	}
1815 
1816 	/*
1817 	 * If hardware flow control is enabled, (re)start output
1818 	 * when CTS is reasserted.
1819 	 */
1820 	if ((za->za_ttycommon.t_cflag & CRTSCTS) &&
1821 	    (x0 & ZSRR0_CTS) && (s0 & ZSRR0_CTS) &&
1822 	    (za->za_rcv_flags_mask & DO_RETRANSMIT))
1823 			za->za_rcv_flags_mask |= DO_TRANSMIT;
1824 
1825 	za->za_ext = 1;
1826 	ZSSETSOFT(zs);
1827 }
1828 
1829 /*
1830  * Receive Interrupt
1831  */
1832 static void
1833 zsa_rxint(struct zscom *zs)
1834 {
1835 	register struct asyncline *za = (struct asyncline *)&zs->zs_priv_str;
1836 	register uchar_t c;
1837 	register uchar_t *rd_cur = zs->zs_rd_cur;
1838 	register uchar_t *rd_lim = zs->zs_rd_lim;
1839 	register mblk_t	*bp;
1840 	register uint_t	fm = za->za_rcv_flags_mask;
1841 
1842 
1843 #ifdef ZSA_DEBUG
1844 	za->za_rd++;
1845 #endif
1846 	c = (fm >> 16) & (SCC_READDATA());
1847 
1848 	/*
1849 	 * Check for character break sequence
1850 	 */
1851 	if ((abort_enable == KIOCABORTALTERNATE) && (za->za_dev == rconsdev)) {
1852 		if (abort_charseq_recognize(c))
1853 			abort_sequence_enter((char *)NULL);
1854 	}
1855 
1856 	if (!rd_cur) {
1857 #ifdef SLAVIO_BUG
1858 		/*
1859 		 * SLAVIO generates FE for the start of break and
1860 		 * during break when parity is set.  End of break is
1861 		 * detected when the first character is received.
1862 		 * This character is always garbage and is thrown away.
1863 		 */
1864 		if (za->za_slav_break) {
1865 			za->za_slav_break = 0;
1866 			za->za_rr0 |= ZSRR0_BREAK;
1867 			zsa_xsint(zs);
1868 			return;
1869 		}
1870 #endif /* SLAVIO_BUG */
1871 
1872 		if (c == 0 && (za->za_rr0 & ZSRR0_BREAK)) {
1873 			/*
1874 			 * A break sequence was under way, and a NUL character
1875 			 * was received. Discard the NUL character, as it is
1876 			 * part of the break sequence; if ZSRR0_BREAK turned
1877 			 * off, indicating that the break sequence has com-
1878 			 * pleted, call "zsa_xsint" to properly handle the
1879 			 * error. It would appear that External/Status
1880 			 * interrupts get lost occasionally, so this ensures
1881 			 * that one is delivered.
1882 			 */
1883 			c = SCC_READ0();
1884 			if (!(c & ZSRR0_BREAK))
1885 				zsa_xsint(zs);
1886 			return;
1887 		}
1888 
1889 #ifdef SLAVIO_BUG
1890 		if (c == 0 && za->za_breakoff) {
1891 			/*
1892 			 * A break sequence completed, but SLAVIO generates
1893 			 * the NULL character interrupt late, so we throw the
1894 			 * NULL away now.
1895 			 */
1896 			return;
1897 		}
1898 
1899 		/*
1900 		 * make sure it gets cleared.
1901 		 */
1902 		za->za_breakoff = 0;
1903 #endif /* SLAVIO_BUG */
1904 
1905 		ZSA_KICK_RCV;	/* We can have M_BREAK msg */
1906 		ZSA_ALLOCB(bp);
1907 		if (!bp) {
1908 			za->za_sw_overrun++;
1909 			ZSSETSOFT(zs);
1910 			return;
1911 		}
1912 		za->za_rcvblk = bp;
1913 		zs->zs_rd_cur = rd_cur = bp->b_wptr;
1914 		zs->zs_rd_lim = rd_lim = bp->b_datap->db_lim;
1915 		if (za->za_kick_rcv_id == 0)
1916 			ZSSETSOFT(zs);
1917 	}
1918 	if (c == 0377 && (fm & DO_ESC)) {
1919 		if (rd_lim < rd_cur + 2) {
1920 			ZSA_ALLOCB(bp);
1921 			ZSA_KICK_RCV;
1922 			if (!bp) {
1923 				za->za_sw_overrun++;
1924 				return;
1925 			}
1926 			za->za_rcvblk = bp;
1927 			zs->zs_rd_cur = rd_cur = bp->b_wptr;
1928 			zs->zs_rd_lim = rd_lim = bp->b_datap->db_lim;
1929 		}
1930 		*rd_cur++ = c;
1931 	}
1932 
1933 
1934 	*rd_cur++ = c;
1935 	zs->zs_rd_cur = rd_cur;
1936 
1937 	if (rd_cur == rd_lim) {
1938 		ZSA_KICK_RCV;
1939 	} else if ((fm & DO_STOPC) && (c == (fm & 0xff))) {
1940 		za->za_do_kick_rcv_in_softint = 1;
1941 		ZSSETSOFT(zs);
1942 	}
1943 
1944 	if ((za->za_flags & ZAS_SERVICEIMM) || g_nocluster) {
1945 		/*
1946 		 * Send the data up immediately
1947 		 */
1948 		ZSA_KICK_RCV;
1949 	}
1950 }
1951 
1952 /*
1953  * Special receive condition interrupt handler.
1954  */
1955 static void
1956 zsa_srint(struct zscom *zs)
1957 {
1958 	register struct asyncline *za = (struct asyncline *)&zs->zs_priv_str;
1959 	register short s1;
1960 	register uchar_t c;
1961 	register uchar_t c1;
1962 	register mblk_t *bp = za->za_rcvblk;
1963 	register uchar_t *rd_cur = zs->zs_rd_cur;
1964 
1965 	SCC_READ(1, s1);
1966 	if (s1 & (ZSRR1_FE | ZSRR1_PE | ZSRR1_DO)) {
1967 		c = SCC_READDATA();	/* swallow bad character */
1968 	}
1969 #ifdef SLAVIO_BUG
1970 	/*
1971 	 * SLAVIO does not handle breaks properly when parity is enabled.
1972 	 *
1973 	 * In general, if a null character is received when a framing
1974 	 * error occurs then it is a break condition and not a real
1975 	 * framing error. The null character must be limited to the
1976 	 * number of bits including the parity bit. For example, a 6
1977 	 * bit character with parity would be null if the lower 7 bits
1978 	 * read from the receive fifo were 0. (The higher order bits are
1979 	 * padded with 1 and/or the stop bits.) The only exception to this
1980 	 * general rule would be an 8 bit null character with parity being
1981 	 * a 1 in the parity bit and a framing error. This exception
1982 	 * can be determined by examining the parity error bit in RREG 1.
1983 	 *
1984 	 * A null character, even parity, 8 bits, no parity error,
1985 	 * (0 0000 0000) with framing error is a break condition.
1986 	 *
1987 	 * A null character, even parity, 8 bits, parity error,
1988 	 * (1 0000 0000) with framing error is a framing error.
1989 	 *
1990 	 * A null character, odd parity, 8 bits, parity error
1991 	 * (0 0000 0000) with framing error is a break condition.
1992 	 *
1993 	 * A null character, odd parity, 8 bits, no parity error,
1994 	 * (1 0000 0000) with framing error is a framing error.
1995 	 */
1996 	if (za->za_ttycommon.t_cflag & PARENB) {
1997 		switch (za->za_ttycommon.t_cflag & CSIZE) {
1998 
1999 		case CS5:
2000 			c1 = c & 0x3f;
2001 			break;
2002 
2003 		case CS6:
2004 			c1 = c & 0x7f;
2005 			break;
2006 
2007 		case CS7:
2008 			c1 = c & 0xff;
2009 			break;
2010 
2011 		case CS8:
2012 			if ((za->za_ttycommon.t_cflag & PARODD) &&
2013 			    !(s1 & ZSRR1_PE))
2014 				c1 = 0xff;
2015 			else if (!(za->za_ttycommon.t_cflag & PARODD) &&
2016 			    (s1 & ZSRR1_PE))
2017 				c1 = 0xff;
2018 			else
2019 				c1 = c;
2020 			break;
2021 		}
2022 
2023 		/*
2024 		 * We fake start of break condition.
2025 		 */
2026 		if ((s1 & ZSRR1_FE) && c1 == 0) {
2027 			za->za_slav_break = 1;
2028 			return;
2029 		}
2030 	}
2031 #endif /* SLAVIO_BUG */
2032 
2033 	if (s1 & ZSRR1_PE) {
2034 
2035 		/*
2036 		 * Mark the parity error so zsa_process will
2037 		 * notice it and send it up in an M_BREAK
2038 		 * message; ldterm will do the actual parity error
2039 		 * processing
2040 		 */
2041 
2042 		if (bp && zs->zs_rd_cur) {	/* M_DATA msg */
2043 			ZSA_KICK_RCV;
2044 			bp = NULL;
2045 		}
2046 		if (!bp)
2047 			ZSA_ALLOCB(bp);
2048 		if (!bp) {
2049 			za->za_sw_overrun++;
2050 			ZSSETSOFT(zs);
2051 		} else {
2052 			za->za_rcvblk = bp;
2053 			zs->zs_rd_cur = rd_cur = bp->b_wptr;
2054 			zs->zs_rd_lim = bp->b_datap->db_lim;
2055 			*rd_cur++ = c;
2056 			zs->zs_rd_cur = rd_cur;
2057 			bp->b_datap->db_type = M_BREAK;
2058 			if (bp->b_datap->db_lim <= rd_cur)
2059 				ZSA_KICK_RCV;
2060 			za->za_do_kick_rcv_in_softint = 1;
2061 			ZSSETSOFT(zs);
2062 
2063 		}
2064 	}
2065 	SCC_WRITE0(ZSWR0_RESET_ERRORS);
2066 	if (s1 & ZSRR1_DO) {
2067 		za->za_hw_overrun++;
2068 		ZSSETSOFT(zs);
2069 	}
2070 }
2071 
2072 /*
2073  * Process software interrupts (or poll)
2074  * Crucial points:
2075  * 3.	BUG - breaks are handled "out-of-band" - their relative position
2076  *	among input events is lost, as well as multiple breaks together.
2077  *	This is probably not a problem in practice.
2078  */
2079 static int
2080 zsa_softint(struct zscom *zs)
2081 {
2082 	register struct asyncline *za = (struct asyncline *)&zs->zs_priv_str;
2083 	register uchar_t r0;
2084 	register uchar_t za_kick_active;
2085 	register int	m_error;
2086 	register int	allocbcount = 0;
2087 	register int 	do_ttycommon_qfull = 0;
2088 	boolean_t	hangup = B_FALSE, unhangup = B_FALSE;
2089 	boolean_t	m_break = B_FALSE, wakeup = B_FALSE;
2090 	register queue_t *q;
2091 	register mblk_t	*bp;
2092 	register mblk_t *head = NULL, *tail = NULL;
2093 
2094 	mutex_enter(zs->zs_excl);
2095 	if (zs->zs_suspended || (zs->zs_flags & ZS_CLOSED)) {
2096 		mutex_exit(zs->zs_excl);
2097 		return (0);
2098 	}
2099 	q = za->za_ttycommon.t_readq;
2100 	if (za->za_flags & ZAS_WOPEN && !q) {
2101 		if (za->za_ext) {
2102 			mutex_enter(zs->zs_excl_hi);
2103 			r0 = SCC_READ0();
2104 			za->za_ext = 0;
2105 			mutex_exit(zs->zs_excl_hi);
2106 			/*
2107 			 * carrier up?
2108 			 */
2109 			if ((r0 & ZSRR0_CD) ||
2110 			    (za->za_ttycommon.t_flags & TS_SOFTCAR)) {
2111 				/*
2112 				 * carrier present
2113 				 */
2114 				if ((za->za_flags & ZAS_CARR_ON) == 0) {
2115 					za->za_flags |= ZAS_CARR_ON;
2116 					mutex_exit(zs->zs_excl);
2117 					cv_broadcast(&zs->zs_flags_cv);
2118 					return (0);
2119 				}
2120 			}
2121 		}
2122 		mutex_exit(zs->zs_excl);
2123 		return (0);
2124 	}
2125 	q = za->za_ttycommon.t_readq;
2126 	if (!q) {
2127 		mutex_exit(zs->zs_excl);
2128 		return (0);
2129 	}
2130 
2131 	m_error = za->za_m_error;
2132 	za->za_m_error = 0;
2133 
2134 	if (za->za_do_kick_rcv_in_softint) {
2135 		mutex_enter(zs->zs_excl_hi);
2136 		ZSA_KICK_RCV;
2137 		za->za_do_kick_rcv_in_softint = 0;
2138 		mutex_exit(zs->zs_excl_hi);
2139 	}
2140 
2141 	za_kick_active = za->za_kick_active;
2142 
2143 	while (!za_kick_active) {
2144 		ZSA_SEEQ(bp);
2145 		if (!bp)
2146 			break;
2147 
2148 		allocbcount++;
2149 
2150 		if (bp->b_datap->db_type <= QPCTL) {
2151 			if (!(canputnext(q))) {
2152 				if (za->za_grace_flow_control >=
2153 				    zsa_grace_flow_control) {
2154 					if (za->za_ttycommon.t_cflag &
2155 					    CRTSXOFF) {
2156 						allocbcount--;
2157 						break;
2158 					}
2159 					ZSA_GETQ(bp);
2160 					freemsg(bp);
2161 					do_ttycommon_qfull = 1;
2162 					continue;
2163 				} else
2164 					za->za_grace_flow_control++;
2165 			} else
2166 				za->za_grace_flow_control = 0;
2167 		}
2168 		ZSA_GETQ(bp);
2169 		if (!head) {
2170 			head = bp;
2171 		} else {
2172 			if (!tail)
2173 				tail = head;
2174 			tail->b_next = bp;
2175 			tail = bp;
2176 		}
2177 	}
2178 
2179 	if (allocbcount)
2180 		ZSA_GETBLOCK(zs, allocbcount);
2181 
2182 	if (za->za_ext) {
2183 		mutex_enter(zs->zs_excl_hi);
2184 		r0 = SCC_READ0();
2185 		za->za_ext = 0;
2186 		/*
2187 		 * carrier up?
2188 		 */
2189 		if ((r0 & ZSRR0_CD) ||
2190 		    (za->za_ttycommon.t_flags & TS_SOFTCAR)) {
2191 			/*
2192 			 * carrier present
2193 			 */
2194 			if ((za->za_flags & ZAS_CARR_ON) == 0) {
2195 				za->za_flags |= ZAS_CARR_ON;
2196 				unhangup = B_TRUE;
2197 				wakeup = B_TRUE;
2198 			}
2199 		} else {
2200 			if ((za->za_flags & ZAS_CARR_ON) &&
2201 			    !(za->za_ttycommon.t_cflag & CLOCAL)) {
2202 				/*
2203 				 * Carrier went away.
2204 				 * Drop DTR, abort any output in progress,
2205 				 * indicate that output is not stopped, and
2206 				 * send a hangup notification upstream.
2207 				 */
2208 				(void) zsmctl(zs, ZSWR5_DTR, DMBIC);
2209 				if ((za->za_flags & ZAS_BUSY) &&
2210 				    (zs->zs_wr_cur != NULL)) {
2211 					zs->zs_wr_cur = NULL;
2212 					zs->zs_wr_lim = NULL;
2213 				}
2214 				hangup = B_TRUE;
2215 				wakeup = B_TRUE;
2216 				za->za_flags &= ~(ZAS_STOPPED | ZAS_CARR_ON |
2217 				    ZAS_BUSY);
2218 				za->za_rcv_flags_mask &= ~(DO_TRANSMIT |
2219 				    DO_RETRANSMIT);
2220 			}
2221 		}
2222 		mutex_exit(zs->zs_excl_hi);
2223 		if (hangup && (bp = za->za_xmitblk) != NULL) {
2224 			za->za_xmitblk = NULL;
2225 			freeb(bp);
2226 		}
2227 	}
2228 
2229 	if (za->za_break != 0) {
2230 		mutex_enter(zs->zs_excl_hi);
2231 		r0 = SCC_READ0();
2232 		mutex_exit(zs->zs_excl_hi);
2233 		if ((r0 & ZSRR0_BREAK) == 0) {
2234 			za->za_break = 0;
2235 			m_break = B_TRUE;
2236 		}
2237 	}
2238 
2239 	/*
2240 	 * If a transmission has finished, indicate that it's
2241 	 * finished, and start that line up again.
2242 	 */
2243 
2244 	mutex_enter(zs->zs_excl_hi);
2245 	if (za->za_rcv_flags_mask & DO_TRANSMIT) {
2246 		za->za_rcv_flags_mask &= ~DO_TRANSMIT;
2247 		za->za_flags &= ~ZAS_BUSY;
2248 
2249 		if ((za->za_ttycommon.t_cflag & CRTSCTS) &&
2250 		    (za->za_rcv_flags_mask & DO_RETRANSMIT) &&
2251 		    zs->zs_wr_cur)
2252 			bp = NULL;
2253 		else {
2254 			za->za_rcv_flags_mask &= ~DO_RETRANSMIT;
2255 			bp = za->za_xmitblk;
2256 			za->za_xmitblk = 0;
2257 		}
2258 		mutex_exit(zs->zs_excl_hi);
2259 		if (bp)
2260 			freemsg(bp);
2261 		zsa_start(zs);
2262 		/* if we didn't start anything, then notify waiters */
2263 		if (!(za->za_flags & ZAS_BUSY))
2264 			wakeup = B_TRUE;
2265 	} else {
2266 		mutex_exit(zs->zs_excl_hi);
2267 	}
2268 
2269 
2270 	/*
2271 	 * A note about these overrun bits: all they do is *tell* someone
2272 	 * about an error- They do not track multiple errors. In fact,
2273 	 * you could consider them latched register bits if you like.
2274 	 * We are only interested in printing the error message once for
2275 	 * any cluster of overrun errors.
2276 	 */
2277 	if ((!za->za_kick_rcv_id) && (zs->zs_rd_cur || za_kick_active)) {
2278 		if (g_zsticks)
2279 			za->za_kick_rcv_id = timeout(zsa_kick_rcv, zs,
2280 			    g_zsticks);
2281 		else
2282 			za->za_kick_rcv_id = timeout(zsa_kick_rcv, zs,
2283 			    zsticks[SPEED(za->za_ttycommon.t_cflag)]);
2284 		za->za_kick_rcv_count = ZA_KICK_RCV_COUNT;
2285 	}
2286 	za->za_soft_active = 1;
2287 	mutex_exit(zs->zs_excl);
2288 
2289 	if (!hangup && do_ttycommon_qfull) {
2290 		ttycommon_qfull(&za->za_ttycommon, q);
2291 		mutex_enter(zs->zs_excl);
2292 		zsa_start(zs);
2293 		mutex_exit(zs->zs_excl);
2294 	}
2295 
2296 	if (za->za_hw_overrun > 10) {
2297 		cmn_err(CE_NOTE, "zs%d: silo overflow\n", UNIT(za->za_dev));
2298 		za->za_hw_overrun = 0;
2299 	}
2300 
2301 	if (za->za_sw_overrun > 10) {
2302 		cmn_err(CE_NOTE, "zs%d:ring buffer overflow\n",
2303 		    UNIT(za->za_dev));
2304 		za->za_sw_overrun = 0;
2305 	}
2306 
2307 	if (unhangup)
2308 		(void) putnextctl(q, M_UNHANGUP);
2309 
2310 	if (m_break)
2311 		(void) putnextctl(q, M_BREAK);
2312 
2313 	while (head) {
2314 		if (!tail) {
2315 			putnext(q, head);
2316 			break;
2317 		}
2318 		bp = head;
2319 		head = head->b_next;
2320 		bp->b_next = NULL;
2321 		putnext(q, bp);
2322 	}
2323 
2324 	if (hangup) {
2325 		int flushflag;
2326 
2327 		/*
2328 		 * If we're in the midst of close, then flush everything.  Don't
2329 		 * leave stale ioctls lying about.
2330 		 */
2331 		flushflag = (zs->zs_flags & ZS_CLOSING) ? FLUSHALL : FLUSHDATA;
2332 		flushq(za->za_ttycommon.t_writeq, flushflag);
2333 		(void) putnextctl(q, M_HANGUP);
2334 	}
2335 
2336 	if (m_error)
2337 		(void) putnextctl1(q, M_ERROR, m_error);
2338 
2339 	za->za_soft_active = 0;
2340 
2341 	if (wakeup || (zs->zs_flags & ZS_CLOSED))
2342 		cv_broadcast(&zs->zs_flags_cv);
2343 
2344 	return (0);
2345 }
2346 
2347 /*
2348  * Start output on a line, unless it's busy, frozen, or otherwise.
2349  */
2350 static void
2351 zsa_start(struct zscom *zs)
2352 {
2353 	register struct asyncline *za = (struct asyncline *)&zs->zs_priv_str;
2354 	register int cc;
2355 	register queue_t *q;
2356 	register mblk_t *bp;
2357 	uchar_t *rptr, *wptr;
2358 
2359 	/*
2360 	 * If the chip is busy (i.e., we're waiting for a break timeout
2361 	 * to expire, or for the current transmission to finish, or for
2362 	 * output to finish draining from chip), don't grab anything new.
2363 	 */
2364 	if ((za->za_flags & (ZAS_BREAK|ZAS_BUSY|ZAS_DRAINING)) ||
2365 	    zs->zs_suspended)
2366 		return;
2367 
2368 	if (za->za_ttycommon.t_cflag & CRTSCTS) {
2369 		mutex_enter(zs->zs_excl_hi);
2370 		if (za->za_rcv_flags_mask & DO_RETRANSMIT) {
2371 			rptr = zs->zs_wr_cur;
2372 			wptr = zs->zs_wr_lim;
2373 			goto zsa_start_retransmit;
2374 
2375 		}
2376 		mutex_exit(zs->zs_excl_hi);
2377 	}
2378 
2379 	/*
2380 	 * If we have a flow-control character to transmit, do it now.
2381 	 */
2382 	if (za->za_flowc != '\0') {
2383 		mutex_enter(zs->zs_excl_hi);
2384 		if (za->za_ttycommon.t_cflag & CRTSCTS) {
2385 			if ((SCC_READ0() & (ZSRR0_CTS|ZSRR0_TX_READY)) !=
2386 			    (ZSRR0_CTS|ZSRR0_TX_READY)) {
2387 				mutex_exit(zs->zs_excl_hi);
2388 				return;
2389 			}
2390 		} else if (!(SCC_READ0() & ZSRR0_TX_READY)) {
2391 			mutex_exit(zs->zs_excl_hi);
2392 			return;
2393 		}
2394 
2395 		ZSDELAY();
2396 		SCC_WRITEDATA(za->za_flowc);
2397 		za->za_flowc = '\0';
2398 		mutex_exit(zs->zs_excl_hi);
2399 		return;
2400 	}
2401 
2402 	/*
2403 	 * If we're waiting for a delay timeout to expire, don't grab
2404 	 * anything new.
2405 	 */
2406 	if (za->za_flags & ZAS_DELAY)
2407 		return;
2408 
2409 	if ((q = za->za_ttycommon.t_writeq) == NULL)
2410 		return;	/* not attached to a stream */
2411 
2412 zsa_start_again:
2413 	for (;;) {
2414 		if ((bp = getq(q)) == NULL)
2415 			return;	/* no data to transmit */
2416 
2417 		/*
2418 		 * We have a message block to work on.
2419 		 * Check whether it's a break, a delay, or an ioctl (the latter
2420 		 * occurs if the ioctl in question was waiting for the output
2421 		 * to drain). If it's one of those, process it immediately.
2422 		 */
2423 		switch (bp->b_datap->db_type) {
2424 
2425 		case M_BREAK:
2426 			/*
2427 			 * Set the break bit, and arrange for "zsa_restart"
2428 			 * to be called in 1/4 second; it will turn the
2429 			 * break bit off, and call "zsa_start" to grab
2430 			 * the next message.
2431 			 */
2432 			mutex_enter(zs->zs_excl_hi);
2433 			SCC_BIS(5, ZSWR5_BREAK);
2434 			mutex_exit(zs->zs_excl_hi);
2435 			if (!za->za_zsa_restart_id) {
2436 				za->za_zsa_restart_id =
2437 				    timeout(zsa_restart, zs, hz/4);
2438 			}
2439 			za->za_flags |= ZAS_BREAK;
2440 			freemsg(bp);
2441 			return;	/* wait for this to finish */
2442 
2443 		case M_DELAY:
2444 			/*
2445 			 * Arrange for "zsa_restart" to be called when the
2446 			 * delay expires; it will turn MTS_DELAY off,
2447 			 * and call "zsa_start" to grab the next message.
2448 			 */
2449 			if (! za->za_zsa_restart_id) {
2450 				za->za_zsa_restart_id = timeout(zsa_restart,
2451 				    zs,
2452 				    (int)(*(unsigned char *)bp->b_rptr + 6));
2453 			}
2454 			za->za_flags |= ZAS_DELAY;
2455 			freemsg(bp);
2456 			return;	/* wait for this to finish */
2457 
2458 		case M_IOCTL:
2459 			/*
2460 			 * This ioctl was waiting for the output ahead of
2461 			 * it to drain; obviously, it has. Do it, and
2462 			 * then grab the next message after it.
2463 			 */
2464 			zsa_ioctl(za, q, bp);
2465 			continue;
2466 		default: /* M_DATA */
2467 			goto zsa_start_transmit;
2468 		}
2469 
2470 	}
2471 zsa_start_transmit:
2472 	/*
2473 	 * We have data to transmit. If output is stopped, put
2474 	 * it back and try again later.
2475 	 */
2476 	if (za->za_flags & ZAS_STOPPED) {
2477 		(void) putbq(q, bp);
2478 		return;
2479 	}
2480 
2481 	za->za_xmitblk = bp;
2482 	rptr = bp->b_rptr;
2483 	wptr = bp->b_wptr;
2484 	cc = wptr - rptr;
2485 	bp = bp->b_cont;
2486 	if (bp != NULL) {
2487 		za->za_xmitblk->b_cont = NULL;
2488 		(void) putbq(q, bp);	/* not done with this message yet */
2489 	}
2490 
2491 	if (rptr >= wptr) {
2492 		freeb(za->za_xmitblk);
2493 		za->za_xmitblk = NULL;
2494 		goto zsa_start_again;
2495 	}
2496 
2497 	/*
2498 	 * In 5-bit mode, the high order bits are used
2499 	 * to indicate character sizes less than five,
2500 	 * so we need to explicitly mask before transmitting
2501 	 */
2502 	if ((za->za_ttycommon.t_cflag & CSIZE) == CS5) {
2503 		register unsigned char *p = rptr;
2504 		register int cnt = cc;
2505 
2506 		while (cnt--)
2507 			*p++ &= (unsigned char) 0x1f;
2508 	}
2509 
2510 	/*
2511 	 * Set up this block for pseudo-DMA.
2512 	 */
2513 
2514 	mutex_enter(zs->zs_excl_hi);
2515 	zs->zs_wr_cur = rptr;
2516 	zs->zs_wr_lim = wptr;
2517 
2518 zsa_start_retransmit:
2519 	za->za_rcv_flags_mask &= ~DO_TRANSMIT;
2520 	if (za->za_ttycommon.t_cflag & CRTSCTS) {
2521 		if ((SCC_READ0() & (ZSRR0_CTS|ZSRR0_TX_READY)) !=
2522 		    (ZSRR0_CTS|ZSRR0_TX_READY)) {
2523 			za->za_rcv_flags_mask |= DO_RETRANSMIT;
2524 			za->za_flags |= ZAS_BUSY;
2525 			mutex_exit(zs->zs_excl_hi);
2526 			return;
2527 		}
2528 		za->za_rcv_flags_mask &= ~DO_RETRANSMIT;
2529 	} else {
2530 		if (!(SCC_READ0() & ZSRR0_TX_READY)) {
2531 			za->za_flags |= ZAS_BUSY;
2532 			mutex_exit(zs->zs_excl_hi);
2533 			return;
2534 		}
2535 	}
2536 	/*
2537 	 * If the transmitter is ready, shove the first
2538 	 * character out.
2539 	 */
2540 	ZSDELAY();
2541 	SCC_WRITEDATA(*rptr++);
2542 #ifdef ZSA_DEBUG
2543 	za->za_wr++;
2544 #endif
2545 	zs->zs_wr_cur = rptr;
2546 	za->za_flags |= ZAS_BUSY;
2547 	zs->zs_flags |= ZS_PROGRESS;
2548 	mutex_exit(zs->zs_excl_hi);
2549 }
2550 
2551 /*
2552  * Restart output on a line after a delay or break timer expired.
2553  */
2554 static void
2555 zsa_restart(void *arg)
2556 {
2557 	struct zscom *zs = arg;
2558 	struct asyncline *za = (struct asyncline *)&zs->zs_priv_str;
2559 
2560 	/*
2561 	 * If break timer expired, turn off the break bit.
2562 	 */
2563 	mutex_enter(zs->zs_excl);
2564 	if (!za->za_zsa_restart_id) {
2565 		mutex_exit(zs->zs_excl);
2566 		return;
2567 	}
2568 	za->za_zsa_restart_id = 0;
2569 	if (za->za_flags & ZAS_BREAK) {
2570 		mutex_enter(zs->zs_excl_hi);
2571 		SCC_BIC(5, ZSWR5_BREAK);
2572 		mutex_exit(zs->zs_excl_hi);
2573 	}
2574 	za->za_flags &= ~(ZAS_DELAY|ZAS_BREAK);
2575 	if (za->za_ttycommon.t_writeq != NULL)
2576 		zsa_start(zs);
2577 	mutex_exit(zs->zs_excl);
2578 	cv_broadcast(&zs->zs_flags_cv);
2579 }
2580 
2581 /*
2582  * See if the receiver has any data after zs_tick delay
2583  */
2584 static void
2585 zsa_kick_rcv(void *arg)
2586 {
2587 	struct zscom *zs = arg;
2588 	struct asyncline *za = (struct asyncline *)&zs->zs_priv_str;
2589 	queue_t *q;
2590 	int	tmp;
2591 	mblk_t	*mp;
2592 	uchar_t za_soft_active, za_kick_active;
2593 	int	allocbcount = 0;
2594 	int do_ttycommon_qfull = 0;
2595 	mblk_t *head = NULL, *tail = NULL;
2596 
2597 	mutex_enter(zs->zs_excl);
2598 	if (za->za_kick_rcv_id == 0 || (zs->zs_flags & ZS_CLOSED)) {
2599 		mutex_exit(zs->zs_excl);
2600 		return;
2601 	}
2602 	za_soft_active = za->za_soft_active;
2603 	za_kick_active = za->za_kick_active;
2604 	q = za->za_ttycommon.t_readq;
2605 	if (!q) {
2606 		mutex_exit(zs->zs_excl);
2607 		return;
2608 	}
2609 	mutex_enter(zs->zs_excl_hi);
2610 	if (zs->zs_rd_cur) {
2611 		ZSA_KICK_RCV;
2612 		za->za_kick_rcv_count = tmp = ZA_KICK_RCV_COUNT;
2613 	} else
2614 		tmp = --za->za_kick_rcv_count;
2615 	if (tmp > 0 || za_soft_active || za_kick_active) {
2616 		mutex_exit(zs->zs_excl_hi);
2617 		if (g_zsticks)
2618 			za->za_kick_rcv_id = timeout(zsa_kick_rcv,
2619 			    zs, g_zsticks);
2620 		else
2621 			za->za_kick_rcv_id = timeout(zsa_kick_rcv,
2622 			    zs, zsticks[SPEED(za->za_ttycommon.t_cflag)]);
2623 		if (za_soft_active || za_kick_active) {
2624 			mutex_exit(zs->zs_excl);
2625 			return;
2626 		}
2627 	} else {
2628 		za->za_kick_rcv_id = 0;
2629 		mutex_exit(zs->zs_excl_hi);
2630 	}
2631 
2632 
2633 	for (;;) {
2634 		ZSA_SEEQ(mp);
2635 		if (!mp)
2636 			break;
2637 
2638 		allocbcount++;
2639 
2640 		if (mp->b_datap->db_type <= QPCTL) {
2641 			if (!(canputnext(q))) {
2642 				if (za->za_grace_flow_control >=
2643 				    zsa_grace_flow_control) {
2644 					if (za->za_ttycommon.t_cflag &
2645 					    CRTSXOFF) {
2646 						allocbcount--;
2647 						break;
2648 					}
2649 					ZSA_GETQ(mp);
2650 					freemsg(mp);
2651 					do_ttycommon_qfull = 1;
2652 					continue;
2653 				} else
2654 					za->za_grace_flow_control++;
2655 			} else
2656 				za->za_grace_flow_control = 0;
2657 		}
2658 		ZSA_GETQ(mp);
2659 		if (!head) {
2660 			head = mp;
2661 		} else {
2662 			if (!tail)
2663 				tail = head;
2664 			tail->b_next = mp;
2665 			tail = mp;
2666 		}
2667 	}
2668 
2669 	if (allocbcount)
2670 		ZSA_GETBLOCK(zs, allocbcount);
2671 
2672 	za->za_kick_active = 1;
2673 	mutex_exit(zs->zs_excl);
2674 
2675 	if (do_ttycommon_qfull) {
2676 		ttycommon_qfull(&za->za_ttycommon, q);
2677 		mutex_enter(zs->zs_excl);
2678 		zsa_start(zs);
2679 		mutex_exit(zs->zs_excl);
2680 	}
2681 
2682 	while (head) {
2683 		if (!tail) {
2684 			putnext(q, head);
2685 			break;
2686 		}
2687 		mp = head;
2688 		head = head->b_next;
2689 		mp->b_next = NULL;
2690 		putnext(q, mp);
2691 
2692 	}
2693 	za->za_kick_active = 0;
2694 
2695 	if (zs->zs_flags & ZS_CLOSED)
2696 		cv_broadcast(&zs->zs_flags_cv);
2697 }
2698 
2699 /*
2700  * Retry an "ioctl", now that "bufcall" claims we may be able to allocate
2701  * the buffer we need.
2702  */
2703 static void
2704 zsa_reioctl(void *arg)
2705 {
2706 	struct asyncline *za = arg;
2707 	struct zscom *zs = za->za_common;
2708 	queue_t *q;
2709 	mblk_t	 *mp;
2710 
2711 	/*
2712 	 * The bufcall is no longer pending.
2713 	 */
2714 	mutex_enter(zs->zs_excl);
2715 	if (!za->za_wbufcid) {
2716 		mutex_exit(zs->zs_excl);
2717 		return;
2718 	}
2719 	za->za_wbufcid = 0;
2720 	if ((q = za->za_ttycommon.t_writeq) == NULL) {
2721 		mutex_exit(zs->zs_excl);
2722 		return;
2723 	}
2724 	if ((mp = za->za_ttycommon.t_iocpending) != NULL) {
2725 		/*
2726 		 * not pending any more
2727 		 */
2728 		za->za_ttycommon.t_iocpending = NULL;
2729 		zsa_ioctl(za, q, mp);
2730 	}
2731 	mutex_exit(zs->zs_excl);
2732 }
2733 
2734 /*
2735  * Process an "ioctl" message sent down to us.
2736  * Note that we don't need to get any locks until we are ready to access
2737  * the hardware. Nothing we access until then is going to be altered
2738  * outside of the STREAMS framework, so we should be safe.
2739  */
2740 static void
2741 zsa_ioctl(struct asyncline *za, queue_t *wq, mblk_t *mp)
2742 {
2743 	register struct zscom *zs = za->za_common;
2744 	register struct iocblk *iocp;
2745 	register unsigned datasize;
2746 	int error;
2747 	register mblk_t *tmp;
2748 
2749 	if (za->za_ttycommon.t_iocpending != NULL) {
2750 		/*
2751 		 * We were holding an "ioctl" response pending the
2752 		 * availability of an "mblk" to hold data to be passed up;
2753 		 * another "ioctl" came through, which means that "ioctl"
2754 		 * must have timed out or been aborted.
2755 		 */
2756 		freemsg(za->za_ttycommon.t_iocpending);
2757 		za->za_ttycommon.t_iocpending = NULL;
2758 	}
2759 
2760 	iocp = (struct iocblk *)mp->b_rptr;
2761 
2762 	/*
2763 	 * The only way in which "ttycommon_ioctl" can fail is if the "ioctl"
2764 	 * requires a response containing data to be returned to the user,
2765 	 * and no mblk could be allocated for the data.
2766 	 * No such "ioctl" alters our state. Thus, we always go ahead and
2767 	 * do any state-changes the "ioctl" calls for. If we couldn't allocate
2768 	 * the data, "ttycommon_ioctl" has stashed the "ioctl" away safely, so
2769 	 * we just call "bufcall" to request that we be called back when we
2770 	 * stand a better chance of allocating the data.
2771 	 */
2772 	mutex_exit(zs->zs_excl);
2773 	datasize = ttycommon_ioctl(&za->za_ttycommon, wq, mp, &error);
2774 	mutex_enter(zs->zs_excl);
2775 	if (za->za_ttycommon.t_flags & TS_SOFTCAR)
2776 		zssoftCAR[zs->zs_unit] = 1;
2777 	else
2778 		zssoftCAR[zs->zs_unit] = 0;
2779 	if (datasize != 0) {
2780 		if (za->za_wbufcid)
2781 			unbufcall(za->za_wbufcid);
2782 		za->za_wbufcid = bufcall(datasize, BPRI_HI, zsa_reioctl, za);
2783 		return;
2784 	}
2785 
2786 
2787 	if (error == 0) {
2788 		/*
2789 		 * "ttycommon_ioctl" did most of the work; we just use the
2790 		 * data it set up.
2791 		 */
2792 		switch (iocp->ioc_cmd) {
2793 
2794 		case TCSETS:
2795 		case TCSETSW:
2796 		case TCSETSF:
2797 		case TCSETA:
2798 		case TCSETAW:
2799 		case TCSETAF:
2800 			mutex_enter(zs->zs_excl_hi);
2801 			zsa_program(za, 1);
2802 			zsa_set_za_rcv_flags_mask(za);
2803 			mutex_exit(zs->zs_excl_hi);
2804 			break;
2805 		}
2806 	} else if (error < 0) {
2807 		/*
2808 		 * "ttycommon_ioctl" didn't do anything; we process it here.
2809 		 */
2810 		error = 0;
2811 
2812 		switch (iocp->ioc_cmd) {
2813 
2814 		case TCSBRK:
2815 			error = miocpullup(mp, sizeof (int));
2816 			if (error != 0)
2817 				break;
2818 
2819 			if (*(int *)mp->b_cont->b_rptr == 0) {
2820 				/*
2821 				 * The delay ensures that a 3 byte transmit
2822 				 * fifo is empty.
2823 				 */
2824 				mutex_exit(zs->zs_excl);
2825 				delay(ztdelay(SPEED(za->za_ttycommon.t_cflag)));
2826 				mutex_enter(zs->zs_excl);
2827 
2828 				/*
2829 				 * Set the break bit, and arrange for
2830 				 * "zsa_restart" to be called in 1/4 second;
2831 				 * it will turn the break bit off, and call
2832 				 * "zsa_start" to grab the next message.
2833 				 */
2834 				mutex_enter(zs->zs_excl_hi);
2835 				SCC_BIS(5, ZSWR5_BREAK);
2836 				if (!za->za_zsa_restart_id) {
2837 					mutex_exit(zs->zs_excl_hi);
2838 					za->za_zsa_restart_id =
2839 					    timeout(zsa_restart, zs, hz / 4);
2840 					mutex_enter(zs->zs_excl_hi);
2841 				}
2842 				za->za_flags |= ZAS_BREAK;
2843 				mutex_exit(zs->zs_excl_hi);
2844 			}
2845 			break;
2846 
2847 		case TIOCSBRK:
2848 			mutex_enter(zs->zs_excl_hi);
2849 			SCC_BIS(5, ZSWR5_BREAK);
2850 			mutex_exit(zs->zs_excl_hi);
2851 			mioc2ack(mp, NULL, 0, 0);
2852 			break;
2853 
2854 		case TIOCCBRK:
2855 			mutex_enter(zs->zs_excl_hi);
2856 			SCC_BIC(5, ZSWR5_BREAK);
2857 			mutex_exit(zs->zs_excl_hi);
2858 			mioc2ack(mp, NULL, 0, 0);
2859 			break;
2860 
2861 		case TIOCMSET:
2862 		case TIOCMBIS:
2863 		case TIOCMBIC: {
2864 			int mlines;
2865 
2866 			if (iocp->ioc_count == TRANSPARENT) {
2867 				mcopyin(mp, NULL, sizeof (int), NULL);
2868 				break;
2869 			}
2870 
2871 			error = miocpullup(mp, sizeof (int));
2872 			if (error != 0)
2873 				break;
2874 
2875 			mlines = *(int *)mp->b_cont->b_rptr;
2876 
2877 			mutex_enter(zs->zs_excl_hi);
2878 			switch (iocp->ioc_cmd) {
2879 			case TIOCMSET:
2880 				(void) zsmctl(zs, dmtozs(mlines), DMSET);
2881 				break;
2882 			case TIOCMBIS:
2883 				(void) zsmctl(zs, dmtozs(mlines), DMBIS);
2884 				break;
2885 			case TIOCMBIC:
2886 				(void) zsmctl(zs, dmtozs(mlines), DMBIC);
2887 				break;
2888 			}
2889 			mutex_exit(zs->zs_excl_hi);
2890 
2891 			mioc2ack(mp, NULL, 0, 0);
2892 			break;
2893 		}
2894 
2895 		case TIOCMGET:
2896 			tmp = allocb(sizeof (int), BPRI_MED);
2897 			if (tmp == NULL) {
2898 				error = EAGAIN;
2899 				break;
2900 			}
2901 			if (iocp->ioc_count != TRANSPARENT)
2902 				mioc2ack(mp, tmp, sizeof (int), 0);
2903 			else
2904 				mcopyout(mp, NULL, sizeof (int), NULL, tmp);
2905 
2906 			mutex_enter(zs->zs_excl_hi);
2907 			*(int *)mp->b_cont->b_rptr =
2908 			    zstodm(zsmctl(zs, 0, DMGET));
2909 			mutex_exit(zs->zs_excl_hi);
2910 			/*
2911 			 * qreply done below
2912 			 */
2913 			break;
2914 
2915 		default:
2916 			/*
2917 			 * If we don't understand it, it's an error. NAK it.
2918 			 */
2919 			error = EINVAL;
2920 			break;
2921 		}
2922 	}
2923 
2924 	if (error != 0) {
2925 		iocp->ioc_error = error;
2926 		mp->b_datap->db_type = M_IOCNAK;
2927 	}
2928 
2929 	ZSA_QREPLY(wq, mp);
2930 }
2931 
2932 
2933 static int
2934 dmtozs(int bits)
2935 {
2936 	register int b = 0;
2937 
2938 	if (bits & TIOCM_CAR)
2939 		b |= ZSRR0_CD;
2940 	if (bits & TIOCM_CTS)
2941 		b |= ZSRR0_CTS;
2942 	if (bits & TIOCM_RTS)
2943 		b |= ZSWR5_RTS;
2944 	if (bits & TIOCM_DTR)
2945 		b |= ZSWR5_DTR;
2946 	return (b);
2947 }
2948 
2949 static int
2950 zstodm(int bits)
2951 {
2952 	register int b;
2953 
2954 	b = 0;
2955 	if (bits & ZSRR0_CD)
2956 		b |= TIOCM_CAR;
2957 	if (bits & ZSRR0_CTS)
2958 		b |= TIOCM_CTS;
2959 	if (bits & ZSWR5_RTS)
2960 		b |= TIOCM_RTS;
2961 	if (bits & ZSWR5_DTR)
2962 		b |= TIOCM_DTR;
2963 	return (b);
2964 }
2965 
2966 /*
2967  * Assemble registers and flags necessary to program the port to our liking.
2968  * For async operation, most of this is based on the values of
2969  * the "c_iflag" and "c_cflag" fields supplied to us.
2970  */
2971 static void
2972 zsa_program(struct asyncline *za, int setibaud)
2973 {
2974 	register struct zscom *zs = za->za_common;
2975 	register struct zs_prog *zspp;
2976 	register int wr3, wr4, wr5, wr15, speed, baudrate, flags = 0;
2977 
2978 	if ((baudrate = SPEED(za->za_ttycommon.t_cflag)) == 0) {
2979 		/*
2980 		 * Hang up line.
2981 		 */
2982 		(void) zsmctl(zs, ZS_OFF, DMSET);
2983 		return;
2984 	}
2985 
2986 	/*
2987 	 * set input speed same as output, as split speed not supported
2988 	 */
2989 	if (setibaud) {
2990 		za->za_ttycommon.t_cflag &= ~(CIBAUD);
2991 		if (baudrate > CBAUD) {
2992 			za->za_ttycommon.t_cflag |= CIBAUDEXT;
2993 			za->za_ttycommon.t_cflag |=
2994 			    (((baudrate - CBAUD - 1) << IBSHIFT) & CIBAUD);
2995 		} else {
2996 			za->za_ttycommon.t_cflag &= ~CIBAUDEXT;
2997 			za->za_ttycommon.t_cflag |=
2998 			    ((baudrate << IBSHIFT) & CIBAUD);
2999 		}
3000 	}
3001 
3002 	/*
3003 	 * Do not allow the console/keyboard device to have its receiver
3004 	 * disabled; doing that would mean you couldn't type an abort
3005 	 * sequence.
3006 	 */
3007 	if ((za->za_dev == rconsdev) || (za->za_dev == kbddev) ||
3008 	    (za->za_dev == stdindev) || (za->za_ttycommon.t_cflag & CREAD))
3009 		wr3 = ZSWR3_RX_ENABLE;
3010 	else
3011 		wr3 = 0;
3012 	wr4 = ZSWR4_X16_CLK;
3013 	wr5 = (zs->zs_wreg[5] & (ZSWR5_RTS|ZSWR5_DTR)) | ZSWR5_TX_ENABLE;
3014 
3015 	if (zsb134_weird && baudrate == B134) {	/* what a joke! */
3016 		/*
3017 		 * XXX - should B134 set all this crap in the compatibility
3018 		 * module, leaving this stuff fairly clean?
3019 		 */
3020 		flags |= ZSP_PARITY_SPECIAL;
3021 		wr3 |= ZSWR3_RX_6;
3022 		wr4 |= ZSWR4_PARITY_ENABLE | ZSWR4_PARITY_EVEN;
3023 		wr4 |= ZSWR4_1_5_STOP;
3024 		wr5 |= ZSWR5_TX_6;
3025 	} else {
3026 
3027 		switch (za->za_ttycommon.t_cflag & CSIZE) {
3028 
3029 		case CS5:
3030 			wr3 |= ZSWR3_RX_5;
3031 			wr5 |= ZSWR5_TX_5;
3032 			break;
3033 
3034 		case CS6:
3035 			wr3 |= ZSWR3_RX_6;
3036 			wr5 |= ZSWR5_TX_6;
3037 			break;
3038 
3039 		case CS7:
3040 			wr3 |= ZSWR3_RX_7;
3041 			wr5 |= ZSWR5_TX_7;
3042 			break;
3043 
3044 		case CS8:
3045 			wr3 |= ZSWR3_RX_8;
3046 			wr5 |= ZSWR5_TX_8;
3047 			break;
3048 		}
3049 
3050 		if (za->za_ttycommon.t_cflag & PARENB) {
3051 			/*
3052 			 * The PARITY_SPECIAL bit causes a special rx
3053 			 * interrupt on parity errors. Turn it on if
3054 			 * we're checking the parity of characters.
3055 			 */
3056 			if (za->za_ttycommon.t_iflag & INPCK)
3057 				flags |= ZSP_PARITY_SPECIAL;
3058 			wr4 |= ZSWR4_PARITY_ENABLE;
3059 			if (!(za->za_ttycommon.t_cflag & PARODD))
3060 				wr4 |= ZSWR4_PARITY_EVEN;
3061 		}
3062 		wr4 |= (za->za_ttycommon.t_cflag & CSTOPB) ?
3063 		    ZSWR4_2_STOP : ZSWR4_1_STOP;
3064 	}
3065 
3066 #if 0
3067 	/*
3068 	 * The AUTO_CD_CTS flag enables the hardware flow control feature of
3069 	 * the 8530, which allows the state of CTS and DCD to control the
3070 	 * enabling of the transmitter and receiver, respectively. The
3071 	 * receiver and transmitter still must have their enable bits set in
3072 	 * WR3 and WR5, respectively, for CTS and DCD to be monitored this way.
3073 	 * Hardware flow control can thus be implemented with no help from
3074 	 * software.
3075 	 */
3076 	if (za->za_ttycommon.t_cflag & CRTSCTS)
3077 		wr3 |= ZSWR3_AUTO_CD_CTS;
3078 #endif
3079 	if (za->za_ttycommon.t_cflag & CRTSCTS)
3080 		wr15 = ZSR15_BREAK | ZSR15_TX_UNDER | ZSR15_CD | ZSR15_CTS;
3081 	else
3082 		wr15 = ZSR15_BREAK | ZSR15_TX_UNDER | ZSR15_CD;
3083 
3084 	speed = zs->zs_wreg[12] + (zs->zs_wreg[13] << 8);
3085 
3086 	/*
3087 	 * Here we assemble a set of changes to be passed to zs_program.
3088 	 * Note: Write Register 15 must be set to enable BREAK and UNDERrun
3089 	 * interrupts.  It must also enable CD interrupts which, although
3090 	 * not processed by the hardware interrupt handler, will be processed
3091 	 * by zsa_process, indirectly resulting in a SIGHUP being delivered
3092 	 * to the controlling process if CD drops.  CTS interrupts must NOT
3093 	 * be enabled.  We don't use them at all, and they will hang IPC/IPX
3094 	 * systems at boot time if synchronous modems that supply transmit
3095 	 * clock are attached to any of their serial ports.
3096 	 */
3097 	if (((zs->zs_wreg[1] & ZSWR1_PARITY_SPECIAL) &&
3098 	    !(flags & ZSP_PARITY_SPECIAL)) ||
3099 	    (!(zs->zs_wreg[1] & ZSWR1_PARITY_SPECIAL) &&
3100 	    (flags & ZSP_PARITY_SPECIAL)) ||
3101 	    wr3 != zs->zs_wreg[3] || wr4 != zs->zs_wreg[4] ||
3102 	    wr5 != zs->zs_wreg[5] || wr15 != zs->zs_wreg[15] ||
3103 	    speed != zs_speeds[baudrate]) {
3104 
3105 		za->za_flags |= ZAS_DRAINING;
3106 		zspp = &zs_prog[zs->zs_unit];
3107 		zspp->zs = zs;
3108 		zspp->flags = (uchar_t)flags;
3109 		zspp->wr4 = (uchar_t)wr4;
3110 		zspp->wr11 = (uchar_t)(ZSWR11_TXCLK_BAUD | ZSWR11_RXCLK_BAUD);
3111 
3112 		speed = zs_speeds[baudrate];
3113 		zspp->wr12 = (uchar_t)(speed & 0xff);
3114 		zspp->wr13 = (uchar_t)((speed >> 8) & 0xff);
3115 		zspp->wr3 = (uchar_t)wr3;
3116 		zspp->wr5 = (uchar_t)wr5;
3117 		zspp->wr15 = (uchar_t)wr15;
3118 
3119 		zs_program(zspp);
3120 		za->za_flags &= ~ZAS_DRAINING;
3121 	}
3122 }
3123 
3124 /*
3125  * Get the current speed of the console and turn it into something
3126  * UNIX knows about - used to preserve console speed when UNIX comes up.
3127  */
3128 int
3129 zsgetspeed(dev_t dev)
3130 {
3131 	register struct zscom *zs;
3132 	register int uspeed, zspeed;
3133 	register uchar_t rr;
3134 
3135 	zs = &zscom[UNIT(dev)];
3136 	SCC_READ(12, zspeed);
3137 	SCC_READ(13, rr);
3138 	zspeed |= rr << 8;
3139 	for (uspeed = 0; uspeed < NSPEED; uspeed++)
3140 		if (zs_speeds[uspeed] == zspeed)
3141 			return (uspeed);
3142 	/*
3143 	 * 9600 baud if we can't figure it out
3144 	 */
3145 	return (ISPEED);
3146 }
3147 
3148 /*
3149  * callback routine when enough memory is available.
3150  */
3151 static void
3152 zsa_callback(void *arg)
3153 {
3154 	struct zscom *zs = arg;
3155 	struct asyncline *za = (struct asyncline *)&zs->zs_priv_str;
3156 	int allocbcount = zsa_rstandby;
3157 
3158 	mutex_enter(zs->zs_excl);
3159 	if (za->za_bufcid) {
3160 		za->za_bufcid = 0;
3161 		ZSA_GETBLOCK(zs, allocbcount);
3162 	}
3163 	mutex_exit(zs->zs_excl);
3164 }
3165 
3166 /*
3167  * Set the receiver flags
3168  */
3169 static void
3170 zsa_set_za_rcv_flags_mask(struct asyncline *za)
3171 {
3172 	register uint_t mask;
3173 
3174 	za->za_rcv_flags_mask &= ~0xFF;
3175 	switch (za->za_ttycommon.t_cflag & CSIZE) {
3176 	case CS5:
3177 		mask = 0x1f;
3178 		break;
3179 	case CS6:
3180 		mask = 0x3f;
3181 		break;
3182 	case CS7:
3183 		mask = 0x7f;
3184 		break;
3185 	default:
3186 		mask = 0xff;
3187 	}
3188 
3189 	za->za_rcv_flags_mask &= ~(0xFF << 16);
3190 	za->za_rcv_flags_mask |=  mask << 16;
3191 
3192 	if ((za->za_ttycommon.t_iflag & PARMRK) &&
3193 	    !(za->za_ttycommon.t_iflag & (IGNPAR|ISTRIP))) {
3194 		za->za_rcv_flags_mask |= DO_ESC;
3195 	} else
3196 		za->za_rcv_flags_mask &= ~DO_ESC;
3197 	if (za->za_ttycommon.t_iflag & IXON) {
3198 		za->za_rcv_flags_mask |= DO_STOPC;
3199 		za->za_rcv_flags_mask &= ~0xFF;
3200 		za->za_rcv_flags_mask |= za->za_ttycommon.t_stopc;
3201 	} else
3202 		za->za_rcv_flags_mask &= ~DO_STOPC;
3203 }
3204 
3205 static int
3206 zsa_suspend(struct zscom *zs)
3207 {
3208 	struct asyncline	*za;
3209 	queue_t			*q;
3210 	mblk_t			*bp = NULL;
3211 	timeout_id_t		restart_id, kick_rcv_id;
3212 	struct zs_prog		*zspp;
3213 
3214 	za = (struct asyncline *)&zs->zs_priv_str;
3215 	mutex_enter(zs->zs_excl);
3216 	if (zs->zs_suspended) {
3217 		mutex_exit(zs->zs_excl);
3218 		return (DDI_SUCCESS);
3219 	}
3220 	zs->zs_suspended = 1;
3221 
3222 	/*
3223 	 * Turn off interrupts and get any bytes in receiver
3224 	 */
3225 	mutex_enter(zs->zs_excl_hi);
3226 	SCC_BIC(1, ZSWR1_INIT);
3227 	ZSA_KICK_RCV;
3228 	restart_id = za->za_zsa_restart_id;
3229 	za->za_zsa_restart_id = 0;
3230 	kick_rcv_id = za->za_kick_rcv_id;
3231 	za->za_kick_rcv_id = 0;
3232 	mutex_exit(zs->zs_excl_hi);
3233 	mutex_exit(zs->zs_excl);
3234 
3235 	/*
3236 	 * Cancel any timeouts
3237 	 */
3238 	if (restart_id)
3239 		(void) untimeout(restart_id);
3240 	if (kick_rcv_id)
3241 		(void) untimeout(kick_rcv_id);
3242 
3243 	/*
3244 	 * Since we have turned off interrupts, zsa_txint will not be called
3245 	 * and no new chars will given to the chip. We just wait for the
3246 	 * current character(s) to drain.
3247 	 */
3248 	delay(ztdelay(za->za_ttycommon.t_cflag & CBAUD));
3249 
3250 	/*
3251 	 * Return remains of partially sent message to queue
3252 	 */
3253 	mutex_enter(zs->zs_excl);
3254 	if ((q = za->za_ttycommon.t_writeq) != NULL) {
3255 		mutex_enter(zs->zs_excl_hi);
3256 		if ((zs->zs_wr_cur) != NULL) {
3257 			za->za_flags &= ~ZAS_BUSY;
3258 			za->za_rcv_flags_mask &= ~DO_RETRANSMIT;
3259 			bp = za->za_xmitblk;
3260 			bp->b_rptr = zs->zs_wr_cur;
3261 			zs->zs_wr_cur = NULL;
3262 			zs->zs_wr_lim = NULL;
3263 			za->za_xmitblk = NULL;
3264 		}
3265 		mutex_exit(zs->zs_excl_hi);
3266 		if (bp)
3267 			(void) putbq(q, bp);
3268 	}
3269 
3270 	/*
3271 	 * Stop any breaks in progress.
3272 	 */
3273 	mutex_enter(zs->zs_excl_hi);
3274 	if (zs->zs_wreg[5] & ZSWR5_BREAK) {
3275 		SCC_BIC(5, ZSWR5_BREAK);
3276 		za->za_flags &= ~ZAS_BREAK;
3277 	}
3278 
3279 	/*
3280 	 * Now get a copy of current registers setting.
3281 	 */
3282 	zspp = &zs_prog[zs->zs_unit];
3283 	zspp->zs = zs;
3284 	zspp->flags = 0;
3285 	zspp->wr3 = zs->zs_wreg[3];
3286 	zspp->wr4 = zs->zs_wreg[4];
3287 	zspp->wr5 = zs->zs_wreg[5];
3288 	zspp->wr11 = zs->zs_wreg[11];
3289 	zspp->wr12 = zs->zs_wreg[12];
3290 	zspp->wr13 = zs->zs_wreg[13];
3291 	zspp->wr15 = zs->zs_wreg[15];
3292 	mutex_exit(zs->zs_excl_hi);
3293 	mutex_exit(zs->zs_excl);
3294 	/*
3295 	 * We do this on the off chance that zsa_close is waiting on a timed
3296 	 * break to complete and nothing else.
3297 	 */
3298 	cv_broadcast(&zs->zs_flags_cv);
3299 	return (DDI_SUCCESS);
3300 }
3301 
3302 static int
3303 zsa_resume(struct zscom *zs)
3304 {
3305 	register struct asyncline *za;
3306 	struct zs_prog	*zspp;
3307 
3308 	za = (struct asyncline *)&zs->zs_priv_str;
3309 	mutex_enter(zs->zs_excl);
3310 	if (!(zs->zs_suspended)) {
3311 		mutex_exit(zs->zs_excl);
3312 		return (DDI_SUCCESS);
3313 	}
3314 
3315 	/*
3316 	 * Restore H/W state
3317 	 */
3318 	mutex_enter(zs->zs_excl_hi);
3319 	zspp = &zs_prog[zs->zs_unit];
3320 	zs_program(zspp);
3321 
3322 	/*
3323 	 * Enable all interrupts for this chip and delay to let chip settle
3324 	 */
3325 	SCC_WRITE(9, ZSWR9_MASTER_IE | ZSWR9_VECTOR_INCL_STAT);
3326 	DELAY(4000);
3327 
3328 	/*
3329 	 * Restart receiving and transmitting
3330 	 */
3331 	zs->zs_suspended = 0;
3332 	za->za_rcv_flags_mask |= DO_TRANSMIT;
3333 	za->za_ext = 1;
3334 	ZSSETSOFT(zs);
3335 	mutex_exit(zs->zs_excl_hi);
3336 	mutex_exit(zs->zs_excl);
3337 
3338 	return (DDI_SUCCESS);
3339 }
3340 
3341 #ifdef ZSA_DEBUG
3342 static void
3343 zsa_print_info(struct zscom *zs)
3344 {
3345 	register struct asyncline *za = (struct asyncline *)&zs->zs_priv_str;
3346 	register queue_t *q = za->za_ttycommon.t_writeq;
3347 
3348 	printf(" next q=%s\n", (RD(q))->q_next->q_qinfo->qi_minfo->mi_idname);
3349 	printf("unit=%d\n", zs->zs_unit);
3350 	printf("tflag:\n");
3351 	if (za->za_ttycommon.t_flags & TS_SOFTCAR) printf(" t_fl:TS_SOFTCAR");
3352 	if (za->za_ttycommon.t_flags & TS_XCLUDE) printf(" t_fl:TS_XCLUDE");
3353 	if (za->za_ttycommon.t_iflag & IGNBRK) printf(" t_ifl:IGNBRK");
3354 	if (za->za_ttycommon.t_iflag & BRKINT) printf(" t_ifl:BRKINT");
3355 	if (za->za_ttycommon.t_iflag & IGNPAR) printf(" t_ifl:IGNPAR");
3356 	if (za->za_ttycommon.t_iflag & PARMRK) printf(" t_ifl:PARMRK");
3357 	if (za->za_ttycommon.t_iflag & INPCK) printf(" t_ifl:INPCK");
3358 	if (za->za_ttycommon.t_iflag & ISTRIP) printf(" t_ifl:ISTRIP");
3359 	if (za->za_ttycommon.t_iflag & INLCR) printf(" t_ifl:INLCR");
3360 	if (za->za_ttycommon.t_iflag & IGNCR) printf(" t_ifl:IGNCR");
3361 	if (za->za_ttycommon.t_iflag & ICRNL) printf(" t_ifl:ICRNL");
3362 	if (za->za_ttycommon.t_iflag & IUCLC) printf(" t_ifl:IUCLC");
3363 	if (za->za_ttycommon.t_iflag & IXON) printf(" t_ifl:IXON");
3364 	if (za->za_ttycommon.t_iflag & IXOFF) printf(" t_ifl:IXOFF");
3365 
3366 	printf("\n");
3367 
3368 
3369 	if (za->za_ttycommon.t_cflag & CSIZE == CS5) printf(" t_cfl:CS5");
3370 	if (za->za_ttycommon.t_cflag & CSIZE == CS6) printf(" t_cfl:CS6");
3371 	if (za->za_ttycommon.t_cflag & CSIZE == CS7) printf(" t_cfl:CS7");
3372 	if (za->za_ttycommon.t_cflag & CSIZE == CS8) printf(" t_cfl:CS8");
3373 	if (za->za_ttycommon.t_cflag & CSTOPB) printf(" t_cfl:CSTOPB");
3374 	if (za->za_ttycommon.t_cflag & CREAD) printf(" t_cfl:CREAD");
3375 	if (za->za_ttycommon.t_cflag & PARENB) printf(" t_cfl:PARENB");
3376 	if (za->za_ttycommon.t_cflag & PARODD) printf(" t_cfl:PARODD");
3377 	if (za->za_ttycommon.t_cflag & HUPCL) printf(" t_cfl:HUPCL");
3378 	if (za->za_ttycommon.t_cflag & CLOCAL) printf(" t_cfl:CLOCAL");
3379 	printf(" t_stopc=%x", za->za_ttycommon.t_stopc);
3380 	printf("\n");
3381 }
3382 #endif
3383 
3384 /*
3385  * Check for abort character sequence
3386  */
3387 static boolean_t
3388 abort_charseq_recognize(uchar_t ch)
3389 {
3390 	static int state = 0;
3391 #define	CNTRL(c) ((c)&037)
3392 	static char sequence[] = { '\r', '~', CNTRL('b') };
3393 
3394 	if (ch == sequence[state]) {
3395 		if (++state >= sizeof (sequence)) {
3396 			state = 0;
3397 			return (B_TRUE);
3398 		}
3399 	} else {
3400 		state = (ch == sequence[0]) ? 1 : 0;
3401 	}
3402 	return (B_FALSE);
3403 }
3404