8322 nl: misleading-indentation
[unleashed/tickless.git] / usr / src / uts / sun / io / zs_async.c
blobaefc6a787b88b15767230f0dad61089d9c29bba5
1 /*
2 * CDDL HEADER START
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
19 * CDDL HEADER END
22 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
24 * Copyright (c) 2016 by Delphix. All rights reserved.
28 * Asynchronous protocol handler for Z8530 chips
29 * Handles normal UNIX support for terminals & modems
32 #include <sys/types.h>
33 #include <sys/param.h>
34 #include <sys/systm.h>
35 #include <sys/sysmacros.h>
36 #include <sys/signal.h>
37 #include <sys/kmem.h>
38 #include <sys/termios.h>
39 #include <sys/stropts.h>
40 #include <sys/stream.h>
41 #include <sys/strsun.h>
42 #include <sys/tty.h>
43 #include <sys/ptyvar.h>
44 #include <sys/cred.h>
45 #include <sys/user.h>
46 #include <sys/proc.h>
47 #include <sys/file.h>
48 #include <sys/uio.h>
49 #include <sys/buf.h>
50 #include <sys/mkdev.h>
51 #include <sys/cmn_err.h>
52 #include <sys/strtty.h>
53 #include <sys/consdev.h>
54 #include <sys/zsdev.h>
55 #include <sys/ser_async.h>
56 #include <sys/debug.h>
57 #include <sys/kbio.h>
58 #include <sys/conf.h>
59 #include <sys/ddi.h>
60 #include <sys/sunddi.h>
61 #include <sys/promif.h>
62 #include <sys/policy.h>
65 * PPS (Pulse Per Second) support.
67 extern void ddi_hardpps(struct timeval *, int);
68 static struct ppsclockev ppsclockev;
70 #ifdef PPSCLOCKLED
71 /* XXX Use these to observe PPS latencies and jitter on a scope */
72 #define LED_ON
73 #define LED_OFF
74 #else
75 #define LED_ON
76 #define LED_OFF
77 #endif
79 #define ZSA_RCV_SIZE 64
80 #define ZA_KICK_RCV_COUNT 3
81 #define ZSA_GRACE_MIN_FLOW_CONTROL 5
82 #define ZSA_GRACE_MAX_FLOW_CONTROL 20
84 int zsasoftdtr = 0; /* if nonzero, softcarrier raises dtr at attach */
85 int zsb134_weird = 0; /* if set, old weird B134 behavior */
86 int g_zsticks = 0; /* if set, becomes the global zsticks value */
87 int g_nocluster = 0; /* if set, disables clustering of received data */
89 unsigned int zsa_rstandby = ZSA_MIN_RSTANDBY;
90 unsigned int zsa_rdone = ZSA_RDONE_MIN;
91 unsigned int zsa_grace_flow_control = ZSA_GRACE_MIN_FLOW_CONTROL;
94 #define NSPEED 18 /* max # of speeds */
95 ushort_t zs_speeds[NSPEED] = {
97 ZSPEED(50), /* 1 */
98 ZSPEED(75), /* 2 */
99 ZSPEED(110), /* 3 */
100 #ifdef lint
101 ZSPEED(134), /* 4 */
102 #else
103 ZSPEED(269/2), /* XXX - This is sleazy */
104 #endif
105 ZSPEED(150), /* 5 */
106 ZSPEED(200), /* 6 */
107 ZSPEED(300), /* 7 */
108 ZSPEED(600), /* 8 */
109 ZSPEED(1200), /* 9 */
110 ZSPEED(1800), /* 10 */
111 ZSPEED(2400), /* 11 */
112 ZSPEED(4800), /* 12 */
113 ZSPEED(9600), /* 13 */
114 ZSPEED(19200), /* 14 */
115 ZSPEED(38400), /* 15 */
116 ZSPEED(57680), /* 16 */
117 ZSPEED(76800) /* 17 */
120 ushort_t zsticks[NSPEED] = {
121 3, /* 0 */
122 3, /* 1 */
123 3, /* 2 */
124 3, /* 3 */
125 3, /* 4 */
126 3, /* 5 */
127 3, /* 6 */
128 3, /* 7 */
129 3, /* 8 */
130 3, /* 9 */
131 3, /* 10 */
132 3, /* 11 */
133 3, /* 12 */
134 3, /* 13 */
135 2, /* 14 */
136 1, /* 15 */
137 1, /* 16 */
138 1 /* 17 */
141 #define ztdelay(nsp) (zsdelay[(nsp)]*(hz/100))
143 ushort_t zsdelay[NSPEED] = {
145 ZDELAY(50), /* 1 */
146 ZDELAY(75), /* 2 */
147 ZDELAY(110), /* 3 */
148 #ifdef lint
149 ZDELAY(134), /* 4 */
150 #else
151 ZDELAY(269/2),
152 #endif
153 ZDELAY(150), /* 5 */
154 ZDELAY(200), /* 6 */
155 ZDELAY(300), /* 7 */
156 ZDELAY(600), /* 8 */
157 ZDELAY(1200), /* 9 */
158 ZDELAY(1800), /* 10 */
159 ZDELAY(2400), /* 11 */
160 ZDELAY(4800), /* 12 */
161 ZDELAY(9600), /* 13 */
162 ZDELAY(19200), /* 14 */
163 ZDELAY(38400), /* 15 */
164 ZDELAY(57600), /* 16 */
165 ZDELAY(76800) /* 17 */
168 ushort_t zslowat[NSPEED] = {
169 3, /* 0 */
170 3, /* 1 */
171 3, /* 2 */
172 3, /* 3 */
173 3, /* 4 */
174 3, /* 5 */
175 3, /* 6 */
176 2, /* 7 */
177 2, /* 8 */
178 2, /* 9 */
179 2, /* 10 */
180 1, /* 11 */
181 1, /* 12 */
182 1, /* 13 */
183 1, /* 14 */
184 1, /* 15 */
185 1, /* 16 */
186 1 /* 17 */
189 ushort_t zshiwat[NSPEED] = {
190 0, /* 0 */
191 1, /* 1 */
192 1, /* 2 */
193 1, /* 3 */
194 1, /* 4 */
195 1, /* 5 */
196 1, /* 6 */
197 1, /* 7 */
198 1, /* 8 */
199 1, /* 9 */
200 1, /* 10 */
201 1, /* 11 */
202 1, /* 12 */
203 3, /* 13 */
204 3, /* 14 */
205 4, /* 15 */
206 4, /* 16 */
207 4 /* 17 */
210 #define SLAVIO_BUG /* this workaround required to fix bug 1102778 */
212 #define SPEED(cflag) \
213 ((cflag) & CBAUDEXT) ? \
214 (((cflag) & 0x1) + CBAUD + 1) : ((cflag) & CBAUD)
217 * Special macros to handle STREAMS operations.
218 * These are required to address memory leakage problems.
219 * WARNING : the macro do NOT call ZSSETSOFT
223 * Should be called holding only the adaptive (zs_excl) mutex.
225 #define ZSA_GETBLOCK(zs, allocbcount) \
227 register int n = zsa_rstandby; \
228 while (--n >= 0 && allocbcount > 0) { \
229 if (!za->za_rstandby[n]) { \
230 if ((za->za_rstandby[n] = allocb(ZSA_RCV_SIZE, \
231 BPRI_MED)) == NULL) { \
232 if (za->za_bufcid == 0) { \
233 za->za_bufcid = bufcall(ZSA_RCV_SIZE, \
234 BPRI_MED, \
235 zsa_callback, zs); \
236 break; \
239 allocbcount--; \
242 if (za->za_ttycommon.t_cflag & CRTSXOFF) { \
243 mutex_enter(zs->zs_excl_hi); \
244 if (!(zs->zs_wreg[5] & ZSWR5_RTS)) { \
245 register int usedcnt = 0; \
246 for (n = 0; n < zsa_rstandby; n++) \
247 if (!za->za_rstandby[n]) \
248 usedcnt++; \
249 if ((ushort_t)usedcnt <= \
250 zslowat[SPEED(za->za_ttycommon.t_cflag)]) \
251 SCC_BIS(5, ZSWR5_RTS); \
253 mutex_exit(zs->zs_excl_hi); \
258 * Should be called holding the spin (zs_excl_hi) mutex.
260 #define ZSA_ALLOCB(mp) \
262 register int n = zsa_rstandby; \
263 while (--n >= 0) { \
264 if ((mp = za->za_rstandby[n]) != NULL) { \
265 za->za_rstandby[n] = NULL; \
266 break; \
269 if (za->za_ttycommon.t_cflag & CRTSXOFF) { \
270 if (!mp) { \
271 if (zs->zs_wreg[5] & ZSWR5_RTS) \
272 SCC_BIC(5, ZSWR5_RTS); \
273 cmn_err(CE_WARN, "zs%d: message lost\n", \
274 UNIT(za->za_dev)); \
275 } else if (zs->zs_wreg[5] & ZSWR5_RTS) { \
276 register int usedcnt = 0; \
277 for (n = 0; n < zsa_rstandby; n++) \
278 if (!za->za_rstandby[n]) \
279 usedcnt++; \
280 if ((ushort_t)usedcnt >= (zsa_rstandby - \
281 zshiwat[SPEED(za->za_ttycommon.t_cflag)])) \
282 SCC_BIC(5, ZSWR5_RTS); \
288 * Should get the spin (zs_excl_hi) mutex.
290 #define ZSA_QREPLY(q, mp) \
292 mutex_enter(zs->zs_excl_hi); \
293 ZSA_PUTQ(mp); \
294 ZSSETSOFT(zs); \
295 mutex_exit(zs->zs_excl_hi); \
299 * Should be called holding the spin (zs_excl_hi) mutex.
301 #define ZSA_PUTQ(mp) \
303 register int wptr, rptr; \
304 wptr = za->za_rdone_wptr; \
305 rptr = za->za_rdone_rptr; \
306 za->za_rdone[wptr] = mp; \
307 if ((wptr)+1 == zsa_rdone) { \
308 za->za_rdone_wptr = wptr = 0; \
309 } else \
310 za->za_rdone_wptr = ++wptr; \
311 if (wptr == rptr) { \
312 SCC_BIC(1, ZSWR1_INIT); \
313 cmn_err(CE_WARN, "zs%d disabled: input buffer overflow", \
314 UNIT(za->za_dev)); \
319 * Should be called holding the spin (zs_excl_hi) mutex.
321 #define ZSA_KICK_RCV \
323 register mblk_t *mp = za->za_rcvblk; \
324 if (mp) { \
325 if (zs->zs_rd_cur) { /* M_DATA */ \
326 mp->b_wptr = zs->zs_rd_cur; \
327 zs->zs_rd_cur = NULL; \
328 zs->zs_rd_lim = NULL; \
330 za->za_rcvblk = NULL; \
331 ZSA_PUTQ(mp); \
332 ZSSETSOFT(zs); \
336 #define ZSA_SEEQ(mp) \
338 if (za->za_rdone_rptr != za->za_rdone_wptr) { \
339 mp = za->za_rdone[za->za_rdone_rptr]; \
340 } else { \
341 mp = NULL; \
347 * Should be called holding only the adaptive (zs_excl) mutex.
349 #define ZSA_GETQ(mp) \
351 if (za->za_rdone_rptr != za->za_rdone_wptr) { \
352 mp = za->za_rdone[za->za_rdone_rptr]; \
353 za->za_rdone[za->za_rdone_rptr++] = NULL; \
354 if (za->za_rdone_rptr == zsa_rdone) \
355 za->za_rdone_rptr = 0; \
356 } else { \
357 mp = NULL; \
362 * Should be called holding only the adaptive (zs_excl) mutex.
364 #define ZSA_FLUSHQ \
366 register mblk_t *tmp; \
367 for (;;) { \
368 ZSA_GETQ(tmp); \
369 if (!(tmp)) \
370 break; \
371 freemsg(tmp); \
377 * Logging definitions
380 #ifdef ZSA_DEBUG
382 #ifdef ZS_DEBUG_ALL
384 extern char zs_h_log[];
385 extern int zs_h_log_n;
387 #define zsa_h_log_clear
389 #define zsa_h_log_add(c) \
391 if (zs_h_log_n >= ZS_H_LOG_MAX) \
392 zs_h_log_n = 0; \
393 zs_h_log[zs_h_log_n++] = 'A' + zs->zs_unit; \
394 zs_h_log[zs_h_log_n++] = c; \
395 zs_h_log[zs_h_log_n] = '\0'; \
398 #else /* ZS_DEBUG_ALL */
400 #define ZSA_H_LOG_MAX 0x4000
401 char zsa_h_log[40][ZSA_H_LOG_MAX +10];
402 int zsa_h_log_n[40];
404 #define zsa_h_log_add(c) \
406 if (zsa_h_log_n[zs->zs_unit] >= ZSA_H_LOG_MAX) \
407 zsa_h_log_n[zs->zs_unit] = 0; \
408 zsa_h_log[zs->zs_unit][zsa_h_log_n[zs->zs_unit]++] = c; \
409 zsa_h_log[zs->zs_unit][zsa_h_log_n[zs->zs_unit]] = '\0'; \
412 #define zsa_h_log_clear \
414 register char *p; \
415 for (p = &zsa_h_log[zs->zs_unit][ZSA_H_LOG_MAX]; \
416 p >= &zsa_h_log[zs->zs_unit][0]; /* null */) \
417 *p-- = '\0'; \
418 zsa_h_log_n[zs->zs_unit] = 0; \
421 #endif /* ZS_DEBUG_ALL */
423 #define ZSA_R0_LOG(r0) \
425 if (r0 & ZSRR0_RX_READY) zsa_h_log_add('R'); \
426 if (r0 & ZSRR0_TIMER) zsa_h_log_add('Z'); \
427 if (r0 & ZSRR0_TX_READY) zsa_h_log_add('T'); \
428 if (r0 & ZSRR0_CD) zsa_h_log_add('D'); \
429 if (r0 & ZSRR0_SYNC) zsa_h_log_add('S'); \
430 if (r0 & ZSRR0_CTS) zsa_h_log_add('C'); \
431 if (r0 & ZSRR0_TXUNDER) zsa_h_log_add('U'); \
432 if (r0 & ZSRR0_BREAK) zsa_h_log_add('B'); \
435 #else /* ZSA_DEBUG */
437 #define zsa_h_log_clear
438 #define zsa_h_log_add(c)
439 #define ZSA_R0_LOG(r0)
441 #endif /* ZSA_DEBUG */
445 static int zsa_open(queue_t *rq, dev_t *dev, int flag, int sflag, cred_t *cr);
446 static int zsa_close(queue_t *q, int flag);
447 static void zsa_wput(queue_t *q, mblk_t *mp);
448 static void zsa_rsrv(queue_t *q);
450 static struct module_info asyncm_info = {
452 "zs",
454 INFPSZ,
455 2048,
459 static struct qinit async_rinit = {
460 putq,
461 (int (*)())zsa_rsrv,
462 zsa_open,
463 zsa_close,
464 NULL,
465 &asyncm_info,
466 NULL
469 static struct qinit async_winit = {
470 (int (*)())zsa_wput,
471 NULL,
472 NULL,
473 NULL,
474 NULL,
475 &asyncm_info,
476 NULL
479 struct streamtab asynctab = {
480 &async_rinit,
481 &async_winit,
482 NULL,
483 NULL,
487 * The async interrupt entry points.
489 static void zsa_txint(struct zscom *zs);
490 static void zsa_xsint(struct zscom *zs);
491 static void zsa_rxint(struct zscom *zs);
492 static void zsa_srint(struct zscom *zs);
493 static int zsa_softint(struct zscom *zs);
494 static int zsa_suspend(struct zscom *zs);
495 static int zsa_resume(struct zscom *zs);
497 static void
498 zsa_null(struct zscom *zs)
500 /* LINTED */
501 register short c;
503 SCC_WRITE0(ZSWR0_RESET_TXINT);
504 SCC_WRITE0(ZSWR0_RESET_STATUS);
505 c = SCC_READDATA();
506 ZSDELAY();
507 SCC_WRITE0(ZSWR0_RESET_ERRORS);
510 /*ARGSUSED*/
511 static int
512 zsa_null_int(struct zscom *zs)
514 return (0);
517 struct zsops zsops_null_async = {
518 zsa_null,
519 zsa_null,
520 zsa_null,
521 zsa_null,
522 zsa_null_int,
523 zsa_null_int,
524 zsa_null_int
527 struct zsops zsops_async = {
528 zsa_txint,
529 zsa_xsint,
530 zsa_rxint,
531 zsa_srint,
532 zsa_softint,
533 zsa_suspend,
534 zsa_resume
537 static int dmtozs(int bits);
538 static int zstodm(int bits);
539 static void zsa_restart(void *);
540 static void zsa_reioctl(void *);
541 static void zsa_ioctl(struct asyncline *za, queue_t *q, mblk_t *mp);
542 static void zsa_program(struct asyncline *za, int setibaud);
543 static void zsa_start(struct zscom *zs);
544 static void zsa_kick_rcv(void *);
545 static void zsa_callback(void *);
546 static void zsa_set_za_rcv_flags_mask(struct asyncline *za);
547 int zsgetspeed(dev_t dev);
549 static boolean_t abort_charseq_recognize(uchar_t ch);
551 /* ARGSUSED */
553 zsc_info(dev_info_t *dip, ddi_info_cmd_t infocmd, void *arg,
554 void **result)
556 register dev_t dev = (dev_t)arg;
557 register int unit, error;
558 register struct zscom *zs;
560 if ((unit = UNIT(dev)) >= nzs)
561 return (DDI_FAILURE);
563 switch (infocmd) {
564 case DDI_INFO_DEVT2DEVINFO:
565 zs = &zscom[unit];
566 *result = zs->zs_dip;
567 error = DDI_SUCCESS;
568 break;
569 case DDI_INFO_DEVT2INSTANCE:
570 *result = (void *)(uintptr_t)(unit / 2);
571 error = DDI_SUCCESS;
572 break;
573 default:
574 error = DDI_FAILURE;
576 return (error);
580 * The Asynchronous Driver.
584 * Determine if the zsminor device is in use as either a stdin or stdout
585 * device, so we can be careful about how we initialize the DUART, if
586 * it is, in fact, in use.
588 * Since this is expensive, we do it once and store away the answers,
589 * since this gets called a number of times per phyical zs device.
590 * Perhaps, this should be in a loadable module, so it can get thrown
591 * away after all the zs devices are attached?
595 * To determine if a given unit is being used by the PROM,
596 * we need to map stdin/stdout devices as known to the PROM
597 * to zs internal minor device numbers:
599 * PROM (real device) zs minor device
601 * "zs", 0, "a" 0 ttya
602 * "zs", 0, "b" 1 ttyb
603 * "zs", 1, "a" 2 keyboard
604 * "zs", 1, "b" 3 mouse
605 * "zs", 2, "a" 4 ttyc
606 * "zs", 2, "b" 5 ttyd
608 * The following value mapping lines assume that insource
609 * and outsink map as "screen, a, b, c, d, ...", and that
610 * zs minors are "a, b, kbd, mouse, c, d, ...".
613 static int zsa_inuse; /* Strictly for debugging */
616 zsa_channel_is_active_in_rom(dev_info_t *dev, int zsminor)
618 char pathname[OBP_MAXPATHLEN];
619 char default_pathname[OBP_MAXPATHLEN];
620 char *stdioname;
621 char minordata[3];
624 * Basically, get my name and compare it to stdio devnames
625 * and if we get a match, then the device is in use as either
626 * stdin or stdout device (console tip line or keyboard device).
628 * We get two forms of the pathname, one complete with the
629 * the channel number, and if the channel is 'a', then
630 * we also deal with the user's ability to default to
631 * channel 'a', by omitting the channel number option.
632 * We then compare these pathnames to both the stdin and
633 * stdout pathnames. If any of these match, then the channel
634 * is in use.
637 (void) ddi_pathname(dev, pathname); /* device pathname */
638 default_pathname[0] = (char)0; /* default pathname if channel 'a' */
639 if ((zsminor & 1) == 0)
640 (void) strcpy(default_pathname, pathname);
641 minordata[0] = ':';
642 minordata[1] = (char)('a' + (zsminor & 1));
643 minordata[2] = (char)0;
644 (void) strcat(pathname, minordata);
646 stdioname = prom_stdinpath();
647 if (strcmp(pathname, stdioname) == 0) {
648 zsa_inuse |= (1 << zsminor);
649 return (1);
651 if (strcmp(default_pathname, stdioname) == 0) {
652 zsa_inuse |= (1 << zsminor);
653 return (1);
656 stdioname = prom_stdoutpath();
657 if (strcmp(pathname, stdioname) == 0) {
658 zsa_inuse |= (1 << zsminor);
659 return (1);
661 if (strcmp(default_pathname, stdioname) == 0) {
662 zsa_inuse |= (1 << zsminor);
663 return (1);
666 return (0);
670 * Initialize zs
672 void
673 zsa_init(struct zscom *zs)
676 * This routine is called near the end of the zs module's attach
677 * process. It initializes the TTY protocol-private data for this
678 * channel that needs to be in place before interrupts are enabled.
680 mutex_enter(zs->zs_excl);
681 mutex_enter(zs->zs_excl_hi);
684 * Raise modem control lines on serial ports associated
685 * with the console and (optionally) softcarrier lines.
686 * Drop modem control lines on all others so that modems
687 * will not answer and portselectors will skip these
688 * lines until they are opened by a getty.
690 if (zsa_channel_is_active_in_rom(zs->zs_dip, zs->zs_unit))
691 (void) zsmctl(zs, ZS_ON, DMSET); /* raise dtr */
692 else if (zsasoftdtr && (zssoftCAR[zs->zs_unit]))
693 (void) zsmctl(zs, ZS_ON, DMSET); /* raise dtr */
694 else
695 (void) zsmctl(zs, ZS_OFF, DMSET); /* drop dtr */
697 if (zsa_rstandby > ZSA_MAX_RSTANDBY)
698 zsa_rstandby = ZSA_MAX_RSTANDBY;
700 if (zsa_rdone > ZSA_RDONE_MAX)
701 zsa_rdone = ZSA_RDONE_MAX;
703 if (zsa_grace_flow_control > ZSA_GRACE_MAX_FLOW_CONTROL)
704 zsa_grace_flow_control = ZSA_GRACE_MAX_FLOW_CONTROL;
706 mutex_exit(zs->zs_excl_hi);
707 mutex_exit(zs->zs_excl);
712 * Open routine.
714 /*ARGSUSED*/
715 static int
716 zsa_open(queue_t *rq, dev_t *dev, int flag, int sflag, cred_t *cr)
718 register struct zscom *zs;
719 register struct asyncline *za;
720 register int speed, unit;
721 struct termios *termiosp;
722 int len;
723 register int allocbcount = zsa_rstandby;
724 boolean_t set_zsoptinit = B_FALSE;
726 unit = UNIT(*dev);
727 if (unit >= nzs)
728 return (ENXIO); /* unit not configured */
730 /* zscom is allocated by zsattach, and thus cannot be NULL here */
731 zs = &zscom[unit];
732 if (zs->zs_ops == NULL) {
733 return (ENXIO); /* device not found by autoconfig */
736 mutex_enter(zs->zs_ocexcl);
737 mutex_enter(zs->zs_excl);
738 again:
739 if ((zs->zs_ops != &zsops_null) &&
740 (zs->zs_ops != &zsops_async)) {
741 mutex_exit(zs->zs_excl);
742 mutex_exit(zs->zs_ocexcl);
743 return (EBUSY); /* another protocol got here first */
746 za = (struct asyncline *)&zs->zs_priv_str;
748 if (zs->zs_suspended) {
749 mutex_exit(zs->zs_excl);
750 mutex_exit(zs->zs_ocexcl);
751 (void) ddi_dev_is_needed(zs->zs_dip, 0, 1);
752 mutex_enter(zs->zs_ocexcl);
753 mutex_enter(zs->zs_excl);
756 /* Mark device as busy (for power management) */
757 (void) pm_busy_component(zs->zs_dip, unit%2+1);
759 if (zs->zs_ops == &zsops_null) {
760 bzero(za, sizeof (zs->zs_priv_str));
761 za->za_common = zs;
762 if (zssoftCAR[zs->zs_unit])
763 za->za_ttycommon.t_flags |= TS_SOFTCAR;
764 zsopinit(zs, &zsops_async);
765 set_zsoptinit = B_TRUE;
766 za->za_rdone_wptr = 0;
767 za->za_rdone_rptr = 0;
770 zs->zs_priv = (caddr_t)za;
773 * Block waiting for carrier to come up,
774 * unless this is a no-delay open.
776 mutex_enter(zs->zs_excl_hi);
777 if (!(za->za_flags & ZAS_ISOPEN)) {
779 * Get the default termios settings (cflag).
780 * These are stored as a property in the
781 * "options" node.
783 mutex_exit(zs->zs_excl_hi);
784 if (ddi_getlongprop(DDI_DEV_T_ANY,
785 ddi_root_node(), 0, "ttymodes",
786 (caddr_t)&termiosp, &len) == DDI_PROP_SUCCESS &&
787 len == sizeof (struct termios)) {
789 za->za_ttycommon.t_cflag = termiosp->c_cflag;
790 kmem_free(termiosp, len);
791 } else {
793 * Gack! Whine about it.
795 cmn_err(CE_WARN,
796 "zs: Couldn't get ttymodes property!");
798 mutex_enter(zs->zs_excl_hi);
799 if ((*dev == rconsdev) || (*dev == kbddev) ||
800 (*dev == stdindev)) {
801 speed = zsgetspeed(*dev);
802 za->za_ttycommon.t_cflag &= ~(CBAUD);
803 if (speed > CBAUD) {
804 za->za_ttycommon.t_cflag |= CBAUDEXT;
805 za->za_ttycommon.t_cflag |=
806 ((speed - CBAUD - 1) & CBAUD);
807 } else {
808 za->za_ttycommon.t_cflag &= ~CBAUDEXT;
809 za->za_ttycommon.t_cflag |= (speed & CBAUD);
812 za->za_overrun = 0;
813 za->za_ttycommon.t_iflag = 0;
814 za->za_ttycommon.t_iocpending = NULL;
815 za->za_ttycommon.t_size.ws_row = 0;
816 za->za_ttycommon.t_size.ws_col = 0;
817 za->za_ttycommon.t_size.ws_xpixel = 0;
818 za->za_ttycommon.t_size.ws_ypixel = 0;
819 za->za_dev = *dev;
820 za->za_wbufcid = 0;
821 zsa_program(za, za->za_ttycommon.t_cflag & (CIBAUDEXT|CIBAUD));
822 zsa_set_za_rcv_flags_mask(za);
823 } else if ((za->za_ttycommon.t_flags & TS_XCLUDE) &&
824 secpolicy_excl_open(cr) != 0) {
825 mutex_exit(zs->zs_excl_hi);
826 if (set_zsoptinit && !(za->za_flags & ISOPEN))
827 zsopinit(zs, &zsops_null);
828 mutex_exit(zs->zs_excl);
829 mutex_exit(zs->zs_ocexcl);
830 return (EBUSY);
831 } else if ((*dev & OUTLINE) && !(za->za_flags & ZAS_OUT)) {
832 mutex_exit(zs->zs_excl_hi);
833 if (set_zsoptinit && !(za->za_flags & ISOPEN))
834 zsopinit(zs, &zsops_null);
835 mutex_exit(zs->zs_excl);
836 mutex_exit(zs->zs_ocexcl);
837 return (EBUSY);
840 if (*dev & OUTLINE)
841 za->za_flags |= ZAS_OUT;
842 (void) zsmctl(zs, ZS_ON, DMSET);
845 * Check carrier.
847 if ((za->za_ttycommon.t_flags & TS_SOFTCAR) ||
848 (zsmctl(zs, 0, DMGET) & ZSRR0_CD))
849 za->za_flags |= ZAS_CARR_ON;
850 mutex_exit(zs->zs_excl_hi);
853 * If FNDELAY and FNONBLOCK are clear, block until carrier up.
854 * Quit on interrupt.
856 if (!(flag & (FNDELAY|FNONBLOCK)) &&
857 !(za->za_ttycommon.t_cflag & CLOCAL)) {
858 if (!(za->za_flags & (ZAS_CARR_ON|ZAS_OUT)) ||
859 ((za->za_flags & ZAS_OUT) && !(*dev & OUTLINE))) {
860 za->za_flags |= ZAS_WOPEN;
861 mutex_exit(zs->zs_excl);
862 if (cv_wait_sig(&zs->zs_flags_cv, zs->zs_ocexcl) == 0) {
863 mutex_enter(zs->zs_excl);
864 if (zs->zs_suspended) {
865 mutex_exit(zs->zs_excl);
866 mutex_exit(zs->zs_ocexcl);
867 (void) ddi_dev_is_needed(zs->zs_dip,
868 0, 1);
869 mutex_enter(zs->zs_ocexcl);
870 mutex_enter(zs->zs_excl);
872 za->za_flags &= ~ZAS_WOPEN;
873 if (set_zsoptinit && !(za->za_flags & ISOPEN))
874 zsopinit(zs, &zsops_null);
875 mutex_exit(zs->zs_excl);
876 mutex_exit(zs->zs_ocexcl);
877 return (EINTR);
879 mutex_enter(zs->zs_excl);
880 za->za_flags &= ~ZAS_WOPEN;
881 if ((zs->zs_ops == &zsops_null) ||
882 (zs->zs_ops == &zsops_async))
883 goto again;
884 else {
885 if (set_zsoptinit && !(za->za_flags & ISOPEN))
886 zsopinit(zs, &zsops_null);
887 mutex_exit(zs->zs_excl);
888 mutex_exit(zs->zs_ocexcl);
889 return (EBUSY);
892 } else if ((za->za_flags & ZAS_OUT) && !(*dev & OUTLINE)) {
893 if (set_zsoptinit && !(za->za_flags & ISOPEN))
894 zsopinit(zs, &zsops_null);
895 mutex_exit(zs->zs_excl);
896 mutex_exit(zs->zs_ocexcl);
897 return (EBUSY);
900 za->za_ttycommon.t_readq = rq;
901 za->za_ttycommon.t_writeq = WR(rq);
902 rq->q_ptr = WR(rq)->q_ptr = (caddr_t)za;
904 za->za_flags |= ZAS_ISOPEN;
905 ZSA_GETBLOCK(zs, allocbcount);
906 qprocson(rq);
907 mutex_exit(zs->zs_excl);
908 mutex_exit(zs->zs_ocexcl);
909 return (0);
912 static void
913 zs_progress_check(void *arg)
915 struct asyncline *za = arg;
916 struct zscom *zs = za->za_common;
917 mblk_t *bp;
920 * We define "progress" as either waiting on a timed break or delay, or
921 * having had at least one transmitter interrupt. If none of these are
922 * true, then just terminate the output and wake up that close thread.
924 mutex_enter(zs->zs_excl);
925 if (!(zs->zs_flags & ZS_PROGRESS) &&
926 !(za->za_flags & (ZAS_BREAK|ZAS_DELAY))) {
927 za->za_flags &= ~ZAS_BUSY;
928 mutex_enter(zs->zs_excl_hi);
929 za->za_rcv_flags_mask &= ~DO_RETRANSMIT;
930 zs->zs_wr_cur = NULL;
931 zs->zs_wr_lim = NULL;
932 bp = za->za_xmitblk;
933 za->za_xmitblk = NULL;
934 mutex_exit(zs->zs_excl_hi);
935 zs->zs_timer = 0;
936 mutex_exit(zs->zs_excl);
937 if (bp != NULL)
938 freeb(bp);
940 * Since this timer is running, we know that we're in exit(2).
941 * That means that the user can't possibly be waiting on any
942 * valid ioctl(2) completion anymore, and we should just flush
943 * everything.
945 flushq(za->za_ttycommon.t_writeq, FLUSHALL);
946 cv_broadcast(&zs->zs_flags_cv);
947 } else {
948 zs->zs_flags &= ~ZS_PROGRESS;
949 zs->zs_timer = timeout(zs_progress_check, za,
950 drv_usectohz(zs_drain_check));
951 mutex_exit(zs->zs_excl);
956 * Close routine.
958 * Important locking note: the zs_ocexcl lock is not held at all in this
959 * routine. This is intentional. That lock is used to coordinate multiple
960 * simultaneous opens on a stream, and there's no such thing as multiple
961 * simultaneous closes on a stream.
964 /*ARGSUSED*/
965 static int
966 zsa_close(queue_t *q, int flag)
968 struct asyncline *za;
969 struct zscom *zs;
970 int i;
971 mblk_t *bp;
972 timeout_id_t za_zsa_restart_id, za_kick_rcv_id;
973 bufcall_id_t za_bufcid, za_wbufcid;
974 int tmp;
976 za = q->q_ptr;
977 ASSERT(za != NULL);
979 zs = za->za_common;
981 mutex_enter(zs->zs_excl);
982 zs->zs_flags |= ZS_CLOSING;
985 * There are two flavors of break -- timed (M_BREAK or TCSBRK) and
986 * untimed (TIOCSBRK). For the timed case, these are enqueued on our
987 * write queue and there's a timer running, so we don't have to worry
988 * about them. For the untimed case, though, the user obviously made a
989 * mistake, because these are handled immediately. We'll terminate the
990 * break now and honor their implicit request by discarding the rest of
991 * the data.
993 if (!(za->za_flags & ZAS_BREAK) && (zs->zs_wreg[5] & ZSWR5_BREAK))
994 goto nodrain;
997 * If the user told us not to delay the close ("non-blocking"), then
998 * don't bother trying to drain.
1000 * If the user did M_STOP (ASYNC_STOPPED), there's no hope of ever
1001 * getting an M_START (since these messages aren't enqueued), and the
1002 * only other way to clear the stop condition is by loss of DCD, which
1003 * would discard the queue data. Thus, we drop the output data if
1004 * ASYNC_STOPPED is set.
1006 if ((flag & (FNDELAY|FNONBLOCK)) || (za->za_flags & ZAS_STOPPED))
1007 goto nodrain;
1010 * If there's any pending output, then we have to try to drain it.
1011 * There are two main cases to be handled:
1012 * - called by close(2): need to drain until done or until
1013 * a signal is received. No timeout.
1014 * - called by exit(2): need to drain while making progress
1015 * or until a timeout occurs. No signals.
1017 * If we can't rely on receiving a signal to get us out of a hung
1018 * session, then we have to use a timer. In this case, we set a timer
1019 * to check for progress in sending the output data -- all that we ask
1020 * (at each interval) is that there's been some progress made. Since
1021 * the interrupt routine grabs buffers from the write queue, we can't
1022 * trust changes in zs_wr_cur. Instead, we use a progress flag.
1024 * Note that loss of carrier will cause the output queue to be flushed,
1025 * and we'll wake up again and finish normally.
1027 if (!ddi_can_receive_sig() && zs_drain_check != 0) {
1028 zs->zs_flags &= ~ZS_PROGRESS;
1029 zs->zs_timer = timeout(zs_progress_check, za,
1030 drv_usectohz(zs_drain_check));
1033 while (zs->zs_wr_cur != NULL ||
1034 za->za_ttycommon.t_writeq->q_first != NULL ||
1035 (za->za_flags & (ZAS_BUSY|ZAS_DELAY|ZAS_BREAK))) {
1036 if (cv_wait_sig(&zs->zs_flags_cv, zs->zs_excl) == 0)
1037 break;
1040 if (zs->zs_timer != 0) {
1041 (void) untimeout(zs->zs_timer);
1042 zs->zs_timer = 0;
1045 nodrain:
1047 * If break is in progress, stop it.
1049 mutex_enter(zs->zs_excl_hi);
1050 if (zs->zs_wreg[5] & ZSWR5_BREAK) {
1051 SCC_BIC(5, ZSWR5_BREAK);
1052 za->za_flags &= ~ZAS_BREAK;
1055 za_wbufcid = za->za_wbufcid;
1056 za_bufcid = za->za_bufcid;
1057 za_zsa_restart_id = za->za_zsa_restart_id;
1058 za_kick_rcv_id = za->za_kick_rcv_id;
1060 za->za_wbufcid = za->za_bufcid = 0;
1061 za->za_zsa_restart_id = za->za_kick_rcv_id = 0;
1064 * If line has HUPCL set or is incompletely opened,
1065 * and it is not the console or the keyboard,
1066 * fix up the modem lines.
1069 zsopinit(zs, &zsops_null_async);
1072 * Nobody, zsh or zs can now open this port until
1073 * zsopinit(zs, &zsops_null);
1077 if ((za->za_dev != rconsdev) && (za->za_dev != kbddev) &&
1078 (za->za_dev != stdindev) &&
1079 (((za->za_flags & (ZAS_WOPEN|ZAS_ISOPEN)) != ZAS_ISOPEN) ||
1080 (za->za_ttycommon.t_cflag & HUPCL))) {
1082 * If DTR is being held high by softcarrier,
1083 * set up the ZS_ON set; if not, hang up.
1085 if (zsasoftdtr && (za->za_ttycommon.t_flags & TS_SOFTCAR))
1086 (void) zsmctl(zs, ZS_ON, DMSET);
1087 else
1088 (void) zsmctl(zs, ZS_OFF, DMSET);
1089 mutex_exit(zs->zs_excl_hi);
1091 * Don't let an interrupt in the middle of close
1092 * bounce us back to the top; just continue
1093 * closing as if nothing had happened.
1095 tmp = cv_reltimedwait_sig(&zs->zs_flags_cv, zs->zs_excl,
1096 drv_usectohz(10000), TR_CLOCK_TICK);
1097 if (zs->zs_suspended) {
1098 mutex_exit(zs->zs_excl);
1099 (void) ddi_dev_is_needed(zs->zs_dip, 0, 1);
1100 mutex_enter(zs->zs_excl);
1102 if (tmp == 0)
1103 goto out;
1104 mutex_enter(zs->zs_excl_hi);
1108 * If nobody's now using it, turn off receiver interrupts.
1110 if ((za->za_flags & (ZAS_ISOPEN|ZAS_WOPEN)) == 0)
1111 SCC_BIC(1, ZSWR1_RIE);
1112 mutex_exit(zs->zs_excl_hi);
1114 out:
1116 * Clear out device state.
1118 ttycommon_close(&za->za_ttycommon);
1120 za->za_ttycommon.t_readq = NULL;
1121 za->za_ttycommon.t_writeq = NULL;
1123 mutex_enter(zs->zs_excl_hi);
1124 za->za_rcv_flags_mask &= ~DO_RETRANSMIT;
1125 zs->zs_wr_cur = NULL;
1126 zs->zs_wr_lim = NULL;
1127 bp = za->za_xmitblk;
1128 za->za_xmitblk = NULL;
1129 mutex_exit(zs->zs_excl_hi);
1130 if (bp)
1131 freemsg(bp);
1133 mutex_enter(zs->zs_excl_hi);
1134 zs->zs_rd_cur = NULL;
1135 zs->zs_rd_lim = NULL;
1136 bp = za->za_rcvblk;
1137 za->za_rcvblk = NULL;
1138 mutex_exit(zs->zs_excl_hi);
1139 if (bp)
1140 freemsg(bp);
1142 for (i = 0; i < zsa_rstandby; i++) {
1143 mutex_enter(zs->zs_excl_hi);
1144 bp = za->za_rstandby[i];
1145 za->za_rstandby[i] = NULL;
1146 mutex_exit(zs->zs_excl_hi);
1147 if (bp)
1148 freemsg(bp);
1151 if (za->za_soft_active || za->za_kick_active) {
1152 zs->zs_flags |= ZS_CLOSED;
1153 while (za->za_soft_active || za->za_kick_active)
1154 cv_wait(&zs->zs_flags_cv, zs->zs_excl);
1156 if (zs->zs_suspended) {
1157 mutex_exit(zs->zs_excl);
1158 (void) ddi_dev_is_needed(zs->zs_dip, 0, 1);
1159 mutex_enter(zs->zs_excl);
1162 ZSA_FLUSHQ;
1163 bzero(za, sizeof (struct asyncline));
1164 qprocsoff(q);
1165 mutex_exit(zs->zs_excl);
1168 * Cancel outstanding "bufcall" request.
1170 if (za_wbufcid)
1171 unbufcall(za_wbufcid);
1172 if (za_bufcid)
1173 unbufcall(za_bufcid);
1176 * Cancel outstanding timeout.
1178 if (za_zsa_restart_id)
1179 (void) untimeout(za_zsa_restart_id);
1181 if (za_kick_rcv_id)
1182 (void) untimeout(za_kick_rcv_id);
1184 q->q_ptr = WR(q)->q_ptr = NULL;
1185 zsopinit(zs, &zsops_null);
1186 cv_broadcast(&zs->zs_flags_cv);
1188 /* Mark device as available for power management */
1189 (void) pm_idle_component(zs->zs_dip, zs->zs_unit%2+1);
1190 return (0);
1194 * Put procedure for write queue.
1195 * Respond to M_STOP, M_START, M_IOCTL, and M_FLUSH messages here;
1196 * set the flow control character for M_STOPI and M_STARTI messages;
1197 * queue up M_BREAK, M_DELAY, and M_DATA messages for processing
1198 * by the start routine, and then call the start routine; discard
1199 * everything else. Note that this driver does not incorporate any
1200 * mechanism to negotiate to handle the canonicalization process.
1201 * It expects that these functions are handled in upper module(s),
1202 * as we do in ldterm.
1204 static void
1205 zsa_wput(queue_t *q, mblk_t *mp)
1207 register struct asyncline *za;
1208 register struct zscom *zs;
1209 register struct copyresp *resp;
1210 register mblk_t *bp = NULL;
1211 int error;
1212 struct iocblk *iocp;
1214 za = (struct asyncline *)q->q_ptr;
1215 zs = za->za_common;
1216 if (zs->zs_flags & ZS_NEEDSOFT) {
1217 zs->zs_flags &= ~ZS_NEEDSOFT;
1218 (void) zsa_softint(zs);
1221 switch (mp->b_datap->db_type) {
1223 case M_STOP:
1225 * Since we don't do real DMA, we can just let the
1226 * chip coast to a stop after applying the brakes.
1228 mutex_enter(zs->zs_excl);
1229 mutex_enter(zs->zs_excl_hi);
1230 za->za_flags |= ZAS_STOPPED;
1231 if ((zs->zs_wr_cur) != NULL) {
1232 za->za_flags &= ~ZAS_BUSY;
1233 za->za_rcv_flags_mask &= ~DO_RETRANSMIT;
1234 bp = za->za_xmitblk;
1235 bp->b_rptr = zs->zs_wr_cur;
1236 zs->zs_wr_cur = NULL;
1237 zs->zs_wr_lim = NULL;
1238 za->za_xmitblk = NULL;
1240 mutex_exit(zs->zs_excl_hi);
1241 if (bp)
1242 (void) putbq(q, bp);
1243 freemsg(mp);
1244 mutex_exit(zs->zs_excl);
1245 break;
1247 case M_START:
1248 mutex_enter(zs->zs_excl);
1249 if (za->za_flags & ZAS_STOPPED) {
1250 za->za_flags &= ~ZAS_STOPPED;
1252 * If an output operation is in progress,
1253 * resume it. Otherwise, prod the start
1254 * routine.
1256 zsa_start(zs);
1258 freemsg(mp);
1259 mutex_exit(zs->zs_excl);
1260 break;
1262 case M_IOCTL:
1263 mutex_enter(zs->zs_excl);
1264 iocp = (struct iocblk *)mp->b_rptr;
1266 switch (iocp->ioc_cmd) {
1268 case TIOCGPPS:
1270 * Get PPS state.
1272 if (mp->b_cont != NULL)
1273 freemsg(mp->b_cont);
1275 mp->b_cont = allocb(sizeof (int), BPRI_HI);
1276 if (mp->b_cont == NULL) {
1277 mp->b_datap->db_type = M_IOCNAK;
1278 iocp->ioc_error = ENOMEM;
1279 ZSA_QREPLY(q, mp);
1280 break;
1282 if (za->za_pps)
1283 *(int *)mp->b_cont->b_wptr = 1;
1284 else
1285 *(int *)mp->b_cont->b_wptr = 0;
1286 mp->b_cont->b_wptr += sizeof (int);
1287 mp->b_datap->db_type = M_IOCACK;
1288 iocp->ioc_count = sizeof (int);
1289 ZSA_QREPLY(q, mp);
1290 break;
1292 case TIOCSPPS:
1294 * Set PPS state.
1296 error = miocpullup(mp, sizeof (int));
1297 if (error != 0) {
1298 mp->b_datap->db_type = M_IOCNAK;
1299 iocp->ioc_error = error;
1300 ZSA_QREPLY(q, mp);
1301 break;
1304 za->za_pps = (*(int *)mp->b_cont->b_rptr != 0);
1305 mp->b_datap->db_type = M_IOCACK;
1306 ZSA_QREPLY(q, mp);
1307 break;
1309 case TIOCGPPSEV:
1312 * Get PPS event data.
1314 void *buf;
1315 #ifdef _SYSCALL32_IMPL
1316 struct ppsclockev32 p32;
1317 #endif
1319 if (mp->b_cont != NULL) {
1320 freemsg(mp->b_cont);
1321 mp->b_cont = NULL;
1323 if (za->za_pps == NULL) {
1324 mp->b_datap->db_type = M_IOCNAK;
1325 iocp->ioc_error = ENXIO;
1326 ZSA_QREPLY(q, mp);
1327 break;
1330 #ifdef _SYSCALL32_IMPL
1331 if ((iocp->ioc_flag & IOC_MODELS) != IOC_NATIVE) {
1332 TIMEVAL_TO_TIMEVAL32(&p32.tv, &ppsclockev.tv);
1333 p32.serial = ppsclockev.serial;
1334 buf = &p32;
1335 iocp->ioc_count = sizeof (struct ppsclockev32);
1336 } else
1337 #endif
1339 buf = &ppsclockev;
1340 iocp->ioc_count = sizeof (struct ppsclockev);
1343 if ((bp = allocb(iocp->ioc_count, BPRI_HI)) == NULL) {
1344 mp->b_datap->db_type = M_IOCNAK;
1345 iocp->ioc_error = ENOMEM;
1346 ZSA_QREPLY(q, mp);
1347 break;
1349 mp->b_cont = bp;
1351 bcopy(buf, bp->b_wptr, iocp->ioc_count);
1352 bp->b_wptr += iocp->ioc_count;
1353 mp->b_datap->db_type = M_IOCACK;
1354 ZSA_QREPLY(q, mp);
1355 break;
1358 case TCSETSW:
1359 case TCSETSF:
1360 case TCSETAW:
1361 case TCSETAF:
1362 case TCSBRK:
1364 * The changes do not take effect until all
1365 * output queued before them is drained.
1366 * Put this message on the queue, so that
1367 * "zsa_start" will see it when it's done
1368 * with the output before it. Poke the
1369 * start routine, just in case.
1371 (void) putq(q, mp);
1372 zsa_start(zs);
1373 break;
1375 default:
1377 * Do it now.
1379 zsa_ioctl(za, q, mp);
1380 break;
1382 mutex_exit(zs->zs_excl);
1383 break;
1386 case M_IOCDATA:
1388 mutex_enter(zs->zs_excl);
1389 resp = (struct copyresp *)mp->b_rptr;
1390 if (resp->cp_rval) {
1392 * Just free message on failure.
1394 freemsg(mp);
1395 mutex_exit(zs->zs_excl);
1396 break;
1398 switch (resp->cp_cmd) {
1400 case TIOCMSET:
1401 mutex_enter(zs->zs_excl_hi);
1402 (void) zsmctl(zs, dmtozs(*(int *)mp->b_cont->b_rptr),
1403 DMSET);
1404 mutex_exit(zs->zs_excl_hi);
1405 mioc2ack(mp, NULL, 0, 0);
1406 ZSA_QREPLY(q, mp);
1407 break;
1409 case TIOCMBIS:
1410 mutex_enter(zs->zs_excl_hi);
1411 (void) zsmctl(zs, dmtozs(*(int *)mp->b_cont->b_rptr),
1412 DMBIS);
1413 mutex_exit(zs->zs_excl_hi);
1414 mioc2ack(mp, NULL, 0, 0);
1415 ZSA_QREPLY(q, mp);
1416 break;
1418 case TIOCMBIC:
1419 mutex_enter(zs->zs_excl_hi);
1420 (void) zsmctl(zs, dmtozs(*(int *)mp->b_cont->b_rptr),
1421 DMBIC);
1422 mutex_exit(zs->zs_excl_hi);
1423 mioc2ack(mp, NULL, 0, 0);
1424 ZSA_QREPLY(q, mp);
1425 break;
1427 case TIOCMGET:
1428 mioc2ack(mp, NULL, 0, 0);
1429 ZSA_QREPLY(q, mp);
1430 break;
1432 default:
1433 freemsg(mp);
1436 mutex_exit(zs->zs_excl);
1437 break;
1440 case M_FLUSH:
1441 mutex_enter(zs->zs_excl);
1442 if (*mp->b_rptr & FLUSHW) {
1445 * Abort any output in progress.
1447 if (za->za_flags & ZAS_BUSY) {
1448 za->za_flags &= ~ZAS_BUSY;
1449 mutex_enter(zs->zs_excl_hi);
1450 za->za_rcv_flags_mask &= ~DO_RETRANSMIT;
1451 zs->zs_wr_cur = NULL;
1452 zs->zs_wr_lim = NULL;
1453 bp = za->za_xmitblk;
1454 za->za_xmitblk = NULL;
1455 mutex_exit(zs->zs_excl_hi);
1456 if (bp)
1457 freemsg(bp);
1460 * Flush our write queue.
1462 flushq(q, FLUSHDATA); /* XXX doesn't flush M_DELAY */
1463 *mp->b_rptr &= ~FLUSHW; /* it has been flushed */
1465 if (*mp->b_rptr & FLUSHR) {
1467 * Flush any data in the temporary receive buffer
1469 mutex_enter(zs->zs_excl_hi);
1470 if ((za->za_ttycommon.t_flags & TS_SOFTCAR) ||
1471 (SCC_READ0() & ZSRR0_CD)) {
1472 ZSA_KICK_RCV;
1473 } else {
1474 ZSA_KICK_RCV;
1475 if (!(SCC_READ0() & ZSRR0_RX_READY)) {
1477 * settle time for 1 character shift
1479 mutex_exit(zs->zs_excl_hi);
1480 mutex_exit(zs->zs_excl);
1481 delay(ztdelay(SPEED(
1482 za->za_ttycommon.t_cflag))/3 + 1);
1483 mutex_enter(zs->zs_excl);
1484 mutex_enter(zs->zs_excl_hi);
1485 if (!(SCC_READ0() & ZSRR0_CD))
1486 ZSA_KICK_RCV;
1488 while ((SCC_READ0() &
1489 (ZSRR0_CD | ZSRR0_RX_READY)) ==
1490 ZSRR0_RX_READY) {
1492 * Empty Receiver
1494 (void) SCC_READDATA();
1497 mutex_exit(zs->zs_excl_hi);
1498 flushq(RD(q), FLUSHDATA);
1499 ZSA_QREPLY(q, mp);
1501 * give the read queues a crack at it
1503 } else
1504 freemsg(mp);
1507 * We must make sure we process messages that survive the
1508 * write-side flush. Without this call, the close protocol
1509 * with ldterm can hang forever. (ldterm will have sent us a
1510 * TCSBRK ioctl that it expects a response to.)
1512 zsa_start(zs);
1513 mutex_exit(zs->zs_excl);
1514 break;
1516 case M_BREAK:
1517 case M_DELAY:
1518 case M_DATA:
1519 mutex_enter(zs->zs_excl);
1521 * Queue the message up to be transmitted,
1522 * and poke the start routine.
1524 (void) putq(q, mp);
1525 zsa_start(zs);
1526 mutex_exit(zs->zs_excl);
1527 break;
1529 case M_STOPI:
1530 mutex_enter(zs->zs_excl);
1531 mutex_enter(zs->zs_excl_hi);
1532 za->za_flowc = za->za_ttycommon.t_stopc;
1533 if ((zs->zs_wr_cur) != NULL) {
1534 za->za_rcv_flags_mask &= ~DO_RETRANSMIT;
1535 bp = za->za_xmitblk;
1536 bp->b_rptr = zs->zs_wr_cur;
1537 zs->zs_wr_cur = NULL;
1538 zs->zs_wr_lim = NULL;
1539 za->za_xmitblk = NULL;
1541 mutex_exit(zs->zs_excl_hi);
1542 if (bp)
1543 (void) putbq(q, bp);
1544 else
1545 zsa_start(zs); /* poke the start routine */
1546 freemsg(mp);
1547 mutex_exit(zs->zs_excl);
1548 break;
1550 case M_STARTI:
1551 mutex_enter(zs->zs_excl);
1552 mutex_enter(zs->zs_excl_hi);
1553 za->za_flowc = za->za_ttycommon.t_startc;
1554 if ((zs->zs_wr_cur) != NULL) {
1555 za->za_rcv_flags_mask &= ~DO_RETRANSMIT;
1556 bp = za->za_xmitblk;
1557 bp->b_rptr = zs->zs_wr_cur;
1558 zs->zs_wr_cur = NULL;
1559 zs->zs_wr_lim = NULL;
1560 za->za_xmitblk = NULL;
1562 mutex_exit(zs->zs_excl_hi);
1563 if (bp)
1564 (void) putbq(q, bp);
1565 else
1566 zsa_start(zs); /* poke the start routine */
1567 freemsg(mp);
1568 mutex_exit(zs->zs_excl);
1569 break;
1571 case M_CTL:
1572 if (MBLKL(mp) >= sizeof (struct iocblk) &&
1573 ((struct iocblk *)mp->b_rptr)->ioc_cmd == MC_POSIXQUERY) {
1574 ((struct iocblk *)mp->b_rptr)->ioc_cmd = MC_HAS_POSIX;
1575 qreply(q, mp);
1576 } else {
1578 * These MC_SERVICE type messages are used by upper
1579 * modules to tell this driver to send input up
1580 * immediately, or that it can wait for normal
1581 * processing that may or may not be done. Sun
1582 * requires these for the mouse module.
1584 mutex_enter(zs->zs_excl);
1585 switch (*mp->b_rptr) {
1587 case MC_SERVICEIMM:
1588 mutex_enter(zs->zs_excl_hi);
1589 za->za_flags |= ZAS_SERVICEIMM;
1590 mutex_exit(zs->zs_excl_hi);
1591 break;
1593 case MC_SERVICEDEF:
1594 mutex_enter(zs->zs_excl_hi);
1595 za->za_flags &= ~ZAS_SERVICEIMM;
1596 mutex_exit(zs->zs_excl_hi);
1597 break;
1599 freemsg(mp);
1600 mutex_exit(zs->zs_excl);
1602 break;
1604 default:
1606 * "No, I don't want a subscription to Chain Store Age,
1607 * thank you anyway."
1609 freemsg(mp);
1610 break;
1615 * zs read service procedure
1617 static void
1618 zsa_rsrv(queue_t *q)
1620 struct asyncline *za;
1621 struct zscom *zs;
1623 if (((za = (struct asyncline *)q->q_ptr) != NULL) &&
1624 (za->za_ttycommon.t_cflag & CRTSXOFF)) {
1625 zs = za->za_common;
1626 mutex_enter(zs->zs_excl_hi);
1627 ZSSETSOFT(zs);
1628 mutex_exit(zs->zs_excl_hi);
1633 * Transmitter interrupt service routine.
1634 * If there's more data to transmit in the current pseudo-DMA block,
1635 * and the transmitter is ready, send the next character if output
1636 * is not stopped or draining.
1637 * Otherwise, queue up a soft interrupt.
1639 static void
1640 zsa_txint(struct zscom *zs)
1642 register struct asyncline *za = (struct asyncline *)&zs->zs_priv_str;
1643 register uchar_t *wr_cur;
1644 register uchar_t s0;
1646 s0 = SCC_READ0();
1648 if ((wr_cur = zs->zs_wr_cur) != NULL) {
1649 if (wr_cur < zs->zs_wr_lim) {
1650 if ((za->za_ttycommon.t_cflag & CRTSCTS) &&
1651 !(s0 & ZSRR0_CTS)) {
1652 SCC_WRITE0(ZSWR0_RESET_TXINT);
1653 za->za_rcv_flags_mask |= DO_RETRANSMIT;
1654 return;
1656 SCC_WRITEDATA(*wr_cur++);
1657 #ifdef ZSA_DEBUG
1658 za->za_wr++;
1659 #endif
1660 zs->zs_wr_cur = wr_cur;
1661 zs->zs_flags |= ZS_PROGRESS;
1662 return;
1663 } else {
1664 zs->zs_wr_cur = NULL;
1665 zs->zs_wr_lim = NULL;
1667 * Use the rcv_flags_mask as it is set and
1668 * test while holding the zs_excl_hi mutex
1670 za->za_rcv_flags_mask |= DO_TRANSMIT;
1671 SCC_WRITE0(ZSWR0_RESET_TXINT);
1672 ZSSETSOFT(zs);
1673 return;
1677 if (za->za_flowc != '\0' && (!(za->za_flags & ZAS_DRAINING))) {
1678 if ((za->za_ttycommon.t_cflag & CRTSCTS) &&
1679 !(s0 & ZSRR0_CTS)) {
1680 SCC_WRITE0(ZSWR0_RESET_TXINT);
1681 return;
1683 SCC_WRITEDATA(za->za_flowc);
1684 za->za_flowc = '\0';
1685 return;
1687 SCC_WRITE0(ZSWR0_RESET_TXINT);
1689 * Set DO_TRANSMIT bit so that the soft interrupt can
1690 * test it and unset the ZAS_BUSY in za_flags while holding
1691 * the mutex zs_excl and zs_excl_hi
1693 za->za_rcv_flags_mask |= DO_TRANSMIT;
1694 ZSSETSOFT(zs);
1698 * External/Status interrupt.
1700 static void
1701 zsa_xsint(struct zscom *zs)
1703 register struct asyncline *za = (struct asyncline *)&zs->zs_priv_str;
1704 register uchar_t s0, x0;
1706 s0 = SCC_READ0();
1707 ZSA_R0_LOG(s0);
1708 x0 = s0 ^ za->za_rr0;
1709 za->za_rr0 = s0;
1710 SCC_WRITE0(ZSWR0_RESET_STATUS);
1713 * PPS (Pulse Per Second) support.
1715 if (za->za_pps && (x0 & ZSRR0_CD) && (s0 & ZSRR0_CD)) {
1717 * This code captures a timestamp at the designated
1718 * transition of the PPS signal (CD asserted). The
1719 * code provides a pointer to the timestamp, as well
1720 * as the hardware counter value at the capture.
1722 * Note: the kernel has nano based time values while
1723 * NTP requires micro based, an in-line fast algorithm
1724 * to convert nsec to usec is used here -- see hrt2ts()
1725 * in common/os/timers.c for a full description.
1727 struct timeval *tvp = &ppsclockev.tv;
1728 timespec_t ts;
1729 int nsec, usec;
1731 LED_OFF;
1732 gethrestime(&ts);
1733 LED_ON;
1734 nsec = ts.tv_nsec;
1735 usec = nsec + (nsec >> 2);
1736 usec = nsec + (usec >> 1);
1737 usec = nsec + (usec >> 2);
1738 usec = nsec + (usec >> 4);
1739 usec = nsec - (usec >> 3);
1740 usec = nsec + (usec >> 2);
1741 usec = nsec + (usec >> 3);
1742 usec = nsec + (usec >> 4);
1743 usec = nsec + (usec >> 1);
1744 usec = nsec + (usec >> 6);
1745 tvp->tv_usec = usec >> 10;
1746 tvp->tv_sec = ts.tv_sec;
1748 ++ppsclockev.serial;
1751 * Because the kernel keeps a high-resolution time, pass the
1752 * current highres timestamp in tvp and zero in usec.
1754 ddi_hardpps(tvp, 0);
1757 ZSA_KICK_RCV;
1759 if ((x0 & ZSRR0_BREAK) && (s0 & ZSRR0_BREAK) == 0) {
1760 #ifdef SLAVIO_BUG
1762 * ZSRR0_BREAK turned off. This means that the break sequence
1763 * has completed (i.e., the stop bit finally arrived).
1765 if ((s0 & ZSRR0_RX_READY) == 0) {
1767 * SLAVIO will generate a separate STATUS change
1768 * interrupt when the break sequence completes.
1769 * SCC will combine both, taking the higher priority
1770 * one, the receive. Should still see the ext/stat.
1771 * bit in REG3 on SCC. If no ext/stat, it must be
1772 * a SLAVIO.
1774 za->za_breakoff = 1;
1775 } else {
1777 * The NUL character in the receiver is part of the
1778 * break sequence; it is discarded.
1780 (void) SCC_READDATA(); /* swallow null */
1782 #else /* SLAVIO_BUG */
1784 * ZSRR0_BREAK turned off. This means that the break sequence
1785 * has completed (i.e., the stop bit finally arrived). The NUL
1786 * character in the receiver is part of the break sequence;
1787 * it is discarded.
1789 (void) SCC_READDATA(); /* swallow null */
1790 #endif /* SLAVIO_BUG */
1791 SCC_WRITE0(ZSWR0_RESET_ERRORS);
1794 * Note: this will cause an abort if a break occurs on
1795 * the "keyboard device", regardless of whether the
1796 * "keyboard device" is a real keyboard or just a
1797 * terminal on a serial line. This permits you to
1798 * abort a workstation by unplugging the keyboard,
1799 * even if the normal abort key sequence isn't working.
1801 if ((za->za_dev == kbddev) ||
1802 ((za->za_dev == rconsdev) || (za->za_dev == stdindev)) &&
1803 (abort_enable != KIOCABORTALTERNATE)) {
1804 abort_sequence_enter((char *)NULL);
1806 * We just broke into the monitor or debugger,
1807 * ignore the break in this case so whatever
1808 * random program that was running doesn't get
1809 * a SIGINT.
1811 return;
1813 za->za_break = 1;
1817 * If hardware flow control is enabled, (re)start output
1818 * when CTS is reasserted.
1820 if ((za->za_ttycommon.t_cflag & CRTSCTS) &&
1821 (x0 & ZSRR0_CTS) && (s0 & ZSRR0_CTS) &&
1822 (za->za_rcv_flags_mask & DO_RETRANSMIT))
1823 za->za_rcv_flags_mask |= DO_TRANSMIT;
1825 za->za_ext = 1;
1826 ZSSETSOFT(zs);
1830 * Receive Interrupt
1832 static void
1833 zsa_rxint(struct zscom *zs)
1835 register struct asyncline *za = (struct asyncline *)&zs->zs_priv_str;
1836 register uchar_t c;
1837 register uchar_t *rd_cur = zs->zs_rd_cur;
1838 register uchar_t *rd_lim = zs->zs_rd_lim;
1839 register mblk_t *bp;
1840 register uint_t fm = za->za_rcv_flags_mask;
1843 #ifdef ZSA_DEBUG
1844 za->za_rd++;
1845 #endif
1846 c = (fm >> 16) & (SCC_READDATA());
1849 * Check for character break sequence
1851 if ((abort_enable == KIOCABORTALTERNATE) && (za->za_dev == rconsdev)) {
1852 if (abort_charseq_recognize(c))
1853 abort_sequence_enter((char *)NULL);
1856 if (!rd_cur) {
1857 #ifdef SLAVIO_BUG
1859 * SLAVIO generates FE for the start of break and
1860 * during break when parity is set. End of break is
1861 * detected when the first character is received.
1862 * This character is always garbage and is thrown away.
1864 if (za->za_slav_break) {
1865 za->za_slav_break = 0;
1866 za->za_rr0 |= ZSRR0_BREAK;
1867 zsa_xsint(zs);
1868 return;
1870 #endif /* SLAVIO_BUG */
1872 if (c == 0 && (za->za_rr0 & ZSRR0_BREAK)) {
1874 * A break sequence was under way, and a NUL character
1875 * was received. Discard the NUL character, as it is
1876 * part of the break sequence; if ZSRR0_BREAK turned
1877 * off, indicating that the break sequence has com-
1878 * pleted, call "zsa_xsint" to properly handle the
1879 * error. It would appear that External/Status
1880 * interrupts get lost occasionally, so this ensures
1881 * that one is delivered.
1883 c = SCC_READ0();
1884 if (!(c & ZSRR0_BREAK))
1885 zsa_xsint(zs);
1886 return;
1889 #ifdef SLAVIO_BUG
1890 if (c == 0 && za->za_breakoff) {
1892 * A break sequence completed, but SLAVIO generates
1893 * the NULL character interrupt late, so we throw the
1894 * NULL away now.
1896 return;
1900 * make sure it gets cleared.
1902 za->za_breakoff = 0;
1903 #endif /* SLAVIO_BUG */
1905 ZSA_KICK_RCV; /* We can have M_BREAK msg */
1906 ZSA_ALLOCB(bp);
1907 if (!bp) {
1908 za->za_sw_overrun++;
1909 ZSSETSOFT(zs);
1910 return;
1912 za->za_rcvblk = bp;
1913 zs->zs_rd_cur = rd_cur = bp->b_wptr;
1914 zs->zs_rd_lim = rd_lim = bp->b_datap->db_lim;
1915 if (za->za_kick_rcv_id == 0)
1916 ZSSETSOFT(zs);
1918 if (c == 0377 && (fm & DO_ESC)) {
1919 if (rd_lim < rd_cur + 2) {
1920 ZSA_ALLOCB(bp);
1921 ZSA_KICK_RCV;
1922 if (!bp) {
1923 za->za_sw_overrun++;
1924 return;
1926 za->za_rcvblk = bp;
1927 zs->zs_rd_cur = rd_cur = bp->b_wptr;
1928 zs->zs_rd_lim = rd_lim = bp->b_datap->db_lim;
1930 *rd_cur++ = c;
1934 *rd_cur++ = c;
1935 zs->zs_rd_cur = rd_cur;
1937 if (rd_cur == rd_lim) {
1938 ZSA_KICK_RCV;
1939 } else if ((fm & DO_STOPC) && (c == (fm & 0xff))) {
1940 za->za_do_kick_rcv_in_softint = 1;
1941 ZSSETSOFT(zs);
1944 if ((za->za_flags & ZAS_SERVICEIMM) || g_nocluster) {
1946 * Send the data up immediately
1948 ZSA_KICK_RCV;
1953 * Special receive condition interrupt handler.
1955 static void
1956 zsa_srint(struct zscom *zs)
1958 register struct asyncline *za = (struct asyncline *)&zs->zs_priv_str;
1959 register short s1;
1960 register uchar_t c;
1961 register uchar_t c1;
1962 register mblk_t *bp = za->za_rcvblk;
1963 register uchar_t *rd_cur = zs->zs_rd_cur;
1965 SCC_READ(1, s1);
1966 if (s1 & (ZSRR1_FE | ZSRR1_PE | ZSRR1_DO)) {
1967 c = SCC_READDATA(); /* swallow bad character */
1969 #ifdef SLAVIO_BUG
1971 * SLAVIO does not handle breaks properly when parity is enabled.
1973 * In general, if a null character is received when a framing
1974 * error occurs then it is a break condition and not a real
1975 * framing error. The null character must be limited to the
1976 * number of bits including the parity bit. For example, a 6
1977 * bit character with parity would be null if the lower 7 bits
1978 * read from the receive fifo were 0. (The higher order bits are
1979 * padded with 1 and/or the stop bits.) The only exception to this
1980 * general rule would be an 8 bit null character with parity being
1981 * a 1 in the parity bit and a framing error. This exception
1982 * can be determined by examining the parity error bit in RREG 1.
1984 * A null character, even parity, 8 bits, no parity error,
1985 * (0 0000 0000) with framing error is a break condition.
1987 * A null character, even parity, 8 bits, parity error,
1988 * (1 0000 0000) with framing error is a framing error.
1990 * A null character, odd parity, 8 bits, parity error
1991 * (0 0000 0000) with framing error is a break condition.
1993 * A null character, odd parity, 8 bits, no parity error,
1994 * (1 0000 0000) with framing error is a framing error.
1996 if (za->za_ttycommon.t_cflag & PARENB) {
1997 switch (za->za_ttycommon.t_cflag & CSIZE) {
1999 case CS5:
2000 c1 = c & 0x3f;
2001 break;
2003 case CS6:
2004 c1 = c & 0x7f;
2005 break;
2007 case CS7:
2008 c1 = c & 0xff;
2009 break;
2011 case CS8:
2012 if ((za->za_ttycommon.t_cflag & PARODD) &&
2013 !(s1 & ZSRR1_PE))
2014 c1 = 0xff;
2015 else if (!(za->za_ttycommon.t_cflag & PARODD) &&
2016 (s1 & ZSRR1_PE))
2017 c1 = 0xff;
2018 else
2019 c1 = c;
2020 break;
2024 * We fake start of break condition.
2026 if ((s1 & ZSRR1_FE) && c1 == 0) {
2027 za->za_slav_break = 1;
2028 return;
2031 #endif /* SLAVIO_BUG */
2033 if (s1 & ZSRR1_PE) {
2036 * Mark the parity error so zsa_process will
2037 * notice it and send it up in an M_BREAK
2038 * message; ldterm will do the actual parity error
2039 * processing
2042 if (bp && zs->zs_rd_cur) { /* M_DATA msg */
2043 ZSA_KICK_RCV;
2044 bp = NULL;
2046 if (!bp)
2047 ZSA_ALLOCB(bp);
2048 if (!bp) {
2049 za->za_sw_overrun++;
2050 ZSSETSOFT(zs);
2051 } else {
2052 za->za_rcvblk = bp;
2053 zs->zs_rd_cur = rd_cur = bp->b_wptr;
2054 zs->zs_rd_lim = bp->b_datap->db_lim;
2055 *rd_cur++ = c;
2056 zs->zs_rd_cur = rd_cur;
2057 bp->b_datap->db_type = M_BREAK;
2058 if (bp->b_datap->db_lim <= rd_cur)
2059 ZSA_KICK_RCV;
2060 za->za_do_kick_rcv_in_softint = 1;
2061 ZSSETSOFT(zs);
2065 SCC_WRITE0(ZSWR0_RESET_ERRORS);
2066 if (s1 & ZSRR1_DO) {
2067 za->za_hw_overrun++;
2068 ZSSETSOFT(zs);
2073 * Process software interrupts (or poll)
2074 * Crucial points:
2075 * 3. BUG - breaks are handled "out-of-band" - their relative position
2076 * among input events is lost, as well as multiple breaks together.
2077 * This is probably not a problem in practice.
2079 static int
2080 zsa_softint(struct zscom *zs)
2082 register struct asyncline *za = (struct asyncline *)&zs->zs_priv_str;
2083 register uchar_t r0;
2084 register uchar_t za_kick_active;
2085 register int m_error;
2086 register int allocbcount = 0;
2087 register int do_ttycommon_qfull = 0;
2088 boolean_t hangup = B_FALSE, unhangup = B_FALSE;
2089 boolean_t m_break = B_FALSE, wakeup = B_FALSE;
2090 register queue_t *q;
2091 register mblk_t *bp;
2092 register mblk_t *head = NULL, *tail = NULL;
2094 mutex_enter(zs->zs_excl);
2095 if (zs->zs_suspended || (zs->zs_flags & ZS_CLOSED)) {
2096 mutex_exit(zs->zs_excl);
2097 return (0);
2099 q = za->za_ttycommon.t_readq;
2100 if (za->za_flags & ZAS_WOPEN && !q) {
2101 if (za->za_ext) {
2102 mutex_enter(zs->zs_excl_hi);
2103 r0 = SCC_READ0();
2104 za->za_ext = 0;
2105 mutex_exit(zs->zs_excl_hi);
2107 * carrier up?
2109 if ((r0 & ZSRR0_CD) ||
2110 (za->za_ttycommon.t_flags & TS_SOFTCAR)) {
2112 * carrier present
2114 if ((za->za_flags & ZAS_CARR_ON) == 0) {
2115 za->za_flags |= ZAS_CARR_ON;
2116 mutex_exit(zs->zs_excl);
2117 cv_broadcast(&zs->zs_flags_cv);
2118 return (0);
2122 mutex_exit(zs->zs_excl);
2123 return (0);
2125 q = za->za_ttycommon.t_readq;
2126 if (!q) {
2127 mutex_exit(zs->zs_excl);
2128 return (0);
2131 m_error = za->za_m_error;
2132 za->za_m_error = 0;
2134 if (za->za_do_kick_rcv_in_softint) {
2135 mutex_enter(zs->zs_excl_hi);
2136 ZSA_KICK_RCV;
2137 za->za_do_kick_rcv_in_softint = 0;
2138 mutex_exit(zs->zs_excl_hi);
2141 za_kick_active = za->za_kick_active;
2143 while (!za_kick_active) {
2144 ZSA_SEEQ(bp);
2145 if (!bp)
2146 break;
2148 allocbcount++;
2150 if (bp->b_datap->db_type <= QPCTL) {
2151 if (!(canputnext(q))) {
2152 if (za->za_grace_flow_control >=
2153 zsa_grace_flow_control) {
2154 if (za->za_ttycommon.t_cflag &
2155 CRTSXOFF) {
2156 allocbcount--;
2157 break;
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;
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;
2179 if (allocbcount)
2180 ZSA_GETBLOCK(zs, allocbcount);
2182 if (za->za_ext) {
2183 mutex_enter(zs->zs_excl_hi);
2184 r0 = SCC_READ0();
2185 za->za_ext = 0;
2187 * carrier up?
2189 if ((r0 & ZSRR0_CD) ||
2190 (za->za_ttycommon.t_flags & TS_SOFTCAR)) {
2192 * carrier present
2194 if ((za->za_flags & ZAS_CARR_ON) == 0) {
2195 za->za_flags |= ZAS_CARR_ON;
2196 unhangup = B_TRUE;
2197 wakeup = B_TRUE;
2199 } else {
2200 if ((za->za_flags & ZAS_CARR_ON) &&
2201 !(za->za_ttycommon.t_cflag & CLOCAL)) {
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.
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;
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);
2222 mutex_exit(zs->zs_excl_hi);
2223 if (hangup && (bp = za->za_xmitblk) != NULL) {
2224 za->za_xmitblk = NULL;
2225 freeb(bp);
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;
2240 * If a transmission has finished, indicate that it's
2241 * finished, and start that line up again.
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;
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;
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);
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.
2277 if ((!za->za_kick_rcv_id) && (zs->zs_rd_cur || za_kick_active)) {
2278 if (g_zsticks)
2279 za->za_kick_rcv_id = timeout(zsa_kick_rcv, zs,
2280 g_zsticks);
2281 else
2282 za->za_kick_rcv_id = timeout(zsa_kick_rcv, zs,
2283 zsticks[SPEED(za->za_ttycommon.t_cflag)]);
2284 za->za_kick_rcv_count = ZA_KICK_RCV_COUNT;
2286 za->za_soft_active = 1;
2287 mutex_exit(zs->zs_excl);
2289 if (!hangup && do_ttycommon_qfull) {
2290 ttycommon_qfull(&za->za_ttycommon, q);
2291 mutex_enter(zs->zs_excl);
2292 zsa_start(zs);
2293 mutex_exit(zs->zs_excl);
2296 if (za->za_hw_overrun > 10) {
2297 cmn_err(CE_NOTE, "zs%d: silo overflow\n", UNIT(za->za_dev));
2298 za->za_hw_overrun = 0;
2301 if (za->za_sw_overrun > 10) {
2302 cmn_err(CE_NOTE, "zs%d:ring buffer overflow\n",
2303 UNIT(za->za_dev));
2304 za->za_sw_overrun = 0;
2307 if (unhangup)
2308 (void) putnextctl(q, M_UNHANGUP);
2310 if (m_break)
2311 (void) putnextctl(q, M_BREAK);
2313 while (head) {
2314 if (!tail) {
2315 putnext(q, head);
2316 break;
2318 bp = head;
2319 head = head->b_next;
2320 bp->b_next = NULL;
2321 putnext(q, bp);
2324 if (hangup) {
2325 int flushflag;
2328 * If we're in the midst of close, then flush everything. Don't
2329 * leave stale ioctls lying about.
2331 flushflag = (zs->zs_flags & ZS_CLOSING) ? FLUSHALL : FLUSHDATA;
2332 flushq(za->za_ttycommon.t_writeq, flushflag);
2333 (void) putnextctl(q, M_HANGUP);
2336 if (m_error)
2337 (void) putnextctl1(q, M_ERROR, m_error);
2339 za->za_soft_active = 0;
2341 if (wakeup || (zs->zs_flags & ZS_CLOSED))
2342 cv_broadcast(&zs->zs_flags_cv);
2344 return (0);
2348 * Start output on a line, unless it's busy, frozen, or otherwise.
2350 static void
2351 zsa_start(struct zscom *zs)
2353 register struct asyncline *za = (struct asyncline *)&zs->zs_priv_str;
2354 register int cc;
2355 register queue_t *q;
2356 register mblk_t *bp;
2357 uchar_t *rptr, *wptr;
2360 * If the chip is busy (i.e., we're waiting for a break timeout
2361 * to expire, or for the current transmission to finish, or for
2362 * output to finish draining from chip), don't grab anything new.
2364 if ((za->za_flags & (ZAS_BREAK|ZAS_BUSY|ZAS_DRAINING)) ||
2365 zs->zs_suspended)
2366 return;
2368 if (za->za_ttycommon.t_cflag & CRTSCTS) {
2369 mutex_enter(zs->zs_excl_hi);
2370 if (za->za_rcv_flags_mask & DO_RETRANSMIT) {
2371 rptr = zs->zs_wr_cur;
2372 wptr = zs->zs_wr_lim;
2373 goto zsa_start_retransmit;
2376 mutex_exit(zs->zs_excl_hi);
2380 * If we have a flow-control character to transmit, do it now.
2382 if (za->za_flowc != '\0') {
2383 mutex_enter(zs->zs_excl_hi);
2384 if (za->za_ttycommon.t_cflag & CRTSCTS) {
2385 if ((SCC_READ0() & (ZSRR0_CTS|ZSRR0_TX_READY)) !=
2386 (ZSRR0_CTS|ZSRR0_TX_READY)) {
2387 mutex_exit(zs->zs_excl_hi);
2388 return;
2390 } else if (!(SCC_READ0() & ZSRR0_TX_READY)) {
2391 mutex_exit(zs->zs_excl_hi);
2392 return;
2395 ZSDELAY();
2396 SCC_WRITEDATA(za->za_flowc);
2397 za->za_flowc = '\0';
2398 mutex_exit(zs->zs_excl_hi);
2399 return;
2403 * If we're waiting for a delay timeout to expire, don't grab
2404 * anything new.
2406 if (za->za_flags & ZAS_DELAY)
2407 return;
2409 if ((q = za->za_ttycommon.t_writeq) == NULL)
2410 return; /* not attached to a stream */
2412 zsa_start_again:
2413 for (;;) {
2414 if ((bp = getq(q)) == NULL)
2415 return; /* no data to transmit */
2418 * We have a message block to work on.
2419 * Check whether it's a break, a delay, or an ioctl (the latter
2420 * occurs if the ioctl in question was waiting for the output
2421 * to drain). If it's one of those, process it immediately.
2423 switch (bp->b_datap->db_type) {
2425 case M_BREAK:
2427 * Set the break bit, and arrange for "zsa_restart"
2428 * to be called in 1/4 second; it will turn the
2429 * break bit off, and call "zsa_start" to grab
2430 * the next message.
2432 mutex_enter(zs->zs_excl_hi);
2433 SCC_BIS(5, ZSWR5_BREAK);
2434 mutex_exit(zs->zs_excl_hi);
2435 if (!za->za_zsa_restart_id) {
2436 za->za_zsa_restart_id =
2437 timeout(zsa_restart, zs, hz/4);
2439 za->za_flags |= ZAS_BREAK;
2440 freemsg(bp);
2441 return; /* wait for this to finish */
2443 case M_DELAY:
2445 * Arrange for "zsa_restart" to be called when the
2446 * delay expires; it will turn MTS_DELAY off,
2447 * and call "zsa_start" to grab the next message.
2449 if (! za->za_zsa_restart_id) {
2450 za->za_zsa_restart_id = timeout(zsa_restart,
2452 (int)(*(unsigned char *)bp->b_rptr + 6));
2454 za->za_flags |= ZAS_DELAY;
2455 freemsg(bp);
2456 return; /* wait for this to finish */
2458 case M_IOCTL:
2460 * This ioctl was waiting for the output ahead of
2461 * it to drain; obviously, it has. Do it, and
2462 * then grab the next message after it.
2464 zsa_ioctl(za, q, bp);
2465 continue;
2466 default: /* M_DATA */
2467 goto zsa_start_transmit;
2471 zsa_start_transmit:
2473 * We have data to transmit. If output is stopped, put
2474 * it back and try again later.
2476 if (za->za_flags & ZAS_STOPPED) {
2477 (void) putbq(q, bp);
2478 return;
2481 za->za_xmitblk = bp;
2482 rptr = bp->b_rptr;
2483 wptr = bp->b_wptr;
2484 cc = wptr - rptr;
2485 bp = bp->b_cont;
2486 if (bp != NULL) {
2487 za->za_xmitblk->b_cont = NULL;
2488 (void) putbq(q, bp); /* not done with this message yet */
2491 if (rptr >= wptr) {
2492 freeb(za->za_xmitblk);
2493 za->za_xmitblk = NULL;
2494 goto zsa_start_again;
2498 * In 5-bit mode, the high order bits are used
2499 * to indicate character sizes less than five,
2500 * so we need to explicitly mask before transmitting
2502 if ((za->za_ttycommon.t_cflag & CSIZE) == CS5) {
2503 register unsigned char *p = rptr;
2504 register int cnt = cc;
2506 while (cnt--)
2507 *p++ &= (unsigned char) 0x1f;
2511 * Set up this block for pseudo-DMA.
2514 mutex_enter(zs->zs_excl_hi);
2515 zs->zs_wr_cur = rptr;
2516 zs->zs_wr_lim = wptr;
2518 zsa_start_retransmit:
2519 za->za_rcv_flags_mask &= ~DO_TRANSMIT;
2520 if (za->za_ttycommon.t_cflag & CRTSCTS) {
2521 if ((SCC_READ0() & (ZSRR0_CTS|ZSRR0_TX_READY)) !=
2522 (ZSRR0_CTS|ZSRR0_TX_READY)) {
2523 za->za_rcv_flags_mask |= DO_RETRANSMIT;
2524 za->za_flags |= ZAS_BUSY;
2525 mutex_exit(zs->zs_excl_hi);
2526 return;
2528 za->za_rcv_flags_mask &= ~DO_RETRANSMIT;
2529 } else {
2530 if (!(SCC_READ0() & ZSRR0_TX_READY)) {
2531 za->za_flags |= ZAS_BUSY;
2532 mutex_exit(zs->zs_excl_hi);
2533 return;
2537 * If the transmitter is ready, shove the first
2538 * character out.
2540 ZSDELAY();
2541 SCC_WRITEDATA(*rptr++);
2542 #ifdef ZSA_DEBUG
2543 za->za_wr++;
2544 #endif
2545 zs->zs_wr_cur = rptr;
2546 za->za_flags |= ZAS_BUSY;
2547 zs->zs_flags |= ZS_PROGRESS;
2548 mutex_exit(zs->zs_excl_hi);
2552 * Restart output on a line after a delay or break timer expired.
2554 static void
2555 zsa_restart(void *arg)
2557 struct zscom *zs = arg;
2558 struct asyncline *za = (struct asyncline *)&zs->zs_priv_str;
2561 * If break timer expired, turn off the break bit.
2563 mutex_enter(zs->zs_excl);
2564 if (!za->za_zsa_restart_id) {
2565 mutex_exit(zs->zs_excl);
2566 return;
2568 za->za_zsa_restart_id = 0;
2569 if (za->za_flags & ZAS_BREAK) {
2570 mutex_enter(zs->zs_excl_hi);
2571 SCC_BIC(5, ZSWR5_BREAK);
2572 mutex_exit(zs->zs_excl_hi);
2574 za->za_flags &= ~(ZAS_DELAY|ZAS_BREAK);
2575 if (za->za_ttycommon.t_writeq != NULL)
2576 zsa_start(zs);
2577 mutex_exit(zs->zs_excl);
2578 cv_broadcast(&zs->zs_flags_cv);
2582 * See if the receiver has any data after zs_tick delay
2584 static void
2585 zsa_kick_rcv(void *arg)
2587 struct zscom *zs = arg;
2588 struct asyncline *za = (struct asyncline *)&zs->zs_priv_str;
2589 queue_t *q;
2590 int tmp;
2591 mblk_t *mp;
2592 uchar_t za_soft_active, za_kick_active;
2593 int allocbcount = 0;
2594 int do_ttycommon_qfull = 0;
2595 mblk_t *head = NULL, *tail = NULL;
2597 mutex_enter(zs->zs_excl);
2598 if (za->za_kick_rcv_id == 0 || (zs->zs_flags & ZS_CLOSED)) {
2599 mutex_exit(zs->zs_excl);
2600 return;
2602 za_soft_active = za->za_soft_active;
2603 za_kick_active = za->za_kick_active;
2604 q = za->za_ttycommon.t_readq;
2605 if (!q) {
2606 mutex_exit(zs->zs_excl);
2607 return;
2609 mutex_enter(zs->zs_excl_hi);
2610 if (zs->zs_rd_cur) {
2611 ZSA_KICK_RCV;
2612 za->za_kick_rcv_count = tmp = ZA_KICK_RCV_COUNT;
2613 } else
2614 tmp = --za->za_kick_rcv_count;
2615 if (tmp > 0 || za_soft_active || za_kick_active) {
2616 mutex_exit(zs->zs_excl_hi);
2617 if (g_zsticks)
2618 za->za_kick_rcv_id = timeout(zsa_kick_rcv,
2619 zs, g_zsticks);
2620 else
2621 za->za_kick_rcv_id = timeout(zsa_kick_rcv,
2622 zs, zsticks[SPEED(za->za_ttycommon.t_cflag)]);
2623 if (za_soft_active || za_kick_active) {
2624 mutex_exit(zs->zs_excl);
2625 return;
2627 } else {
2628 za->za_kick_rcv_id = 0;
2629 mutex_exit(zs->zs_excl_hi);
2633 for (;;) {
2634 ZSA_SEEQ(mp);
2635 if (!mp)
2636 break;
2638 allocbcount++;
2640 if (mp->b_datap->db_type <= QPCTL) {
2641 if (!(canputnext(q))) {
2642 if (za->za_grace_flow_control >=
2643 zsa_grace_flow_control) {
2644 if (za->za_ttycommon.t_cflag &
2645 CRTSXOFF) {
2646 allocbcount--;
2647 break;
2649 ZSA_GETQ(mp);
2650 freemsg(mp);
2651 do_ttycommon_qfull = 1;
2652 continue;
2653 } else
2654 za->za_grace_flow_control++;
2655 } else
2656 za->za_grace_flow_control = 0;
2658 ZSA_GETQ(mp);
2659 if (!head) {
2660 head = mp;
2661 } else {
2662 if (!tail)
2663 tail = head;
2664 tail->b_next = mp;
2665 tail = mp;
2669 if (allocbcount)
2670 ZSA_GETBLOCK(zs, allocbcount);
2672 za->za_kick_active = 1;
2673 mutex_exit(zs->zs_excl);
2675 if (do_ttycommon_qfull) {
2676 ttycommon_qfull(&za->za_ttycommon, q);
2677 mutex_enter(zs->zs_excl);
2678 zsa_start(zs);
2679 mutex_exit(zs->zs_excl);
2682 while (head) {
2683 if (!tail) {
2684 putnext(q, head);
2685 break;
2687 mp = head;
2688 head = head->b_next;
2689 mp->b_next = NULL;
2690 putnext(q, mp);
2693 za->za_kick_active = 0;
2695 if (zs->zs_flags & ZS_CLOSED)
2696 cv_broadcast(&zs->zs_flags_cv);
2700 * Retry an "ioctl", now that "bufcall" claims we may be able to allocate
2701 * the buffer we need.
2703 static void
2704 zsa_reioctl(void *arg)
2706 struct asyncline *za = arg;
2707 struct zscom *zs = za->za_common;
2708 queue_t *q;
2709 mblk_t *mp;
2712 * The bufcall is no longer pending.
2714 mutex_enter(zs->zs_excl);
2715 if (!za->za_wbufcid) {
2716 mutex_exit(zs->zs_excl);
2717 return;
2719 za->za_wbufcid = 0;
2720 if ((q = za->za_ttycommon.t_writeq) == NULL) {
2721 mutex_exit(zs->zs_excl);
2722 return;
2724 if ((mp = za->za_ttycommon.t_iocpending) != NULL) {
2726 * not pending any more
2728 za->za_ttycommon.t_iocpending = NULL;
2729 zsa_ioctl(za, q, mp);
2731 mutex_exit(zs->zs_excl);
2735 * Process an "ioctl" message sent down to us.
2736 * Note that we don't need to get any locks until we are ready to access
2737 * the hardware. Nothing we access until then is going to be altered
2738 * outside of the STREAMS framework, so we should be safe.
2740 static void
2741 zsa_ioctl(struct asyncline *za, queue_t *wq, mblk_t *mp)
2743 register struct zscom *zs = za->za_common;
2744 register struct iocblk *iocp;
2745 register unsigned datasize;
2746 int error;
2747 register mblk_t *tmp;
2749 if (za->za_ttycommon.t_iocpending != NULL) {
2751 * We were holding an "ioctl" response pending the
2752 * availability of an "mblk" to hold data to be passed up;
2753 * another "ioctl" came through, which means that "ioctl"
2754 * must have timed out or been aborted.
2756 freemsg(za->za_ttycommon.t_iocpending);
2757 za->za_ttycommon.t_iocpending = NULL;
2760 iocp = (struct iocblk *)mp->b_rptr;
2763 * The only way in which "ttycommon_ioctl" can fail is if the "ioctl"
2764 * requires a response containing data to be returned to the user,
2765 * and no mblk could be allocated for the data.
2766 * No such "ioctl" alters our state. Thus, we always go ahead and
2767 * do any state-changes the "ioctl" calls for. If we couldn't allocate
2768 * the data, "ttycommon_ioctl" has stashed the "ioctl" away safely, so
2769 * we just call "bufcall" to request that we be called back when we
2770 * stand a better chance of allocating the data.
2772 mutex_exit(zs->zs_excl);
2773 datasize = ttycommon_ioctl(&za->za_ttycommon, wq, mp, &error);
2774 mutex_enter(zs->zs_excl);
2775 if (za->za_ttycommon.t_flags & TS_SOFTCAR)
2776 zssoftCAR[zs->zs_unit] = 1;
2777 else
2778 zssoftCAR[zs->zs_unit] = 0;
2779 if (datasize != 0) {
2780 if (za->za_wbufcid)
2781 unbufcall(za->za_wbufcid);
2782 za->za_wbufcid = bufcall(datasize, BPRI_HI, zsa_reioctl, za);
2783 return;
2787 if (error == 0) {
2789 * "ttycommon_ioctl" did most of the work; we just use the
2790 * data it set up.
2792 switch (iocp->ioc_cmd) {
2794 case TCSETS:
2795 case TCSETSW:
2796 case TCSETSF:
2797 case TCSETA:
2798 case TCSETAW:
2799 case TCSETAF:
2800 mutex_enter(zs->zs_excl_hi);
2801 zsa_program(za, 1);
2802 zsa_set_za_rcv_flags_mask(za);
2803 mutex_exit(zs->zs_excl_hi);
2804 break;
2806 } else if (error < 0) {
2808 * "ttycommon_ioctl" didn't do anything; we process it here.
2810 error = 0;
2812 switch (iocp->ioc_cmd) {
2814 case TCSBRK:
2815 error = miocpullup(mp, sizeof (int));
2816 if (error != 0)
2817 break;
2819 if (*(int *)mp->b_cont->b_rptr == 0) {
2821 * The delay ensures that a 3 byte transmit
2822 * fifo is empty.
2824 mutex_exit(zs->zs_excl);
2825 delay(ztdelay(SPEED(za->za_ttycommon.t_cflag)));
2826 mutex_enter(zs->zs_excl);
2829 * Set the break bit, and arrange for
2830 * "zsa_restart" to be called in 1/4 second;
2831 * it will turn the break bit off, and call
2832 * "zsa_start" to grab the next message.
2834 mutex_enter(zs->zs_excl_hi);
2835 SCC_BIS(5, ZSWR5_BREAK);
2836 if (!za->za_zsa_restart_id) {
2837 mutex_exit(zs->zs_excl_hi);
2838 za->za_zsa_restart_id =
2839 timeout(zsa_restart, zs, hz / 4);
2840 mutex_enter(zs->zs_excl_hi);
2842 za->za_flags |= ZAS_BREAK;
2843 mutex_exit(zs->zs_excl_hi);
2845 break;
2847 case TIOCSBRK:
2848 mutex_enter(zs->zs_excl_hi);
2849 SCC_BIS(5, ZSWR5_BREAK);
2850 mutex_exit(zs->zs_excl_hi);
2851 mioc2ack(mp, NULL, 0, 0);
2852 break;
2854 case TIOCCBRK:
2855 mutex_enter(zs->zs_excl_hi);
2856 SCC_BIC(5, ZSWR5_BREAK);
2857 mutex_exit(zs->zs_excl_hi);
2858 mioc2ack(mp, NULL, 0, 0);
2859 break;
2861 case TIOCMSET:
2862 case TIOCMBIS:
2863 case TIOCMBIC: {
2864 int mlines;
2866 if (iocp->ioc_count == TRANSPARENT) {
2867 mcopyin(mp, NULL, sizeof (int), NULL);
2868 break;
2871 error = miocpullup(mp, sizeof (int));
2872 if (error != 0)
2873 break;
2875 mlines = *(int *)mp->b_cont->b_rptr;
2877 mutex_enter(zs->zs_excl_hi);
2878 switch (iocp->ioc_cmd) {
2879 case TIOCMSET:
2880 (void) zsmctl(zs, dmtozs(mlines), DMSET);
2881 break;
2882 case TIOCMBIS:
2883 (void) zsmctl(zs, dmtozs(mlines), DMBIS);
2884 break;
2885 case TIOCMBIC:
2886 (void) zsmctl(zs, dmtozs(mlines), DMBIC);
2887 break;
2889 mutex_exit(zs->zs_excl_hi);
2891 mioc2ack(mp, NULL, 0, 0);
2892 break;
2895 case TIOCMGET:
2896 tmp = allocb(sizeof (int), BPRI_MED);
2897 if (tmp == NULL) {
2898 error = EAGAIN;
2899 break;
2901 if (iocp->ioc_count != TRANSPARENT)
2902 mioc2ack(mp, tmp, sizeof (int), 0);
2903 else
2904 mcopyout(mp, NULL, sizeof (int), NULL, tmp);
2906 mutex_enter(zs->zs_excl_hi);
2907 *(int *)mp->b_cont->b_rptr =
2908 zstodm(zsmctl(zs, 0, DMGET));
2909 mutex_exit(zs->zs_excl_hi);
2911 * qreply done below
2913 break;
2915 default:
2917 * If we don't understand it, it's an error. NAK it.
2919 error = EINVAL;
2920 break;
2924 if (error != 0) {
2925 iocp->ioc_error = error;
2926 mp->b_datap->db_type = M_IOCNAK;
2929 ZSA_QREPLY(wq, mp);
2933 static int
2934 dmtozs(int bits)
2936 register int b = 0;
2938 if (bits & TIOCM_CAR)
2939 b |= ZSRR0_CD;
2940 if (bits & TIOCM_CTS)
2941 b |= ZSRR0_CTS;
2942 if (bits & TIOCM_RTS)
2943 b |= ZSWR5_RTS;
2944 if (bits & TIOCM_DTR)
2945 b |= ZSWR5_DTR;
2946 return (b);
2949 static int
2950 zstodm(int bits)
2952 register int b;
2954 b = 0;
2955 if (bits & ZSRR0_CD)
2956 b |= TIOCM_CAR;
2957 if (bits & ZSRR0_CTS)
2958 b |= TIOCM_CTS;
2959 if (bits & ZSWR5_RTS)
2960 b |= TIOCM_RTS;
2961 if (bits & ZSWR5_DTR)
2962 b |= TIOCM_DTR;
2963 return (b);
2967 * Assemble registers and flags necessary to program the port to our liking.
2968 * For async operation, most of this is based on the values of
2969 * the "c_iflag" and "c_cflag" fields supplied to us.
2971 static void
2972 zsa_program(struct asyncline *za, int setibaud)
2974 register struct zscom *zs = za->za_common;
2975 register struct zs_prog *zspp;
2976 register int wr3, wr4, wr5, wr15, speed, baudrate, flags = 0;
2978 if ((baudrate = SPEED(za->za_ttycommon.t_cflag)) == 0) {
2980 * Hang up line.
2982 (void) zsmctl(zs, ZS_OFF, DMSET);
2983 return;
2987 * set input speed same as output, as split speed not supported
2989 if (setibaud) {
2990 za->za_ttycommon.t_cflag &= ~(CIBAUD);
2991 if (baudrate > CBAUD) {
2992 za->za_ttycommon.t_cflag |= CIBAUDEXT;
2993 za->za_ttycommon.t_cflag |=
2994 (((baudrate - CBAUD - 1) << IBSHIFT) & CIBAUD);
2995 } else {
2996 za->za_ttycommon.t_cflag &= ~CIBAUDEXT;
2997 za->za_ttycommon.t_cflag |=
2998 ((baudrate << IBSHIFT) & CIBAUD);
3003 * Do not allow the console/keyboard device to have its receiver
3004 * disabled; doing that would mean you couldn't type an abort
3005 * sequence.
3007 if ((za->za_dev == rconsdev) || (za->za_dev == kbddev) ||
3008 (za->za_dev == stdindev) || (za->za_ttycommon.t_cflag & CREAD))
3009 wr3 = ZSWR3_RX_ENABLE;
3010 else
3011 wr3 = 0;
3012 wr4 = ZSWR4_X16_CLK;
3013 wr5 = (zs->zs_wreg[5] & (ZSWR5_RTS|ZSWR5_DTR)) | ZSWR5_TX_ENABLE;
3015 if (zsb134_weird && baudrate == B134) { /* what a joke! */
3017 * XXX - should B134 set all this crap in the compatibility
3018 * module, leaving this stuff fairly clean?
3020 flags |= ZSP_PARITY_SPECIAL;
3021 wr3 |= ZSWR3_RX_6;
3022 wr4 |= ZSWR4_PARITY_ENABLE | ZSWR4_PARITY_EVEN;
3023 wr4 |= ZSWR4_1_5_STOP;
3024 wr5 |= ZSWR5_TX_6;
3025 } else {
3027 switch (za->za_ttycommon.t_cflag & CSIZE) {
3029 case CS5:
3030 wr3 |= ZSWR3_RX_5;
3031 wr5 |= ZSWR5_TX_5;
3032 break;
3034 case CS6:
3035 wr3 |= ZSWR3_RX_6;
3036 wr5 |= ZSWR5_TX_6;
3037 break;
3039 case CS7:
3040 wr3 |= ZSWR3_RX_7;
3041 wr5 |= ZSWR5_TX_7;
3042 break;
3044 case CS8:
3045 wr3 |= ZSWR3_RX_8;
3046 wr5 |= ZSWR5_TX_8;
3047 break;
3050 if (za->za_ttycommon.t_cflag & PARENB) {
3052 * The PARITY_SPECIAL bit causes a special rx
3053 * interrupt on parity errors. Turn it on if
3054 * we're checking the parity of characters.
3056 if (za->za_ttycommon.t_iflag & INPCK)
3057 flags |= ZSP_PARITY_SPECIAL;
3058 wr4 |= ZSWR4_PARITY_ENABLE;
3059 if (!(za->za_ttycommon.t_cflag & PARODD))
3060 wr4 |= ZSWR4_PARITY_EVEN;
3062 wr4 |= (za->za_ttycommon.t_cflag & CSTOPB) ?
3063 ZSWR4_2_STOP : ZSWR4_1_STOP;
3066 #if 0
3068 * The AUTO_CD_CTS flag enables the hardware flow control feature of
3069 * the 8530, which allows the state of CTS and DCD to control the
3070 * enabling of the transmitter and receiver, respectively. The
3071 * receiver and transmitter still must have their enable bits set in
3072 * WR3 and WR5, respectively, for CTS and DCD to be monitored this way.
3073 * Hardware flow control can thus be implemented with no help from
3074 * software.
3076 if (za->za_ttycommon.t_cflag & CRTSCTS)
3077 wr3 |= ZSWR3_AUTO_CD_CTS;
3078 #endif
3079 if (za->za_ttycommon.t_cflag & CRTSCTS)
3080 wr15 = ZSR15_BREAK | ZSR15_TX_UNDER | ZSR15_CD | ZSR15_CTS;
3081 else
3082 wr15 = ZSR15_BREAK | ZSR15_TX_UNDER | ZSR15_CD;
3084 speed = zs->zs_wreg[12] + (zs->zs_wreg[13] << 8);
3087 * Here we assemble a set of changes to be passed to zs_program.
3088 * Note: Write Register 15 must be set to enable BREAK and UNDERrun
3089 * interrupts. It must also enable CD interrupts which, although
3090 * not processed by the hardware interrupt handler, will be processed
3091 * by zsa_process, indirectly resulting in a SIGHUP being delivered
3092 * to the controlling process if CD drops. CTS interrupts must NOT
3093 * be enabled. We don't use them at all, and they will hang IPC/IPX
3094 * systems at boot time if synchronous modems that supply transmit
3095 * clock are attached to any of their serial ports.
3097 if (((zs->zs_wreg[1] & ZSWR1_PARITY_SPECIAL) &&
3098 !(flags & ZSP_PARITY_SPECIAL)) ||
3099 (!(zs->zs_wreg[1] & ZSWR1_PARITY_SPECIAL) &&
3100 (flags & ZSP_PARITY_SPECIAL)) ||
3101 wr3 != zs->zs_wreg[3] || wr4 != zs->zs_wreg[4] ||
3102 wr5 != zs->zs_wreg[5] || wr15 != zs->zs_wreg[15] ||
3103 speed != zs_speeds[baudrate]) {
3105 za->za_flags |= ZAS_DRAINING;
3106 zspp = &zs_prog[zs->zs_unit];
3107 zspp->zs = zs;
3108 zspp->flags = (uchar_t)flags;
3109 zspp->wr4 = (uchar_t)wr4;
3110 zspp->wr11 = (uchar_t)(ZSWR11_TXCLK_BAUD | ZSWR11_RXCLK_BAUD);
3112 speed = zs_speeds[baudrate];
3113 zspp->wr12 = (uchar_t)(speed & 0xff);
3114 zspp->wr13 = (uchar_t)((speed >> 8) & 0xff);
3115 zspp->wr3 = (uchar_t)wr3;
3116 zspp->wr5 = (uchar_t)wr5;
3117 zspp->wr15 = (uchar_t)wr15;
3119 zs_program(zspp);
3120 za->za_flags &= ~ZAS_DRAINING;
3125 * Get the current speed of the console and turn it into something
3126 * UNIX knows about - used to preserve console speed when UNIX comes up.
3129 zsgetspeed(dev_t dev)
3131 register struct zscom *zs;
3132 register int uspeed, zspeed;
3133 register uchar_t rr;
3135 zs = &zscom[UNIT(dev)];
3136 SCC_READ(12, zspeed);
3137 SCC_READ(13, rr);
3138 zspeed |= rr << 8;
3139 for (uspeed = 0; uspeed < NSPEED; uspeed++)
3140 if (zs_speeds[uspeed] == zspeed)
3141 return (uspeed);
3143 * 9600 baud if we can't figure it out
3145 return (ISPEED);
3149 * callback routine when enough memory is available.
3151 static void
3152 zsa_callback(void *arg)
3154 struct zscom *zs = arg;
3155 struct asyncline *za = (struct asyncline *)&zs->zs_priv_str;
3156 int allocbcount = zsa_rstandby;
3158 mutex_enter(zs->zs_excl);
3159 if (za->za_bufcid) {
3160 za->za_bufcid = 0;
3161 ZSA_GETBLOCK(zs, allocbcount);
3163 mutex_exit(zs->zs_excl);
3167 * Set the receiver flags
3169 static void
3170 zsa_set_za_rcv_flags_mask(struct asyncline *za)
3172 register uint_t mask;
3174 za->za_rcv_flags_mask &= ~0xFF;
3175 switch (za->za_ttycommon.t_cflag & CSIZE) {
3176 case CS5:
3177 mask = 0x1f;
3178 break;
3179 case CS6:
3180 mask = 0x3f;
3181 break;
3182 case CS7:
3183 mask = 0x7f;
3184 break;
3185 default:
3186 mask = 0xff;
3189 za->za_rcv_flags_mask &= ~(0xFF << 16);
3190 za->za_rcv_flags_mask |= mask << 16;
3192 if ((za->za_ttycommon.t_iflag & PARMRK) &&
3193 !(za->za_ttycommon.t_iflag & (IGNPAR|ISTRIP))) {
3194 za->za_rcv_flags_mask |= DO_ESC;
3195 } else
3196 za->za_rcv_flags_mask &= ~DO_ESC;
3197 if (za->za_ttycommon.t_iflag & IXON) {
3198 za->za_rcv_flags_mask |= DO_STOPC;
3199 za->za_rcv_flags_mask &= ~0xFF;
3200 za->za_rcv_flags_mask |= za->za_ttycommon.t_stopc;
3201 } else
3202 za->za_rcv_flags_mask &= ~DO_STOPC;
3205 static int
3206 zsa_suspend(struct zscom *zs)
3208 struct asyncline *za;
3209 queue_t *q;
3210 mblk_t *bp = NULL;
3211 timeout_id_t restart_id, kick_rcv_id;
3212 struct zs_prog *zspp;
3214 za = (struct asyncline *)&zs->zs_priv_str;
3215 mutex_enter(zs->zs_excl);
3216 if (zs->zs_suspended) {
3217 mutex_exit(zs->zs_excl);
3218 return (DDI_SUCCESS);
3220 zs->zs_suspended = 1;
3223 * Turn off interrupts and get any bytes in receiver
3225 mutex_enter(zs->zs_excl_hi);
3226 SCC_BIC(1, ZSWR1_INIT);
3227 ZSA_KICK_RCV;
3228 restart_id = za->za_zsa_restart_id;
3229 za->za_zsa_restart_id = 0;
3230 kick_rcv_id = za->za_kick_rcv_id;
3231 za->za_kick_rcv_id = 0;
3232 mutex_exit(zs->zs_excl_hi);
3233 mutex_exit(zs->zs_excl);
3236 * Cancel any timeouts
3238 if (restart_id)
3239 (void) untimeout(restart_id);
3240 if (kick_rcv_id)
3241 (void) untimeout(kick_rcv_id);
3244 * Since we have turned off interrupts, zsa_txint will not be called
3245 * and no new chars will given to the chip. We just wait for the
3246 * current character(s) to drain.
3248 delay(ztdelay(za->za_ttycommon.t_cflag & CBAUD));
3251 * Return remains of partially sent message to queue
3253 mutex_enter(zs->zs_excl);
3254 if ((q = za->za_ttycommon.t_writeq) != NULL) {
3255 mutex_enter(zs->zs_excl_hi);
3256 if ((zs->zs_wr_cur) != NULL) {
3257 za->za_flags &= ~ZAS_BUSY;
3258 za->za_rcv_flags_mask &= ~DO_RETRANSMIT;
3259 bp = za->za_xmitblk;
3260 bp->b_rptr = zs->zs_wr_cur;
3261 zs->zs_wr_cur = NULL;
3262 zs->zs_wr_lim = NULL;
3263 za->za_xmitblk = NULL;
3265 mutex_exit(zs->zs_excl_hi);
3266 if (bp)
3267 (void) putbq(q, bp);
3271 * Stop any breaks in progress.
3273 mutex_enter(zs->zs_excl_hi);
3274 if (zs->zs_wreg[5] & ZSWR5_BREAK) {
3275 SCC_BIC(5, ZSWR5_BREAK);
3276 za->za_flags &= ~ZAS_BREAK;
3280 * Now get a copy of current registers setting.
3282 zspp = &zs_prog[zs->zs_unit];
3283 zspp->zs = zs;
3284 zspp->flags = 0;
3285 zspp->wr3 = zs->zs_wreg[3];
3286 zspp->wr4 = zs->zs_wreg[4];
3287 zspp->wr5 = zs->zs_wreg[5];
3288 zspp->wr11 = zs->zs_wreg[11];
3289 zspp->wr12 = zs->zs_wreg[12];
3290 zspp->wr13 = zs->zs_wreg[13];
3291 zspp->wr15 = zs->zs_wreg[15];
3292 mutex_exit(zs->zs_excl_hi);
3293 mutex_exit(zs->zs_excl);
3295 * We do this on the off chance that zsa_close is waiting on a timed
3296 * break to complete and nothing else.
3298 cv_broadcast(&zs->zs_flags_cv);
3299 return (DDI_SUCCESS);
3302 static int
3303 zsa_resume(struct zscom *zs)
3305 register struct asyncline *za;
3306 struct zs_prog *zspp;
3308 za = (struct asyncline *)&zs->zs_priv_str;
3309 mutex_enter(zs->zs_excl);
3310 if (!(zs->zs_suspended)) {
3311 mutex_exit(zs->zs_excl);
3312 return (DDI_SUCCESS);
3316 * Restore H/W state
3318 mutex_enter(zs->zs_excl_hi);
3319 zspp = &zs_prog[zs->zs_unit];
3320 zs_program(zspp);
3323 * Enable all interrupts for this chip and delay to let chip settle
3325 SCC_WRITE(9, ZSWR9_MASTER_IE | ZSWR9_VECTOR_INCL_STAT);
3326 DELAY(4000);
3329 * Restart receiving and transmitting
3331 zs->zs_suspended = 0;
3332 za->za_rcv_flags_mask |= DO_TRANSMIT;
3333 za->za_ext = 1;
3334 ZSSETSOFT(zs);
3335 mutex_exit(zs->zs_excl_hi);
3336 mutex_exit(zs->zs_excl);
3338 return (DDI_SUCCESS);
3341 #ifdef ZSA_DEBUG
3342 static void
3343 zsa_print_info(struct zscom *zs)
3345 register struct asyncline *za = (struct asyncline *)&zs->zs_priv_str;
3346 register queue_t *q = za->za_ttycommon.t_writeq;
3348 printf(" next q=%s\n", (RD(q))->q_next->q_qinfo->qi_minfo->mi_idname);
3349 printf("unit=%d\n", zs->zs_unit);
3350 printf("tflag:\n");
3351 if (za->za_ttycommon.t_flags & TS_SOFTCAR) printf(" t_fl:TS_SOFTCAR");
3352 if (za->za_ttycommon.t_flags & TS_XCLUDE) printf(" t_fl:TS_XCLUDE");
3353 if (za->za_ttycommon.t_iflag & IGNBRK) printf(" t_ifl:IGNBRK");
3354 if (za->za_ttycommon.t_iflag & BRKINT) printf(" t_ifl:BRKINT");
3355 if (za->za_ttycommon.t_iflag & IGNPAR) printf(" t_ifl:IGNPAR");
3356 if (za->za_ttycommon.t_iflag & PARMRK) printf(" t_ifl:PARMRK");
3357 if (za->za_ttycommon.t_iflag & INPCK) printf(" t_ifl:INPCK");
3358 if (za->za_ttycommon.t_iflag & ISTRIP) printf(" t_ifl:ISTRIP");
3359 if (za->za_ttycommon.t_iflag & INLCR) printf(" t_ifl:INLCR");
3360 if (za->za_ttycommon.t_iflag & IGNCR) printf(" t_ifl:IGNCR");
3361 if (za->za_ttycommon.t_iflag & ICRNL) printf(" t_ifl:ICRNL");
3362 if (za->za_ttycommon.t_iflag & IUCLC) printf(" t_ifl:IUCLC");
3363 if (za->za_ttycommon.t_iflag & IXON) printf(" t_ifl:IXON");
3364 if (za->za_ttycommon.t_iflag & IXOFF) printf(" t_ifl:IXOFF");
3366 printf("\n");
3369 if (za->za_ttycommon.t_cflag & CSIZE == CS5) printf(" t_cfl:CS5");
3370 if (za->za_ttycommon.t_cflag & CSIZE == CS6) printf(" t_cfl:CS6");
3371 if (za->za_ttycommon.t_cflag & CSIZE == CS7) printf(" t_cfl:CS7");
3372 if (za->za_ttycommon.t_cflag & CSIZE == CS8) printf(" t_cfl:CS8");
3373 if (za->za_ttycommon.t_cflag & CSTOPB) printf(" t_cfl:CSTOPB");
3374 if (za->za_ttycommon.t_cflag & CREAD) printf(" t_cfl:CREAD");
3375 if (za->za_ttycommon.t_cflag & PARENB) printf(" t_cfl:PARENB");
3376 if (za->za_ttycommon.t_cflag & PARODD) printf(" t_cfl:PARODD");
3377 if (za->za_ttycommon.t_cflag & HUPCL) printf(" t_cfl:HUPCL");
3378 if (za->za_ttycommon.t_cflag & CLOCAL) printf(" t_cfl:CLOCAL");
3379 printf(" t_stopc=%x", za->za_ttycommon.t_stopc);
3380 printf("\n");
3382 #endif
3385 * Check for abort character sequence
3387 static boolean_t
3388 abort_charseq_recognize(uchar_t ch)
3390 static int state = 0;
3391 #define CNTRL(c) ((c)&037)
3392 static char sequence[] = { '\r', '~', CNTRL('b') };
3394 if (ch == sequence[state]) {
3395 if (++state >= sizeof (sequence)) {
3396 state = 0;
3397 return (B_TRUE);
3399 } else {
3400 state = (ch == sequence[0]) ? 1 : 0;
3402 return (B_FALSE);