kernel: remove unused utsname_set_machine()
[unleashed.git] / usr / src / uts / sun / io / zs_async.c
blob5c30f6bb6bce37ce9daea1fd79c7388c01cf12c9
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 ZSPEED(269/2), /* XXX - This is sleazy */
101 ZSPEED(150), /* 5 */
102 ZSPEED(200), /* 6 */
103 ZSPEED(300), /* 7 */
104 ZSPEED(600), /* 8 */
105 ZSPEED(1200), /* 9 */
106 ZSPEED(1800), /* 10 */
107 ZSPEED(2400), /* 11 */
108 ZSPEED(4800), /* 12 */
109 ZSPEED(9600), /* 13 */
110 ZSPEED(19200), /* 14 */
111 ZSPEED(38400), /* 15 */
112 ZSPEED(57680), /* 16 */
113 ZSPEED(76800) /* 17 */
116 ushort_t zsticks[NSPEED] = {
117 3, /* 0 */
118 3, /* 1 */
119 3, /* 2 */
120 3, /* 3 */
121 3, /* 4 */
122 3, /* 5 */
123 3, /* 6 */
124 3, /* 7 */
125 3, /* 8 */
126 3, /* 9 */
127 3, /* 10 */
128 3, /* 11 */
129 3, /* 12 */
130 3, /* 13 */
131 2, /* 14 */
132 1, /* 15 */
133 1, /* 16 */
134 1 /* 17 */
137 #define ztdelay(nsp) (zsdelay[(nsp)]*(hz/100))
139 ushort_t zsdelay[NSPEED] = {
141 ZDELAY(50), /* 1 */
142 ZDELAY(75), /* 2 */
143 ZDELAY(110), /* 3 */
144 ZDELAY(269/2),
145 ZDELAY(150), /* 5 */
146 ZDELAY(200), /* 6 */
147 ZDELAY(300), /* 7 */
148 ZDELAY(600), /* 8 */
149 ZDELAY(1200), /* 9 */
150 ZDELAY(1800), /* 10 */
151 ZDELAY(2400), /* 11 */
152 ZDELAY(4800), /* 12 */
153 ZDELAY(9600), /* 13 */
154 ZDELAY(19200), /* 14 */
155 ZDELAY(38400), /* 15 */
156 ZDELAY(57600), /* 16 */
157 ZDELAY(76800) /* 17 */
160 ushort_t zslowat[NSPEED] = {
161 3, /* 0 */
162 3, /* 1 */
163 3, /* 2 */
164 3, /* 3 */
165 3, /* 4 */
166 3, /* 5 */
167 3, /* 6 */
168 2, /* 7 */
169 2, /* 8 */
170 2, /* 9 */
171 2, /* 10 */
172 1, /* 11 */
173 1, /* 12 */
174 1, /* 13 */
175 1, /* 14 */
176 1, /* 15 */
177 1, /* 16 */
178 1 /* 17 */
181 ushort_t zshiwat[NSPEED] = {
182 0, /* 0 */
183 1, /* 1 */
184 1, /* 2 */
185 1, /* 3 */
186 1, /* 4 */
187 1, /* 5 */
188 1, /* 6 */
189 1, /* 7 */
190 1, /* 8 */
191 1, /* 9 */
192 1, /* 10 */
193 1, /* 11 */
194 1, /* 12 */
195 3, /* 13 */
196 3, /* 14 */
197 4, /* 15 */
198 4, /* 16 */
199 4 /* 17 */
202 #define SLAVIO_BUG /* this workaround required to fix bug 1102778 */
204 #define SPEED(cflag) \
205 ((cflag) & CBAUDEXT) ? \
206 (((cflag) & 0x1) + CBAUD + 1) : ((cflag) & CBAUD)
209 * Special macros to handle STREAMS operations.
210 * These are required to address memory leakage problems.
211 * WARNING : the macro do NOT call ZSSETSOFT
215 * Should be called holding only the adaptive (zs_excl) mutex.
217 #define ZSA_GETBLOCK(zs, allocbcount) \
219 register int n = zsa_rstandby; \
220 while (--n >= 0 && allocbcount > 0) { \
221 if (!za->za_rstandby[n]) { \
222 if ((za->za_rstandby[n] = allocb(ZSA_RCV_SIZE, \
223 BPRI_MED)) == NULL) { \
224 if (za->za_bufcid == 0) { \
225 za->za_bufcid = bufcall(ZSA_RCV_SIZE, \
226 BPRI_MED, \
227 zsa_callback, zs); \
228 break; \
231 allocbcount--; \
234 if (za->za_ttycommon.t_cflag & CRTSXOFF) { \
235 mutex_enter(zs->zs_excl_hi); \
236 if (!(zs->zs_wreg[5] & ZSWR5_RTS)) { \
237 register int usedcnt = 0; \
238 for (n = 0; n < zsa_rstandby; n++) \
239 if (!za->za_rstandby[n]) \
240 usedcnt++; \
241 if ((ushort_t)usedcnt <= \
242 zslowat[SPEED(za->za_ttycommon.t_cflag)]) \
243 SCC_BIS(5, ZSWR5_RTS); \
245 mutex_exit(zs->zs_excl_hi); \
250 * Should be called holding the spin (zs_excl_hi) mutex.
252 #define ZSA_ALLOCB(mp) \
254 register int n = zsa_rstandby; \
255 while (--n >= 0) { \
256 if ((mp = za->za_rstandby[n]) != NULL) { \
257 za->za_rstandby[n] = NULL; \
258 break; \
261 if (za->za_ttycommon.t_cflag & CRTSXOFF) { \
262 if (!mp) { \
263 if (zs->zs_wreg[5] & ZSWR5_RTS) \
264 SCC_BIC(5, ZSWR5_RTS); \
265 cmn_err(CE_WARN, "zs%d: message lost\n", \
266 UNIT(za->za_dev)); \
267 } else if (zs->zs_wreg[5] & ZSWR5_RTS) { \
268 register int usedcnt = 0; \
269 for (n = 0; n < zsa_rstandby; n++) \
270 if (!za->za_rstandby[n]) \
271 usedcnt++; \
272 if ((ushort_t)usedcnt >= (zsa_rstandby - \
273 zshiwat[SPEED(za->za_ttycommon.t_cflag)])) \
274 SCC_BIC(5, ZSWR5_RTS); \
280 * Should get the spin (zs_excl_hi) mutex.
282 #define ZSA_QREPLY(q, mp) \
284 mutex_enter(zs->zs_excl_hi); \
285 ZSA_PUTQ(mp); \
286 ZSSETSOFT(zs); \
287 mutex_exit(zs->zs_excl_hi); \
291 * Should be called holding the spin (zs_excl_hi) mutex.
293 #define ZSA_PUTQ(mp) \
295 register int wptr, rptr; \
296 wptr = za->za_rdone_wptr; \
297 rptr = za->za_rdone_rptr; \
298 za->za_rdone[wptr] = mp; \
299 if ((wptr)+1 == zsa_rdone) { \
300 za->za_rdone_wptr = wptr = 0; \
301 } else \
302 za->za_rdone_wptr = ++wptr; \
303 if (wptr == rptr) { \
304 SCC_BIC(1, ZSWR1_INIT); \
305 cmn_err(CE_WARN, "zs%d disabled: input buffer overflow", \
306 UNIT(za->za_dev)); \
311 * Should be called holding the spin (zs_excl_hi) mutex.
313 #define ZSA_KICK_RCV \
315 register mblk_t *mp = za->za_rcvblk; \
316 if (mp) { \
317 if (zs->zs_rd_cur) { /* M_DATA */ \
318 mp->b_wptr = zs->zs_rd_cur; \
319 zs->zs_rd_cur = NULL; \
320 zs->zs_rd_lim = NULL; \
322 za->za_rcvblk = NULL; \
323 ZSA_PUTQ(mp); \
324 ZSSETSOFT(zs); \
328 #define ZSA_SEEQ(mp) \
330 if (za->za_rdone_rptr != za->za_rdone_wptr) { \
331 mp = za->za_rdone[za->za_rdone_rptr]; \
332 } else { \
333 mp = NULL; \
339 * Should be called holding only the adaptive (zs_excl) mutex.
341 #define ZSA_GETQ(mp) \
343 if (za->za_rdone_rptr != za->za_rdone_wptr) { \
344 mp = za->za_rdone[za->za_rdone_rptr]; \
345 za->za_rdone[za->za_rdone_rptr++] = NULL; \
346 if (za->za_rdone_rptr == zsa_rdone) \
347 za->za_rdone_rptr = 0; \
348 } else { \
349 mp = NULL; \
354 * Should be called holding only the adaptive (zs_excl) mutex.
356 #define ZSA_FLUSHQ \
358 register mblk_t *tmp; \
359 for (;;) { \
360 ZSA_GETQ(tmp); \
361 if (!(tmp)) \
362 break; \
363 freemsg(tmp); \
369 * Logging definitions
372 #ifdef ZSA_DEBUG
374 #ifdef ZS_DEBUG_ALL
376 extern char zs_h_log[];
377 extern int zs_h_log_n;
379 #define zsa_h_log_clear
381 #define zsa_h_log_add(c) \
383 if (zs_h_log_n >= ZS_H_LOG_MAX) \
384 zs_h_log_n = 0; \
385 zs_h_log[zs_h_log_n++] = 'A' + zs->zs_unit; \
386 zs_h_log[zs_h_log_n++] = c; \
387 zs_h_log[zs_h_log_n] = '\0'; \
390 #else /* ZS_DEBUG_ALL */
392 #define ZSA_H_LOG_MAX 0x4000
393 char zsa_h_log[40][ZSA_H_LOG_MAX +10];
394 int zsa_h_log_n[40];
396 #define zsa_h_log_add(c) \
398 if (zsa_h_log_n[zs->zs_unit] >= ZSA_H_LOG_MAX) \
399 zsa_h_log_n[zs->zs_unit] = 0; \
400 zsa_h_log[zs->zs_unit][zsa_h_log_n[zs->zs_unit]++] = c; \
401 zsa_h_log[zs->zs_unit][zsa_h_log_n[zs->zs_unit]] = '\0'; \
404 #define zsa_h_log_clear \
406 register char *p; \
407 for (p = &zsa_h_log[zs->zs_unit][ZSA_H_LOG_MAX]; \
408 p >= &zsa_h_log[zs->zs_unit][0]; /* null */) \
409 *p-- = '\0'; \
410 zsa_h_log_n[zs->zs_unit] = 0; \
413 #endif /* ZS_DEBUG_ALL */
415 #define ZSA_R0_LOG(r0) \
417 if (r0 & ZSRR0_RX_READY) zsa_h_log_add('R'); \
418 if (r0 & ZSRR0_TIMER) zsa_h_log_add('Z'); \
419 if (r0 & ZSRR0_TX_READY) zsa_h_log_add('T'); \
420 if (r0 & ZSRR0_CD) zsa_h_log_add('D'); \
421 if (r0 & ZSRR0_SYNC) zsa_h_log_add('S'); \
422 if (r0 & ZSRR0_CTS) zsa_h_log_add('C'); \
423 if (r0 & ZSRR0_TXUNDER) zsa_h_log_add('U'); \
424 if (r0 & ZSRR0_BREAK) zsa_h_log_add('B'); \
427 #else /* ZSA_DEBUG */
429 #define zsa_h_log_clear
430 #define zsa_h_log_add(c)
431 #define ZSA_R0_LOG(r0)
433 #endif /* ZSA_DEBUG */
437 static int zsa_open(queue_t *rq, dev_t *dev, int flag, int sflag, cred_t *cr);
438 static int zsa_close(queue_t *q, int flag);
439 static void zsa_wput(queue_t *q, mblk_t *mp);
440 static void zsa_rsrv(queue_t *q);
442 static struct module_info asyncm_info = {
444 "zs",
446 INFPSZ,
447 2048,
451 static struct qinit async_rinit = {
452 putq,
453 (int (*)())zsa_rsrv,
454 zsa_open,
455 zsa_close,
456 NULL,
457 &asyncm_info,
458 NULL
461 static struct qinit async_winit = {
462 (int (*)())zsa_wput,
463 NULL,
464 NULL,
465 NULL,
466 NULL,
467 &asyncm_info,
468 NULL
471 struct streamtab asynctab = {
472 &async_rinit,
473 &async_winit,
474 NULL,
475 NULL,
479 * The async interrupt entry points.
481 static void zsa_txint(struct zscom *zs);
482 static void zsa_xsint(struct zscom *zs);
483 static void zsa_rxint(struct zscom *zs);
484 static void zsa_srint(struct zscom *zs);
485 static int zsa_softint(struct zscom *zs);
486 static int zsa_suspend(struct zscom *zs);
487 static int zsa_resume(struct zscom *zs);
489 static void
490 zsa_null(struct zscom *zs)
492 /* LINTED */
493 register short c;
495 SCC_WRITE0(ZSWR0_RESET_TXINT);
496 SCC_WRITE0(ZSWR0_RESET_STATUS);
497 c = SCC_READDATA();
498 ZSDELAY();
499 SCC_WRITE0(ZSWR0_RESET_ERRORS);
502 /*ARGSUSED*/
503 static int
504 zsa_null_int(struct zscom *zs)
506 return (0);
509 struct zsops zsops_null_async = {
510 zsa_null,
511 zsa_null,
512 zsa_null,
513 zsa_null,
514 zsa_null_int,
515 zsa_null_int,
516 zsa_null_int
519 struct zsops zsops_async = {
520 zsa_txint,
521 zsa_xsint,
522 zsa_rxint,
523 zsa_srint,
524 zsa_softint,
525 zsa_suspend,
526 zsa_resume
529 static int dmtozs(int bits);
530 static int zstodm(int bits);
531 static void zsa_restart(void *);
532 static void zsa_reioctl(void *);
533 static void zsa_ioctl(struct asyncline *za, queue_t *q, mblk_t *mp);
534 static void zsa_program(struct asyncline *za, int setibaud);
535 static void zsa_start(struct zscom *zs);
536 static void zsa_kick_rcv(void *);
537 static void zsa_callback(void *);
538 static void zsa_set_za_rcv_flags_mask(struct asyncline *za);
539 int zsgetspeed(dev_t dev);
541 static boolean_t abort_charseq_recognize(uchar_t ch);
543 /* ARGSUSED */
545 zsc_info(dev_info_t *dip, ddi_info_cmd_t infocmd, void *arg,
546 void **result)
548 register dev_t dev = (dev_t)arg;
549 register int unit, error;
550 register struct zscom *zs;
552 if ((unit = UNIT(dev)) >= nzs)
553 return (DDI_FAILURE);
555 switch (infocmd) {
556 case DDI_INFO_DEVT2DEVINFO:
557 zs = &zscom[unit];
558 *result = zs->zs_dip;
559 error = DDI_SUCCESS;
560 break;
561 case DDI_INFO_DEVT2INSTANCE:
562 *result = (void *)(uintptr_t)(unit / 2);
563 error = DDI_SUCCESS;
564 break;
565 default:
566 error = DDI_FAILURE;
568 return (error);
572 * The Asynchronous Driver.
576 * Determine if the zsminor device is in use as either a stdin or stdout
577 * device, so we can be careful about how we initialize the DUART, if
578 * it is, in fact, in use.
580 * Since this is expensive, we do it once and store away the answers,
581 * since this gets called a number of times per phyical zs device.
582 * Perhaps, this should be in a loadable module, so it can get thrown
583 * away after all the zs devices are attached?
587 * To determine if a given unit is being used by the PROM,
588 * we need to map stdin/stdout devices as known to the PROM
589 * to zs internal minor device numbers:
591 * PROM (real device) zs minor device
593 * "zs", 0, "a" 0 ttya
594 * "zs", 0, "b" 1 ttyb
595 * "zs", 1, "a" 2 keyboard
596 * "zs", 1, "b" 3 mouse
597 * "zs", 2, "a" 4 ttyc
598 * "zs", 2, "b" 5 ttyd
600 * The following value mapping lines assume that insource
601 * and outsink map as "screen, a, b, c, d, ...", and that
602 * zs minors are "a, b, kbd, mouse, c, d, ...".
605 static int zsa_inuse; /* Strictly for debugging */
608 zsa_channel_is_active_in_rom(dev_info_t *dev, int zsminor)
610 char pathname[OBP_MAXPATHLEN];
611 char default_pathname[OBP_MAXPATHLEN];
612 char *stdioname;
613 char minordata[3];
616 * Basically, get my name and compare it to stdio devnames
617 * and if we get a match, then the device is in use as either
618 * stdin or stdout device (console tip line or keyboard device).
620 * We get two forms of the pathname, one complete with the
621 * the channel number, and if the channel is 'a', then
622 * we also deal with the user's ability to default to
623 * channel 'a', by omitting the channel number option.
624 * We then compare these pathnames to both the stdin and
625 * stdout pathnames. If any of these match, then the channel
626 * is in use.
629 (void) ddi_pathname(dev, pathname); /* device pathname */
630 default_pathname[0] = '\0'; /* default pathname if channel 'a' */
631 if ((zsminor & 1) == 0)
632 (void) strcpy(default_pathname, pathname);
633 minordata[0] = ':';
634 minordata[1] = (char)('a' + (zsminor & 1));
635 minordata[2] = '\0';
636 (void) strcat(pathname, minordata);
638 stdioname = prom_stdinpath();
639 if (strcmp(pathname, stdioname) == 0) {
640 zsa_inuse |= (1 << zsminor);
641 return (1);
643 if (strcmp(default_pathname, stdioname) == 0) {
644 zsa_inuse |= (1 << zsminor);
645 return (1);
648 stdioname = prom_stdoutpath();
649 if (strcmp(pathname, stdioname) == 0) {
650 zsa_inuse |= (1 << zsminor);
651 return (1);
653 if (strcmp(default_pathname, stdioname) == 0) {
654 zsa_inuse |= (1 << zsminor);
655 return (1);
658 return (0);
662 * Initialize zs
664 void
665 zsa_init(struct zscom *zs)
668 * This routine is called near the end of the zs module's attach
669 * process. It initializes the TTY protocol-private data for this
670 * channel that needs to be in place before interrupts are enabled.
672 mutex_enter(zs->zs_excl);
673 mutex_enter(zs->zs_excl_hi);
676 * Raise modem control lines on serial ports associated
677 * with the console and (optionally) softcarrier lines.
678 * Drop modem control lines on all others so that modems
679 * will not answer and portselectors will skip these
680 * lines until they are opened by a getty.
682 if (zsa_channel_is_active_in_rom(zs->zs_dip, zs->zs_unit))
683 (void) zsmctl(zs, ZS_ON, DMSET); /* raise dtr */
684 else if (zsasoftdtr && (zssoftCAR[zs->zs_unit]))
685 (void) zsmctl(zs, ZS_ON, DMSET); /* raise dtr */
686 else
687 (void) zsmctl(zs, ZS_OFF, DMSET); /* drop dtr */
689 if (zsa_rstandby > ZSA_MAX_RSTANDBY)
690 zsa_rstandby = ZSA_MAX_RSTANDBY;
692 if (zsa_rdone > ZSA_RDONE_MAX)
693 zsa_rdone = ZSA_RDONE_MAX;
695 if (zsa_grace_flow_control > ZSA_GRACE_MAX_FLOW_CONTROL)
696 zsa_grace_flow_control = ZSA_GRACE_MAX_FLOW_CONTROL;
698 mutex_exit(zs->zs_excl_hi);
699 mutex_exit(zs->zs_excl);
704 * Open routine.
706 /*ARGSUSED*/
707 static int
708 zsa_open(queue_t *rq, dev_t *dev, int flag, int sflag, cred_t *cr)
710 register struct zscom *zs;
711 register struct asyncline *za;
712 register int speed, unit;
713 struct termios *termiosp;
714 int len;
715 register int allocbcount = zsa_rstandby;
716 boolean_t set_zsoptinit = B_FALSE;
718 unit = UNIT(*dev);
719 if (unit >= nzs)
720 return (ENXIO); /* unit not configured */
722 /* zscom is allocated by zsattach, and thus cannot be NULL here */
723 zs = &zscom[unit];
724 if (zs->zs_ops == NULL) {
725 return (ENXIO); /* device not found by autoconfig */
728 mutex_enter(zs->zs_ocexcl);
729 mutex_enter(zs->zs_excl);
730 again:
731 if ((zs->zs_ops != &zsops_null) &&
732 (zs->zs_ops != &zsops_async)) {
733 mutex_exit(zs->zs_excl);
734 mutex_exit(zs->zs_ocexcl);
735 return (EBUSY); /* another protocol got here first */
738 za = (struct asyncline *)&zs->zs_priv_str;
740 if (zs->zs_suspended) {
741 mutex_exit(zs->zs_excl);
742 mutex_exit(zs->zs_ocexcl);
743 (void) ddi_dev_is_needed(zs->zs_dip, 0, 1);
744 mutex_enter(zs->zs_ocexcl);
745 mutex_enter(zs->zs_excl);
748 /* Mark device as busy (for power management) */
749 (void) pm_busy_component(zs->zs_dip, unit%2+1);
751 if (zs->zs_ops == &zsops_null) {
752 bzero(za, sizeof (zs->zs_priv_str));
753 za->za_common = zs;
754 if (zssoftCAR[zs->zs_unit])
755 za->za_ttycommon.t_flags |= TS_SOFTCAR;
756 zsopinit(zs, &zsops_async);
757 set_zsoptinit = B_TRUE;
758 za->za_rdone_wptr = 0;
759 za->za_rdone_rptr = 0;
762 zs->zs_priv = (caddr_t)za;
765 * Block waiting for carrier to come up,
766 * unless this is a no-delay open.
768 mutex_enter(zs->zs_excl_hi);
769 if (!(za->za_flags & ZAS_ISOPEN)) {
771 * Get the default termios settings (cflag).
772 * These are stored as a property in the
773 * "options" node.
775 mutex_exit(zs->zs_excl_hi);
776 if (ddi_getlongprop(DDI_DEV_T_ANY,
777 ddi_root_node(), 0, "ttymodes",
778 (caddr_t)&termiosp, &len) == DDI_PROP_SUCCESS &&
779 len == sizeof (struct termios)) {
781 za->za_ttycommon.t_cflag = termiosp->c_cflag;
782 kmem_free(termiosp, len);
783 } else {
785 * Gack! Whine about it.
787 cmn_err(CE_WARN,
788 "zs: Couldn't get ttymodes property!");
790 mutex_enter(zs->zs_excl_hi);
791 if ((*dev == rconsdev) || (*dev == kbddev) ||
792 (*dev == stdindev)) {
793 speed = zsgetspeed(*dev);
794 za->za_ttycommon.t_cflag &= ~(CBAUD);
795 if (speed > CBAUD) {
796 za->za_ttycommon.t_cflag |= CBAUDEXT;
797 za->za_ttycommon.t_cflag |=
798 ((speed - CBAUD - 1) & CBAUD);
799 } else {
800 za->za_ttycommon.t_cflag &= ~CBAUDEXT;
801 za->za_ttycommon.t_cflag |= (speed & CBAUD);
804 za->za_overrun = 0;
805 za->za_ttycommon.t_iflag = 0;
806 za->za_ttycommon.t_iocpending = NULL;
807 za->za_ttycommon.t_size.ws_row = 0;
808 za->za_ttycommon.t_size.ws_col = 0;
809 za->za_ttycommon.t_size.ws_xpixel = 0;
810 za->za_ttycommon.t_size.ws_ypixel = 0;
811 za->za_dev = *dev;
812 za->za_wbufcid = 0;
813 zsa_program(za, za->za_ttycommon.t_cflag & (CIBAUDEXT|CIBAUD));
814 zsa_set_za_rcv_flags_mask(za);
815 } else if ((za->za_ttycommon.t_flags & TS_XCLUDE) &&
816 secpolicy_excl_open(cr) != 0) {
817 mutex_exit(zs->zs_excl_hi);
818 if (set_zsoptinit && !(za->za_flags & ISOPEN))
819 zsopinit(zs, &zsops_null);
820 mutex_exit(zs->zs_excl);
821 mutex_exit(zs->zs_ocexcl);
822 return (EBUSY);
823 } else if ((*dev & OUTLINE) && !(za->za_flags & ZAS_OUT)) {
824 mutex_exit(zs->zs_excl_hi);
825 if (set_zsoptinit && !(za->za_flags & ISOPEN))
826 zsopinit(zs, &zsops_null);
827 mutex_exit(zs->zs_excl);
828 mutex_exit(zs->zs_ocexcl);
829 return (EBUSY);
832 if (*dev & OUTLINE)
833 za->za_flags |= ZAS_OUT;
834 (void) zsmctl(zs, ZS_ON, DMSET);
837 * Check carrier.
839 if ((za->za_ttycommon.t_flags & TS_SOFTCAR) ||
840 (zsmctl(zs, 0, DMGET) & ZSRR0_CD))
841 za->za_flags |= ZAS_CARR_ON;
842 mutex_exit(zs->zs_excl_hi);
845 * If FNDELAY and FNONBLOCK are clear, block until carrier up.
846 * Quit on interrupt.
848 if (!(flag & (FNDELAY|FNONBLOCK)) &&
849 !(za->za_ttycommon.t_cflag & CLOCAL)) {
850 if (!(za->za_flags & (ZAS_CARR_ON|ZAS_OUT)) ||
851 ((za->za_flags & ZAS_OUT) && !(*dev & OUTLINE))) {
852 za->za_flags |= ZAS_WOPEN;
853 mutex_exit(zs->zs_excl);
854 if (cv_wait_sig(&zs->zs_flags_cv, zs->zs_ocexcl) == 0) {
855 mutex_enter(zs->zs_excl);
856 if (zs->zs_suspended) {
857 mutex_exit(zs->zs_excl);
858 mutex_exit(zs->zs_ocexcl);
859 (void) ddi_dev_is_needed(zs->zs_dip,
860 0, 1);
861 mutex_enter(zs->zs_ocexcl);
862 mutex_enter(zs->zs_excl);
864 za->za_flags &= ~ZAS_WOPEN;
865 if (set_zsoptinit && !(za->za_flags & ISOPEN))
866 zsopinit(zs, &zsops_null);
867 mutex_exit(zs->zs_excl);
868 mutex_exit(zs->zs_ocexcl);
869 return (EINTR);
871 mutex_enter(zs->zs_excl);
872 za->za_flags &= ~ZAS_WOPEN;
873 if ((zs->zs_ops == &zsops_null) ||
874 (zs->zs_ops == &zsops_async))
875 goto again;
876 else {
877 if (set_zsoptinit && !(za->za_flags & ISOPEN))
878 zsopinit(zs, &zsops_null);
879 mutex_exit(zs->zs_excl);
880 mutex_exit(zs->zs_ocexcl);
881 return (EBUSY);
884 } else if ((za->za_flags & ZAS_OUT) && !(*dev & OUTLINE)) {
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 za->za_ttycommon.t_readq = rq;
893 za->za_ttycommon.t_writeq = WR(rq);
894 rq->q_ptr = WR(rq)->q_ptr = (caddr_t)za;
896 za->za_flags |= ZAS_ISOPEN;
897 ZSA_GETBLOCK(zs, allocbcount);
898 qprocson(rq);
899 mutex_exit(zs->zs_excl);
900 mutex_exit(zs->zs_ocexcl);
901 return (0);
904 static void
905 zs_progress_check(void *arg)
907 struct asyncline *za = arg;
908 struct zscom *zs = za->za_common;
909 mblk_t *bp;
912 * We define "progress" as either waiting on a timed break or delay, or
913 * having had at least one transmitter interrupt. If none of these are
914 * true, then just terminate the output and wake up that close thread.
916 mutex_enter(zs->zs_excl);
917 if (!(zs->zs_flags & ZS_PROGRESS) &&
918 !(za->za_flags & (ZAS_BREAK|ZAS_DELAY))) {
919 za->za_flags &= ~ZAS_BUSY;
920 mutex_enter(zs->zs_excl_hi);
921 za->za_rcv_flags_mask &= ~DO_RETRANSMIT;
922 zs->zs_wr_cur = NULL;
923 zs->zs_wr_lim = NULL;
924 bp = za->za_xmitblk;
925 za->za_xmitblk = NULL;
926 mutex_exit(zs->zs_excl_hi);
927 zs->zs_timer = 0;
928 mutex_exit(zs->zs_excl);
929 if (bp != NULL)
930 freeb(bp);
932 * Since this timer is running, we know that we're in exit(2).
933 * That means that the user can't possibly be waiting on any
934 * valid ioctl(2) completion anymore, and we should just flush
935 * everything.
937 flushq(za->za_ttycommon.t_writeq, FLUSHALL);
938 cv_broadcast(&zs->zs_flags_cv);
939 } else {
940 zs->zs_flags &= ~ZS_PROGRESS;
941 zs->zs_timer = timeout(zs_progress_check, za,
942 drv_usectohz(zs_drain_check));
943 mutex_exit(zs->zs_excl);
948 * Close routine.
950 * Important locking note: the zs_ocexcl lock is not held at all in this
951 * routine. This is intentional. That lock is used to coordinate multiple
952 * simultaneous opens on a stream, and there's no such thing as multiple
953 * simultaneous closes on a stream.
956 /*ARGSUSED*/
957 static int
958 zsa_close(queue_t *q, int flag)
960 struct asyncline *za;
961 struct zscom *zs;
962 int i;
963 mblk_t *bp;
964 timeout_id_t za_zsa_restart_id, za_kick_rcv_id;
965 bufcall_id_t za_bufcid, za_wbufcid;
966 int tmp;
968 za = q->q_ptr;
969 ASSERT(za != NULL);
971 zs = za->za_common;
973 mutex_enter(zs->zs_excl);
974 zs->zs_flags |= ZS_CLOSING;
977 * There are two flavors of break -- timed (M_BREAK or TCSBRK) and
978 * untimed (TIOCSBRK). For the timed case, these are enqueued on our
979 * write queue and there's a timer running, so we don't have to worry
980 * about them. For the untimed case, though, the user obviously made a
981 * mistake, because these are handled immediately. We'll terminate the
982 * break now and honor their implicit request by discarding the rest of
983 * the data.
985 if (!(za->za_flags & ZAS_BREAK) && (zs->zs_wreg[5] & ZSWR5_BREAK))
986 goto nodrain;
989 * If the user told us not to delay the close ("non-blocking"), then
990 * don't bother trying to drain.
992 * If the user did M_STOP (ASYNC_STOPPED), there's no hope of ever
993 * getting an M_START (since these messages aren't enqueued), and the
994 * only other way to clear the stop condition is by loss of DCD, which
995 * would discard the queue data. Thus, we drop the output data if
996 * ASYNC_STOPPED is set.
998 if ((flag & (FNDELAY|FNONBLOCK)) || (za->za_flags & ZAS_STOPPED))
999 goto nodrain;
1002 * If there's any pending output, then we have to try to drain it.
1003 * There are two main cases to be handled:
1004 * - called by close(2): need to drain until done or until
1005 * a signal is received. No timeout.
1006 * - called by exit(2): need to drain while making progress
1007 * or until a timeout occurs. No signals.
1009 * If we can't rely on receiving a signal to get us out of a hung
1010 * session, then we have to use a timer. In this case, we set a timer
1011 * to check for progress in sending the output data -- all that we ask
1012 * (at each interval) is that there's been some progress made. Since
1013 * the interrupt routine grabs buffers from the write queue, we can't
1014 * trust changes in zs_wr_cur. Instead, we use a progress flag.
1016 * Note that loss of carrier will cause the output queue to be flushed,
1017 * and we'll wake up again and finish normally.
1019 if (!ddi_can_receive_sig() && zs_drain_check != 0) {
1020 zs->zs_flags &= ~ZS_PROGRESS;
1021 zs->zs_timer = timeout(zs_progress_check, za,
1022 drv_usectohz(zs_drain_check));
1025 while (zs->zs_wr_cur != NULL ||
1026 za->za_ttycommon.t_writeq->q_first != NULL ||
1027 (za->za_flags & (ZAS_BUSY|ZAS_DELAY|ZAS_BREAK))) {
1028 if (cv_wait_sig(&zs->zs_flags_cv, zs->zs_excl) == 0)
1029 break;
1032 if (zs->zs_timer != 0) {
1033 (void) untimeout(zs->zs_timer);
1034 zs->zs_timer = 0;
1037 nodrain:
1039 * If break is in progress, stop it.
1041 mutex_enter(zs->zs_excl_hi);
1042 if (zs->zs_wreg[5] & ZSWR5_BREAK) {
1043 SCC_BIC(5, ZSWR5_BREAK);
1044 za->za_flags &= ~ZAS_BREAK;
1047 za_wbufcid = za->za_wbufcid;
1048 za_bufcid = za->za_bufcid;
1049 za_zsa_restart_id = za->za_zsa_restart_id;
1050 za_kick_rcv_id = za->za_kick_rcv_id;
1052 za->za_wbufcid = za->za_bufcid = 0;
1053 za->za_zsa_restart_id = za->za_kick_rcv_id = 0;
1056 * If line has HUPCL set or is incompletely opened,
1057 * and it is not the console or the keyboard,
1058 * fix up the modem lines.
1061 zsopinit(zs, &zsops_null_async);
1064 * Nobody, zsh or zs can now open this port until
1065 * zsopinit(zs, &zsops_null);
1069 if ((za->za_dev != rconsdev) && (za->za_dev != kbddev) &&
1070 (za->za_dev != stdindev) &&
1071 (((za->za_flags & (ZAS_WOPEN|ZAS_ISOPEN)) != ZAS_ISOPEN) ||
1072 (za->za_ttycommon.t_cflag & HUPCL))) {
1074 * If DTR is being held high by softcarrier,
1075 * set up the ZS_ON set; if not, hang up.
1077 if (zsasoftdtr && (za->za_ttycommon.t_flags & TS_SOFTCAR))
1078 (void) zsmctl(zs, ZS_ON, DMSET);
1079 else
1080 (void) zsmctl(zs, ZS_OFF, DMSET);
1081 mutex_exit(zs->zs_excl_hi);
1083 * Don't let an interrupt in the middle of close
1084 * bounce us back to the top; just continue
1085 * closing as if nothing had happened.
1087 tmp = cv_reltimedwait_sig(&zs->zs_flags_cv, zs->zs_excl,
1088 drv_usectohz(10000), TR_CLOCK_TICK);
1089 if (zs->zs_suspended) {
1090 mutex_exit(zs->zs_excl);
1091 (void) ddi_dev_is_needed(zs->zs_dip, 0, 1);
1092 mutex_enter(zs->zs_excl);
1094 if (tmp == 0)
1095 goto out;
1096 mutex_enter(zs->zs_excl_hi);
1100 * If nobody's now using it, turn off receiver interrupts.
1102 if ((za->za_flags & (ZAS_ISOPEN|ZAS_WOPEN)) == 0)
1103 SCC_BIC(1, ZSWR1_RIE);
1104 mutex_exit(zs->zs_excl_hi);
1106 out:
1108 * Clear out device state.
1110 ttycommon_close(&za->za_ttycommon);
1112 za->za_ttycommon.t_readq = NULL;
1113 za->za_ttycommon.t_writeq = NULL;
1115 mutex_enter(zs->zs_excl_hi);
1116 za->za_rcv_flags_mask &= ~DO_RETRANSMIT;
1117 zs->zs_wr_cur = NULL;
1118 zs->zs_wr_lim = NULL;
1119 bp = za->za_xmitblk;
1120 za->za_xmitblk = NULL;
1121 mutex_exit(zs->zs_excl_hi);
1122 if (bp)
1123 freemsg(bp);
1125 mutex_enter(zs->zs_excl_hi);
1126 zs->zs_rd_cur = NULL;
1127 zs->zs_rd_lim = NULL;
1128 bp = za->za_rcvblk;
1129 za->za_rcvblk = NULL;
1130 mutex_exit(zs->zs_excl_hi);
1131 if (bp)
1132 freemsg(bp);
1134 for (i = 0; i < zsa_rstandby; i++) {
1135 mutex_enter(zs->zs_excl_hi);
1136 bp = za->za_rstandby[i];
1137 za->za_rstandby[i] = NULL;
1138 mutex_exit(zs->zs_excl_hi);
1139 if (bp)
1140 freemsg(bp);
1143 if (za->za_soft_active || za->za_kick_active) {
1144 zs->zs_flags |= ZS_CLOSED;
1145 while (za->za_soft_active || za->za_kick_active)
1146 cv_wait(&zs->zs_flags_cv, zs->zs_excl);
1148 if (zs->zs_suspended) {
1149 mutex_exit(zs->zs_excl);
1150 (void) ddi_dev_is_needed(zs->zs_dip, 0, 1);
1151 mutex_enter(zs->zs_excl);
1154 ZSA_FLUSHQ;
1155 bzero(za, sizeof (struct asyncline));
1156 qprocsoff(q);
1157 mutex_exit(zs->zs_excl);
1160 * Cancel outstanding "bufcall" request.
1162 if (za_wbufcid)
1163 unbufcall(za_wbufcid);
1164 if (za_bufcid)
1165 unbufcall(za_bufcid);
1168 * Cancel outstanding timeout.
1170 if (za_zsa_restart_id)
1171 (void) untimeout(za_zsa_restart_id);
1173 if (za_kick_rcv_id)
1174 (void) untimeout(za_kick_rcv_id);
1176 q->q_ptr = WR(q)->q_ptr = NULL;
1177 zsopinit(zs, &zsops_null);
1178 cv_broadcast(&zs->zs_flags_cv);
1180 /* Mark device as available for power management */
1181 (void) pm_idle_component(zs->zs_dip, zs->zs_unit%2+1);
1182 return (0);
1186 * Put procedure for write queue.
1187 * Respond to M_STOP, M_START, M_IOCTL, and M_FLUSH messages here;
1188 * set the flow control character for M_STOPI and M_STARTI messages;
1189 * queue up M_BREAK, M_DELAY, and M_DATA messages for processing
1190 * by the start routine, and then call the start routine; discard
1191 * everything else. Note that this driver does not incorporate any
1192 * mechanism to negotiate to handle the canonicalization process.
1193 * It expects that these functions are handled in upper module(s),
1194 * as we do in ldterm.
1196 static void
1197 zsa_wput(queue_t *q, mblk_t *mp)
1199 register struct asyncline *za;
1200 register struct zscom *zs;
1201 register struct copyresp *resp;
1202 register mblk_t *bp = NULL;
1203 int error;
1204 struct iocblk *iocp;
1206 za = (struct asyncline *)q->q_ptr;
1207 zs = za->za_common;
1208 if (zs->zs_flags & ZS_NEEDSOFT) {
1209 zs->zs_flags &= ~ZS_NEEDSOFT;
1210 (void) zsa_softint(zs);
1213 switch (mp->b_datap->db_type) {
1215 case M_STOP:
1217 * Since we don't do real DMA, we can just let the
1218 * chip coast to a stop after applying the brakes.
1220 mutex_enter(zs->zs_excl);
1221 mutex_enter(zs->zs_excl_hi);
1222 za->za_flags |= ZAS_STOPPED;
1223 if ((zs->zs_wr_cur) != NULL) {
1224 za->za_flags &= ~ZAS_BUSY;
1225 za->za_rcv_flags_mask &= ~DO_RETRANSMIT;
1226 bp = za->za_xmitblk;
1227 bp->b_rptr = zs->zs_wr_cur;
1228 zs->zs_wr_cur = NULL;
1229 zs->zs_wr_lim = NULL;
1230 za->za_xmitblk = NULL;
1232 mutex_exit(zs->zs_excl_hi);
1233 if (bp)
1234 (void) putbq(q, bp);
1235 freemsg(mp);
1236 mutex_exit(zs->zs_excl);
1237 break;
1239 case M_START:
1240 mutex_enter(zs->zs_excl);
1241 if (za->za_flags & ZAS_STOPPED) {
1242 za->za_flags &= ~ZAS_STOPPED;
1244 * If an output operation is in progress,
1245 * resume it. Otherwise, prod the start
1246 * routine.
1248 zsa_start(zs);
1250 freemsg(mp);
1251 mutex_exit(zs->zs_excl);
1252 break;
1254 case M_IOCTL:
1255 mutex_enter(zs->zs_excl);
1256 iocp = (struct iocblk *)mp->b_rptr;
1258 switch (iocp->ioc_cmd) {
1260 case TIOCGPPS:
1262 * Get PPS state.
1264 if (mp->b_cont != NULL)
1265 freemsg(mp->b_cont);
1267 mp->b_cont = allocb(sizeof (int), BPRI_HI);
1268 if (mp->b_cont == NULL) {
1269 mp->b_datap->db_type = M_IOCNAK;
1270 iocp->ioc_error = ENOMEM;
1271 ZSA_QREPLY(q, mp);
1272 break;
1274 if (za->za_pps)
1275 *(int *)mp->b_cont->b_wptr = 1;
1276 else
1277 *(int *)mp->b_cont->b_wptr = 0;
1278 mp->b_cont->b_wptr += sizeof (int);
1279 mp->b_datap->db_type = M_IOCACK;
1280 iocp->ioc_count = sizeof (int);
1281 ZSA_QREPLY(q, mp);
1282 break;
1284 case TIOCSPPS:
1286 * Set PPS state.
1288 error = miocpullup(mp, sizeof (int));
1289 if (error != 0) {
1290 mp->b_datap->db_type = M_IOCNAK;
1291 iocp->ioc_error = error;
1292 ZSA_QREPLY(q, mp);
1293 break;
1296 za->za_pps = (*(int *)mp->b_cont->b_rptr != 0);
1297 mp->b_datap->db_type = M_IOCACK;
1298 ZSA_QREPLY(q, mp);
1299 break;
1301 case TIOCGPPSEV:
1304 * Get PPS event data.
1306 void *buf;
1307 #ifdef _SYSCALL32_IMPL
1308 struct ppsclockev32 p32;
1309 #endif
1311 if (mp->b_cont != NULL) {
1312 freemsg(mp->b_cont);
1313 mp->b_cont = NULL;
1315 if (za->za_pps == NULL) {
1316 mp->b_datap->db_type = M_IOCNAK;
1317 iocp->ioc_error = ENXIO;
1318 ZSA_QREPLY(q, mp);
1319 break;
1322 #ifdef _SYSCALL32_IMPL
1323 if ((iocp->ioc_flag & IOC_MODELS) != IOC_NATIVE) {
1324 TIMEVAL_TO_TIMEVAL32(&p32.tv, &ppsclockev.tv);
1325 p32.serial = ppsclockev.serial;
1326 buf = &p32;
1327 iocp->ioc_count = sizeof (struct ppsclockev32);
1328 } else
1329 #endif
1331 buf = &ppsclockev;
1332 iocp->ioc_count = sizeof (struct ppsclockev);
1335 if ((bp = allocb(iocp->ioc_count, BPRI_HI)) == NULL) {
1336 mp->b_datap->db_type = M_IOCNAK;
1337 iocp->ioc_error = ENOMEM;
1338 ZSA_QREPLY(q, mp);
1339 break;
1341 mp->b_cont = bp;
1343 bcopy(buf, bp->b_wptr, iocp->ioc_count);
1344 bp->b_wptr += iocp->ioc_count;
1345 mp->b_datap->db_type = M_IOCACK;
1346 ZSA_QREPLY(q, mp);
1347 break;
1350 case TCSETSW:
1351 case TCSETSF:
1352 case TCSETAW:
1353 case TCSETAF:
1354 case TCSBRK:
1356 * The changes do not take effect until all
1357 * output queued before them is drained.
1358 * Put this message on the queue, so that
1359 * "zsa_start" will see it when it's done
1360 * with the output before it. Poke the
1361 * start routine, just in case.
1363 (void) putq(q, mp);
1364 zsa_start(zs);
1365 break;
1367 default:
1369 * Do it now.
1371 zsa_ioctl(za, q, mp);
1372 break;
1374 mutex_exit(zs->zs_excl);
1375 break;
1378 case M_IOCDATA:
1380 mutex_enter(zs->zs_excl);
1381 resp = (struct copyresp *)mp->b_rptr;
1382 if (resp->cp_rval) {
1384 * Just free message on failure.
1386 freemsg(mp);
1387 mutex_exit(zs->zs_excl);
1388 break;
1390 switch (resp->cp_cmd) {
1392 case TIOCMSET:
1393 mutex_enter(zs->zs_excl_hi);
1394 (void) zsmctl(zs, dmtozs(*(int *)mp->b_cont->b_rptr),
1395 DMSET);
1396 mutex_exit(zs->zs_excl_hi);
1397 mioc2ack(mp, NULL, 0, 0);
1398 ZSA_QREPLY(q, mp);
1399 break;
1401 case TIOCMBIS:
1402 mutex_enter(zs->zs_excl_hi);
1403 (void) zsmctl(zs, dmtozs(*(int *)mp->b_cont->b_rptr),
1404 DMBIS);
1405 mutex_exit(zs->zs_excl_hi);
1406 mioc2ack(mp, NULL, 0, 0);
1407 ZSA_QREPLY(q, mp);
1408 break;
1410 case TIOCMBIC:
1411 mutex_enter(zs->zs_excl_hi);
1412 (void) zsmctl(zs, dmtozs(*(int *)mp->b_cont->b_rptr),
1413 DMBIC);
1414 mutex_exit(zs->zs_excl_hi);
1415 mioc2ack(mp, NULL, 0, 0);
1416 ZSA_QREPLY(q, mp);
1417 break;
1419 case TIOCMGET:
1420 mioc2ack(mp, NULL, 0, 0);
1421 ZSA_QREPLY(q, mp);
1422 break;
1424 default:
1425 freemsg(mp);
1428 mutex_exit(zs->zs_excl);
1429 break;
1432 case M_FLUSH:
1433 mutex_enter(zs->zs_excl);
1434 if (*mp->b_rptr & FLUSHW) {
1437 * Abort any output in progress.
1439 if (za->za_flags & ZAS_BUSY) {
1440 za->za_flags &= ~ZAS_BUSY;
1441 mutex_enter(zs->zs_excl_hi);
1442 za->za_rcv_flags_mask &= ~DO_RETRANSMIT;
1443 zs->zs_wr_cur = NULL;
1444 zs->zs_wr_lim = NULL;
1445 bp = za->za_xmitblk;
1446 za->za_xmitblk = NULL;
1447 mutex_exit(zs->zs_excl_hi);
1448 if (bp)
1449 freemsg(bp);
1452 * Flush our write queue.
1454 flushq(q, FLUSHDATA); /* XXX doesn't flush M_DELAY */
1455 *mp->b_rptr &= ~FLUSHW; /* it has been flushed */
1457 if (*mp->b_rptr & FLUSHR) {
1459 * Flush any data in the temporary receive buffer
1461 mutex_enter(zs->zs_excl_hi);
1462 if ((za->za_ttycommon.t_flags & TS_SOFTCAR) ||
1463 (SCC_READ0() & ZSRR0_CD)) {
1464 ZSA_KICK_RCV;
1465 } else {
1466 ZSA_KICK_RCV;
1467 if (!(SCC_READ0() & ZSRR0_RX_READY)) {
1469 * settle time for 1 character shift
1471 mutex_exit(zs->zs_excl_hi);
1472 mutex_exit(zs->zs_excl);
1473 delay(ztdelay(SPEED(
1474 za->za_ttycommon.t_cflag))/3 + 1);
1475 mutex_enter(zs->zs_excl);
1476 mutex_enter(zs->zs_excl_hi);
1477 if (!(SCC_READ0() & ZSRR0_CD))
1478 ZSA_KICK_RCV;
1480 while ((SCC_READ0() &
1481 (ZSRR0_CD | ZSRR0_RX_READY)) ==
1482 ZSRR0_RX_READY) {
1484 * Empty Receiver
1486 (void) SCC_READDATA();
1489 mutex_exit(zs->zs_excl_hi);
1490 flushq(RD(q), FLUSHDATA);
1491 ZSA_QREPLY(q, mp);
1493 * give the read queues a crack at it
1495 } else
1496 freemsg(mp);
1499 * We must make sure we process messages that survive the
1500 * write-side flush. Without this call, the close protocol
1501 * with ldterm can hang forever. (ldterm will have sent us a
1502 * TCSBRK ioctl that it expects a response to.)
1504 zsa_start(zs);
1505 mutex_exit(zs->zs_excl);
1506 break;
1508 case M_BREAK:
1509 case M_DELAY:
1510 case M_DATA:
1511 mutex_enter(zs->zs_excl);
1513 * Queue the message up to be transmitted,
1514 * and poke the start routine.
1516 (void) putq(q, mp);
1517 zsa_start(zs);
1518 mutex_exit(zs->zs_excl);
1519 break;
1521 case M_STOPI:
1522 mutex_enter(zs->zs_excl);
1523 mutex_enter(zs->zs_excl_hi);
1524 za->za_flowc = za->za_ttycommon.t_stopc;
1525 if ((zs->zs_wr_cur) != NULL) {
1526 za->za_rcv_flags_mask &= ~DO_RETRANSMIT;
1527 bp = za->za_xmitblk;
1528 bp->b_rptr = zs->zs_wr_cur;
1529 zs->zs_wr_cur = NULL;
1530 zs->zs_wr_lim = NULL;
1531 za->za_xmitblk = NULL;
1533 mutex_exit(zs->zs_excl_hi);
1534 if (bp)
1535 (void) putbq(q, bp);
1536 else
1537 zsa_start(zs); /* poke the start routine */
1538 freemsg(mp);
1539 mutex_exit(zs->zs_excl);
1540 break;
1542 case M_STARTI:
1543 mutex_enter(zs->zs_excl);
1544 mutex_enter(zs->zs_excl_hi);
1545 za->za_flowc = za->za_ttycommon.t_startc;
1546 if ((zs->zs_wr_cur) != NULL) {
1547 za->za_rcv_flags_mask &= ~DO_RETRANSMIT;
1548 bp = za->za_xmitblk;
1549 bp->b_rptr = zs->zs_wr_cur;
1550 zs->zs_wr_cur = NULL;
1551 zs->zs_wr_lim = NULL;
1552 za->za_xmitblk = NULL;
1554 mutex_exit(zs->zs_excl_hi);
1555 if (bp)
1556 (void) putbq(q, bp);
1557 else
1558 zsa_start(zs); /* poke the start routine */
1559 freemsg(mp);
1560 mutex_exit(zs->zs_excl);
1561 break;
1563 case M_CTL:
1564 if (MBLKL(mp) >= sizeof (struct iocblk) &&
1565 ((struct iocblk *)mp->b_rptr)->ioc_cmd == MC_POSIXQUERY) {
1566 ((struct iocblk *)mp->b_rptr)->ioc_cmd = MC_HAS_POSIX;
1567 qreply(q, mp);
1568 } else {
1570 * These MC_SERVICE type messages are used by upper
1571 * modules to tell this driver to send input up
1572 * immediately, or that it can wait for normal
1573 * processing that may or may not be done. Sun
1574 * requires these for the mouse module.
1576 mutex_enter(zs->zs_excl);
1577 switch (*mp->b_rptr) {
1579 case MC_SERVICEIMM:
1580 mutex_enter(zs->zs_excl_hi);
1581 za->za_flags |= ZAS_SERVICEIMM;
1582 mutex_exit(zs->zs_excl_hi);
1583 break;
1585 case MC_SERVICEDEF:
1586 mutex_enter(zs->zs_excl_hi);
1587 za->za_flags &= ~ZAS_SERVICEIMM;
1588 mutex_exit(zs->zs_excl_hi);
1589 break;
1591 freemsg(mp);
1592 mutex_exit(zs->zs_excl);
1594 break;
1596 default:
1598 * "No, I don't want a subscription to Chain Store Age,
1599 * thank you anyway."
1601 freemsg(mp);
1602 break;
1607 * zs read service procedure
1609 static void
1610 zsa_rsrv(queue_t *q)
1612 struct asyncline *za;
1613 struct zscom *zs;
1615 if (((za = (struct asyncline *)q->q_ptr) != NULL) &&
1616 (za->za_ttycommon.t_cflag & CRTSXOFF)) {
1617 zs = za->za_common;
1618 mutex_enter(zs->zs_excl_hi);
1619 ZSSETSOFT(zs);
1620 mutex_exit(zs->zs_excl_hi);
1625 * Transmitter interrupt service routine.
1626 * If there's more data to transmit in the current pseudo-DMA block,
1627 * and the transmitter is ready, send the next character if output
1628 * is not stopped or draining.
1629 * Otherwise, queue up a soft interrupt.
1631 static void
1632 zsa_txint(struct zscom *zs)
1634 register struct asyncline *za = (struct asyncline *)&zs->zs_priv_str;
1635 register uchar_t *wr_cur;
1636 register uchar_t s0;
1638 s0 = SCC_READ0();
1640 if ((wr_cur = zs->zs_wr_cur) != NULL) {
1641 if (wr_cur < zs->zs_wr_lim) {
1642 if ((za->za_ttycommon.t_cflag & CRTSCTS) &&
1643 !(s0 & ZSRR0_CTS)) {
1644 SCC_WRITE0(ZSWR0_RESET_TXINT);
1645 za->za_rcv_flags_mask |= DO_RETRANSMIT;
1646 return;
1648 SCC_WRITEDATA(*wr_cur++);
1649 #ifdef ZSA_DEBUG
1650 za->za_wr++;
1651 #endif
1652 zs->zs_wr_cur = wr_cur;
1653 zs->zs_flags |= ZS_PROGRESS;
1654 return;
1655 } else {
1656 zs->zs_wr_cur = NULL;
1657 zs->zs_wr_lim = NULL;
1659 * Use the rcv_flags_mask as it is set and
1660 * test while holding the zs_excl_hi mutex
1662 za->za_rcv_flags_mask |= DO_TRANSMIT;
1663 SCC_WRITE0(ZSWR0_RESET_TXINT);
1664 ZSSETSOFT(zs);
1665 return;
1669 if (za->za_flowc != '\0' && (!(za->za_flags & ZAS_DRAINING))) {
1670 if ((za->za_ttycommon.t_cflag & CRTSCTS) &&
1671 !(s0 & ZSRR0_CTS)) {
1672 SCC_WRITE0(ZSWR0_RESET_TXINT);
1673 return;
1675 SCC_WRITEDATA(za->za_flowc);
1676 za->za_flowc = '\0';
1677 return;
1679 SCC_WRITE0(ZSWR0_RESET_TXINT);
1681 * Set DO_TRANSMIT bit so that the soft interrupt can
1682 * test it and unset the ZAS_BUSY in za_flags while holding
1683 * the mutex zs_excl and zs_excl_hi
1685 za->za_rcv_flags_mask |= DO_TRANSMIT;
1686 ZSSETSOFT(zs);
1690 * External/Status interrupt.
1692 static void
1693 zsa_xsint(struct zscom *zs)
1695 register struct asyncline *za = (struct asyncline *)&zs->zs_priv_str;
1696 register uchar_t s0, x0;
1698 s0 = SCC_READ0();
1699 ZSA_R0_LOG(s0);
1700 x0 = s0 ^ za->za_rr0;
1701 za->za_rr0 = s0;
1702 SCC_WRITE0(ZSWR0_RESET_STATUS);
1705 * PPS (Pulse Per Second) support.
1707 if (za->za_pps && (x0 & ZSRR0_CD) && (s0 & ZSRR0_CD)) {
1709 * This code captures a timestamp at the designated
1710 * transition of the PPS signal (CD asserted). The
1711 * code provides a pointer to the timestamp, as well
1712 * as the hardware counter value at the capture.
1714 * Note: the kernel has nano based time values while
1715 * NTP requires micro based, an in-line fast algorithm
1716 * to convert nsec to usec is used here -- see hrt2ts()
1717 * in kernel/os/timers.c for a full description.
1719 struct timeval *tvp = &ppsclockev.tv;
1720 timespec_t ts;
1721 int nsec, usec;
1723 LED_OFF;
1724 gethrestime(&ts);
1725 LED_ON;
1726 nsec = ts.tv_nsec;
1727 usec = nsec + (nsec >> 2);
1728 usec = nsec + (usec >> 1);
1729 usec = nsec + (usec >> 2);
1730 usec = nsec + (usec >> 4);
1731 usec = nsec - (usec >> 3);
1732 usec = nsec + (usec >> 2);
1733 usec = nsec + (usec >> 3);
1734 usec = nsec + (usec >> 4);
1735 usec = nsec + (usec >> 1);
1736 usec = nsec + (usec >> 6);
1737 tvp->tv_usec = usec >> 10;
1738 tvp->tv_sec = ts.tv_sec;
1740 ++ppsclockev.serial;
1743 * Because the kernel keeps a high-resolution time, pass the
1744 * current highres timestamp in tvp and zero in usec.
1746 ddi_hardpps(tvp, 0);
1749 ZSA_KICK_RCV;
1751 if ((x0 & ZSRR0_BREAK) && (s0 & ZSRR0_BREAK) == 0) {
1752 #ifdef SLAVIO_BUG
1754 * ZSRR0_BREAK turned off. This means that the break sequence
1755 * has completed (i.e., the stop bit finally arrived).
1757 if ((s0 & ZSRR0_RX_READY) == 0) {
1759 * SLAVIO will generate a separate STATUS change
1760 * interrupt when the break sequence completes.
1761 * SCC will combine both, taking the higher priority
1762 * one, the receive. Should still see the ext/stat.
1763 * bit in REG3 on SCC. If no ext/stat, it must be
1764 * a SLAVIO.
1766 za->za_breakoff = 1;
1767 } else {
1769 * The NUL character in the receiver is part of the
1770 * break sequence; it is discarded.
1772 (void) SCC_READDATA(); /* swallow null */
1774 #else /* SLAVIO_BUG */
1776 * ZSRR0_BREAK turned off. This means that the break sequence
1777 * has completed (i.e., the stop bit finally arrived). The NUL
1778 * character in the receiver is part of the break sequence;
1779 * it is discarded.
1781 (void) SCC_READDATA(); /* swallow null */
1782 #endif /* SLAVIO_BUG */
1783 SCC_WRITE0(ZSWR0_RESET_ERRORS);
1786 * Note: this will cause an abort if a break occurs on
1787 * the "keyboard device", regardless of whether the
1788 * "keyboard device" is a real keyboard or just a
1789 * terminal on a serial line. This permits you to
1790 * abort a workstation by unplugging the keyboard,
1791 * even if the normal abort key sequence isn't working.
1793 if ((za->za_dev == kbddev) ||
1794 ((za->za_dev == rconsdev) || (za->za_dev == stdindev)) &&
1795 (abort_enable != KIOCABORTALTERNATE)) {
1796 abort_sequence_enter(NULL);
1798 * We just broke into the monitor or debugger,
1799 * ignore the break in this case so whatever
1800 * random program that was running doesn't get
1801 * a SIGINT.
1803 return;
1805 za->za_break = 1;
1809 * If hardware flow control is enabled, (re)start output
1810 * when CTS is reasserted.
1812 if ((za->za_ttycommon.t_cflag & CRTSCTS) &&
1813 (x0 & ZSRR0_CTS) && (s0 & ZSRR0_CTS) &&
1814 (za->za_rcv_flags_mask & DO_RETRANSMIT))
1815 za->za_rcv_flags_mask |= DO_TRANSMIT;
1817 za->za_ext = 1;
1818 ZSSETSOFT(zs);
1822 * Receive Interrupt
1824 static void
1825 zsa_rxint(struct zscom *zs)
1827 register struct asyncline *za = (struct asyncline *)&zs->zs_priv_str;
1828 register uchar_t c;
1829 register uchar_t *rd_cur = zs->zs_rd_cur;
1830 register uchar_t *rd_lim = zs->zs_rd_lim;
1831 register mblk_t *bp;
1832 register uint_t fm = za->za_rcv_flags_mask;
1835 #ifdef ZSA_DEBUG
1836 za->za_rd++;
1837 #endif
1838 c = (fm >> 16) & (SCC_READDATA());
1841 * Check for character break sequence
1843 if ((abort_enable == KIOCABORTALTERNATE) && (za->za_dev == rconsdev)) {
1844 if (abort_charseq_recognize(c))
1845 abort_sequence_enter(NULL);
1848 if (!rd_cur) {
1849 #ifdef SLAVIO_BUG
1851 * SLAVIO generates FE for the start of break and
1852 * during break when parity is set. End of break is
1853 * detected when the first character is received.
1854 * This character is always garbage and is thrown away.
1856 if (za->za_slav_break) {
1857 za->za_slav_break = 0;
1858 za->za_rr0 |= ZSRR0_BREAK;
1859 zsa_xsint(zs);
1860 return;
1862 #endif /* SLAVIO_BUG */
1864 if (c == 0 && (za->za_rr0 & ZSRR0_BREAK)) {
1866 * A break sequence was under way, and a NUL character
1867 * was received. Discard the NUL character, as it is
1868 * part of the break sequence; if ZSRR0_BREAK turned
1869 * off, indicating that the break sequence has com-
1870 * pleted, call "zsa_xsint" to properly handle the
1871 * error. It would appear that External/Status
1872 * interrupts get lost occasionally, so this ensures
1873 * that one is delivered.
1875 c = SCC_READ0();
1876 if (!(c & ZSRR0_BREAK))
1877 zsa_xsint(zs);
1878 return;
1881 #ifdef SLAVIO_BUG
1882 if (c == 0 && za->za_breakoff) {
1884 * A break sequence completed, but SLAVIO generates
1885 * the NULL character interrupt late, so we throw the
1886 * NULL away now.
1888 return;
1892 * make sure it gets cleared.
1894 za->za_breakoff = 0;
1895 #endif /* SLAVIO_BUG */
1897 ZSA_KICK_RCV; /* We can have M_BREAK msg */
1898 ZSA_ALLOCB(bp);
1899 if (!bp) {
1900 za->za_sw_overrun++;
1901 ZSSETSOFT(zs);
1902 return;
1904 za->za_rcvblk = bp;
1905 zs->zs_rd_cur = rd_cur = bp->b_wptr;
1906 zs->zs_rd_lim = rd_lim = bp->b_datap->db_lim;
1907 if (za->za_kick_rcv_id == 0)
1908 ZSSETSOFT(zs);
1910 if (c == 0377 && (fm & DO_ESC)) {
1911 if (rd_lim < rd_cur + 2) {
1912 ZSA_ALLOCB(bp);
1913 ZSA_KICK_RCV;
1914 if (!bp) {
1915 za->za_sw_overrun++;
1916 return;
1918 za->za_rcvblk = bp;
1919 zs->zs_rd_cur = rd_cur = bp->b_wptr;
1920 zs->zs_rd_lim = rd_lim = bp->b_datap->db_lim;
1922 *rd_cur++ = c;
1926 *rd_cur++ = c;
1927 zs->zs_rd_cur = rd_cur;
1929 if (rd_cur == rd_lim) {
1930 ZSA_KICK_RCV;
1931 } else if ((fm & DO_STOPC) && (c == (fm & 0xff))) {
1932 za->za_do_kick_rcv_in_softint = 1;
1933 ZSSETSOFT(zs);
1936 if ((za->za_flags & ZAS_SERVICEIMM) || g_nocluster) {
1938 * Send the data up immediately
1940 ZSA_KICK_RCV;
1945 * Special receive condition interrupt handler.
1947 static void
1948 zsa_srint(struct zscom *zs)
1950 register struct asyncline *za = (struct asyncline *)&zs->zs_priv_str;
1951 register short s1;
1952 register uchar_t c;
1953 register uchar_t c1;
1954 register mblk_t *bp = za->za_rcvblk;
1955 register uchar_t *rd_cur = zs->zs_rd_cur;
1957 SCC_READ(1, s1);
1958 if (s1 & (ZSRR1_FE | ZSRR1_PE | ZSRR1_DO)) {
1959 c = SCC_READDATA(); /* swallow bad character */
1961 #ifdef SLAVIO_BUG
1963 * SLAVIO does not handle breaks properly when parity is enabled.
1965 * In general, if a null character is received when a framing
1966 * error occurs then it is a break condition and not a real
1967 * framing error. The null character must be limited to the
1968 * number of bits including the parity bit. For example, a 6
1969 * bit character with parity would be null if the lower 7 bits
1970 * read from the receive fifo were 0. (The higher order bits are
1971 * padded with 1 and/or the stop bits.) The only exception to this
1972 * general rule would be an 8 bit null character with parity being
1973 * a 1 in the parity bit and a framing error. This exception
1974 * can be determined by examining the parity error bit in RREG 1.
1976 * A null character, even parity, 8 bits, no parity error,
1977 * (0 0000 0000) with framing error is a break condition.
1979 * A null character, even parity, 8 bits, parity error,
1980 * (1 0000 0000) with framing error is a framing error.
1982 * A null character, odd parity, 8 bits, parity error
1983 * (0 0000 0000) with framing error is a break condition.
1985 * A null character, odd parity, 8 bits, no parity error,
1986 * (1 0000 0000) with framing error is a framing error.
1988 if (za->za_ttycommon.t_cflag & PARENB) {
1989 switch (za->za_ttycommon.t_cflag & CSIZE) {
1991 case CS5:
1992 c1 = c & 0x3f;
1993 break;
1995 case CS6:
1996 c1 = c & 0x7f;
1997 break;
1999 case CS7:
2000 c1 = c & 0xff;
2001 break;
2003 case CS8:
2004 if ((za->za_ttycommon.t_cflag & PARODD) &&
2005 !(s1 & ZSRR1_PE))
2006 c1 = 0xff;
2007 else if (!(za->za_ttycommon.t_cflag & PARODD) &&
2008 (s1 & ZSRR1_PE))
2009 c1 = 0xff;
2010 else
2011 c1 = c;
2012 break;
2016 * We fake start of break condition.
2018 if ((s1 & ZSRR1_FE) && c1 == 0) {
2019 za->za_slav_break = 1;
2020 return;
2023 #endif /* SLAVIO_BUG */
2025 if (s1 & ZSRR1_PE) {
2028 * Mark the parity error so zsa_process will
2029 * notice it and send it up in an M_BREAK
2030 * message; ldterm will do the actual parity error
2031 * processing
2034 if (bp && zs->zs_rd_cur) { /* M_DATA msg */
2035 ZSA_KICK_RCV;
2036 bp = NULL;
2038 if (!bp)
2039 ZSA_ALLOCB(bp);
2040 if (!bp) {
2041 za->za_sw_overrun++;
2042 ZSSETSOFT(zs);
2043 } else {
2044 za->za_rcvblk = bp;
2045 zs->zs_rd_cur = rd_cur = bp->b_wptr;
2046 zs->zs_rd_lim = bp->b_datap->db_lim;
2047 *rd_cur++ = c;
2048 zs->zs_rd_cur = rd_cur;
2049 bp->b_datap->db_type = M_BREAK;
2050 if (bp->b_datap->db_lim <= rd_cur)
2051 ZSA_KICK_RCV;
2052 za->za_do_kick_rcv_in_softint = 1;
2053 ZSSETSOFT(zs);
2057 SCC_WRITE0(ZSWR0_RESET_ERRORS);
2058 if (s1 & ZSRR1_DO) {
2059 za->za_hw_overrun++;
2060 ZSSETSOFT(zs);
2065 * Process software interrupts (or poll)
2066 * Crucial points:
2067 * 3. BUG - breaks are handled "out-of-band" - their relative position
2068 * among input events is lost, as well as multiple breaks together.
2069 * This is probably not a problem in practice.
2071 static int
2072 zsa_softint(struct zscom *zs)
2074 register struct asyncline *za = (struct asyncline *)&zs->zs_priv_str;
2075 register uchar_t r0;
2076 register uchar_t za_kick_active;
2077 register int m_error;
2078 register int allocbcount = 0;
2079 register int do_ttycommon_qfull = 0;
2080 boolean_t hangup = B_FALSE, unhangup = B_FALSE;
2081 boolean_t m_break = B_FALSE, wakeup = B_FALSE;
2082 register queue_t *q;
2083 register mblk_t *bp;
2084 register mblk_t *head = NULL, *tail = NULL;
2086 mutex_enter(zs->zs_excl);
2087 if (zs->zs_suspended || (zs->zs_flags & ZS_CLOSED)) {
2088 mutex_exit(zs->zs_excl);
2089 return (0);
2091 q = za->za_ttycommon.t_readq;
2092 if (za->za_flags & ZAS_WOPEN && !q) {
2093 if (za->za_ext) {
2094 mutex_enter(zs->zs_excl_hi);
2095 r0 = SCC_READ0();
2096 za->za_ext = 0;
2097 mutex_exit(zs->zs_excl_hi);
2099 * carrier up?
2101 if ((r0 & ZSRR0_CD) ||
2102 (za->za_ttycommon.t_flags & TS_SOFTCAR)) {
2104 * carrier present
2106 if ((za->za_flags & ZAS_CARR_ON) == 0) {
2107 za->za_flags |= ZAS_CARR_ON;
2108 mutex_exit(zs->zs_excl);
2109 cv_broadcast(&zs->zs_flags_cv);
2110 return (0);
2114 mutex_exit(zs->zs_excl);
2115 return (0);
2117 q = za->za_ttycommon.t_readq;
2118 if (!q) {
2119 mutex_exit(zs->zs_excl);
2120 return (0);
2123 m_error = za->za_m_error;
2124 za->za_m_error = 0;
2126 if (za->za_do_kick_rcv_in_softint) {
2127 mutex_enter(zs->zs_excl_hi);
2128 ZSA_KICK_RCV;
2129 za->za_do_kick_rcv_in_softint = 0;
2130 mutex_exit(zs->zs_excl_hi);
2133 za_kick_active = za->za_kick_active;
2135 while (!za_kick_active) {
2136 ZSA_SEEQ(bp);
2137 if (!bp)
2138 break;
2140 allocbcount++;
2142 if (bp->b_datap->db_type <= QPCTL) {
2143 if (!(canputnext(q))) {
2144 if (za->za_grace_flow_control >=
2145 zsa_grace_flow_control) {
2146 if (za->za_ttycommon.t_cflag &
2147 CRTSXOFF) {
2148 allocbcount--;
2149 break;
2151 ZSA_GETQ(bp);
2152 freemsg(bp);
2153 do_ttycommon_qfull = 1;
2154 continue;
2155 } else
2156 za->za_grace_flow_control++;
2157 } else
2158 za->za_grace_flow_control = 0;
2160 ZSA_GETQ(bp);
2161 if (!head) {
2162 head = bp;
2163 } else {
2164 if (!tail)
2165 tail = head;
2166 tail->b_next = bp;
2167 tail = bp;
2171 if (allocbcount)
2172 ZSA_GETBLOCK(zs, allocbcount);
2174 if (za->za_ext) {
2175 mutex_enter(zs->zs_excl_hi);
2176 r0 = SCC_READ0();
2177 za->za_ext = 0;
2179 * carrier up?
2181 if ((r0 & ZSRR0_CD) ||
2182 (za->za_ttycommon.t_flags & TS_SOFTCAR)) {
2184 * carrier present
2186 if ((za->za_flags & ZAS_CARR_ON) == 0) {
2187 za->za_flags |= ZAS_CARR_ON;
2188 unhangup = B_TRUE;
2189 wakeup = B_TRUE;
2191 } else {
2192 if ((za->za_flags & ZAS_CARR_ON) &&
2193 !(za->za_ttycommon.t_cflag & CLOCAL)) {
2195 * Carrier went away.
2196 * Drop DTR, abort any output in progress,
2197 * indicate that output is not stopped, and
2198 * send a hangup notification upstream.
2200 (void) zsmctl(zs, ZSWR5_DTR, DMBIC);
2201 if ((za->za_flags & ZAS_BUSY) &&
2202 (zs->zs_wr_cur != NULL)) {
2203 zs->zs_wr_cur = NULL;
2204 zs->zs_wr_lim = NULL;
2206 hangup = B_TRUE;
2207 wakeup = B_TRUE;
2208 za->za_flags &= ~(ZAS_STOPPED | ZAS_CARR_ON |
2209 ZAS_BUSY);
2210 za->za_rcv_flags_mask &= ~(DO_TRANSMIT |
2211 DO_RETRANSMIT);
2214 mutex_exit(zs->zs_excl_hi);
2215 if (hangup && (bp = za->za_xmitblk) != NULL) {
2216 za->za_xmitblk = NULL;
2217 freeb(bp);
2221 if (za->za_break != 0) {
2222 mutex_enter(zs->zs_excl_hi);
2223 r0 = SCC_READ0();
2224 mutex_exit(zs->zs_excl_hi);
2225 if ((r0 & ZSRR0_BREAK) == 0) {
2226 za->za_break = 0;
2227 m_break = B_TRUE;
2232 * If a transmission has finished, indicate that it's
2233 * finished, and start that line up again.
2236 mutex_enter(zs->zs_excl_hi);
2237 if (za->za_rcv_flags_mask & DO_TRANSMIT) {
2238 za->za_rcv_flags_mask &= ~DO_TRANSMIT;
2239 za->za_flags &= ~ZAS_BUSY;
2241 if ((za->za_ttycommon.t_cflag & CRTSCTS) &&
2242 (za->za_rcv_flags_mask & DO_RETRANSMIT) &&
2243 zs->zs_wr_cur)
2244 bp = NULL;
2245 else {
2246 za->za_rcv_flags_mask &= ~DO_RETRANSMIT;
2247 bp = za->za_xmitblk;
2248 za->za_xmitblk = 0;
2250 mutex_exit(zs->zs_excl_hi);
2251 if (bp)
2252 freemsg(bp);
2253 zsa_start(zs);
2254 /* if we didn't start anything, then notify waiters */
2255 if (!(za->za_flags & ZAS_BUSY))
2256 wakeup = B_TRUE;
2257 } else {
2258 mutex_exit(zs->zs_excl_hi);
2263 * A note about these overrun bits: all they do is *tell* someone
2264 * about an error- They do not track multiple errors. In fact,
2265 * you could consider them latched register bits if you like.
2266 * We are only interested in printing the error message once for
2267 * any cluster of overrun errrors.
2269 if ((!za->za_kick_rcv_id) && (zs->zs_rd_cur || za_kick_active)) {
2270 if (g_zsticks)
2271 za->za_kick_rcv_id = timeout(zsa_kick_rcv, zs,
2272 g_zsticks);
2273 else
2274 za->za_kick_rcv_id = timeout(zsa_kick_rcv, zs,
2275 zsticks[SPEED(za->za_ttycommon.t_cflag)]);
2276 za->za_kick_rcv_count = ZA_KICK_RCV_COUNT;
2278 za->za_soft_active = 1;
2279 mutex_exit(zs->zs_excl);
2281 if (!hangup && do_ttycommon_qfull) {
2282 ttycommon_qfull(&za->za_ttycommon, q);
2283 mutex_enter(zs->zs_excl);
2284 zsa_start(zs);
2285 mutex_exit(zs->zs_excl);
2288 if (za->za_hw_overrun > 10) {
2289 cmn_err(CE_NOTE, "zs%d: silo overflow\n", UNIT(za->za_dev));
2290 za->za_hw_overrun = 0;
2293 if (za->za_sw_overrun > 10) {
2294 cmn_err(CE_NOTE, "zs%d:ring buffer overflow\n",
2295 UNIT(za->za_dev));
2296 za->za_sw_overrun = 0;
2299 if (unhangup)
2300 (void) putnextctl(q, M_UNHANGUP);
2302 if (m_break)
2303 (void) putnextctl(q, M_BREAK);
2305 while (head) {
2306 if (!tail) {
2307 putnext(q, head);
2308 break;
2310 bp = head;
2311 head = head->b_next;
2312 bp->b_next = NULL;
2313 putnext(q, bp);
2316 if (hangup) {
2317 int flushflag;
2320 * If we're in the midst of close, then flush everything. Don't
2321 * leave stale ioctls lying about.
2323 flushflag = (zs->zs_flags & ZS_CLOSING) ? FLUSHALL : FLUSHDATA;
2324 flushq(za->za_ttycommon.t_writeq, flushflag);
2325 (void) putnextctl(q, M_HANGUP);
2328 if (m_error)
2329 (void) putnextctl1(q, M_ERROR, m_error);
2331 za->za_soft_active = 0;
2333 if (wakeup || (zs->zs_flags & ZS_CLOSED))
2334 cv_broadcast(&zs->zs_flags_cv);
2336 return (0);
2340 * Start output on a line, unless it's busy, frozen, or otherwise.
2342 static void
2343 zsa_start(struct zscom *zs)
2345 register struct asyncline *za = (struct asyncline *)&zs->zs_priv_str;
2346 register int cc;
2347 register queue_t *q;
2348 register mblk_t *bp;
2349 uchar_t *rptr, *wptr;
2352 * If the chip is busy (i.e., we're waiting for a break timeout
2353 * to expire, or for the current transmission to finish, or for
2354 * output to finish draining from chip), don't grab anything new.
2356 if ((za->za_flags & (ZAS_BREAK|ZAS_BUSY|ZAS_DRAINING)) ||
2357 zs->zs_suspended)
2358 return;
2360 if (za->za_ttycommon.t_cflag & CRTSCTS) {
2361 mutex_enter(zs->zs_excl_hi);
2362 if (za->za_rcv_flags_mask & DO_RETRANSMIT) {
2363 rptr = zs->zs_wr_cur;
2364 wptr = zs->zs_wr_lim;
2365 goto zsa_start_retransmit;
2368 mutex_exit(zs->zs_excl_hi);
2372 * If we have a flow-control character to transmit, do it now.
2374 if (za->za_flowc != '\0') {
2375 mutex_enter(zs->zs_excl_hi);
2376 if (za->za_ttycommon.t_cflag & CRTSCTS) {
2377 if ((SCC_READ0() & (ZSRR0_CTS|ZSRR0_TX_READY)) !=
2378 (ZSRR0_CTS|ZSRR0_TX_READY)) {
2379 mutex_exit(zs->zs_excl_hi);
2380 return;
2382 } else if (!(SCC_READ0() & ZSRR0_TX_READY)) {
2383 mutex_exit(zs->zs_excl_hi);
2384 return;
2387 ZSDELAY();
2388 SCC_WRITEDATA(za->za_flowc);
2389 za->za_flowc = '\0';
2390 mutex_exit(zs->zs_excl_hi);
2391 return;
2395 * If we're waiting for a delay timeout to expire, don't grab
2396 * anything new.
2398 if (za->za_flags & ZAS_DELAY)
2399 return;
2401 if ((q = za->za_ttycommon.t_writeq) == NULL)
2402 return; /* not attached to a stream */
2404 zsa_start_again:
2405 for (;;) {
2406 if ((bp = getq(q)) == NULL)
2407 return; /* no data to transmit */
2410 * We have a message block to work on.
2411 * Check whether it's a break, a delay, or an ioctl (the latter
2412 * occurs if the ioctl in question was waiting for the output
2413 * to drain). If it's one of those, process it immediately.
2415 switch (bp->b_datap->db_type) {
2417 case M_BREAK:
2419 * Set the break bit, and arrange for "zsa_restart"
2420 * to be called in 1/4 second; it will turn the
2421 * break bit off, and call "zsa_start" to grab
2422 * the next message.
2424 mutex_enter(zs->zs_excl_hi);
2425 SCC_BIS(5, ZSWR5_BREAK);
2426 mutex_exit(zs->zs_excl_hi);
2427 if (!za->za_zsa_restart_id) {
2428 za->za_zsa_restart_id =
2429 timeout(zsa_restart, zs, hz/4);
2431 za->za_flags |= ZAS_BREAK;
2432 freemsg(bp);
2433 return; /* wait for this to finish */
2435 case M_DELAY:
2437 * Arrange for "zsa_restart" to be called when the
2438 * delay expires; it will turn MTS_DELAY off,
2439 * and call "zsa_start" to grab the next message.
2441 if (! za->za_zsa_restart_id) {
2442 za->za_zsa_restart_id = timeout(zsa_restart,
2444 (int)(*(unsigned char *)bp->b_rptr + 6));
2446 za->za_flags |= ZAS_DELAY;
2447 freemsg(bp);
2448 return; /* wait for this to finish */
2450 case M_IOCTL:
2452 * This ioctl was waiting for the output ahead of
2453 * it to drain; obviously, it has. Do it, and
2454 * then grab the next message after it.
2456 zsa_ioctl(za, q, bp);
2457 continue;
2458 default: /* M_DATA */
2459 goto zsa_start_transmit;
2463 zsa_start_transmit:
2465 * We have data to transmit. If output is stopped, put
2466 * it back and try again later.
2468 if (za->za_flags & ZAS_STOPPED) {
2469 (void) putbq(q, bp);
2470 return;
2473 za->za_xmitblk = bp;
2474 rptr = bp->b_rptr;
2475 wptr = bp->b_wptr;
2476 cc = wptr - rptr;
2477 bp = bp->b_cont;
2478 if (bp != NULL) {
2479 za->za_xmitblk->b_cont = NULL;
2480 (void) putbq(q, bp); /* not done with this message yet */
2483 if (rptr >= wptr) {
2484 freeb(za->za_xmitblk);
2485 za->za_xmitblk = NULL;
2486 goto zsa_start_again;
2490 * In 5-bit mode, the high order bits are used
2491 * to indicate character sizes less than five,
2492 * so we need to explicitly mask before transmitting
2494 if ((za->za_ttycommon.t_cflag & CSIZE) == CS5) {
2495 register unsigned char *p = rptr;
2496 register int cnt = cc;
2498 while (cnt--)
2499 *p++ &= (unsigned char) 0x1f;
2503 * Set up this block for pseudo-DMA.
2506 mutex_enter(zs->zs_excl_hi);
2507 zs->zs_wr_cur = rptr;
2508 zs->zs_wr_lim = wptr;
2510 zsa_start_retransmit:
2511 za->za_rcv_flags_mask &= ~DO_TRANSMIT;
2512 if (za->za_ttycommon.t_cflag & CRTSCTS) {
2513 if ((SCC_READ0() & (ZSRR0_CTS|ZSRR0_TX_READY)) !=
2514 (ZSRR0_CTS|ZSRR0_TX_READY)) {
2515 za->za_rcv_flags_mask |= DO_RETRANSMIT;
2516 za->za_flags |= ZAS_BUSY;
2517 mutex_exit(zs->zs_excl_hi);
2518 return;
2520 za->za_rcv_flags_mask &= ~DO_RETRANSMIT;
2521 } else {
2522 if (!(SCC_READ0() & ZSRR0_TX_READY)) {
2523 za->za_flags |= ZAS_BUSY;
2524 mutex_exit(zs->zs_excl_hi);
2525 return;
2529 * If the transmitter is ready, shove the first
2530 * character out.
2532 ZSDELAY();
2533 SCC_WRITEDATA(*rptr++);
2534 #ifdef ZSA_DEBUG
2535 za->za_wr++;
2536 #endif
2537 zs->zs_wr_cur = rptr;
2538 za->za_flags |= ZAS_BUSY;
2539 zs->zs_flags |= ZS_PROGRESS;
2540 mutex_exit(zs->zs_excl_hi);
2544 * Restart output on a line after a delay or break timer expired.
2546 static void
2547 zsa_restart(void *arg)
2549 struct zscom *zs = arg;
2550 struct asyncline *za = (struct asyncline *)&zs->zs_priv_str;
2553 * If break timer expired, turn off the break bit.
2555 mutex_enter(zs->zs_excl);
2556 if (!za->za_zsa_restart_id) {
2557 mutex_exit(zs->zs_excl);
2558 return;
2560 za->za_zsa_restart_id = 0;
2561 if (za->za_flags & ZAS_BREAK) {
2562 mutex_enter(zs->zs_excl_hi);
2563 SCC_BIC(5, ZSWR5_BREAK);
2564 mutex_exit(zs->zs_excl_hi);
2566 za->za_flags &= ~(ZAS_DELAY|ZAS_BREAK);
2567 if (za->za_ttycommon.t_writeq != NULL)
2568 zsa_start(zs);
2569 mutex_exit(zs->zs_excl);
2570 cv_broadcast(&zs->zs_flags_cv);
2574 * See if the receiver has any data after zs_tick delay
2576 static void
2577 zsa_kick_rcv(void *arg)
2579 struct zscom *zs = arg;
2580 struct asyncline *za = (struct asyncline *)&zs->zs_priv_str;
2581 queue_t *q;
2582 int tmp;
2583 mblk_t *mp;
2584 uchar_t za_soft_active, za_kick_active;
2585 int allocbcount = 0;
2586 int do_ttycommon_qfull = 0;
2587 mblk_t *head = NULL, *tail = NULL;
2589 mutex_enter(zs->zs_excl);
2590 if (za->za_kick_rcv_id == 0 || (zs->zs_flags & ZS_CLOSED)) {
2591 mutex_exit(zs->zs_excl);
2592 return;
2594 za_soft_active = za->za_soft_active;
2595 za_kick_active = za->za_kick_active;
2596 q = za->za_ttycommon.t_readq;
2597 if (!q) {
2598 mutex_exit(zs->zs_excl);
2599 return;
2601 mutex_enter(zs->zs_excl_hi);
2602 if (zs->zs_rd_cur) {
2603 ZSA_KICK_RCV;
2604 za->za_kick_rcv_count = tmp = ZA_KICK_RCV_COUNT;
2605 } else
2606 tmp = --za->za_kick_rcv_count;
2607 if (tmp > 0 || za_soft_active || za_kick_active) {
2608 mutex_exit(zs->zs_excl_hi);
2609 if (g_zsticks)
2610 za->za_kick_rcv_id = timeout(zsa_kick_rcv,
2611 zs, g_zsticks);
2612 else
2613 za->za_kick_rcv_id = timeout(zsa_kick_rcv,
2614 zs, zsticks[SPEED(za->za_ttycommon.t_cflag)]);
2615 if (za_soft_active || za_kick_active) {
2616 mutex_exit(zs->zs_excl);
2617 return;
2619 } else {
2620 za->za_kick_rcv_id = 0;
2621 mutex_exit(zs->zs_excl_hi);
2625 for (;;) {
2626 ZSA_SEEQ(mp);
2627 if (!mp)
2628 break;
2630 allocbcount++;
2632 if (mp->b_datap->db_type <= QPCTL) {
2633 if (!(canputnext(q))) {
2634 if (za->za_grace_flow_control >=
2635 zsa_grace_flow_control) {
2636 if (za->za_ttycommon.t_cflag &
2637 CRTSXOFF) {
2638 allocbcount--;
2639 break;
2641 ZSA_GETQ(mp);
2642 freemsg(mp);
2643 do_ttycommon_qfull = 1;
2644 continue;
2645 } else
2646 za->za_grace_flow_control++;
2647 } else
2648 za->za_grace_flow_control = 0;
2650 ZSA_GETQ(mp);
2651 if (!head) {
2652 head = mp;
2653 } else {
2654 if (!tail)
2655 tail = head;
2656 tail->b_next = mp;
2657 tail = mp;
2661 if (allocbcount)
2662 ZSA_GETBLOCK(zs, allocbcount);
2664 za->za_kick_active = 1;
2665 mutex_exit(zs->zs_excl);
2667 if (do_ttycommon_qfull) {
2668 ttycommon_qfull(&za->za_ttycommon, q);
2669 mutex_enter(zs->zs_excl);
2670 zsa_start(zs);
2671 mutex_exit(zs->zs_excl);
2674 while (head) {
2675 if (!tail) {
2676 putnext(q, head);
2677 break;
2679 mp = head;
2680 head = head->b_next;
2681 mp->b_next = NULL;
2682 putnext(q, mp);
2685 za->za_kick_active = 0;
2687 if (zs->zs_flags & ZS_CLOSED)
2688 cv_broadcast(&zs->zs_flags_cv);
2692 * Retry an "ioctl", now that "bufcall" claims we may be able to allocate
2693 * the buffer we need.
2695 static void
2696 zsa_reioctl(void *arg)
2698 struct asyncline *za = arg;
2699 struct zscom *zs = za->za_common;
2700 queue_t *q;
2701 mblk_t *mp;
2704 * The bufcall is no longer pending.
2706 mutex_enter(zs->zs_excl);
2707 if (!za->za_wbufcid) {
2708 mutex_exit(zs->zs_excl);
2709 return;
2711 za->za_wbufcid = 0;
2712 if ((q = za->za_ttycommon.t_writeq) == NULL) {
2713 mutex_exit(zs->zs_excl);
2714 return;
2716 if ((mp = za->za_ttycommon.t_iocpending) != NULL) {
2718 * not pending any more
2720 za->za_ttycommon.t_iocpending = NULL;
2721 zsa_ioctl(za, q, mp);
2723 mutex_exit(zs->zs_excl);
2727 * Process an "ioctl" message sent down to us.
2728 * Note that we don't need to get any locks until we are ready to access
2729 * the hardware. Nothing we access until then is going to be altered
2730 * outside of the STREAMS framework, so we should be safe.
2732 static void
2733 zsa_ioctl(struct asyncline *za, queue_t *wq, mblk_t *mp)
2735 register struct zscom *zs = za->za_common;
2736 register struct iocblk *iocp;
2737 register unsigned datasize;
2738 int error;
2739 register mblk_t *tmp;
2741 if (za->za_ttycommon.t_iocpending != NULL) {
2743 * We were holding an "ioctl" response pending the
2744 * availability of an "mblk" to hold data to be passed up;
2745 * another "ioctl" came through, which means that "ioctl"
2746 * must have timed out or been aborted.
2748 freemsg(za->za_ttycommon.t_iocpending);
2749 za->za_ttycommon.t_iocpending = NULL;
2752 iocp = (struct iocblk *)mp->b_rptr;
2755 * The only way in which "ttycommon_ioctl" can fail is if the "ioctl"
2756 * requires a response containing data to be returned to the user,
2757 * and no mblk could be allocated for the data.
2758 * No such "ioctl" alters our state. Thus, we always go ahead and
2759 * do any state-changes the "ioctl" calls for. If we couldn't allocate
2760 * the data, "ttycommon_ioctl" has stashed the "ioctl" away safely, so
2761 * we just call "bufcall" to request that we be called back when we
2762 * stand a better chance of allocating the data.
2764 mutex_exit(zs->zs_excl);
2765 datasize = ttycommon_ioctl(&za->za_ttycommon, wq, mp, &error);
2766 mutex_enter(zs->zs_excl);
2767 if (za->za_ttycommon.t_flags & TS_SOFTCAR)
2768 zssoftCAR[zs->zs_unit] = 1;
2769 else
2770 zssoftCAR[zs->zs_unit] = 0;
2771 if (datasize != 0) {
2772 if (za->za_wbufcid)
2773 unbufcall(za->za_wbufcid);
2774 za->za_wbufcid = bufcall(datasize, BPRI_HI, zsa_reioctl, za);
2775 return;
2779 if (error == 0) {
2781 * "ttycommon_ioctl" did most of the work; we just use the
2782 * data it set up.
2784 switch (iocp->ioc_cmd) {
2786 case TCSETS:
2787 case TCSETSW:
2788 case TCSETSF:
2789 case TCSETA:
2790 case TCSETAW:
2791 case TCSETAF:
2792 mutex_enter(zs->zs_excl_hi);
2793 zsa_program(za, 1);
2794 zsa_set_za_rcv_flags_mask(za);
2795 mutex_exit(zs->zs_excl_hi);
2796 break;
2798 } else if (error < 0) {
2800 * "ttycommon_ioctl" didn't do anything; we process it here.
2802 error = 0;
2804 switch (iocp->ioc_cmd) {
2806 case TCSBRK:
2807 error = miocpullup(mp, sizeof (int));
2808 if (error != 0)
2809 break;
2811 if (*(int *)mp->b_cont->b_rptr == 0) {
2813 * The delay ensures that a 3 byte transmit
2814 * fifo is empty.
2816 mutex_exit(zs->zs_excl);
2817 delay(ztdelay(SPEED(za->za_ttycommon.t_cflag)));
2818 mutex_enter(zs->zs_excl);
2821 * Set the break bit, and arrange for
2822 * "zsa_restart" to be called in 1/4 second;
2823 * it will turn the break bit off, and call
2824 * "zsa_start" to grab the next message.
2826 mutex_enter(zs->zs_excl_hi);
2827 SCC_BIS(5, ZSWR5_BREAK);
2828 if (!za->za_zsa_restart_id) {
2829 mutex_exit(zs->zs_excl_hi);
2830 za->za_zsa_restart_id =
2831 timeout(zsa_restart, zs, hz / 4);
2832 mutex_enter(zs->zs_excl_hi);
2834 za->za_flags |= ZAS_BREAK;
2835 mutex_exit(zs->zs_excl_hi);
2837 break;
2839 case TIOCSBRK:
2840 mutex_enter(zs->zs_excl_hi);
2841 SCC_BIS(5, ZSWR5_BREAK);
2842 mutex_exit(zs->zs_excl_hi);
2843 mioc2ack(mp, NULL, 0, 0);
2844 break;
2846 case TIOCCBRK:
2847 mutex_enter(zs->zs_excl_hi);
2848 SCC_BIC(5, ZSWR5_BREAK);
2849 mutex_exit(zs->zs_excl_hi);
2850 mioc2ack(mp, NULL, 0, 0);
2851 break;
2853 case TIOCMSET:
2854 case TIOCMBIS:
2855 case TIOCMBIC: {
2856 int mlines;
2858 if (iocp->ioc_count == TRANSPARENT) {
2859 mcopyin(mp, NULL, sizeof (int), NULL);
2860 break;
2863 error = miocpullup(mp, sizeof (int));
2864 if (error != 0)
2865 break;
2867 mlines = *(int *)mp->b_cont->b_rptr;
2869 mutex_enter(zs->zs_excl_hi);
2870 switch (iocp->ioc_cmd) {
2871 case TIOCMSET:
2872 (void) zsmctl(zs, dmtozs(mlines), DMSET);
2873 break;
2874 case TIOCMBIS:
2875 (void) zsmctl(zs, dmtozs(mlines), DMBIS);
2876 break;
2877 case TIOCMBIC:
2878 (void) zsmctl(zs, dmtozs(mlines), DMBIC);
2879 break;
2881 mutex_exit(zs->zs_excl_hi);
2883 mioc2ack(mp, NULL, 0, 0);
2884 break;
2887 case TIOCMGET:
2888 tmp = allocb(sizeof (int), BPRI_MED);
2889 if (tmp == NULL) {
2890 error = EAGAIN;
2891 break;
2893 if (iocp->ioc_count != TRANSPARENT)
2894 mioc2ack(mp, tmp, sizeof (int), 0);
2895 else
2896 mcopyout(mp, NULL, sizeof (int), NULL, tmp);
2898 mutex_enter(zs->zs_excl_hi);
2899 *(int *)mp->b_cont->b_rptr =
2900 zstodm(zsmctl(zs, 0, DMGET));
2901 mutex_exit(zs->zs_excl_hi);
2903 * qreply done below
2905 break;
2907 default:
2909 * If we don't understand it, it's an error. NAK it.
2911 error = EINVAL;
2912 break;
2916 if (error != 0) {
2917 iocp->ioc_error = error;
2918 mp->b_datap->db_type = M_IOCNAK;
2921 ZSA_QREPLY(wq, mp);
2925 static int
2926 dmtozs(int bits)
2928 register int b = 0;
2930 if (bits & TIOCM_CAR)
2931 b |= ZSRR0_CD;
2932 if (bits & TIOCM_CTS)
2933 b |= ZSRR0_CTS;
2934 if (bits & TIOCM_RTS)
2935 b |= ZSWR5_RTS;
2936 if (bits & TIOCM_DTR)
2937 b |= ZSWR5_DTR;
2938 return (b);
2941 static int
2942 zstodm(int bits)
2944 register int b;
2946 b = 0;
2947 if (bits & ZSRR0_CD)
2948 b |= TIOCM_CAR;
2949 if (bits & ZSRR0_CTS)
2950 b |= TIOCM_CTS;
2951 if (bits & ZSWR5_RTS)
2952 b |= TIOCM_RTS;
2953 if (bits & ZSWR5_DTR)
2954 b |= TIOCM_DTR;
2955 return (b);
2959 * Assemble registers and flags necessary to program the port to our liking.
2960 * For async operation, most of this is based on the values of
2961 * the "c_iflag" and "c_cflag" fields supplied to us.
2963 static void
2964 zsa_program(struct asyncline *za, int setibaud)
2966 register struct zscom *zs = za->za_common;
2967 register struct zs_prog *zspp;
2968 register int wr3, wr4, wr5, wr15, speed, baudrate, flags = 0;
2970 if ((baudrate = SPEED(za->za_ttycommon.t_cflag)) == 0) {
2972 * Hang up line.
2974 (void) zsmctl(zs, ZS_OFF, DMSET);
2975 return;
2979 * set input speed same as output, as split speed not supported
2981 if (setibaud) {
2982 za->za_ttycommon.t_cflag &= ~(CIBAUD);
2983 if (baudrate > CBAUD) {
2984 za->za_ttycommon.t_cflag |= CIBAUDEXT;
2985 za->za_ttycommon.t_cflag |=
2986 (((baudrate - CBAUD - 1) << IBSHIFT) & CIBAUD);
2987 } else {
2988 za->za_ttycommon.t_cflag &= ~CIBAUDEXT;
2989 za->za_ttycommon.t_cflag |=
2990 ((baudrate << IBSHIFT) & CIBAUD);
2995 * Do not allow the console/keyboard device to have its receiver
2996 * disabled; doing that would mean you couldn't type an abort
2997 * sequence.
2999 if ((za->za_dev == rconsdev) || (za->za_dev == kbddev) ||
3000 (za->za_dev == stdindev) || (za->za_ttycommon.t_cflag & CREAD))
3001 wr3 = ZSWR3_RX_ENABLE;
3002 else
3003 wr3 = 0;
3004 wr4 = ZSWR4_X16_CLK;
3005 wr5 = (zs->zs_wreg[5] & (ZSWR5_RTS|ZSWR5_DTR)) | ZSWR5_TX_ENABLE;
3007 if (zsb134_weird && baudrate == B134) { /* what a joke! */
3009 * XXX - should B134 set all this crap in the compatibility
3010 * module, leaving this stuff fairly clean?
3012 flags |= ZSP_PARITY_SPECIAL;
3013 wr3 |= ZSWR3_RX_6;
3014 wr4 |= ZSWR4_PARITY_ENABLE | ZSWR4_PARITY_EVEN;
3015 wr4 |= ZSWR4_1_5_STOP;
3016 wr5 |= ZSWR5_TX_6;
3017 } else {
3019 switch (za->za_ttycommon.t_cflag & CSIZE) {
3021 case CS5:
3022 wr3 |= ZSWR3_RX_5;
3023 wr5 |= ZSWR5_TX_5;
3024 break;
3026 case CS6:
3027 wr3 |= ZSWR3_RX_6;
3028 wr5 |= ZSWR5_TX_6;
3029 break;
3031 case CS7:
3032 wr3 |= ZSWR3_RX_7;
3033 wr5 |= ZSWR5_TX_7;
3034 break;
3036 case CS8:
3037 wr3 |= ZSWR3_RX_8;
3038 wr5 |= ZSWR5_TX_8;
3039 break;
3042 if (za->za_ttycommon.t_cflag & PARENB) {
3044 * The PARITY_SPECIAL bit causes a special rx
3045 * interrupt on parity errors. Turn it on if
3046 * we're checking the parity of characters.
3048 if (za->za_ttycommon.t_iflag & INPCK)
3049 flags |= ZSP_PARITY_SPECIAL;
3050 wr4 |= ZSWR4_PARITY_ENABLE;
3051 if (!(za->za_ttycommon.t_cflag & PARODD))
3052 wr4 |= ZSWR4_PARITY_EVEN;
3054 wr4 |= (za->za_ttycommon.t_cflag & CSTOPB) ?
3055 ZSWR4_2_STOP : ZSWR4_1_STOP;
3058 #if 0
3060 * The AUTO_CD_CTS flag enables the hardware flow control feature of
3061 * the 8530, which allows the state of CTS and DCD to control the
3062 * enabling of the transmitter and receiver, respectively. The
3063 * receiver and transmitter still must have their enable bits set in
3064 * WR3 and WR5, respectively, for CTS and DCD to be monitored this way.
3065 * Hardware flow control can thus be implemented with no help from
3066 * software.
3068 if (za->za_ttycommon.t_cflag & CRTSCTS)
3069 wr3 |= ZSWR3_AUTO_CD_CTS;
3070 #endif
3071 if (za->za_ttycommon.t_cflag & CRTSCTS)
3072 wr15 = ZSR15_BREAK | ZSR15_TX_UNDER | ZSR15_CD | ZSR15_CTS;
3073 else
3074 wr15 = ZSR15_BREAK | ZSR15_TX_UNDER | ZSR15_CD;
3076 speed = zs->zs_wreg[12] + (zs->zs_wreg[13] << 8);
3079 * Here we assemble a set of changes to be passed to zs_program.
3080 * Note: Write Register 15 must be set to enable BREAK and UNDERrun
3081 * interrupts. It must also enable CD interrupts which, although
3082 * not processed by the hardware interrupt handler, will be processed
3083 * by zsa_process, indirectly resulting in a SIGHUP being delivered
3084 * to the controlling process if CD drops. CTS interrupts must NOT
3085 * be enabled. We don't use them at all, and they will hang IPC/IPX
3086 * systems at boot time if synchronous modems that supply transmit
3087 * clock are attached to any of their serial ports.
3089 if (((zs->zs_wreg[1] & ZSWR1_PARITY_SPECIAL) &&
3090 !(flags & ZSP_PARITY_SPECIAL)) ||
3091 (!(zs->zs_wreg[1] & ZSWR1_PARITY_SPECIAL) &&
3092 (flags & ZSP_PARITY_SPECIAL)) ||
3093 wr3 != zs->zs_wreg[3] || wr4 != zs->zs_wreg[4] ||
3094 wr5 != zs->zs_wreg[5] || wr15 != zs->zs_wreg[15] ||
3095 speed != zs_speeds[baudrate]) {
3097 za->za_flags |= ZAS_DRAINING;
3098 zspp = &zs_prog[zs->zs_unit];
3099 zspp->zs = zs;
3100 zspp->flags = (uchar_t)flags;
3101 zspp->wr4 = (uchar_t)wr4;
3102 zspp->wr11 = (uchar_t)(ZSWR11_TXCLK_BAUD | ZSWR11_RXCLK_BAUD);
3104 speed = zs_speeds[baudrate];
3105 zspp->wr12 = (uchar_t)(speed & 0xff);
3106 zspp->wr13 = (uchar_t)((speed >> 8) & 0xff);
3107 zspp->wr3 = (uchar_t)wr3;
3108 zspp->wr5 = (uchar_t)wr5;
3109 zspp->wr15 = (uchar_t)wr15;
3111 zs_program(zspp);
3112 za->za_flags &= ~ZAS_DRAINING;
3117 * Get the current speed of the console and turn it into something
3118 * UNIX knows about - used to preserve console speed when UNIX comes up.
3121 zsgetspeed(dev_t dev)
3123 register struct zscom *zs;
3124 register int uspeed, zspeed;
3125 register uchar_t rr;
3127 zs = &zscom[UNIT(dev)];
3128 SCC_READ(12, zspeed);
3129 SCC_READ(13, rr);
3130 zspeed |= rr << 8;
3131 for (uspeed = 0; uspeed < NSPEED; uspeed++)
3132 if (zs_speeds[uspeed] == zspeed)
3133 return (uspeed);
3135 * 9600 baud if we can't figure it out
3137 return (ISPEED);
3141 * callback routine when enough memory is available.
3143 static void
3144 zsa_callback(void *arg)
3146 struct zscom *zs = arg;
3147 struct asyncline *za = (struct asyncline *)&zs->zs_priv_str;
3148 int allocbcount = zsa_rstandby;
3150 mutex_enter(zs->zs_excl);
3151 if (za->za_bufcid) {
3152 za->za_bufcid = 0;
3153 ZSA_GETBLOCK(zs, allocbcount);
3155 mutex_exit(zs->zs_excl);
3159 * Set the receiver flags
3161 static void
3162 zsa_set_za_rcv_flags_mask(struct asyncline *za)
3164 register uint_t mask;
3166 za->za_rcv_flags_mask &= ~0xFF;
3167 switch (za->za_ttycommon.t_cflag & CSIZE) {
3168 case CS5:
3169 mask = 0x1f;
3170 break;
3171 case CS6:
3172 mask = 0x3f;
3173 break;
3174 case CS7:
3175 mask = 0x7f;
3176 break;
3177 default:
3178 mask = 0xff;
3181 za->za_rcv_flags_mask &= ~(0xFF << 16);
3182 za->za_rcv_flags_mask |= mask << 16;
3184 if ((za->za_ttycommon.t_iflag & PARMRK) &&
3185 !(za->za_ttycommon.t_iflag & (IGNPAR|ISTRIP))) {
3186 za->za_rcv_flags_mask |= DO_ESC;
3187 } else
3188 za->za_rcv_flags_mask &= ~DO_ESC;
3189 if (za->za_ttycommon.t_iflag & IXON) {
3190 za->za_rcv_flags_mask |= DO_STOPC;
3191 za->za_rcv_flags_mask &= ~0xFF;
3192 za->za_rcv_flags_mask |= za->za_ttycommon.t_stopc;
3193 } else
3194 za->za_rcv_flags_mask &= ~DO_STOPC;
3197 static int
3198 zsa_suspend(struct zscom *zs)
3200 struct asyncline *za;
3201 queue_t *q;
3202 mblk_t *bp = NULL;
3203 timeout_id_t restart_id, kick_rcv_id;
3204 struct zs_prog *zspp;
3206 za = (struct asyncline *)&zs->zs_priv_str;
3207 mutex_enter(zs->zs_excl);
3208 if (zs->zs_suspended) {
3209 mutex_exit(zs->zs_excl);
3210 return (DDI_SUCCESS);
3212 zs->zs_suspended = 1;
3215 * Turn off interrupts and get any bytes in receiver
3217 mutex_enter(zs->zs_excl_hi);
3218 SCC_BIC(1, ZSWR1_INIT);
3219 ZSA_KICK_RCV;
3220 restart_id = za->za_zsa_restart_id;
3221 za->za_zsa_restart_id = 0;
3222 kick_rcv_id = za->za_kick_rcv_id;
3223 za->za_kick_rcv_id = 0;
3224 mutex_exit(zs->zs_excl_hi);
3225 mutex_exit(zs->zs_excl);
3228 * Cancel any timeouts
3230 if (restart_id)
3231 (void) untimeout(restart_id);
3232 if (kick_rcv_id)
3233 (void) untimeout(kick_rcv_id);
3236 * Since we have turned off interrupts, zsa_txint will not be called
3237 * and no new chars will given to the chip. We just wait for the
3238 * current character(s) to drain.
3240 delay(ztdelay(za->za_ttycommon.t_cflag & CBAUD));
3243 * Return remains of partially sent message to queue
3245 mutex_enter(zs->zs_excl);
3246 if ((q = za->za_ttycommon.t_writeq) != NULL) {
3247 mutex_enter(zs->zs_excl_hi);
3248 if ((zs->zs_wr_cur) != NULL) {
3249 za->za_flags &= ~ZAS_BUSY;
3250 za->za_rcv_flags_mask &= ~DO_RETRANSMIT;
3251 bp = za->za_xmitblk;
3252 bp->b_rptr = zs->zs_wr_cur;
3253 zs->zs_wr_cur = NULL;
3254 zs->zs_wr_lim = NULL;
3255 za->za_xmitblk = NULL;
3257 mutex_exit(zs->zs_excl_hi);
3258 if (bp)
3259 (void) putbq(q, bp);
3263 * Stop any breaks in progress.
3265 mutex_enter(zs->zs_excl_hi);
3266 if (zs->zs_wreg[5] & ZSWR5_BREAK) {
3267 SCC_BIC(5, ZSWR5_BREAK);
3268 za->za_flags &= ~ZAS_BREAK;
3272 * Now get a copy of current registers setting.
3274 zspp = &zs_prog[zs->zs_unit];
3275 zspp->zs = zs;
3276 zspp->flags = 0;
3277 zspp->wr3 = zs->zs_wreg[3];
3278 zspp->wr4 = zs->zs_wreg[4];
3279 zspp->wr5 = zs->zs_wreg[5];
3280 zspp->wr11 = zs->zs_wreg[11];
3281 zspp->wr12 = zs->zs_wreg[12];
3282 zspp->wr13 = zs->zs_wreg[13];
3283 zspp->wr15 = zs->zs_wreg[15];
3284 mutex_exit(zs->zs_excl_hi);
3285 mutex_exit(zs->zs_excl);
3287 * We do this on the off chance that zsa_close is waiting on a timed
3288 * break to complete and nothing else.
3290 cv_broadcast(&zs->zs_flags_cv);
3291 return (DDI_SUCCESS);
3294 static int
3295 zsa_resume(struct zscom *zs)
3297 register struct asyncline *za;
3298 struct zs_prog *zspp;
3300 za = (struct asyncline *)&zs->zs_priv_str;
3301 mutex_enter(zs->zs_excl);
3302 if (!(zs->zs_suspended)) {
3303 mutex_exit(zs->zs_excl);
3304 return (DDI_SUCCESS);
3308 * Restore H/W state
3310 mutex_enter(zs->zs_excl_hi);
3311 zspp = &zs_prog[zs->zs_unit];
3312 zs_program(zspp);
3315 * Enable all interrupts for this chip and delay to let chip settle
3317 SCC_WRITE(9, ZSWR9_MASTER_IE | ZSWR9_VECTOR_INCL_STAT);
3318 DELAY(4000);
3321 * Restart receiving and transmitting
3323 zs->zs_suspended = 0;
3324 za->za_rcv_flags_mask |= DO_TRANSMIT;
3325 za->za_ext = 1;
3326 ZSSETSOFT(zs);
3327 mutex_exit(zs->zs_excl_hi);
3328 mutex_exit(zs->zs_excl);
3330 return (DDI_SUCCESS);
3333 #ifdef ZSA_DEBUG
3334 static void
3335 zsa_print_info(struct zscom *zs)
3337 register struct asyncline *za = (struct asyncline *)&zs->zs_priv_str;
3338 register queue_t *q = za->za_ttycommon.t_writeq;
3340 printf(" next q=%s\n", (RD(q))->q_next->q_qinfo->qi_minfo->mi_idname);
3341 printf("unit=%d\n", zs->zs_unit);
3342 printf("tflag:\n");
3343 if (za->za_ttycommon.t_flags & TS_SOFTCAR) printf(" t_fl:TS_SOFTCAR");
3344 if (za->za_ttycommon.t_flags & TS_XCLUDE) printf(" t_fl:TS_XCLUDE");
3345 if (za->za_ttycommon.t_iflag & IGNBRK) printf(" t_ifl:IGNBRK");
3346 if (za->za_ttycommon.t_iflag & BRKINT) printf(" t_ifl:BRKINT");
3347 if (za->za_ttycommon.t_iflag & IGNPAR) printf(" t_ifl:IGNPAR");
3348 if (za->za_ttycommon.t_iflag & PARMRK) printf(" t_ifl:PARMRK");
3349 if (za->za_ttycommon.t_iflag & INPCK) printf(" t_ifl:INPCK");
3350 if (za->za_ttycommon.t_iflag & ISTRIP) printf(" t_ifl:ISTRIP");
3351 if (za->za_ttycommon.t_iflag & INLCR) printf(" t_ifl:INLCR");
3352 if (za->za_ttycommon.t_iflag & IGNCR) printf(" t_ifl:IGNCR");
3353 if (za->za_ttycommon.t_iflag & ICRNL) printf(" t_ifl:ICRNL");
3354 if (za->za_ttycommon.t_iflag & IUCLC) printf(" t_ifl:IUCLC");
3355 if (za->za_ttycommon.t_iflag & IXON) printf(" t_ifl:IXON");
3356 if (za->za_ttycommon.t_iflag & IXOFF) printf(" t_ifl:IXOFF");
3358 printf("\n");
3361 if (za->za_ttycommon.t_cflag & CSIZE == CS5) printf(" t_cfl:CS5");
3362 if (za->za_ttycommon.t_cflag & CSIZE == CS6) printf(" t_cfl:CS6");
3363 if (za->za_ttycommon.t_cflag & CSIZE == CS7) printf(" t_cfl:CS7");
3364 if (za->za_ttycommon.t_cflag & CSIZE == CS8) printf(" t_cfl:CS8");
3365 if (za->za_ttycommon.t_cflag & CSTOPB) printf(" t_cfl:CSTOPB");
3366 if (za->za_ttycommon.t_cflag & CREAD) printf(" t_cfl:CREAD");
3367 if (za->za_ttycommon.t_cflag & PARENB) printf(" t_cfl:PARENB");
3368 if (za->za_ttycommon.t_cflag & PARODD) printf(" t_cfl:PARODD");
3369 if (za->za_ttycommon.t_cflag & HUPCL) printf(" t_cfl:HUPCL");
3370 if (za->za_ttycommon.t_cflag & CLOCAL) printf(" t_cfl:CLOCAL");
3371 printf(" t_stopc=%x", za->za_ttycommon.t_stopc);
3372 printf("\n");
3374 #endif
3377 * Check for abort character sequence
3379 static boolean_t
3380 abort_charseq_recognize(uchar_t ch)
3382 static int state = 0;
3383 #define CNTRL(c) ((c)&037)
3384 static char sequence[] = { '\r', '~', CNTRL('b') };
3386 if (ch == sequence[state]) {
3387 if (++state >= sizeof (sequence)) {
3388 state = 0;
3389 return (B_TRUE);
3391 } else {
3392 state = (ch == sequence[0]) ? 1 : 0;
3394 return (B_FALSE);