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
] = {
103 ZSPEED(269/2), /* XXX - This is sleazy */
109 ZSPEED(1200), /* 9 */
110 ZSPEED(1800), /* 10 */
111 ZSPEED(2400), /* 11 */
112 ZSPEED(4800), /* 12 */
113 ZSPEED(9600), /* 13 */
114 ZSPEED(19200), /* 14 */
115 ZSPEED(38400), /* 15 */
116 ZSPEED(57680), /* 16 */
117 ZSPEED(76800) /* 17 */
120 ushort_t zsticks
[NSPEED
] = {
141 #define ztdelay(nsp) (zsdelay[(nsp)]*(hz/100))
143 ushort_t zsdelay
[NSPEED
] = {
157 ZDELAY(1200), /* 9 */
158 ZDELAY(1800), /* 10 */
159 ZDELAY(2400), /* 11 */
160 ZDELAY(4800), /* 12 */
161 ZDELAY(9600), /* 13 */
162 ZDELAY(19200), /* 14 */
163 ZDELAY(38400), /* 15 */
164 ZDELAY(57600), /* 16 */
165 ZDELAY(76800) /* 17 */
168 ushort_t zslowat
[NSPEED
] = {
189 ushort_t zshiwat
[NSPEED
] = {
210 #define SLAVIO_BUG /* this workaround required to fix bug 1102778 */
212 #define SPEED(cflag) \
213 ((cflag) & CBAUDEXT) ? \
214 (((cflag) & 0x1) + CBAUD + 1) : ((cflag) & CBAUD)
217 * Special macros to handle STREAMS operations.
218 * These are required to address memory leakage problems.
219 * WARNING : the macro do NOT call ZSSETSOFT
223 * Should be called holding only the adaptive (zs_excl) mutex.
225 #define ZSA_GETBLOCK(zs, allocbcount) \
227 register int n = zsa_rstandby; \
228 while (--n >= 0 && allocbcount > 0) { \
229 if (!za->za_rstandby[n]) { \
230 if ((za->za_rstandby[n] = allocb(ZSA_RCV_SIZE, \
231 BPRI_MED)) == NULL) { \
232 if (za->za_bufcid == 0) { \
233 za->za_bufcid = bufcall(ZSA_RCV_SIZE, \
242 if (za->za_ttycommon.t_cflag & CRTSXOFF) { \
243 mutex_enter(zs->zs_excl_hi); \
244 if (!(zs->zs_wreg[5] & ZSWR5_RTS)) { \
245 register int usedcnt = 0; \
246 for (n = 0; n < zsa_rstandby; n++) \
247 if (!za->za_rstandby[n]) \
249 if ((ushort_t)usedcnt <= \
250 zslowat[SPEED(za->za_ttycommon.t_cflag)]) \
251 SCC_BIS(5, ZSWR5_RTS); \
253 mutex_exit(zs->zs_excl_hi); \
258 * Should be called holding the spin (zs_excl_hi) mutex.
260 #define ZSA_ALLOCB(mp) \
262 register int n = zsa_rstandby; \
264 if ((mp = za->za_rstandby[n]) != NULL) { \
265 za->za_rstandby[n] = NULL; \
269 if (za->za_ttycommon.t_cflag & CRTSXOFF) { \
271 if (zs->zs_wreg[5] & ZSWR5_RTS) \
272 SCC_BIC(5, ZSWR5_RTS); \
273 cmn_err(CE_WARN, "zs%d: message lost\n", \
275 } else if (zs->zs_wreg[5] & ZSWR5_RTS) { \
276 register int usedcnt = 0; \
277 for (n = 0; n < zsa_rstandby; n++) \
278 if (!za->za_rstandby[n]) \
280 if ((ushort_t)usedcnt >= (zsa_rstandby - \
281 zshiwat[SPEED(za->za_ttycommon.t_cflag)])) \
282 SCC_BIC(5, ZSWR5_RTS); \
288 * Should get the spin (zs_excl_hi) mutex.
290 #define ZSA_QREPLY(q, mp) \
292 mutex_enter(zs->zs_excl_hi); \
295 mutex_exit(zs->zs_excl_hi); \
299 * Should be called holding the spin (zs_excl_hi) mutex.
301 #define ZSA_PUTQ(mp) \
303 register int wptr, rptr; \
304 wptr = za->za_rdone_wptr; \
305 rptr = za->za_rdone_rptr; \
306 za->za_rdone[wptr] = mp; \
307 if ((wptr)+1 == zsa_rdone) { \
308 za->za_rdone_wptr = wptr = 0; \
310 za->za_rdone_wptr = ++wptr; \
311 if (wptr == rptr) { \
312 SCC_BIC(1, ZSWR1_INIT); \
313 cmn_err(CE_WARN, "zs%d disabled: input buffer overflow", \
319 * Should be called holding the spin (zs_excl_hi) mutex.
321 #define ZSA_KICK_RCV \
323 register mblk_t *mp = za->za_rcvblk; \
325 if (zs->zs_rd_cur) { /* M_DATA */ \
326 mp->b_wptr = zs->zs_rd_cur; \
327 zs->zs_rd_cur = NULL; \
328 zs->zs_rd_lim = NULL; \
330 za->za_rcvblk = NULL; \
336 #define ZSA_SEEQ(mp) \
338 if (za->za_rdone_rptr != za->za_rdone_wptr) { \
339 mp = za->za_rdone[za->za_rdone_rptr]; \
347 * Should be called holding only the adaptive (zs_excl) mutex.
349 #define ZSA_GETQ(mp) \
351 if (za->za_rdone_rptr != za->za_rdone_wptr) { \
352 mp = za->za_rdone[za->za_rdone_rptr]; \
353 za->za_rdone[za->za_rdone_rptr++] = NULL; \
354 if (za->za_rdone_rptr == zsa_rdone) \
355 za->za_rdone_rptr = 0; \
362 * Should be called holding only the adaptive (zs_excl) mutex.
366 register mblk_t *tmp; \
377 * Logging definitions
384 extern char zs_h_log
[];
385 extern int zs_h_log_n
;
387 #define zsa_h_log_clear
389 #define zsa_h_log_add(c) \
391 if (zs_h_log_n >= ZS_H_LOG_MAX) \
393 zs_h_log[zs_h_log_n++] = 'A' + zs->zs_unit; \
394 zs_h_log[zs_h_log_n++] = c; \
395 zs_h_log[zs_h_log_n] = '\0'; \
398 #else /* ZS_DEBUG_ALL */
400 #define ZSA_H_LOG_MAX 0x4000
401 char zsa_h_log
[40][ZSA_H_LOG_MAX
+10];
404 #define zsa_h_log_add(c) \
406 if (zsa_h_log_n[zs->zs_unit] >= ZSA_H_LOG_MAX) \
407 zsa_h_log_n[zs->zs_unit] = 0; \
408 zsa_h_log[zs->zs_unit][zsa_h_log_n[zs->zs_unit]++] = c; \
409 zsa_h_log[zs->zs_unit][zsa_h_log_n[zs->zs_unit]] = '\0'; \
412 #define zsa_h_log_clear \
415 for (p = &zsa_h_log[zs->zs_unit][ZSA_H_LOG_MAX]; \
416 p >= &zsa_h_log[zs->zs_unit][0]; /* null */) \
418 zsa_h_log_n[zs->zs_unit] = 0; \
421 #endif /* ZS_DEBUG_ALL */
423 #define ZSA_R0_LOG(r0) \
425 if (r0 & ZSRR0_RX_READY) zsa_h_log_add('R'); \
426 if (r0 & ZSRR0_TIMER) zsa_h_log_add('Z'); \
427 if (r0 & ZSRR0_TX_READY) zsa_h_log_add('T'); \
428 if (r0 & ZSRR0_CD) zsa_h_log_add('D'); \
429 if (r0 & ZSRR0_SYNC) zsa_h_log_add('S'); \
430 if (r0 & ZSRR0_CTS) zsa_h_log_add('C'); \
431 if (r0 & ZSRR0_TXUNDER) zsa_h_log_add('U'); \
432 if (r0 & ZSRR0_BREAK) zsa_h_log_add('B'); \
435 #else /* ZSA_DEBUG */
437 #define zsa_h_log_clear
438 #define zsa_h_log_add(c)
439 #define ZSA_R0_LOG(r0)
441 #endif /* ZSA_DEBUG */
445 static int zsa_open(queue_t
*rq
, dev_t
*dev
, int flag
, int sflag
, cred_t
*cr
);
446 static int zsa_close(queue_t
*q
, int flag
);
447 static void zsa_wput(queue_t
*q
, mblk_t
*mp
);
448 static void zsa_rsrv(queue_t
*q
);
450 static struct module_info asyncm_info
= {
459 static struct qinit async_rinit
= {
469 static struct qinit async_winit
= {
479 struct streamtab asynctab
= {
487 * The async interrupt entry points.
489 static void zsa_txint(struct zscom
*zs
);
490 static void zsa_xsint(struct zscom
*zs
);
491 static void zsa_rxint(struct zscom
*zs
);
492 static void zsa_srint(struct zscom
*zs
);
493 static int zsa_softint(struct zscom
*zs
);
494 static int zsa_suspend(struct zscom
*zs
);
495 static int zsa_resume(struct zscom
*zs
);
498 zsa_null(struct zscom
*zs
)
503 SCC_WRITE0(ZSWR0_RESET_TXINT
);
504 SCC_WRITE0(ZSWR0_RESET_STATUS
);
507 SCC_WRITE0(ZSWR0_RESET_ERRORS
);
512 zsa_null_int(struct zscom
*zs
)
517 struct zsops zsops_null_async
= {
527 struct zsops zsops_async
= {
537 static int dmtozs(int bits
);
538 static int zstodm(int bits
);
539 static void zsa_restart(void *);
540 static void zsa_reioctl(void *);
541 static void zsa_ioctl(struct asyncline
*za
, queue_t
*q
, mblk_t
*mp
);
542 static void zsa_program(struct asyncline
*za
, int setibaud
);
543 static void zsa_start(struct zscom
*zs
);
544 static void zsa_kick_rcv(void *);
545 static void zsa_callback(void *);
546 static void zsa_set_za_rcv_flags_mask(struct asyncline
*za
);
547 int zsgetspeed(dev_t dev
);
549 static boolean_t
abort_charseq_recognize(uchar_t ch
);
553 zsc_info(dev_info_t
*dip
, ddi_info_cmd_t infocmd
, void *arg
,
556 register dev_t dev
= (dev_t
)arg
;
557 register int unit
, error
;
558 register struct zscom
*zs
;
560 if ((unit
= UNIT(dev
)) >= nzs
)
561 return (DDI_FAILURE
);
564 case DDI_INFO_DEVT2DEVINFO
:
566 *result
= zs
->zs_dip
;
569 case DDI_INFO_DEVT2INSTANCE
:
570 *result
= (void *)(uintptr_t)(unit
/ 2);
580 * The Asynchronous Driver.
584 * Determine if the zsminor device is in use as either a stdin or stdout
585 * device, so we can be careful about how we initialize the DUART, if
586 * it is, in fact, in use.
588 * Since this is expensive, we do it once and store away the answers,
589 * since this gets called a number of times per phyical zs device.
590 * Perhaps, this should be in a loadable module, so it can get thrown
591 * away after all the zs devices are attached?
595 * To determine if a given unit is being used by the PROM,
596 * we need to map stdin/stdout devices as known to the PROM
597 * to zs internal minor device numbers:
599 * PROM (real device) zs minor device
601 * "zs", 0, "a" 0 ttya
602 * "zs", 0, "b" 1 ttyb
603 * "zs", 1, "a" 2 keyboard
604 * "zs", 1, "b" 3 mouse
605 * "zs", 2, "a" 4 ttyc
606 * "zs", 2, "b" 5 ttyd
608 * The following value mapping lines assume that insource
609 * and outsink map as "screen, a, b, c, d, ...", and that
610 * zs minors are "a, b, kbd, mouse, c, d, ...".
613 static int zsa_inuse
; /* Strictly for debugging */
616 zsa_channel_is_active_in_rom(dev_info_t
*dev
, int zsminor
)
618 char pathname
[OBP_MAXPATHLEN
];
619 char default_pathname
[OBP_MAXPATHLEN
];
624 * Basically, get my name and compare it to stdio devnames
625 * and if we get a match, then the device is in use as either
626 * stdin or stdout device (console tip line or keyboard device).
628 * We get two forms of the pathname, one complete with the
629 * the channel number, and if the channel is 'a', then
630 * we also deal with the user's ability to default to
631 * channel 'a', by omitting the channel number option.
632 * We then compare these pathnames to both the stdin and
633 * stdout pathnames. If any of these match, then the channel
637 (void) ddi_pathname(dev
, pathname
); /* device pathname */
638 default_pathname
[0] = (char)0; /* default pathname if channel 'a' */
639 if ((zsminor
& 1) == 0)
640 (void) strcpy(default_pathname
, pathname
);
642 minordata
[1] = (char)('a' + (zsminor
& 1));
643 minordata
[2] = (char)0;
644 (void) strcat(pathname
, minordata
);
646 stdioname
= prom_stdinpath();
647 if (strcmp(pathname
, stdioname
) == 0) {
648 zsa_inuse
|= (1 << zsminor
);
651 if (strcmp(default_pathname
, stdioname
) == 0) {
652 zsa_inuse
|= (1 << zsminor
);
656 stdioname
= prom_stdoutpath();
657 if (strcmp(pathname
, stdioname
) == 0) {
658 zsa_inuse
|= (1 << zsminor
);
661 if (strcmp(default_pathname
, stdioname
) == 0) {
662 zsa_inuse
|= (1 << zsminor
);
673 zsa_init(struct zscom
*zs
)
676 * This routine is called near the end of the zs module's attach
677 * process. It initializes the TTY protocol-private data for this
678 * channel that needs to be in place before interrupts are enabled.
680 mutex_enter(zs
->zs_excl
);
681 mutex_enter(zs
->zs_excl_hi
);
684 * Raise modem control lines on serial ports associated
685 * with the console and (optionally) softcarrier lines.
686 * Drop modem control lines on all others so that modems
687 * will not answer and portselectors will skip these
688 * lines until they are opened by a getty.
690 if (zsa_channel_is_active_in_rom(zs
->zs_dip
, zs
->zs_unit
))
691 (void) zsmctl(zs
, ZS_ON
, DMSET
); /* raise dtr */
692 else if (zsasoftdtr
&& (zssoftCAR
[zs
->zs_unit
]))
693 (void) zsmctl(zs
, ZS_ON
, DMSET
); /* raise dtr */
695 (void) zsmctl(zs
, ZS_OFF
, DMSET
); /* drop dtr */
697 if (zsa_rstandby
> ZSA_MAX_RSTANDBY
)
698 zsa_rstandby
= ZSA_MAX_RSTANDBY
;
700 if (zsa_rdone
> ZSA_RDONE_MAX
)
701 zsa_rdone
= ZSA_RDONE_MAX
;
703 if (zsa_grace_flow_control
> ZSA_GRACE_MAX_FLOW_CONTROL
)
704 zsa_grace_flow_control
= ZSA_GRACE_MAX_FLOW_CONTROL
;
706 mutex_exit(zs
->zs_excl_hi
);
707 mutex_exit(zs
->zs_excl
);
716 zsa_open(queue_t
*rq
, dev_t
*dev
, int flag
, int sflag
, cred_t
*cr
)
718 register struct zscom
*zs
;
719 register struct asyncline
*za
;
720 register int speed
, unit
;
721 struct termios
*termiosp
;
723 register int allocbcount
= zsa_rstandby
;
724 boolean_t set_zsoptinit
= B_FALSE
;
728 return (ENXIO
); /* unit not configured */
730 /* zscom is allocated by zsattach, and thus cannot be NULL here */
732 if (zs
->zs_ops
== NULL
) {
733 return (ENXIO
); /* device not found by autoconfig */
736 mutex_enter(zs
->zs_ocexcl
);
737 mutex_enter(zs
->zs_excl
);
739 if ((zs
->zs_ops
!= &zsops_null
) &&
740 (zs
->zs_ops
!= &zsops_async
)) {
741 mutex_exit(zs
->zs_excl
);
742 mutex_exit(zs
->zs_ocexcl
);
743 return (EBUSY
); /* another protocol got here first */
746 za
= (struct asyncline
*)&zs
->zs_priv_str
;
748 if (zs
->zs_suspended
) {
749 mutex_exit(zs
->zs_excl
);
750 mutex_exit(zs
->zs_ocexcl
);
751 (void) ddi_dev_is_needed(zs
->zs_dip
, 0, 1);
752 mutex_enter(zs
->zs_ocexcl
);
753 mutex_enter(zs
->zs_excl
);
756 /* Mark device as busy (for power management) */
757 (void) pm_busy_component(zs
->zs_dip
, unit
%2+1);
759 if (zs
->zs_ops
== &zsops_null
) {
760 bzero(za
, sizeof (zs
->zs_priv_str
));
762 if (zssoftCAR
[zs
->zs_unit
])
763 za
->za_ttycommon
.t_flags
|= TS_SOFTCAR
;
764 zsopinit(zs
, &zsops_async
);
765 set_zsoptinit
= B_TRUE
;
766 za
->za_rdone_wptr
= 0;
767 za
->za_rdone_rptr
= 0;
770 zs
->zs_priv
= (caddr_t
)za
;
773 * Block waiting for carrier to come up,
774 * unless this is a no-delay open.
776 mutex_enter(zs
->zs_excl_hi
);
777 if (!(za
->za_flags
& ZAS_ISOPEN
)) {
779 * Get the default termios settings (cflag).
780 * These are stored as a property in the
783 mutex_exit(zs
->zs_excl_hi
);
784 if (ddi_getlongprop(DDI_DEV_T_ANY
,
785 ddi_root_node(), 0, "ttymodes",
786 (caddr_t
)&termiosp
, &len
) == DDI_PROP_SUCCESS
&&
787 len
== sizeof (struct termios
)) {
789 za
->za_ttycommon
.t_cflag
= termiosp
->c_cflag
;
790 kmem_free(termiosp
, len
);
793 * Gack! Whine about it.
796 "zs: Couldn't get ttymodes property!");
798 mutex_enter(zs
->zs_excl_hi
);
799 if ((*dev
== rconsdev
) || (*dev
== kbddev
) ||
800 (*dev
== stdindev
)) {
801 speed
= zsgetspeed(*dev
);
802 za
->za_ttycommon
.t_cflag
&= ~(CBAUD
);
804 za
->za_ttycommon
.t_cflag
|= CBAUDEXT
;
805 za
->za_ttycommon
.t_cflag
|=
806 ((speed
- CBAUD
- 1) & CBAUD
);
808 za
->za_ttycommon
.t_cflag
&= ~CBAUDEXT
;
809 za
->za_ttycommon
.t_cflag
|= (speed
& CBAUD
);
813 za
->za_ttycommon
.t_iflag
= 0;
814 za
->za_ttycommon
.t_iocpending
= NULL
;
815 za
->za_ttycommon
.t_size
.ws_row
= 0;
816 za
->za_ttycommon
.t_size
.ws_col
= 0;
817 za
->za_ttycommon
.t_size
.ws_xpixel
= 0;
818 za
->za_ttycommon
.t_size
.ws_ypixel
= 0;
821 zsa_program(za
, za
->za_ttycommon
.t_cflag
& (CIBAUDEXT
|CIBAUD
));
822 zsa_set_za_rcv_flags_mask(za
);
823 } else if ((za
->za_ttycommon
.t_flags
& TS_XCLUDE
) &&
824 secpolicy_excl_open(cr
) != 0) {
825 mutex_exit(zs
->zs_excl_hi
);
826 if (set_zsoptinit
&& !(za
->za_flags
& ISOPEN
))
827 zsopinit(zs
, &zsops_null
);
828 mutex_exit(zs
->zs_excl
);
829 mutex_exit(zs
->zs_ocexcl
);
831 } else if ((*dev
& OUTLINE
) && !(za
->za_flags
& ZAS_OUT
)) {
832 mutex_exit(zs
->zs_excl_hi
);
833 if (set_zsoptinit
&& !(za
->za_flags
& ISOPEN
))
834 zsopinit(zs
, &zsops_null
);
835 mutex_exit(zs
->zs_excl
);
836 mutex_exit(zs
->zs_ocexcl
);
841 za
->za_flags
|= ZAS_OUT
;
842 (void) zsmctl(zs
, ZS_ON
, DMSET
);
847 if ((za
->za_ttycommon
.t_flags
& TS_SOFTCAR
) ||
848 (zsmctl(zs
, 0, DMGET
) & ZSRR0_CD
))
849 za
->za_flags
|= ZAS_CARR_ON
;
850 mutex_exit(zs
->zs_excl_hi
);
853 * If FNDELAY and FNONBLOCK are clear, block until carrier up.
856 if (!(flag
& (FNDELAY
|FNONBLOCK
)) &&
857 !(za
->za_ttycommon
.t_cflag
& CLOCAL
)) {
858 if (!(za
->za_flags
& (ZAS_CARR_ON
|ZAS_OUT
)) ||
859 ((za
->za_flags
& ZAS_OUT
) && !(*dev
& OUTLINE
))) {
860 za
->za_flags
|= ZAS_WOPEN
;
861 mutex_exit(zs
->zs_excl
);
862 if (cv_wait_sig(&zs
->zs_flags_cv
, zs
->zs_ocexcl
) == 0) {
863 mutex_enter(zs
->zs_excl
);
864 if (zs
->zs_suspended
) {
865 mutex_exit(zs
->zs_excl
);
866 mutex_exit(zs
->zs_ocexcl
);
867 (void) ddi_dev_is_needed(zs
->zs_dip
,
869 mutex_enter(zs
->zs_ocexcl
);
870 mutex_enter(zs
->zs_excl
);
872 za
->za_flags
&= ~ZAS_WOPEN
;
873 if (set_zsoptinit
&& !(za
->za_flags
& ISOPEN
))
874 zsopinit(zs
, &zsops_null
);
875 mutex_exit(zs
->zs_excl
);
876 mutex_exit(zs
->zs_ocexcl
);
879 mutex_enter(zs
->zs_excl
);
880 za
->za_flags
&= ~ZAS_WOPEN
;
881 if ((zs
->zs_ops
== &zsops_null
) ||
882 (zs
->zs_ops
== &zsops_async
))
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 } else if ((za
->za_flags
& ZAS_OUT
) && !(*dev
& OUTLINE
)) {
893 if (set_zsoptinit
&& !(za
->za_flags
& ISOPEN
))
894 zsopinit(zs
, &zsops_null
);
895 mutex_exit(zs
->zs_excl
);
896 mutex_exit(zs
->zs_ocexcl
);
900 za
->za_ttycommon
.t_readq
= rq
;
901 za
->za_ttycommon
.t_writeq
= WR(rq
);
902 rq
->q_ptr
= WR(rq
)->q_ptr
= (caddr_t
)za
;
904 za
->za_flags
|= ZAS_ISOPEN
;
905 ZSA_GETBLOCK(zs
, allocbcount
);
907 mutex_exit(zs
->zs_excl
);
908 mutex_exit(zs
->zs_ocexcl
);
913 zs_progress_check(void *arg
)
915 struct asyncline
*za
= arg
;
916 struct zscom
*zs
= za
->za_common
;
920 * We define "progress" as either waiting on a timed break or delay, or
921 * having had at least one transmitter interrupt. If none of these are
922 * true, then just terminate the output and wake up that close thread.
924 mutex_enter(zs
->zs_excl
);
925 if (!(zs
->zs_flags
& ZS_PROGRESS
) &&
926 !(za
->za_flags
& (ZAS_BREAK
|ZAS_DELAY
))) {
927 za
->za_flags
&= ~ZAS_BUSY
;
928 mutex_enter(zs
->zs_excl_hi
);
929 za
->za_rcv_flags_mask
&= ~DO_RETRANSMIT
;
930 zs
->zs_wr_cur
= NULL
;
931 zs
->zs_wr_lim
= NULL
;
933 za
->za_xmitblk
= NULL
;
934 mutex_exit(zs
->zs_excl_hi
);
936 mutex_exit(zs
->zs_excl
);
940 * Since this timer is running, we know that we're in exit(2).
941 * That means that the user can't possibly be waiting on any
942 * valid ioctl(2) completion anymore, and we should just flush
945 flushq(za
->za_ttycommon
.t_writeq
, FLUSHALL
);
946 cv_broadcast(&zs
->zs_flags_cv
);
948 zs
->zs_flags
&= ~ZS_PROGRESS
;
949 zs
->zs_timer
= timeout(zs_progress_check
, za
,
950 drv_usectohz(zs_drain_check
));
951 mutex_exit(zs
->zs_excl
);
958 * Important locking note: the zs_ocexcl lock is not held at all in this
959 * routine. This is intentional. That lock is used to coordinate multiple
960 * simultaneous opens on a stream, and there's no such thing as multiple
961 * simultaneous closes on a stream.
966 zsa_close(queue_t
*q
, int flag
)
968 struct asyncline
*za
;
972 timeout_id_t za_zsa_restart_id
, za_kick_rcv_id
;
973 bufcall_id_t za_bufcid
, za_wbufcid
;
981 mutex_enter(zs
->zs_excl
);
982 zs
->zs_flags
|= ZS_CLOSING
;
985 * There are two flavors of break -- timed (M_BREAK or TCSBRK) and
986 * untimed (TIOCSBRK). For the timed case, these are enqueued on our
987 * write queue and there's a timer running, so we don't have to worry
988 * about them. For the untimed case, though, the user obviously made a
989 * mistake, because these are handled immediately. We'll terminate the
990 * break now and honor their implicit request by discarding the rest of
993 if (!(za
->za_flags
& ZAS_BREAK
) && (zs
->zs_wreg
[5] & ZSWR5_BREAK
))
997 * If the user told us not to delay the close ("non-blocking"), then
998 * don't bother trying to drain.
1000 * If the user did M_STOP (ASYNC_STOPPED), there's no hope of ever
1001 * getting an M_START (since these messages aren't enqueued), and the
1002 * only other way to clear the stop condition is by loss of DCD, which
1003 * would discard the queue data. Thus, we drop the output data if
1004 * ASYNC_STOPPED is set.
1006 if ((flag
& (FNDELAY
|FNONBLOCK
)) || (za
->za_flags
& ZAS_STOPPED
))
1010 * If there's any pending output, then we have to try to drain it.
1011 * There are two main cases to be handled:
1012 * - called by close(2): need to drain until done or until
1013 * a signal is received. No timeout.
1014 * - called by exit(2): need to drain while making progress
1015 * or until a timeout occurs. No signals.
1017 * If we can't rely on receiving a signal to get us out of a hung
1018 * session, then we have to use a timer. In this case, we set a timer
1019 * to check for progress in sending the output data -- all that we ask
1020 * (at each interval) is that there's been some progress made. Since
1021 * the interrupt routine grabs buffers from the write queue, we can't
1022 * trust changes in zs_wr_cur. Instead, we use a progress flag.
1024 * Note that loss of carrier will cause the output queue to be flushed,
1025 * and we'll wake up again and finish normally.
1027 if (!ddi_can_receive_sig() && zs_drain_check
!= 0) {
1028 zs
->zs_flags
&= ~ZS_PROGRESS
;
1029 zs
->zs_timer
= timeout(zs_progress_check
, za
,
1030 drv_usectohz(zs_drain_check
));
1033 while (zs
->zs_wr_cur
!= NULL
||
1034 za
->za_ttycommon
.t_writeq
->q_first
!= NULL
||
1035 (za
->za_flags
& (ZAS_BUSY
|ZAS_DELAY
|ZAS_BREAK
))) {
1036 if (cv_wait_sig(&zs
->zs_flags_cv
, zs
->zs_excl
) == 0)
1040 if (zs
->zs_timer
!= 0) {
1041 (void) untimeout(zs
->zs_timer
);
1047 * If break is in progress, stop it.
1049 mutex_enter(zs
->zs_excl_hi
);
1050 if (zs
->zs_wreg
[5] & ZSWR5_BREAK
) {
1051 SCC_BIC(5, ZSWR5_BREAK
);
1052 za
->za_flags
&= ~ZAS_BREAK
;
1055 za_wbufcid
= za
->za_wbufcid
;
1056 za_bufcid
= za
->za_bufcid
;
1057 za_zsa_restart_id
= za
->za_zsa_restart_id
;
1058 za_kick_rcv_id
= za
->za_kick_rcv_id
;
1060 za
->za_wbufcid
= za
->za_bufcid
= 0;
1061 za
->za_zsa_restart_id
= za
->za_kick_rcv_id
= 0;
1064 * If line has HUPCL set or is incompletely opened,
1065 * and it is not the console or the keyboard,
1066 * fix up the modem lines.
1069 zsopinit(zs
, &zsops_null_async
);
1072 * Nobody, zsh or zs can now open this port until
1073 * zsopinit(zs, &zsops_null);
1077 if ((za
->za_dev
!= rconsdev
) && (za
->za_dev
!= kbddev
) &&
1078 (za
->za_dev
!= stdindev
) &&
1079 (((za
->za_flags
& (ZAS_WOPEN
|ZAS_ISOPEN
)) != ZAS_ISOPEN
) ||
1080 (za
->za_ttycommon
.t_cflag
& HUPCL
))) {
1082 * If DTR is being held high by softcarrier,
1083 * set up the ZS_ON set; if not, hang up.
1085 if (zsasoftdtr
&& (za
->za_ttycommon
.t_flags
& TS_SOFTCAR
))
1086 (void) zsmctl(zs
, ZS_ON
, DMSET
);
1088 (void) zsmctl(zs
, ZS_OFF
, DMSET
);
1089 mutex_exit(zs
->zs_excl_hi
);
1091 * Don't let an interrupt in the middle of close
1092 * bounce us back to the top; just continue
1093 * closing as if nothing had happened.
1095 tmp
= cv_reltimedwait_sig(&zs
->zs_flags_cv
, zs
->zs_excl
,
1096 drv_usectohz(10000), TR_CLOCK_TICK
);
1097 if (zs
->zs_suspended
) {
1098 mutex_exit(zs
->zs_excl
);
1099 (void) ddi_dev_is_needed(zs
->zs_dip
, 0, 1);
1100 mutex_enter(zs
->zs_excl
);
1104 mutex_enter(zs
->zs_excl_hi
);
1108 * If nobody's now using it, turn off receiver interrupts.
1110 if ((za
->za_flags
& (ZAS_ISOPEN
|ZAS_WOPEN
)) == 0)
1111 SCC_BIC(1, ZSWR1_RIE
);
1112 mutex_exit(zs
->zs_excl_hi
);
1116 * Clear out device state.
1118 ttycommon_close(&za
->za_ttycommon
);
1120 za
->za_ttycommon
.t_readq
= NULL
;
1121 za
->za_ttycommon
.t_writeq
= NULL
;
1123 mutex_enter(zs
->zs_excl_hi
);
1124 za
->za_rcv_flags_mask
&= ~DO_RETRANSMIT
;
1125 zs
->zs_wr_cur
= NULL
;
1126 zs
->zs_wr_lim
= NULL
;
1127 bp
= za
->za_xmitblk
;
1128 za
->za_xmitblk
= NULL
;
1129 mutex_exit(zs
->zs_excl_hi
);
1133 mutex_enter(zs
->zs_excl_hi
);
1134 zs
->zs_rd_cur
= NULL
;
1135 zs
->zs_rd_lim
= NULL
;
1137 za
->za_rcvblk
= NULL
;
1138 mutex_exit(zs
->zs_excl_hi
);
1142 for (i
= 0; i
< zsa_rstandby
; i
++) {
1143 mutex_enter(zs
->zs_excl_hi
);
1144 bp
= za
->za_rstandby
[i
];
1145 za
->za_rstandby
[i
] = NULL
;
1146 mutex_exit(zs
->zs_excl_hi
);
1151 if (za
->za_soft_active
|| za
->za_kick_active
) {
1152 zs
->zs_flags
|= ZS_CLOSED
;
1153 while (za
->za_soft_active
|| za
->za_kick_active
)
1154 cv_wait(&zs
->zs_flags_cv
, zs
->zs_excl
);
1156 if (zs
->zs_suspended
) {
1157 mutex_exit(zs
->zs_excl
);
1158 (void) ddi_dev_is_needed(zs
->zs_dip
, 0, 1);
1159 mutex_enter(zs
->zs_excl
);
1163 bzero(za
, sizeof (struct asyncline
));
1165 mutex_exit(zs
->zs_excl
);
1168 * Cancel outstanding "bufcall" request.
1171 unbufcall(za_wbufcid
);
1173 unbufcall(za_bufcid
);
1176 * Cancel outstanding timeout.
1178 if (za_zsa_restart_id
)
1179 (void) untimeout(za_zsa_restart_id
);
1182 (void) untimeout(za_kick_rcv_id
);
1184 q
->q_ptr
= WR(q
)->q_ptr
= NULL
;
1185 zsopinit(zs
, &zsops_null
);
1186 cv_broadcast(&zs
->zs_flags_cv
);
1188 /* Mark device as available for power management */
1189 (void) pm_idle_component(zs
->zs_dip
, zs
->zs_unit
%2+1);
1194 * Put procedure for write queue.
1195 * Respond to M_STOP, M_START, M_IOCTL, and M_FLUSH messages here;
1196 * set the flow control character for M_STOPI and M_STARTI messages;
1197 * queue up M_BREAK, M_DELAY, and M_DATA messages for processing
1198 * by the start routine, and then call the start routine; discard
1199 * everything else. Note that this driver does not incorporate any
1200 * mechanism to negotiate to handle the canonicalization process.
1201 * It expects that these functions are handled in upper module(s),
1202 * as we do in ldterm.
1205 zsa_wput(queue_t
*q
, mblk_t
*mp
)
1207 register struct asyncline
*za
;
1208 register struct zscom
*zs
;
1209 register struct copyresp
*resp
;
1210 register mblk_t
*bp
= NULL
;
1212 struct iocblk
*iocp
;
1214 za
= (struct asyncline
*)q
->q_ptr
;
1216 if (zs
->zs_flags
& ZS_NEEDSOFT
) {
1217 zs
->zs_flags
&= ~ZS_NEEDSOFT
;
1218 (void) zsa_softint(zs
);
1221 switch (mp
->b_datap
->db_type
) {
1225 * Since we don't do real DMA, we can just let the
1226 * chip coast to a stop after applying the brakes.
1228 mutex_enter(zs
->zs_excl
);
1229 mutex_enter(zs
->zs_excl_hi
);
1230 za
->za_flags
|= ZAS_STOPPED
;
1231 if ((zs
->zs_wr_cur
) != NULL
) {
1232 za
->za_flags
&= ~ZAS_BUSY
;
1233 za
->za_rcv_flags_mask
&= ~DO_RETRANSMIT
;
1234 bp
= za
->za_xmitblk
;
1235 bp
->b_rptr
= zs
->zs_wr_cur
;
1236 zs
->zs_wr_cur
= NULL
;
1237 zs
->zs_wr_lim
= NULL
;
1238 za
->za_xmitblk
= NULL
;
1240 mutex_exit(zs
->zs_excl_hi
);
1242 (void) putbq(q
, bp
);
1244 mutex_exit(zs
->zs_excl
);
1248 mutex_enter(zs
->zs_excl
);
1249 if (za
->za_flags
& ZAS_STOPPED
) {
1250 za
->za_flags
&= ~ZAS_STOPPED
;
1252 * If an output operation is in progress,
1253 * resume it. Otherwise, prod the start
1259 mutex_exit(zs
->zs_excl
);
1263 mutex_enter(zs
->zs_excl
);
1264 iocp
= (struct iocblk
*)mp
->b_rptr
;
1266 switch (iocp
->ioc_cmd
) {
1272 if (mp
->b_cont
!= NULL
)
1273 freemsg(mp
->b_cont
);
1275 mp
->b_cont
= allocb(sizeof (int), BPRI_HI
);
1276 if (mp
->b_cont
== NULL
) {
1277 mp
->b_datap
->db_type
= M_IOCNAK
;
1278 iocp
->ioc_error
= ENOMEM
;
1283 *(int *)mp
->b_cont
->b_wptr
= 1;
1285 *(int *)mp
->b_cont
->b_wptr
= 0;
1286 mp
->b_cont
->b_wptr
+= sizeof (int);
1287 mp
->b_datap
->db_type
= M_IOCACK
;
1288 iocp
->ioc_count
= sizeof (int);
1296 error
= miocpullup(mp
, sizeof (int));
1298 mp
->b_datap
->db_type
= M_IOCNAK
;
1299 iocp
->ioc_error
= error
;
1304 za
->za_pps
= (*(int *)mp
->b_cont
->b_rptr
!= 0);
1305 mp
->b_datap
->db_type
= M_IOCACK
;
1312 * Get PPS event data.
1315 #ifdef _SYSCALL32_IMPL
1316 struct ppsclockev32 p32
;
1319 if (mp
->b_cont
!= NULL
) {
1320 freemsg(mp
->b_cont
);
1323 if (za
->za_pps
== NULL
) {
1324 mp
->b_datap
->db_type
= M_IOCNAK
;
1325 iocp
->ioc_error
= ENXIO
;
1330 #ifdef _SYSCALL32_IMPL
1331 if ((iocp
->ioc_flag
& IOC_MODELS
) != IOC_NATIVE
) {
1332 TIMEVAL_TO_TIMEVAL32(&p32
.tv
, &ppsclockev
.tv
);
1333 p32
.serial
= ppsclockev
.serial
;
1335 iocp
->ioc_count
= sizeof (struct ppsclockev32
);
1340 iocp
->ioc_count
= sizeof (struct ppsclockev
);
1343 if ((bp
= allocb(iocp
->ioc_count
, BPRI_HI
)) == NULL
) {
1344 mp
->b_datap
->db_type
= M_IOCNAK
;
1345 iocp
->ioc_error
= ENOMEM
;
1351 bcopy(buf
, bp
->b_wptr
, iocp
->ioc_count
);
1352 bp
->b_wptr
+= iocp
->ioc_count
;
1353 mp
->b_datap
->db_type
= M_IOCACK
;
1364 * The changes do not take effect until all
1365 * output queued before them is drained.
1366 * Put this message on the queue, so that
1367 * "zsa_start" will see it when it's done
1368 * with the output before it. Poke the
1369 * start routine, just in case.
1379 zsa_ioctl(za
, q
, mp
);
1382 mutex_exit(zs
->zs_excl
);
1388 mutex_enter(zs
->zs_excl
);
1389 resp
= (struct copyresp
*)mp
->b_rptr
;
1390 if (resp
->cp_rval
) {
1392 * Just free message on failure.
1395 mutex_exit(zs
->zs_excl
);
1398 switch (resp
->cp_cmd
) {
1401 mutex_enter(zs
->zs_excl_hi
);
1402 (void) zsmctl(zs
, dmtozs(*(int *)mp
->b_cont
->b_rptr
),
1404 mutex_exit(zs
->zs_excl_hi
);
1405 mioc2ack(mp
, NULL
, 0, 0);
1410 mutex_enter(zs
->zs_excl_hi
);
1411 (void) zsmctl(zs
, dmtozs(*(int *)mp
->b_cont
->b_rptr
),
1413 mutex_exit(zs
->zs_excl_hi
);
1414 mioc2ack(mp
, NULL
, 0, 0);
1419 mutex_enter(zs
->zs_excl_hi
);
1420 (void) zsmctl(zs
, dmtozs(*(int *)mp
->b_cont
->b_rptr
),
1422 mutex_exit(zs
->zs_excl_hi
);
1423 mioc2ack(mp
, NULL
, 0, 0);
1428 mioc2ack(mp
, NULL
, 0, 0);
1436 mutex_exit(zs
->zs_excl
);
1441 mutex_enter(zs
->zs_excl
);
1442 if (*mp
->b_rptr
& FLUSHW
) {
1445 * Abort any output in progress.
1447 if (za
->za_flags
& ZAS_BUSY
) {
1448 za
->za_flags
&= ~ZAS_BUSY
;
1449 mutex_enter(zs
->zs_excl_hi
);
1450 za
->za_rcv_flags_mask
&= ~DO_RETRANSMIT
;
1451 zs
->zs_wr_cur
= NULL
;
1452 zs
->zs_wr_lim
= NULL
;
1453 bp
= za
->za_xmitblk
;
1454 za
->za_xmitblk
= NULL
;
1455 mutex_exit(zs
->zs_excl_hi
);
1460 * Flush our write queue.
1462 flushq(q
, FLUSHDATA
); /* XXX doesn't flush M_DELAY */
1463 *mp
->b_rptr
&= ~FLUSHW
; /* it has been flushed */
1465 if (*mp
->b_rptr
& FLUSHR
) {
1467 * Flush any data in the temporary receive buffer
1469 mutex_enter(zs
->zs_excl_hi
);
1470 if ((za
->za_ttycommon
.t_flags
& TS_SOFTCAR
) ||
1471 (SCC_READ0() & ZSRR0_CD
)) {
1475 if (!(SCC_READ0() & ZSRR0_RX_READY
)) {
1477 * settle time for 1 character shift
1479 mutex_exit(zs
->zs_excl_hi
);
1480 mutex_exit(zs
->zs_excl
);
1481 delay(ztdelay(SPEED(
1482 za
->za_ttycommon
.t_cflag
))/3 + 1);
1483 mutex_enter(zs
->zs_excl
);
1484 mutex_enter(zs
->zs_excl_hi
);
1485 if (!(SCC_READ0() & ZSRR0_CD
))
1488 while ((SCC_READ0() &
1489 (ZSRR0_CD
| ZSRR0_RX_READY
)) ==
1494 (void) SCC_READDATA();
1497 mutex_exit(zs
->zs_excl_hi
);
1498 flushq(RD(q
), FLUSHDATA
);
1501 * give the read queues a crack at it
1507 * We must make sure we process messages that survive the
1508 * write-side flush. Without this call, the close protocol
1509 * with ldterm can hang forever. (ldterm will have sent us a
1510 * TCSBRK ioctl that it expects a response to.)
1513 mutex_exit(zs
->zs_excl
);
1519 mutex_enter(zs
->zs_excl
);
1521 * Queue the message up to be transmitted,
1522 * and poke the start routine.
1526 mutex_exit(zs
->zs_excl
);
1530 mutex_enter(zs
->zs_excl
);
1531 mutex_enter(zs
->zs_excl_hi
);
1532 za
->za_flowc
= za
->za_ttycommon
.t_stopc
;
1533 if ((zs
->zs_wr_cur
) != NULL
) {
1534 za
->za_rcv_flags_mask
&= ~DO_RETRANSMIT
;
1535 bp
= za
->za_xmitblk
;
1536 bp
->b_rptr
= zs
->zs_wr_cur
;
1537 zs
->zs_wr_cur
= NULL
;
1538 zs
->zs_wr_lim
= NULL
;
1539 za
->za_xmitblk
= NULL
;
1541 mutex_exit(zs
->zs_excl_hi
);
1543 (void) putbq(q
, bp
);
1545 zsa_start(zs
); /* poke the start routine */
1547 mutex_exit(zs
->zs_excl
);
1551 mutex_enter(zs
->zs_excl
);
1552 mutex_enter(zs
->zs_excl_hi
);
1553 za
->za_flowc
= za
->za_ttycommon
.t_startc
;
1554 if ((zs
->zs_wr_cur
) != NULL
) {
1555 za
->za_rcv_flags_mask
&= ~DO_RETRANSMIT
;
1556 bp
= za
->za_xmitblk
;
1557 bp
->b_rptr
= zs
->zs_wr_cur
;
1558 zs
->zs_wr_cur
= NULL
;
1559 zs
->zs_wr_lim
= NULL
;
1560 za
->za_xmitblk
= NULL
;
1562 mutex_exit(zs
->zs_excl_hi
);
1564 (void) putbq(q
, bp
);
1566 zsa_start(zs
); /* poke the start routine */
1568 mutex_exit(zs
->zs_excl
);
1572 if (MBLKL(mp
) >= sizeof (struct iocblk
) &&
1573 ((struct iocblk
*)mp
->b_rptr
)->ioc_cmd
== MC_POSIXQUERY
) {
1574 ((struct iocblk
*)mp
->b_rptr
)->ioc_cmd
= MC_HAS_POSIX
;
1578 * These MC_SERVICE type messages are used by upper
1579 * modules to tell this driver to send input up
1580 * immediately, or that it can wait for normal
1581 * processing that may or may not be done. Sun
1582 * requires these for the mouse module.
1584 mutex_enter(zs
->zs_excl
);
1585 switch (*mp
->b_rptr
) {
1588 mutex_enter(zs
->zs_excl_hi
);
1589 za
->za_flags
|= ZAS_SERVICEIMM
;
1590 mutex_exit(zs
->zs_excl_hi
);
1594 mutex_enter(zs
->zs_excl_hi
);
1595 za
->za_flags
&= ~ZAS_SERVICEIMM
;
1596 mutex_exit(zs
->zs_excl_hi
);
1600 mutex_exit(zs
->zs_excl
);
1606 * "No, I don't want a subscription to Chain Store Age,
1607 * thank you anyway."
1615 * zs read service procedure
1618 zsa_rsrv(queue_t
*q
)
1620 struct asyncline
*za
;
1623 if (((za
= (struct asyncline
*)q
->q_ptr
) != NULL
) &&
1624 (za
->za_ttycommon
.t_cflag
& CRTSXOFF
)) {
1626 mutex_enter(zs
->zs_excl_hi
);
1628 mutex_exit(zs
->zs_excl_hi
);
1633 * Transmitter interrupt service routine.
1634 * If there's more data to transmit in the current pseudo-DMA block,
1635 * and the transmitter is ready, send the next character if output
1636 * is not stopped or draining.
1637 * Otherwise, queue up a soft interrupt.
1640 zsa_txint(struct zscom
*zs
)
1642 register struct asyncline
*za
= (struct asyncline
*)&zs
->zs_priv_str
;
1643 register uchar_t
*wr_cur
;
1644 register uchar_t s0
;
1648 if ((wr_cur
= zs
->zs_wr_cur
) != NULL
) {
1649 if (wr_cur
< zs
->zs_wr_lim
) {
1650 if ((za
->za_ttycommon
.t_cflag
& CRTSCTS
) &&
1651 !(s0
& ZSRR0_CTS
)) {
1652 SCC_WRITE0(ZSWR0_RESET_TXINT
);
1653 za
->za_rcv_flags_mask
|= DO_RETRANSMIT
;
1656 SCC_WRITEDATA(*wr_cur
++);
1660 zs
->zs_wr_cur
= wr_cur
;
1661 zs
->zs_flags
|= ZS_PROGRESS
;
1664 zs
->zs_wr_cur
= NULL
;
1665 zs
->zs_wr_lim
= NULL
;
1667 * Use the rcv_flags_mask as it is set and
1668 * test while holding the zs_excl_hi mutex
1670 za
->za_rcv_flags_mask
|= DO_TRANSMIT
;
1671 SCC_WRITE0(ZSWR0_RESET_TXINT
);
1677 if (za
->za_flowc
!= '\0' && (!(za
->za_flags
& ZAS_DRAINING
))) {
1678 if ((za
->za_ttycommon
.t_cflag
& CRTSCTS
) &&
1679 !(s0
& ZSRR0_CTS
)) {
1680 SCC_WRITE0(ZSWR0_RESET_TXINT
);
1683 SCC_WRITEDATA(za
->za_flowc
);
1684 za
->za_flowc
= '\0';
1687 SCC_WRITE0(ZSWR0_RESET_TXINT
);
1689 * Set DO_TRANSMIT bit so that the soft interrupt can
1690 * test it and unset the ZAS_BUSY in za_flags while holding
1691 * the mutex zs_excl and zs_excl_hi
1693 za
->za_rcv_flags_mask
|= DO_TRANSMIT
;
1698 * External/Status interrupt.
1701 zsa_xsint(struct zscom
*zs
)
1703 register struct asyncline
*za
= (struct asyncline
*)&zs
->zs_priv_str
;
1704 register uchar_t s0
, x0
;
1708 x0
= s0
^ za
->za_rr0
;
1710 SCC_WRITE0(ZSWR0_RESET_STATUS
);
1713 * PPS (Pulse Per Second) support.
1715 if (za
->za_pps
&& (x0
& ZSRR0_CD
) && (s0
& ZSRR0_CD
)) {
1717 * This code captures a timestamp at the designated
1718 * transition of the PPS signal (CD asserted). The
1719 * code provides a pointer to the timestamp, as well
1720 * as the hardware counter value at the capture.
1722 * Note: the kernel has nano based time values while
1723 * NTP requires micro based, an in-line fast algorithm
1724 * to convert nsec to usec is used here -- see hrt2ts()
1725 * in common/os/timers.c for a full description.
1727 struct timeval
*tvp
= &ppsclockev
.tv
;
1735 usec
= nsec
+ (nsec
>> 2);
1736 usec
= nsec
+ (usec
>> 1);
1737 usec
= nsec
+ (usec
>> 2);
1738 usec
= nsec
+ (usec
>> 4);
1739 usec
= nsec
- (usec
>> 3);
1740 usec
= nsec
+ (usec
>> 2);
1741 usec
= nsec
+ (usec
>> 3);
1742 usec
= nsec
+ (usec
>> 4);
1743 usec
= nsec
+ (usec
>> 1);
1744 usec
= nsec
+ (usec
>> 6);
1745 tvp
->tv_usec
= usec
>> 10;
1746 tvp
->tv_sec
= ts
.tv_sec
;
1748 ++ppsclockev
.serial
;
1751 * Because the kernel keeps a high-resolution time, pass the
1752 * current highres timestamp in tvp and zero in usec.
1754 ddi_hardpps(tvp
, 0);
1759 if ((x0
& ZSRR0_BREAK
) && (s0
& ZSRR0_BREAK
) == 0) {
1762 * ZSRR0_BREAK turned off. This means that the break sequence
1763 * has completed (i.e., the stop bit finally arrived).
1765 if ((s0
& ZSRR0_RX_READY
) == 0) {
1767 * SLAVIO will generate a separate STATUS change
1768 * interrupt when the break sequence completes.
1769 * SCC will combine both, taking the higher priority
1770 * one, the receive. Should still see the ext/stat.
1771 * bit in REG3 on SCC. If no ext/stat, it must be
1774 za
->za_breakoff
= 1;
1777 * The NUL character in the receiver is part of the
1778 * break sequence; it is discarded.
1780 (void) SCC_READDATA(); /* swallow null */
1782 #else /* SLAVIO_BUG */
1784 * ZSRR0_BREAK turned off. This means that the break sequence
1785 * has completed (i.e., the stop bit finally arrived). The NUL
1786 * character in the receiver is part of the break sequence;
1789 (void) SCC_READDATA(); /* swallow null */
1790 #endif /* SLAVIO_BUG */
1791 SCC_WRITE0(ZSWR0_RESET_ERRORS
);
1794 * Note: this will cause an abort if a break occurs on
1795 * the "keyboard device", regardless of whether the
1796 * "keyboard device" is a real keyboard or just a
1797 * terminal on a serial line. This permits you to
1798 * abort a workstation by unplugging the keyboard,
1799 * even if the normal abort key sequence isn't working.
1801 if ((za
->za_dev
== kbddev
) ||
1802 ((za
->za_dev
== rconsdev
) || (za
->za_dev
== stdindev
)) &&
1803 (abort_enable
!= KIOCABORTALTERNATE
)) {
1804 abort_sequence_enter((char *)NULL
);
1806 * We just broke into the monitor or debugger,
1807 * ignore the break in this case so whatever
1808 * random program that was running doesn't get
1817 * If hardware flow control is enabled, (re)start output
1818 * when CTS is reasserted.
1820 if ((za
->za_ttycommon
.t_cflag
& CRTSCTS
) &&
1821 (x0
& ZSRR0_CTS
) && (s0
& ZSRR0_CTS
) &&
1822 (za
->za_rcv_flags_mask
& DO_RETRANSMIT
))
1823 za
->za_rcv_flags_mask
|= DO_TRANSMIT
;
1833 zsa_rxint(struct zscom
*zs
)
1835 register struct asyncline
*za
= (struct asyncline
*)&zs
->zs_priv_str
;
1837 register uchar_t
*rd_cur
= zs
->zs_rd_cur
;
1838 register uchar_t
*rd_lim
= zs
->zs_rd_lim
;
1839 register mblk_t
*bp
;
1840 register uint_t fm
= za
->za_rcv_flags_mask
;
1846 c
= (fm
>> 16) & (SCC_READDATA());
1849 * Check for character break sequence
1851 if ((abort_enable
== KIOCABORTALTERNATE
) && (za
->za_dev
== rconsdev
)) {
1852 if (abort_charseq_recognize(c
))
1853 abort_sequence_enter((char *)NULL
);
1859 * SLAVIO generates FE for the start of break and
1860 * during break when parity is set. End of break is
1861 * detected when the first character is received.
1862 * This character is always garbage and is thrown away.
1864 if (za
->za_slav_break
) {
1865 za
->za_slav_break
= 0;
1866 za
->za_rr0
|= ZSRR0_BREAK
;
1870 #endif /* SLAVIO_BUG */
1872 if (c
== 0 && (za
->za_rr0
& ZSRR0_BREAK
)) {
1874 * A break sequence was under way, and a NUL character
1875 * was received. Discard the NUL character, as it is
1876 * part of the break sequence; if ZSRR0_BREAK turned
1877 * off, indicating that the break sequence has com-
1878 * pleted, call "zsa_xsint" to properly handle the
1879 * error. It would appear that External/Status
1880 * interrupts get lost occasionally, so this ensures
1881 * that one is delivered.
1884 if (!(c
& ZSRR0_BREAK
))
1890 if (c
== 0 && za
->za_breakoff
) {
1892 * A break sequence completed, but SLAVIO generates
1893 * the NULL character interrupt late, so we throw the
1900 * make sure it gets cleared.
1902 za
->za_breakoff
= 0;
1903 #endif /* SLAVIO_BUG */
1905 ZSA_KICK_RCV
; /* We can have M_BREAK msg */
1908 za
->za_sw_overrun
++;
1913 zs
->zs_rd_cur
= rd_cur
= bp
->b_wptr
;
1914 zs
->zs_rd_lim
= rd_lim
= bp
->b_datap
->db_lim
;
1915 if (za
->za_kick_rcv_id
== 0)
1918 if (c
== 0377 && (fm
& DO_ESC
)) {
1919 if (rd_lim
< rd_cur
+ 2) {
1923 za
->za_sw_overrun
++;
1927 zs
->zs_rd_cur
= rd_cur
= bp
->b_wptr
;
1928 zs
->zs_rd_lim
= rd_lim
= bp
->b_datap
->db_lim
;
1935 zs
->zs_rd_cur
= rd_cur
;
1937 if (rd_cur
== rd_lim
) {
1939 } else if ((fm
& DO_STOPC
) && (c
== (fm
& 0xff))) {
1940 za
->za_do_kick_rcv_in_softint
= 1;
1944 if ((za
->za_flags
& ZAS_SERVICEIMM
) || g_nocluster
) {
1946 * Send the data up immediately
1953 * Special receive condition interrupt handler.
1956 zsa_srint(struct zscom
*zs
)
1958 register struct asyncline
*za
= (struct asyncline
*)&zs
->zs_priv_str
;
1961 register uchar_t c1
;
1962 register mblk_t
*bp
= za
->za_rcvblk
;
1963 register uchar_t
*rd_cur
= zs
->zs_rd_cur
;
1966 if (s1
& (ZSRR1_FE
| ZSRR1_PE
| ZSRR1_DO
)) {
1967 c
= SCC_READDATA(); /* swallow bad character */
1971 * SLAVIO does not handle breaks properly when parity is enabled.
1973 * In general, if a null character is received when a framing
1974 * error occurs then it is a break condition and not a real
1975 * framing error. The null character must be limited to the
1976 * number of bits including the parity bit. For example, a 6
1977 * bit character with parity would be null if the lower 7 bits
1978 * read from the receive fifo were 0. (The higher order bits are
1979 * padded with 1 and/or the stop bits.) The only exception to this
1980 * general rule would be an 8 bit null character with parity being
1981 * a 1 in the parity bit and a framing error. This exception
1982 * can be determined by examining the parity error bit in RREG 1.
1984 * A null character, even parity, 8 bits, no parity error,
1985 * (0 0000 0000) with framing error is a break condition.
1987 * A null character, even parity, 8 bits, parity error,
1988 * (1 0000 0000) with framing error is a framing error.
1990 * A null character, odd parity, 8 bits, parity error
1991 * (0 0000 0000) with framing error is a break condition.
1993 * A null character, odd parity, 8 bits, no parity error,
1994 * (1 0000 0000) with framing error is a framing error.
1996 if (za
->za_ttycommon
.t_cflag
& PARENB
) {
1997 switch (za
->za_ttycommon
.t_cflag
& CSIZE
) {
2012 if ((za
->za_ttycommon
.t_cflag
& PARODD
) &&
2015 else if (!(za
->za_ttycommon
.t_cflag
& PARODD
) &&
2024 * We fake start of break condition.
2026 if ((s1
& ZSRR1_FE
) && c1
== 0) {
2027 za
->za_slav_break
= 1;
2031 #endif /* SLAVIO_BUG */
2033 if (s1
& ZSRR1_PE
) {
2036 * Mark the parity error so zsa_process will
2037 * notice it and send it up in an M_BREAK
2038 * message; ldterm will do the actual parity error
2042 if (bp
&& zs
->zs_rd_cur
) { /* M_DATA msg */
2049 za
->za_sw_overrun
++;
2053 zs
->zs_rd_cur
= rd_cur
= bp
->b_wptr
;
2054 zs
->zs_rd_lim
= bp
->b_datap
->db_lim
;
2056 zs
->zs_rd_cur
= rd_cur
;
2057 bp
->b_datap
->db_type
= M_BREAK
;
2058 if (bp
->b_datap
->db_lim
<= rd_cur
)
2060 za
->za_do_kick_rcv_in_softint
= 1;
2065 SCC_WRITE0(ZSWR0_RESET_ERRORS
);
2066 if (s1
& ZSRR1_DO
) {
2067 za
->za_hw_overrun
++;
2073 * Process software interrupts (or poll)
2075 * 3. BUG - breaks are handled "out-of-band" - their relative position
2076 * among input events is lost, as well as multiple breaks together.
2077 * This is probably not a problem in practice.
2080 zsa_softint(struct zscom
*zs
)
2082 register struct asyncline
*za
= (struct asyncline
*)&zs
->zs_priv_str
;
2083 register uchar_t r0
;
2084 register uchar_t za_kick_active
;
2085 register int m_error
;
2086 register int allocbcount
= 0;
2087 register int do_ttycommon_qfull
= 0;
2088 boolean_t hangup
= B_FALSE
, unhangup
= B_FALSE
;
2089 boolean_t m_break
= B_FALSE
, wakeup
= B_FALSE
;
2090 register queue_t
*q
;
2091 register mblk_t
*bp
;
2092 register mblk_t
*head
= NULL
, *tail
= NULL
;
2094 mutex_enter(zs
->zs_excl
);
2095 if (zs
->zs_suspended
|| (zs
->zs_flags
& ZS_CLOSED
)) {
2096 mutex_exit(zs
->zs_excl
);
2099 q
= za
->za_ttycommon
.t_readq
;
2100 if (za
->za_flags
& ZAS_WOPEN
&& !q
) {
2102 mutex_enter(zs
->zs_excl_hi
);
2105 mutex_exit(zs
->zs_excl_hi
);
2109 if ((r0
& ZSRR0_CD
) ||
2110 (za
->za_ttycommon
.t_flags
& TS_SOFTCAR
)) {
2114 if ((za
->za_flags
& ZAS_CARR_ON
) == 0) {
2115 za
->za_flags
|= ZAS_CARR_ON
;
2116 mutex_exit(zs
->zs_excl
);
2117 cv_broadcast(&zs
->zs_flags_cv
);
2122 mutex_exit(zs
->zs_excl
);
2125 q
= za
->za_ttycommon
.t_readq
;
2127 mutex_exit(zs
->zs_excl
);
2131 m_error
= za
->za_m_error
;
2134 if (za
->za_do_kick_rcv_in_softint
) {
2135 mutex_enter(zs
->zs_excl_hi
);
2137 za
->za_do_kick_rcv_in_softint
= 0;
2138 mutex_exit(zs
->zs_excl_hi
);
2141 za_kick_active
= za
->za_kick_active
;
2143 while (!za_kick_active
) {
2150 if (bp
->b_datap
->db_type
<= QPCTL
) {
2151 if (!(canputnext(q
))) {
2152 if (za
->za_grace_flow_control
>=
2153 zsa_grace_flow_control
) {
2154 if (za
->za_ttycommon
.t_cflag
&
2161 do_ttycommon_qfull
= 1;
2164 za
->za_grace_flow_control
++;
2166 za
->za_grace_flow_control
= 0;
2180 ZSA_GETBLOCK(zs
, allocbcount
);
2183 mutex_enter(zs
->zs_excl_hi
);
2189 if ((r0
& ZSRR0_CD
) ||
2190 (za
->za_ttycommon
.t_flags
& TS_SOFTCAR
)) {
2194 if ((za
->za_flags
& ZAS_CARR_ON
) == 0) {
2195 za
->za_flags
|= ZAS_CARR_ON
;
2200 if ((za
->za_flags
& ZAS_CARR_ON
) &&
2201 !(za
->za_ttycommon
.t_cflag
& CLOCAL
)) {
2203 * Carrier went away.
2204 * Drop DTR, abort any output in progress,
2205 * indicate that output is not stopped, and
2206 * send a hangup notification upstream.
2208 (void) zsmctl(zs
, ZSWR5_DTR
, DMBIC
);
2209 if ((za
->za_flags
& ZAS_BUSY
) &&
2210 (zs
->zs_wr_cur
!= NULL
)) {
2211 zs
->zs_wr_cur
= NULL
;
2212 zs
->zs_wr_lim
= NULL
;
2216 za
->za_flags
&= ~(ZAS_STOPPED
| ZAS_CARR_ON
|
2218 za
->za_rcv_flags_mask
&= ~(DO_TRANSMIT
|
2222 mutex_exit(zs
->zs_excl_hi
);
2223 if (hangup
&& (bp
= za
->za_xmitblk
) != NULL
) {
2224 za
->za_xmitblk
= NULL
;
2229 if (za
->za_break
!= 0) {
2230 mutex_enter(zs
->zs_excl_hi
);
2232 mutex_exit(zs
->zs_excl_hi
);
2233 if ((r0
& ZSRR0_BREAK
) == 0) {
2240 * If a transmission has finished, indicate that it's
2241 * finished, and start that line up again.
2244 mutex_enter(zs
->zs_excl_hi
);
2245 if (za
->za_rcv_flags_mask
& DO_TRANSMIT
) {
2246 za
->za_rcv_flags_mask
&= ~DO_TRANSMIT
;
2247 za
->za_flags
&= ~ZAS_BUSY
;
2249 if ((za
->za_ttycommon
.t_cflag
& CRTSCTS
) &&
2250 (za
->za_rcv_flags_mask
& DO_RETRANSMIT
) &&
2254 za
->za_rcv_flags_mask
&= ~DO_RETRANSMIT
;
2255 bp
= za
->za_xmitblk
;
2258 mutex_exit(zs
->zs_excl_hi
);
2262 /* if we didn't start anything, then notify waiters */
2263 if (!(za
->za_flags
& ZAS_BUSY
))
2266 mutex_exit(zs
->zs_excl_hi
);
2271 * A note about these overrun bits: all they do is *tell* someone
2272 * about an error- They do not track multiple errors. In fact,
2273 * you could consider them latched register bits if you like.
2274 * We are only interested in printing the error message once for
2275 * any cluster of overrun errrors.
2277 if ((!za
->za_kick_rcv_id
) && (zs
->zs_rd_cur
|| za_kick_active
)) {
2279 za
->za_kick_rcv_id
= timeout(zsa_kick_rcv
, zs
,
2282 za
->za_kick_rcv_id
= timeout(zsa_kick_rcv
, zs
,
2283 zsticks
[SPEED(za
->za_ttycommon
.t_cflag
)]);
2284 za
->za_kick_rcv_count
= ZA_KICK_RCV_COUNT
;
2286 za
->za_soft_active
= 1;
2287 mutex_exit(zs
->zs_excl
);
2289 if (!hangup
&& do_ttycommon_qfull
) {
2290 ttycommon_qfull(&za
->za_ttycommon
, q
);
2291 mutex_enter(zs
->zs_excl
);
2293 mutex_exit(zs
->zs_excl
);
2296 if (za
->za_hw_overrun
> 10) {
2297 cmn_err(CE_NOTE
, "zs%d: silo overflow\n", UNIT(za
->za_dev
));
2298 za
->za_hw_overrun
= 0;
2301 if (za
->za_sw_overrun
> 10) {
2302 cmn_err(CE_NOTE
, "zs%d:ring buffer overflow\n",
2304 za
->za_sw_overrun
= 0;
2308 (void) putnextctl(q
, M_UNHANGUP
);
2311 (void) putnextctl(q
, M_BREAK
);
2319 head
= head
->b_next
;
2328 * If we're in the midst of close, then flush everything. Don't
2329 * leave stale ioctls lying about.
2331 flushflag
= (zs
->zs_flags
& ZS_CLOSING
) ? FLUSHALL
: FLUSHDATA
;
2332 flushq(za
->za_ttycommon
.t_writeq
, flushflag
);
2333 (void) putnextctl(q
, M_HANGUP
);
2337 (void) putnextctl1(q
, M_ERROR
, m_error
);
2339 za
->za_soft_active
= 0;
2341 if (wakeup
|| (zs
->zs_flags
& ZS_CLOSED
))
2342 cv_broadcast(&zs
->zs_flags_cv
);
2348 * Start output on a line, unless it's busy, frozen, or otherwise.
2351 zsa_start(struct zscom
*zs
)
2353 register struct asyncline
*za
= (struct asyncline
*)&zs
->zs_priv_str
;
2355 register queue_t
*q
;
2356 register mblk_t
*bp
;
2357 uchar_t
*rptr
, *wptr
;
2360 * If the chip is busy (i.e., we're waiting for a break timeout
2361 * to expire, or for the current transmission to finish, or for
2362 * output to finish draining from chip), don't grab anything new.
2364 if ((za
->za_flags
& (ZAS_BREAK
|ZAS_BUSY
|ZAS_DRAINING
)) ||
2368 if (za
->za_ttycommon
.t_cflag
& CRTSCTS
) {
2369 mutex_enter(zs
->zs_excl_hi
);
2370 if (za
->za_rcv_flags_mask
& DO_RETRANSMIT
) {
2371 rptr
= zs
->zs_wr_cur
;
2372 wptr
= zs
->zs_wr_lim
;
2373 goto zsa_start_retransmit
;
2376 mutex_exit(zs
->zs_excl_hi
);
2380 * If we have a flow-control character to transmit, do it now.
2382 if (za
->za_flowc
!= '\0') {
2383 mutex_enter(zs
->zs_excl_hi
);
2384 if (za
->za_ttycommon
.t_cflag
& CRTSCTS
) {
2385 if ((SCC_READ0() & (ZSRR0_CTS
|ZSRR0_TX_READY
)) !=
2386 (ZSRR0_CTS
|ZSRR0_TX_READY
)) {
2387 mutex_exit(zs
->zs_excl_hi
);
2390 } else if (!(SCC_READ0() & ZSRR0_TX_READY
)) {
2391 mutex_exit(zs
->zs_excl_hi
);
2396 SCC_WRITEDATA(za
->za_flowc
);
2397 za
->za_flowc
= '\0';
2398 mutex_exit(zs
->zs_excl_hi
);
2403 * If we're waiting for a delay timeout to expire, don't grab
2406 if (za
->za_flags
& ZAS_DELAY
)
2409 if ((q
= za
->za_ttycommon
.t_writeq
) == NULL
)
2410 return; /* not attached to a stream */
2414 if ((bp
= getq(q
)) == NULL
)
2415 return; /* no data to transmit */
2418 * We have a message block to work on.
2419 * Check whether it's a break, a delay, or an ioctl (the latter
2420 * occurs if the ioctl in question was waiting for the output
2421 * to drain). If it's one of those, process it immediately.
2423 switch (bp
->b_datap
->db_type
) {
2427 * Set the break bit, and arrange for "zsa_restart"
2428 * to be called in 1/4 second; it will turn the
2429 * break bit off, and call "zsa_start" to grab
2432 mutex_enter(zs
->zs_excl_hi
);
2433 SCC_BIS(5, ZSWR5_BREAK
);
2434 mutex_exit(zs
->zs_excl_hi
);
2435 if (!za
->za_zsa_restart_id
) {
2436 za
->za_zsa_restart_id
=
2437 timeout(zsa_restart
, zs
, hz
/4);
2439 za
->za_flags
|= ZAS_BREAK
;
2441 return; /* wait for this to finish */
2445 * Arrange for "zsa_restart" to be called when the
2446 * delay expires; it will turn MTS_DELAY off,
2447 * and call "zsa_start" to grab the next message.
2449 if (! za
->za_zsa_restart_id
) {
2450 za
->za_zsa_restart_id
= timeout(zsa_restart
,
2452 (int)(*(unsigned char *)bp
->b_rptr
+ 6));
2454 za
->za_flags
|= ZAS_DELAY
;
2456 return; /* wait for this to finish */
2460 * This ioctl was waiting for the output ahead of
2461 * it to drain; obviously, it has. Do it, and
2462 * then grab the next message after it.
2464 zsa_ioctl(za
, q
, bp
);
2466 default: /* M_DATA */
2467 goto zsa_start_transmit
;
2473 * We have data to transmit. If output is stopped, put
2474 * it back and try again later.
2476 if (za
->za_flags
& ZAS_STOPPED
) {
2477 (void) putbq(q
, bp
);
2481 za
->za_xmitblk
= bp
;
2487 za
->za_xmitblk
->b_cont
= NULL
;
2488 (void) putbq(q
, bp
); /* not done with this message yet */
2492 freeb(za
->za_xmitblk
);
2493 za
->za_xmitblk
= NULL
;
2494 goto zsa_start_again
;
2498 * In 5-bit mode, the high order bits are used
2499 * to indicate character sizes less than five,
2500 * so we need to explicitly mask before transmitting
2502 if ((za
->za_ttycommon
.t_cflag
& CSIZE
) == CS5
) {
2503 register unsigned char *p
= rptr
;
2504 register int cnt
= cc
;
2507 *p
++ &= (unsigned char) 0x1f;
2511 * Set up this block for pseudo-DMA.
2514 mutex_enter(zs
->zs_excl_hi
);
2515 zs
->zs_wr_cur
= rptr
;
2516 zs
->zs_wr_lim
= wptr
;
2518 zsa_start_retransmit
:
2519 za
->za_rcv_flags_mask
&= ~DO_TRANSMIT
;
2520 if (za
->za_ttycommon
.t_cflag
& CRTSCTS
) {
2521 if ((SCC_READ0() & (ZSRR0_CTS
|ZSRR0_TX_READY
)) !=
2522 (ZSRR0_CTS
|ZSRR0_TX_READY
)) {
2523 za
->za_rcv_flags_mask
|= DO_RETRANSMIT
;
2524 za
->za_flags
|= ZAS_BUSY
;
2525 mutex_exit(zs
->zs_excl_hi
);
2528 za
->za_rcv_flags_mask
&= ~DO_RETRANSMIT
;
2530 if (!(SCC_READ0() & ZSRR0_TX_READY
)) {
2531 za
->za_flags
|= ZAS_BUSY
;
2532 mutex_exit(zs
->zs_excl_hi
);
2537 * If the transmitter is ready, shove the first
2541 SCC_WRITEDATA(*rptr
++);
2545 zs
->zs_wr_cur
= rptr
;
2546 za
->za_flags
|= ZAS_BUSY
;
2547 zs
->zs_flags
|= ZS_PROGRESS
;
2548 mutex_exit(zs
->zs_excl_hi
);
2552 * Restart output on a line after a delay or break timer expired.
2555 zsa_restart(void *arg
)
2557 struct zscom
*zs
= arg
;
2558 struct asyncline
*za
= (struct asyncline
*)&zs
->zs_priv_str
;
2561 * If break timer expired, turn off the break bit.
2563 mutex_enter(zs
->zs_excl
);
2564 if (!za
->za_zsa_restart_id
) {
2565 mutex_exit(zs
->zs_excl
);
2568 za
->za_zsa_restart_id
= 0;
2569 if (za
->za_flags
& ZAS_BREAK
) {
2570 mutex_enter(zs
->zs_excl_hi
);
2571 SCC_BIC(5, ZSWR5_BREAK
);
2572 mutex_exit(zs
->zs_excl_hi
);
2574 za
->za_flags
&= ~(ZAS_DELAY
|ZAS_BREAK
);
2575 if (za
->za_ttycommon
.t_writeq
!= NULL
)
2577 mutex_exit(zs
->zs_excl
);
2578 cv_broadcast(&zs
->zs_flags_cv
);
2582 * See if the receiver has any data after zs_tick delay
2585 zsa_kick_rcv(void *arg
)
2587 struct zscom
*zs
= arg
;
2588 struct asyncline
*za
= (struct asyncline
*)&zs
->zs_priv_str
;
2592 uchar_t za_soft_active
, za_kick_active
;
2593 int allocbcount
= 0;
2594 int do_ttycommon_qfull
= 0;
2595 mblk_t
*head
= NULL
, *tail
= NULL
;
2597 mutex_enter(zs
->zs_excl
);
2598 if (za
->za_kick_rcv_id
== 0 || (zs
->zs_flags
& ZS_CLOSED
)) {
2599 mutex_exit(zs
->zs_excl
);
2602 za_soft_active
= za
->za_soft_active
;
2603 za_kick_active
= za
->za_kick_active
;
2604 q
= za
->za_ttycommon
.t_readq
;
2606 mutex_exit(zs
->zs_excl
);
2609 mutex_enter(zs
->zs_excl_hi
);
2610 if (zs
->zs_rd_cur
) {
2612 za
->za_kick_rcv_count
= tmp
= ZA_KICK_RCV_COUNT
;
2614 tmp
= --za
->za_kick_rcv_count
;
2615 if (tmp
> 0 || za_soft_active
|| za_kick_active
) {
2616 mutex_exit(zs
->zs_excl_hi
);
2618 za
->za_kick_rcv_id
= timeout(zsa_kick_rcv
,
2621 za
->za_kick_rcv_id
= timeout(zsa_kick_rcv
,
2622 zs
, zsticks
[SPEED(za
->za_ttycommon
.t_cflag
)]);
2623 if (za_soft_active
|| za_kick_active
) {
2624 mutex_exit(zs
->zs_excl
);
2628 za
->za_kick_rcv_id
= 0;
2629 mutex_exit(zs
->zs_excl_hi
);
2640 if (mp
->b_datap
->db_type
<= QPCTL
) {
2641 if (!(canputnext(q
))) {
2642 if (za
->za_grace_flow_control
>=
2643 zsa_grace_flow_control
) {
2644 if (za
->za_ttycommon
.t_cflag
&
2651 do_ttycommon_qfull
= 1;
2654 za
->za_grace_flow_control
++;
2656 za
->za_grace_flow_control
= 0;
2670 ZSA_GETBLOCK(zs
, allocbcount
);
2672 za
->za_kick_active
= 1;
2673 mutex_exit(zs
->zs_excl
);
2675 if (do_ttycommon_qfull
) {
2676 ttycommon_qfull(&za
->za_ttycommon
, q
);
2677 mutex_enter(zs
->zs_excl
);
2679 mutex_exit(zs
->zs_excl
);
2688 head
= head
->b_next
;
2693 za
->za_kick_active
= 0;
2695 if (zs
->zs_flags
& ZS_CLOSED
)
2696 cv_broadcast(&zs
->zs_flags_cv
);
2700 * Retry an "ioctl", now that "bufcall" claims we may be able to allocate
2701 * the buffer we need.
2704 zsa_reioctl(void *arg
)
2706 struct asyncline
*za
= arg
;
2707 struct zscom
*zs
= za
->za_common
;
2712 * The bufcall is no longer pending.
2714 mutex_enter(zs
->zs_excl
);
2715 if (!za
->za_wbufcid
) {
2716 mutex_exit(zs
->zs_excl
);
2720 if ((q
= za
->za_ttycommon
.t_writeq
) == NULL
) {
2721 mutex_exit(zs
->zs_excl
);
2724 if ((mp
= za
->za_ttycommon
.t_iocpending
) != NULL
) {
2726 * not pending any more
2728 za
->za_ttycommon
.t_iocpending
= NULL
;
2729 zsa_ioctl(za
, q
, mp
);
2731 mutex_exit(zs
->zs_excl
);
2735 * Process an "ioctl" message sent down to us.
2736 * Note that we don't need to get any locks until we are ready to access
2737 * the hardware. Nothing we access until then is going to be altered
2738 * outside of the STREAMS framework, so we should be safe.
2741 zsa_ioctl(struct asyncline
*za
, queue_t
*wq
, mblk_t
*mp
)
2743 register struct zscom
*zs
= za
->za_common
;
2744 register struct iocblk
*iocp
;
2745 register unsigned datasize
;
2747 register mblk_t
*tmp
;
2749 if (za
->za_ttycommon
.t_iocpending
!= NULL
) {
2751 * We were holding an "ioctl" response pending the
2752 * availability of an "mblk" to hold data to be passed up;
2753 * another "ioctl" came through, which means that "ioctl"
2754 * must have timed out or been aborted.
2756 freemsg(za
->za_ttycommon
.t_iocpending
);
2757 za
->za_ttycommon
.t_iocpending
= NULL
;
2760 iocp
= (struct iocblk
*)mp
->b_rptr
;
2763 * The only way in which "ttycommon_ioctl" can fail is if the "ioctl"
2764 * requires a response containing data to be returned to the user,
2765 * and no mblk could be allocated for the data.
2766 * No such "ioctl" alters our state. Thus, we always go ahead and
2767 * do any state-changes the "ioctl" calls for. If we couldn't allocate
2768 * the data, "ttycommon_ioctl" has stashed the "ioctl" away safely, so
2769 * we just call "bufcall" to request that we be called back when we
2770 * stand a better chance of allocating the data.
2772 mutex_exit(zs
->zs_excl
);
2773 datasize
= ttycommon_ioctl(&za
->za_ttycommon
, wq
, mp
, &error
);
2774 mutex_enter(zs
->zs_excl
);
2775 if (za
->za_ttycommon
.t_flags
& TS_SOFTCAR
)
2776 zssoftCAR
[zs
->zs_unit
] = 1;
2778 zssoftCAR
[zs
->zs_unit
] = 0;
2779 if (datasize
!= 0) {
2781 unbufcall(za
->za_wbufcid
);
2782 za
->za_wbufcid
= bufcall(datasize
, BPRI_HI
, zsa_reioctl
, za
);
2789 * "ttycommon_ioctl" did most of the work; we just use the
2792 switch (iocp
->ioc_cmd
) {
2800 mutex_enter(zs
->zs_excl_hi
);
2802 zsa_set_za_rcv_flags_mask(za
);
2803 mutex_exit(zs
->zs_excl_hi
);
2806 } else if (error
< 0) {
2808 * "ttycommon_ioctl" didn't do anything; we process it here.
2812 switch (iocp
->ioc_cmd
) {
2815 error
= miocpullup(mp
, sizeof (int));
2819 if (*(int *)mp
->b_cont
->b_rptr
== 0) {
2821 * The delay ensures that a 3 byte transmit
2824 mutex_exit(zs
->zs_excl
);
2825 delay(ztdelay(SPEED(za
->za_ttycommon
.t_cflag
)));
2826 mutex_enter(zs
->zs_excl
);
2829 * Set the break bit, and arrange for
2830 * "zsa_restart" to be called in 1/4 second;
2831 * it will turn the break bit off, and call
2832 * "zsa_start" to grab the next message.
2834 mutex_enter(zs
->zs_excl_hi
);
2835 SCC_BIS(5, ZSWR5_BREAK
);
2836 if (!za
->za_zsa_restart_id
) {
2837 mutex_exit(zs
->zs_excl_hi
);
2838 za
->za_zsa_restart_id
=
2839 timeout(zsa_restart
, zs
, hz
/ 4);
2840 mutex_enter(zs
->zs_excl_hi
);
2842 za
->za_flags
|= ZAS_BREAK
;
2843 mutex_exit(zs
->zs_excl_hi
);
2848 mutex_enter(zs
->zs_excl_hi
);
2849 SCC_BIS(5, ZSWR5_BREAK
);
2850 mutex_exit(zs
->zs_excl_hi
);
2851 mioc2ack(mp
, NULL
, 0, 0);
2855 mutex_enter(zs
->zs_excl_hi
);
2856 SCC_BIC(5, ZSWR5_BREAK
);
2857 mutex_exit(zs
->zs_excl_hi
);
2858 mioc2ack(mp
, NULL
, 0, 0);
2866 if (iocp
->ioc_count
== TRANSPARENT
) {
2867 mcopyin(mp
, NULL
, sizeof (int), NULL
);
2871 error
= miocpullup(mp
, sizeof (int));
2875 mlines
= *(int *)mp
->b_cont
->b_rptr
;
2877 mutex_enter(zs
->zs_excl_hi
);
2878 switch (iocp
->ioc_cmd
) {
2880 (void) zsmctl(zs
, dmtozs(mlines
), DMSET
);
2883 (void) zsmctl(zs
, dmtozs(mlines
), DMBIS
);
2886 (void) zsmctl(zs
, dmtozs(mlines
), DMBIC
);
2889 mutex_exit(zs
->zs_excl_hi
);
2891 mioc2ack(mp
, NULL
, 0, 0);
2896 tmp
= allocb(sizeof (int), BPRI_MED
);
2901 if (iocp
->ioc_count
!= TRANSPARENT
)
2902 mioc2ack(mp
, tmp
, sizeof (int), 0);
2904 mcopyout(mp
, NULL
, sizeof (int), NULL
, tmp
);
2906 mutex_enter(zs
->zs_excl_hi
);
2907 *(int *)mp
->b_cont
->b_rptr
=
2908 zstodm(zsmctl(zs
, 0, DMGET
));
2909 mutex_exit(zs
->zs_excl_hi
);
2917 * If we don't understand it, it's an error. NAK it.
2925 iocp
->ioc_error
= error
;
2926 mp
->b_datap
->db_type
= M_IOCNAK
;
2938 if (bits
& TIOCM_CAR
)
2940 if (bits
& TIOCM_CTS
)
2942 if (bits
& TIOCM_RTS
)
2944 if (bits
& TIOCM_DTR
)
2955 if (bits
& ZSRR0_CD
)
2957 if (bits
& ZSRR0_CTS
)
2959 if (bits
& ZSWR5_RTS
)
2961 if (bits
& ZSWR5_DTR
)
2967 * Assemble registers and flags necessary to program the port to our liking.
2968 * For async operation, most of this is based on the values of
2969 * the "c_iflag" and "c_cflag" fields supplied to us.
2972 zsa_program(struct asyncline
*za
, int setibaud
)
2974 register struct zscom
*zs
= za
->za_common
;
2975 register struct zs_prog
*zspp
;
2976 register int wr3
, wr4
, wr5
, wr15
, speed
, baudrate
, flags
= 0;
2978 if ((baudrate
= SPEED(za
->za_ttycommon
.t_cflag
)) == 0) {
2982 (void) zsmctl(zs
, ZS_OFF
, DMSET
);
2987 * set input speed same as output, as split speed not supported
2990 za
->za_ttycommon
.t_cflag
&= ~(CIBAUD
);
2991 if (baudrate
> CBAUD
) {
2992 za
->za_ttycommon
.t_cflag
|= CIBAUDEXT
;
2993 za
->za_ttycommon
.t_cflag
|=
2994 (((baudrate
- CBAUD
- 1) << IBSHIFT
) & CIBAUD
);
2996 za
->za_ttycommon
.t_cflag
&= ~CIBAUDEXT
;
2997 za
->za_ttycommon
.t_cflag
|=
2998 ((baudrate
<< IBSHIFT
) & CIBAUD
);
3003 * Do not allow the console/keyboard device to have its receiver
3004 * disabled; doing that would mean you couldn't type an abort
3007 if ((za
->za_dev
== rconsdev
) || (za
->za_dev
== kbddev
) ||
3008 (za
->za_dev
== stdindev
) || (za
->za_ttycommon
.t_cflag
& CREAD
))
3009 wr3
= ZSWR3_RX_ENABLE
;
3012 wr4
= ZSWR4_X16_CLK
;
3013 wr5
= (zs
->zs_wreg
[5] & (ZSWR5_RTS
|ZSWR5_DTR
)) | ZSWR5_TX_ENABLE
;
3015 if (zsb134_weird
&& baudrate
== B134
) { /* what a joke! */
3017 * XXX - should B134 set all this crap in the compatibility
3018 * module, leaving this stuff fairly clean?
3020 flags
|= ZSP_PARITY_SPECIAL
;
3022 wr4
|= ZSWR4_PARITY_ENABLE
| ZSWR4_PARITY_EVEN
;
3023 wr4
|= ZSWR4_1_5_STOP
;
3027 switch (za
->za_ttycommon
.t_cflag
& CSIZE
) {
3050 if (za
->za_ttycommon
.t_cflag
& PARENB
) {
3052 * The PARITY_SPECIAL bit causes a special rx
3053 * interrupt on parity errors. Turn it on if
3054 * we're checking the parity of characters.
3056 if (za
->za_ttycommon
.t_iflag
& INPCK
)
3057 flags
|= ZSP_PARITY_SPECIAL
;
3058 wr4
|= ZSWR4_PARITY_ENABLE
;
3059 if (!(za
->za_ttycommon
.t_cflag
& PARODD
))
3060 wr4
|= ZSWR4_PARITY_EVEN
;
3062 wr4
|= (za
->za_ttycommon
.t_cflag
& CSTOPB
) ?
3063 ZSWR4_2_STOP
: ZSWR4_1_STOP
;
3068 * The AUTO_CD_CTS flag enables the hardware flow control feature of
3069 * the 8530, which allows the state of CTS and DCD to control the
3070 * enabling of the transmitter and receiver, respectively. The
3071 * receiver and transmitter still must have their enable bits set in
3072 * WR3 and WR5, respectively, for CTS and DCD to be monitored this way.
3073 * Hardware flow control can thus be implemented with no help from
3076 if (za
->za_ttycommon
.t_cflag
& CRTSCTS
)
3077 wr3
|= ZSWR3_AUTO_CD_CTS
;
3079 if (za
->za_ttycommon
.t_cflag
& CRTSCTS
)
3080 wr15
= ZSR15_BREAK
| ZSR15_TX_UNDER
| ZSR15_CD
| ZSR15_CTS
;
3082 wr15
= ZSR15_BREAK
| ZSR15_TX_UNDER
| ZSR15_CD
;
3084 speed
= zs
->zs_wreg
[12] + (zs
->zs_wreg
[13] << 8);
3087 * Here we assemble a set of changes to be passed to zs_program.
3088 * Note: Write Register 15 must be set to enable BREAK and UNDERrun
3089 * interrupts. It must also enable CD interrupts which, although
3090 * not processed by the hardware interrupt handler, will be processed
3091 * by zsa_process, indirectly resulting in a SIGHUP being delivered
3092 * to the controlling process if CD drops. CTS interrupts must NOT
3093 * be enabled. We don't use them at all, and they will hang IPC/IPX
3094 * systems at boot time if synchronous modems that supply transmit
3095 * clock are attached to any of their serial ports.
3097 if (((zs
->zs_wreg
[1] & ZSWR1_PARITY_SPECIAL
) &&
3098 !(flags
& ZSP_PARITY_SPECIAL
)) ||
3099 (!(zs
->zs_wreg
[1] & ZSWR1_PARITY_SPECIAL
) &&
3100 (flags
& ZSP_PARITY_SPECIAL
)) ||
3101 wr3
!= zs
->zs_wreg
[3] || wr4
!= zs
->zs_wreg
[4] ||
3102 wr5
!= zs
->zs_wreg
[5] || wr15
!= zs
->zs_wreg
[15] ||
3103 speed
!= zs_speeds
[baudrate
]) {
3105 za
->za_flags
|= ZAS_DRAINING
;
3106 zspp
= &zs_prog
[zs
->zs_unit
];
3108 zspp
->flags
= (uchar_t
)flags
;
3109 zspp
->wr4
= (uchar_t
)wr4
;
3110 zspp
->wr11
= (uchar_t
)(ZSWR11_TXCLK_BAUD
| ZSWR11_RXCLK_BAUD
);
3112 speed
= zs_speeds
[baudrate
];
3113 zspp
->wr12
= (uchar_t
)(speed
& 0xff);
3114 zspp
->wr13
= (uchar_t
)((speed
>> 8) & 0xff);
3115 zspp
->wr3
= (uchar_t
)wr3
;
3116 zspp
->wr5
= (uchar_t
)wr5
;
3117 zspp
->wr15
= (uchar_t
)wr15
;
3120 za
->za_flags
&= ~ZAS_DRAINING
;
3125 * Get the current speed of the console and turn it into something
3126 * UNIX knows about - used to preserve console speed when UNIX comes up.
3129 zsgetspeed(dev_t dev
)
3131 register struct zscom
*zs
;
3132 register int uspeed
, zspeed
;
3133 register uchar_t rr
;
3135 zs
= &zscom
[UNIT(dev
)];
3136 SCC_READ(12, zspeed
);
3139 for (uspeed
= 0; uspeed
< NSPEED
; uspeed
++)
3140 if (zs_speeds
[uspeed
] == zspeed
)
3143 * 9600 baud if we can't figure it out
3149 * callback routine when enough memory is available.
3152 zsa_callback(void *arg
)
3154 struct zscom
*zs
= arg
;
3155 struct asyncline
*za
= (struct asyncline
*)&zs
->zs_priv_str
;
3156 int allocbcount
= zsa_rstandby
;
3158 mutex_enter(zs
->zs_excl
);
3159 if (za
->za_bufcid
) {
3161 ZSA_GETBLOCK(zs
, allocbcount
);
3163 mutex_exit(zs
->zs_excl
);
3167 * Set the receiver flags
3170 zsa_set_za_rcv_flags_mask(struct asyncline
*za
)
3172 register uint_t mask
;
3174 za
->za_rcv_flags_mask
&= ~0xFF;
3175 switch (za
->za_ttycommon
.t_cflag
& CSIZE
) {
3189 za
->za_rcv_flags_mask
&= ~(0xFF << 16);
3190 za
->za_rcv_flags_mask
|= mask
<< 16;
3192 if ((za
->za_ttycommon
.t_iflag
& PARMRK
) &&
3193 !(za
->za_ttycommon
.t_iflag
& (IGNPAR
|ISTRIP
))) {
3194 za
->za_rcv_flags_mask
|= DO_ESC
;
3196 za
->za_rcv_flags_mask
&= ~DO_ESC
;
3197 if (za
->za_ttycommon
.t_iflag
& IXON
) {
3198 za
->za_rcv_flags_mask
|= DO_STOPC
;
3199 za
->za_rcv_flags_mask
&= ~0xFF;
3200 za
->za_rcv_flags_mask
|= za
->za_ttycommon
.t_stopc
;
3202 za
->za_rcv_flags_mask
&= ~DO_STOPC
;
3206 zsa_suspend(struct zscom
*zs
)
3208 struct asyncline
*za
;
3211 timeout_id_t restart_id
, kick_rcv_id
;
3212 struct zs_prog
*zspp
;
3214 za
= (struct asyncline
*)&zs
->zs_priv_str
;
3215 mutex_enter(zs
->zs_excl
);
3216 if (zs
->zs_suspended
) {
3217 mutex_exit(zs
->zs_excl
);
3218 return (DDI_SUCCESS
);
3220 zs
->zs_suspended
= 1;
3223 * Turn off interrupts and get any bytes in receiver
3225 mutex_enter(zs
->zs_excl_hi
);
3226 SCC_BIC(1, ZSWR1_INIT
);
3228 restart_id
= za
->za_zsa_restart_id
;
3229 za
->za_zsa_restart_id
= 0;
3230 kick_rcv_id
= za
->za_kick_rcv_id
;
3231 za
->za_kick_rcv_id
= 0;
3232 mutex_exit(zs
->zs_excl_hi
);
3233 mutex_exit(zs
->zs_excl
);
3236 * Cancel any timeouts
3239 (void) untimeout(restart_id
);
3241 (void) untimeout(kick_rcv_id
);
3244 * Since we have turned off interrupts, zsa_txint will not be called
3245 * and no new chars will given to the chip. We just wait for the
3246 * current character(s) to drain.
3248 delay(ztdelay(za
->za_ttycommon
.t_cflag
& CBAUD
));
3251 * Return remains of partially sent message to queue
3253 mutex_enter(zs
->zs_excl
);
3254 if ((q
= za
->za_ttycommon
.t_writeq
) != NULL
) {
3255 mutex_enter(zs
->zs_excl_hi
);
3256 if ((zs
->zs_wr_cur
) != NULL
) {
3257 za
->za_flags
&= ~ZAS_BUSY
;
3258 za
->za_rcv_flags_mask
&= ~DO_RETRANSMIT
;
3259 bp
= za
->za_xmitblk
;
3260 bp
->b_rptr
= zs
->zs_wr_cur
;
3261 zs
->zs_wr_cur
= NULL
;
3262 zs
->zs_wr_lim
= NULL
;
3263 za
->za_xmitblk
= NULL
;
3265 mutex_exit(zs
->zs_excl_hi
);
3267 (void) putbq(q
, bp
);
3271 * Stop any breaks in progress.
3273 mutex_enter(zs
->zs_excl_hi
);
3274 if (zs
->zs_wreg
[5] & ZSWR5_BREAK
) {
3275 SCC_BIC(5, ZSWR5_BREAK
);
3276 za
->za_flags
&= ~ZAS_BREAK
;
3280 * Now get a copy of current registers setting.
3282 zspp
= &zs_prog
[zs
->zs_unit
];
3285 zspp
->wr3
= zs
->zs_wreg
[3];
3286 zspp
->wr4
= zs
->zs_wreg
[4];
3287 zspp
->wr5
= zs
->zs_wreg
[5];
3288 zspp
->wr11
= zs
->zs_wreg
[11];
3289 zspp
->wr12
= zs
->zs_wreg
[12];
3290 zspp
->wr13
= zs
->zs_wreg
[13];
3291 zspp
->wr15
= zs
->zs_wreg
[15];
3292 mutex_exit(zs
->zs_excl_hi
);
3293 mutex_exit(zs
->zs_excl
);
3295 * We do this on the off chance that zsa_close is waiting on a timed
3296 * break to complete and nothing else.
3298 cv_broadcast(&zs
->zs_flags_cv
);
3299 return (DDI_SUCCESS
);
3303 zsa_resume(struct zscom
*zs
)
3305 register struct asyncline
*za
;
3306 struct zs_prog
*zspp
;
3308 za
= (struct asyncline
*)&zs
->zs_priv_str
;
3309 mutex_enter(zs
->zs_excl
);
3310 if (!(zs
->zs_suspended
)) {
3311 mutex_exit(zs
->zs_excl
);
3312 return (DDI_SUCCESS
);
3318 mutex_enter(zs
->zs_excl_hi
);
3319 zspp
= &zs_prog
[zs
->zs_unit
];
3323 * Enable all interrupts for this chip and delay to let chip settle
3325 SCC_WRITE(9, ZSWR9_MASTER_IE
| ZSWR9_VECTOR_INCL_STAT
);
3329 * Restart receiving and transmitting
3331 zs
->zs_suspended
= 0;
3332 za
->za_rcv_flags_mask
|= DO_TRANSMIT
;
3335 mutex_exit(zs
->zs_excl_hi
);
3336 mutex_exit(zs
->zs_excl
);
3338 return (DDI_SUCCESS
);
3343 zsa_print_info(struct zscom
*zs
)
3345 register struct asyncline
*za
= (struct asyncline
*)&zs
->zs_priv_str
;
3346 register queue_t
*q
= za
->za_ttycommon
.t_writeq
;
3348 printf(" next q=%s\n", (RD(q
))->q_next
->q_qinfo
->qi_minfo
->mi_idname
);
3349 printf("unit=%d\n", zs
->zs_unit
);
3351 if (za
->za_ttycommon
.t_flags
& TS_SOFTCAR
) printf(" t_fl:TS_SOFTCAR");
3352 if (za
->za_ttycommon
.t_flags
& TS_XCLUDE
) printf(" t_fl:TS_XCLUDE");
3353 if (za
->za_ttycommon
.t_iflag
& IGNBRK
) printf(" t_ifl:IGNBRK");
3354 if (za
->za_ttycommon
.t_iflag
& BRKINT
) printf(" t_ifl:BRKINT");
3355 if (za
->za_ttycommon
.t_iflag
& IGNPAR
) printf(" t_ifl:IGNPAR");
3356 if (za
->za_ttycommon
.t_iflag
& PARMRK
) printf(" t_ifl:PARMRK");
3357 if (za
->za_ttycommon
.t_iflag
& INPCK
) printf(" t_ifl:INPCK");
3358 if (za
->za_ttycommon
.t_iflag
& ISTRIP
) printf(" t_ifl:ISTRIP");
3359 if (za
->za_ttycommon
.t_iflag
& INLCR
) printf(" t_ifl:INLCR");
3360 if (za
->za_ttycommon
.t_iflag
& IGNCR
) printf(" t_ifl:IGNCR");
3361 if (za
->za_ttycommon
.t_iflag
& ICRNL
) printf(" t_ifl:ICRNL");
3362 if (za
->za_ttycommon
.t_iflag
& IUCLC
) printf(" t_ifl:IUCLC");
3363 if (za
->za_ttycommon
.t_iflag
& IXON
) printf(" t_ifl:IXON");
3364 if (za
->za_ttycommon
.t_iflag
& IXOFF
) printf(" t_ifl:IXOFF");
3369 if (za
->za_ttycommon
.t_cflag
& CSIZE
== CS5
) printf(" t_cfl:CS5");
3370 if (za
->za_ttycommon
.t_cflag
& CSIZE
== CS6
) printf(" t_cfl:CS6");
3371 if (za
->za_ttycommon
.t_cflag
& CSIZE
== CS7
) printf(" t_cfl:CS7");
3372 if (za
->za_ttycommon
.t_cflag
& CSIZE
== CS8
) printf(" t_cfl:CS8");
3373 if (za
->za_ttycommon
.t_cflag
& CSTOPB
) printf(" t_cfl:CSTOPB");
3374 if (za
->za_ttycommon
.t_cflag
& CREAD
) printf(" t_cfl:CREAD");
3375 if (za
->za_ttycommon
.t_cflag
& PARENB
) printf(" t_cfl:PARENB");
3376 if (za
->za_ttycommon
.t_cflag
& PARODD
) printf(" t_cfl:PARODD");
3377 if (za
->za_ttycommon
.t_cflag
& HUPCL
) printf(" t_cfl:HUPCL");
3378 if (za
->za_ttycommon
.t_cflag
& CLOCAL
) printf(" t_cfl:CLOCAL");
3379 printf(" t_stopc=%x", za
->za_ttycommon
.t_stopc
);
3385 * Check for abort character sequence
3388 abort_charseq_recognize(uchar_t ch
)
3390 static int state
= 0;
3391 #define CNTRL(c) ((c)&037)
3392 static char sequence
[] = { '\r', '~', CNTRL('b') };
3394 if (ch
== sequence
[state
]) {
3395 if (++state
>= sizeof (sequence
)) {
3400 state
= (ch
== sequence
[0]) ? 1 : 0;