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