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