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]
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>
38 #include <sys/termios.h>
39 #include <sys/stropts.h>
40 #include <sys/stream.h>
41 #include <sys/strsun.h>
43 #include <sys/ptyvar.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>
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
;
71 /* XXX Use these to observe PPS latencies and jitter on a scope */
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
] = {
100 ZSPEED(269/2), /* XXX - This is sleazy */
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
] = {
137 #define ztdelay(nsp) (zsdelay[(nsp)]*(hz/100))
139 ushort_t zsdelay
[NSPEED
] = {
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
] = {
181 ushort_t zshiwat
[NSPEED
] = {
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, \
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]) \
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; \
256 if ((mp = za->za_rstandby[n]) != NULL) { \
257 za->za_rstandby[n] = NULL; \
261 if (za->za_ttycommon.t_cflag & CRTSXOFF) { \
263 if (zs->zs_wreg[5] & ZSWR5_RTS) \
264 SCC_BIC(5, ZSWR5_RTS); \
265 cmn_err(CE_WARN, "zs%d: message lost\n", \
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]) \
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); \
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; \
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", \
311 * Should be called holding the spin (zs_excl_hi) mutex.
313 #define ZSA_KICK_RCV \
315 register mblk_t *mp = za->za_rcvblk; \
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; \
328 #define ZSA_SEEQ(mp) \
330 if (za->za_rdone_rptr != za->za_rdone_wptr) { \
331 mp = za->za_rdone[za->za_rdone_rptr]; \
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; \
354 * Should be called holding only the adaptive (zs_excl) mutex.
358 register mblk_t *tmp; \
369 * Logging definitions
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) \
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];
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 \
407 for (p = &zsa_h_log[zs->zs_unit][ZSA_H_LOG_MAX]; \
408 p >= &zsa_h_log[zs->zs_unit][0]; /* null */) \
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
= {
451 static struct qinit async_rinit
= {
461 static struct qinit async_winit
= {
471 struct streamtab asynctab
= {
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
);
490 zsa_null(struct zscom
*zs
)
495 SCC_WRITE0(ZSWR0_RESET_TXINT
);
496 SCC_WRITE0(ZSWR0_RESET_STATUS
);
499 SCC_WRITE0(ZSWR0_RESET_ERRORS
);
504 zsa_null_int(struct zscom
*zs
)
509 struct zsops zsops_null_async
= {
519 struct zsops zsops_async
= {
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
);
545 zsc_info(dev_info_t
*dip
, ddi_info_cmd_t infocmd
, void *arg
,
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
);
556 case DDI_INFO_DEVT2DEVINFO
:
558 *result
= zs
->zs_dip
;
561 case DDI_INFO_DEVT2INSTANCE
:
562 *result
= (void *)(uintptr_t)(unit
/ 2);
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
];
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
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
);
634 minordata
[1] = (char)('a' + (zsminor
& 1));
636 (void) strcat(pathname
, minordata
);
638 stdioname
= prom_stdinpath();
639 if (strcmp(pathname
, stdioname
) == 0) {
640 zsa_inuse
|= (1 << zsminor
);
643 if (strcmp(default_pathname
, stdioname
) == 0) {
644 zsa_inuse
|= (1 << zsminor
);
648 stdioname
= prom_stdoutpath();
649 if (strcmp(pathname
, stdioname
) == 0) {
650 zsa_inuse
|= (1 << zsminor
);
653 if (strcmp(default_pathname
, stdioname
) == 0) {
654 zsa_inuse
|= (1 << zsminor
);
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 */
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
);
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
;
715 register int allocbcount
= zsa_rstandby
;
716 boolean_t set_zsoptinit
= B_FALSE
;
720 return (ENXIO
); /* unit not configured */
722 /* zscom is allocated by zsattach, and thus cannot be NULL here */
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
);
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
));
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
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
);
785 * Gack! Whine about it.
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
);
796 za
->za_ttycommon
.t_cflag
|= CBAUDEXT
;
797 za
->za_ttycommon
.t_cflag
|=
798 ((speed
- CBAUD
- 1) & CBAUD
);
800 za
->za_ttycommon
.t_cflag
&= ~CBAUDEXT
;
801 za
->za_ttycommon
.t_cflag
|= (speed
& CBAUD
);
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;
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
);
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
);
833 za
->za_flags
|= ZAS_OUT
;
834 (void) zsmctl(zs
, ZS_ON
, DMSET
);
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.
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
,
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
);
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
))
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
);
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
);
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
);
899 mutex_exit(zs
->zs_excl
);
900 mutex_exit(zs
->zs_ocexcl
);
905 zs_progress_check(void *arg
)
907 struct asyncline
*za
= arg
;
908 struct zscom
*zs
= za
->za_common
;
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
;
925 za
->za_xmitblk
= NULL
;
926 mutex_exit(zs
->zs_excl_hi
);
928 mutex_exit(zs
->zs_excl
);
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
937 flushq(za
->za_ttycommon
.t_writeq
, FLUSHALL
);
938 cv_broadcast(&zs
->zs_flags_cv
);
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
);
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.
958 zsa_close(queue_t
*q
, int flag
)
960 struct asyncline
*za
;
964 timeout_id_t za_zsa_restart_id
, za_kick_rcv_id
;
965 bufcall_id_t za_bufcid
, za_wbufcid
;
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
985 if (!(za
->za_flags
& ZAS_BREAK
) && (zs
->zs_wreg
[5] & ZSWR5_BREAK
))
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
))
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)
1032 if (zs
->zs_timer
!= 0) {
1033 (void) untimeout(zs
->zs_timer
);
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
);
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
);
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
);
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
);
1125 mutex_enter(zs
->zs_excl_hi
);
1126 zs
->zs_rd_cur
= NULL
;
1127 zs
->zs_rd_lim
= NULL
;
1129 za
->za_rcvblk
= NULL
;
1130 mutex_exit(zs
->zs_excl_hi
);
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
);
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
);
1155 bzero(za
, sizeof (struct asyncline
));
1157 mutex_exit(zs
->zs_excl
);
1160 * Cancel outstanding "bufcall" request.
1163 unbufcall(za_wbufcid
);
1165 unbufcall(za_bufcid
);
1168 * Cancel outstanding timeout.
1170 if (za_zsa_restart_id
)
1171 (void) untimeout(za_zsa_restart_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);
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.
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
;
1204 struct iocblk
*iocp
;
1206 za
= (struct asyncline
*)q
->q_ptr
;
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
) {
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
);
1234 (void) putbq(q
, bp
);
1236 mutex_exit(zs
->zs_excl
);
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
1251 mutex_exit(zs
->zs_excl
);
1255 mutex_enter(zs
->zs_excl
);
1256 iocp
= (struct iocblk
*)mp
->b_rptr
;
1258 switch (iocp
->ioc_cmd
) {
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
;
1275 *(int *)mp
->b_cont
->b_wptr
= 1;
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);
1288 error
= miocpullup(mp
, sizeof (int));
1290 mp
->b_datap
->db_type
= M_IOCNAK
;
1291 iocp
->ioc_error
= error
;
1296 za
->za_pps
= (*(int *)mp
->b_cont
->b_rptr
!= 0);
1297 mp
->b_datap
->db_type
= M_IOCACK
;
1304 * Get PPS event data.
1307 #ifdef _SYSCALL32_IMPL
1308 struct ppsclockev32 p32
;
1311 if (mp
->b_cont
!= NULL
) {
1312 freemsg(mp
->b_cont
);
1315 if (za
->za_pps
== NULL
) {
1316 mp
->b_datap
->db_type
= M_IOCNAK
;
1317 iocp
->ioc_error
= ENXIO
;
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
;
1327 iocp
->ioc_count
= sizeof (struct ppsclockev32
);
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
;
1343 bcopy(buf
, bp
->b_wptr
, iocp
->ioc_count
);
1344 bp
->b_wptr
+= iocp
->ioc_count
;
1345 mp
->b_datap
->db_type
= M_IOCACK
;
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.
1371 zsa_ioctl(za
, q
, mp
);
1374 mutex_exit(zs
->zs_excl
);
1380 mutex_enter(zs
->zs_excl
);
1381 resp
= (struct copyresp
*)mp
->b_rptr
;
1382 if (resp
->cp_rval
) {
1384 * Just free message on failure.
1387 mutex_exit(zs
->zs_excl
);
1390 switch (resp
->cp_cmd
) {
1393 mutex_enter(zs
->zs_excl_hi
);
1394 (void) zsmctl(zs
, dmtozs(*(int *)mp
->b_cont
->b_rptr
),
1396 mutex_exit(zs
->zs_excl_hi
);
1397 mioc2ack(mp
, NULL
, 0, 0);
1402 mutex_enter(zs
->zs_excl_hi
);
1403 (void) zsmctl(zs
, dmtozs(*(int *)mp
->b_cont
->b_rptr
),
1405 mutex_exit(zs
->zs_excl_hi
);
1406 mioc2ack(mp
, NULL
, 0, 0);
1411 mutex_enter(zs
->zs_excl_hi
);
1412 (void) zsmctl(zs
, dmtozs(*(int *)mp
->b_cont
->b_rptr
),
1414 mutex_exit(zs
->zs_excl_hi
);
1415 mioc2ack(mp
, NULL
, 0, 0);
1420 mioc2ack(mp
, NULL
, 0, 0);
1428 mutex_exit(zs
->zs_excl
);
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
);
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
)) {
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
))
1480 while ((SCC_READ0() &
1481 (ZSRR0_CD
| ZSRR0_RX_READY
)) ==
1486 (void) SCC_READDATA();
1489 mutex_exit(zs
->zs_excl_hi
);
1490 flushq(RD(q
), FLUSHDATA
);
1493 * give the read queues a crack at it
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.)
1505 mutex_exit(zs
->zs_excl
);
1511 mutex_enter(zs
->zs_excl
);
1513 * Queue the message up to be transmitted,
1514 * and poke the start routine.
1518 mutex_exit(zs
->zs_excl
);
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
);
1535 (void) putbq(q
, bp
);
1537 zsa_start(zs
); /* poke the start routine */
1539 mutex_exit(zs
->zs_excl
);
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
);
1556 (void) putbq(q
, bp
);
1558 zsa_start(zs
); /* poke the start routine */
1560 mutex_exit(zs
->zs_excl
);
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
;
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
) {
1580 mutex_enter(zs
->zs_excl_hi
);
1581 za
->za_flags
|= ZAS_SERVICEIMM
;
1582 mutex_exit(zs
->zs_excl_hi
);
1586 mutex_enter(zs
->zs_excl_hi
);
1587 za
->za_flags
&= ~ZAS_SERVICEIMM
;
1588 mutex_exit(zs
->zs_excl_hi
);
1592 mutex_exit(zs
->zs_excl
);
1598 * "No, I don't want a subscription to Chain Store Age,
1599 * thank you anyway."
1607 * zs read service procedure
1610 zsa_rsrv(queue_t
*q
)
1612 struct asyncline
*za
;
1615 if (((za
= (struct asyncline
*)q
->q_ptr
) != NULL
) &&
1616 (za
->za_ttycommon
.t_cflag
& CRTSXOFF
)) {
1618 mutex_enter(zs
->zs_excl_hi
);
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.
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
;
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
;
1648 SCC_WRITEDATA(*wr_cur
++);
1652 zs
->zs_wr_cur
= wr_cur
;
1653 zs
->zs_flags
|= ZS_PROGRESS
;
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
);
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
);
1675 SCC_WRITEDATA(za
->za_flowc
);
1676 za
->za_flowc
= '\0';
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
;
1690 * External/Status interrupt.
1693 zsa_xsint(struct zscom
*zs
)
1695 register struct asyncline
*za
= (struct asyncline
*)&zs
->zs_priv_str
;
1696 register uchar_t s0
, x0
;
1700 x0
= s0
^ za
->za_rr0
;
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
;
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);
1751 if ((x0
& ZSRR0_BREAK
) && (s0
& ZSRR0_BREAK
) == 0) {
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
1766 za
->za_breakoff
= 1;
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;
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
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
;
1825 zsa_rxint(struct zscom
*zs
)
1827 register struct asyncline
*za
= (struct asyncline
*)&zs
->zs_priv_str
;
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
;
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
);
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
;
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.
1876 if (!(c
& ZSRR0_BREAK
))
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
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 */
1900 za
->za_sw_overrun
++;
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)
1910 if (c
== 0377 && (fm
& DO_ESC
)) {
1911 if (rd_lim
< rd_cur
+ 2) {
1915 za
->za_sw_overrun
++;
1919 zs
->zs_rd_cur
= rd_cur
= bp
->b_wptr
;
1920 zs
->zs_rd_lim
= rd_lim
= bp
->b_datap
->db_lim
;
1927 zs
->zs_rd_cur
= rd_cur
;
1929 if (rd_cur
== rd_lim
) {
1931 } else if ((fm
& DO_STOPC
) && (c
== (fm
& 0xff))) {
1932 za
->za_do_kick_rcv_in_softint
= 1;
1936 if ((za
->za_flags
& ZAS_SERVICEIMM
) || g_nocluster
) {
1938 * Send the data up immediately
1945 * Special receive condition interrupt handler.
1948 zsa_srint(struct zscom
*zs
)
1950 register struct asyncline
*za
= (struct asyncline
*)&zs
->zs_priv_str
;
1953 register uchar_t c1
;
1954 register mblk_t
*bp
= za
->za_rcvblk
;
1955 register uchar_t
*rd_cur
= zs
->zs_rd_cur
;
1958 if (s1
& (ZSRR1_FE
| ZSRR1_PE
| ZSRR1_DO
)) {
1959 c
= SCC_READDATA(); /* swallow bad character */
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
) {
2004 if ((za
->za_ttycommon
.t_cflag
& PARODD
) &&
2007 else if (!(za
->za_ttycommon
.t_cflag
& PARODD
) &&
2016 * We fake start of break condition.
2018 if ((s1
& ZSRR1_FE
) && c1
== 0) {
2019 za
->za_slav_break
= 1;
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
2034 if (bp
&& zs
->zs_rd_cur
) { /* M_DATA msg */
2041 za
->za_sw_overrun
++;
2045 zs
->zs_rd_cur
= rd_cur
= bp
->b_wptr
;
2046 zs
->zs_rd_lim
= bp
->b_datap
->db_lim
;
2048 zs
->zs_rd_cur
= rd_cur
;
2049 bp
->b_datap
->db_type
= M_BREAK
;
2050 if (bp
->b_datap
->db_lim
<= rd_cur
)
2052 za
->za_do_kick_rcv_in_softint
= 1;
2057 SCC_WRITE0(ZSWR0_RESET_ERRORS
);
2058 if (s1
& ZSRR1_DO
) {
2059 za
->za_hw_overrun
++;
2065 * Process software interrupts (or poll)
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.
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
);
2091 q
= za
->za_ttycommon
.t_readq
;
2092 if (za
->za_flags
& ZAS_WOPEN
&& !q
) {
2094 mutex_enter(zs
->zs_excl_hi
);
2097 mutex_exit(zs
->zs_excl_hi
);
2101 if ((r0
& ZSRR0_CD
) ||
2102 (za
->za_ttycommon
.t_flags
& TS_SOFTCAR
)) {
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
);
2114 mutex_exit(zs
->zs_excl
);
2117 q
= za
->za_ttycommon
.t_readq
;
2119 mutex_exit(zs
->zs_excl
);
2123 m_error
= za
->za_m_error
;
2126 if (za
->za_do_kick_rcv_in_softint
) {
2127 mutex_enter(zs
->zs_excl_hi
);
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
) {
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
&
2153 do_ttycommon_qfull
= 1;
2156 za
->za_grace_flow_control
++;
2158 za
->za_grace_flow_control
= 0;
2172 ZSA_GETBLOCK(zs
, allocbcount
);
2175 mutex_enter(zs
->zs_excl_hi
);
2181 if ((r0
& ZSRR0_CD
) ||
2182 (za
->za_ttycommon
.t_flags
& TS_SOFTCAR
)) {
2186 if ((za
->za_flags
& ZAS_CARR_ON
) == 0) {
2187 za
->za_flags
|= ZAS_CARR_ON
;
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
;
2208 za
->za_flags
&= ~(ZAS_STOPPED
| ZAS_CARR_ON
|
2210 za
->za_rcv_flags_mask
&= ~(DO_TRANSMIT
|
2214 mutex_exit(zs
->zs_excl_hi
);
2215 if (hangup
&& (bp
= za
->za_xmitblk
) != NULL
) {
2216 za
->za_xmitblk
= NULL
;
2221 if (za
->za_break
!= 0) {
2222 mutex_enter(zs
->zs_excl_hi
);
2224 mutex_exit(zs
->zs_excl_hi
);
2225 if ((r0
& ZSRR0_BREAK
) == 0) {
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
) &&
2246 za
->za_rcv_flags_mask
&= ~DO_RETRANSMIT
;
2247 bp
= za
->za_xmitblk
;
2250 mutex_exit(zs
->zs_excl_hi
);
2254 /* if we didn't start anything, then notify waiters */
2255 if (!(za
->za_flags
& ZAS_BUSY
))
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
)) {
2271 za
->za_kick_rcv_id
= timeout(zsa_kick_rcv
, zs
,
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
);
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",
2296 za
->za_sw_overrun
= 0;
2300 (void) putnextctl(q
, M_UNHANGUP
);
2303 (void) putnextctl(q
, M_BREAK
);
2311 head
= head
->b_next
;
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
);
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
);
2340 * Start output on a line, unless it's busy, frozen, or otherwise.
2343 zsa_start(struct zscom
*zs
)
2345 register struct asyncline
*za
= (struct asyncline
*)&zs
->zs_priv_str
;
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
)) ||
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
);
2382 } else if (!(SCC_READ0() & ZSRR0_TX_READY
)) {
2383 mutex_exit(zs
->zs_excl_hi
);
2388 SCC_WRITEDATA(za
->za_flowc
);
2389 za
->za_flowc
= '\0';
2390 mutex_exit(zs
->zs_excl_hi
);
2395 * If we're waiting for a delay timeout to expire, don't grab
2398 if (za
->za_flags
& ZAS_DELAY
)
2401 if ((q
= za
->za_ttycommon
.t_writeq
) == NULL
)
2402 return; /* not attached to a stream */
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
) {
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
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
;
2433 return; /* wait for this to finish */
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
;
2448 return; /* wait for this to finish */
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
);
2458 default: /* M_DATA */
2459 goto 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
);
2473 za
->za_xmitblk
= bp
;
2479 za
->za_xmitblk
->b_cont
= NULL
;
2480 (void) putbq(q
, bp
); /* not done with this message yet */
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
;
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
);
2520 za
->za_rcv_flags_mask
&= ~DO_RETRANSMIT
;
2522 if (!(SCC_READ0() & ZSRR0_TX_READY
)) {
2523 za
->za_flags
|= ZAS_BUSY
;
2524 mutex_exit(zs
->zs_excl_hi
);
2529 * If the transmitter is ready, shove the first
2533 SCC_WRITEDATA(*rptr
++);
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.
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
);
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
)
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
2577 zsa_kick_rcv(void *arg
)
2579 struct zscom
*zs
= arg
;
2580 struct asyncline
*za
= (struct asyncline
*)&zs
->zs_priv_str
;
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
);
2594 za_soft_active
= za
->za_soft_active
;
2595 za_kick_active
= za
->za_kick_active
;
2596 q
= za
->za_ttycommon
.t_readq
;
2598 mutex_exit(zs
->zs_excl
);
2601 mutex_enter(zs
->zs_excl_hi
);
2602 if (zs
->zs_rd_cur
) {
2604 za
->za_kick_rcv_count
= tmp
= ZA_KICK_RCV_COUNT
;
2606 tmp
= --za
->za_kick_rcv_count
;
2607 if (tmp
> 0 || za_soft_active
|| za_kick_active
) {
2608 mutex_exit(zs
->zs_excl_hi
);
2610 za
->za_kick_rcv_id
= timeout(zsa_kick_rcv
,
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
);
2620 za
->za_kick_rcv_id
= 0;
2621 mutex_exit(zs
->zs_excl_hi
);
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
&
2643 do_ttycommon_qfull
= 1;
2646 za
->za_grace_flow_control
++;
2648 za
->za_grace_flow_control
= 0;
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
);
2671 mutex_exit(zs
->zs_excl
);
2680 head
= head
->b_next
;
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.
2696 zsa_reioctl(void *arg
)
2698 struct asyncline
*za
= arg
;
2699 struct zscom
*zs
= za
->za_common
;
2704 * The bufcall is no longer pending.
2706 mutex_enter(zs
->zs_excl
);
2707 if (!za
->za_wbufcid
) {
2708 mutex_exit(zs
->zs_excl
);
2712 if ((q
= za
->za_ttycommon
.t_writeq
) == NULL
) {
2713 mutex_exit(zs
->zs_excl
);
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.
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
;
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;
2770 zssoftCAR
[zs
->zs_unit
] = 0;
2771 if (datasize
!= 0) {
2773 unbufcall(za
->za_wbufcid
);
2774 za
->za_wbufcid
= bufcall(datasize
, BPRI_HI
, zsa_reioctl
, za
);
2781 * "ttycommon_ioctl" did most of the work; we just use the
2784 switch (iocp
->ioc_cmd
) {
2792 mutex_enter(zs
->zs_excl_hi
);
2794 zsa_set_za_rcv_flags_mask(za
);
2795 mutex_exit(zs
->zs_excl_hi
);
2798 } else if (error
< 0) {
2800 * "ttycommon_ioctl" didn't do anything; we process it here.
2804 switch (iocp
->ioc_cmd
) {
2807 error
= miocpullup(mp
, sizeof (int));
2811 if (*(int *)mp
->b_cont
->b_rptr
== 0) {
2813 * The delay ensures that a 3 byte transmit
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
);
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);
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);
2858 if (iocp
->ioc_count
== TRANSPARENT
) {
2859 mcopyin(mp
, NULL
, sizeof (int), NULL
);
2863 error
= miocpullup(mp
, sizeof (int));
2867 mlines
= *(int *)mp
->b_cont
->b_rptr
;
2869 mutex_enter(zs
->zs_excl_hi
);
2870 switch (iocp
->ioc_cmd
) {
2872 (void) zsmctl(zs
, dmtozs(mlines
), DMSET
);
2875 (void) zsmctl(zs
, dmtozs(mlines
), DMBIS
);
2878 (void) zsmctl(zs
, dmtozs(mlines
), DMBIC
);
2881 mutex_exit(zs
->zs_excl_hi
);
2883 mioc2ack(mp
, NULL
, 0, 0);
2888 tmp
= allocb(sizeof (int), BPRI_MED
);
2893 if (iocp
->ioc_count
!= TRANSPARENT
)
2894 mioc2ack(mp
, tmp
, sizeof (int), 0);
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
);
2909 * If we don't understand it, it's an error. NAK it.
2917 iocp
->ioc_error
= error
;
2918 mp
->b_datap
->db_type
= M_IOCNAK
;
2930 if (bits
& TIOCM_CAR
)
2932 if (bits
& TIOCM_CTS
)
2934 if (bits
& TIOCM_RTS
)
2936 if (bits
& TIOCM_DTR
)
2947 if (bits
& ZSRR0_CD
)
2949 if (bits
& ZSRR0_CTS
)
2951 if (bits
& ZSWR5_RTS
)
2953 if (bits
& ZSWR5_DTR
)
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.
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) {
2974 (void) zsmctl(zs
, ZS_OFF
, DMSET
);
2979 * set input speed same as output, as split speed not supported
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
);
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
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
;
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
;
3014 wr4
|= ZSWR4_PARITY_ENABLE
| ZSWR4_PARITY_EVEN
;
3015 wr4
|= ZSWR4_1_5_STOP
;
3019 switch (za
->za_ttycommon
.t_cflag
& CSIZE
) {
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
;
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
3068 if (za
->za_ttycommon
.t_cflag
& CRTSCTS
)
3069 wr3
|= ZSWR3_AUTO_CD_CTS
;
3071 if (za
->za_ttycommon
.t_cflag
& CRTSCTS
)
3072 wr15
= ZSR15_BREAK
| ZSR15_TX_UNDER
| ZSR15_CD
| ZSR15_CTS
;
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
];
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
;
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
);
3131 for (uspeed
= 0; uspeed
< NSPEED
; uspeed
++)
3132 if (zs_speeds
[uspeed
] == zspeed
)
3135 * 9600 baud if we can't figure it out
3141 * callback routine when enough memory is available.
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
) {
3153 ZSA_GETBLOCK(zs
, allocbcount
);
3155 mutex_exit(zs
->zs_excl
);
3159 * Set the receiver flags
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
) {
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
;
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
;
3194 za
->za_rcv_flags_mask
&= ~DO_STOPC
;
3198 zsa_suspend(struct zscom
*zs
)
3200 struct asyncline
*za
;
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
);
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
3231 (void) untimeout(restart_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
);
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
];
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
);
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
);
3310 mutex_enter(zs
->zs_excl_hi
);
3311 zspp
= &zs_prog
[zs
->zs_unit
];
3315 * Enable all interrupts for this chip and delay to let chip settle
3317 SCC_WRITE(9, ZSWR9_MASTER_IE
| ZSWR9_VECTOR_INCL_STAT
);
3321 * Restart receiving and transmitting
3323 zs
->zs_suspended
= 0;
3324 za
->za_rcv_flags_mask
|= DO_TRANSMIT
;
3327 mutex_exit(zs
->zs_excl_hi
);
3328 mutex_exit(zs
->zs_excl
);
3330 return (DDI_SUCCESS
);
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
);
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");
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
);
3377 * Check for abort character sequence
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
)) {
3392 state
= (ch
== sequence
[0]) ? 1 : 0;