1 /*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
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.
12 *
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]
18 *
19 * CDDL HEADER END
20 */
21 /*
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.
25 * Copyright (c) 2019 Peter Tribble.
26 */
27
28 /*
29 * Asynchronous protocol handler for Z8530 chips
30 * Handles normal UNIX support for terminals & modems
31 */
32
33 #include <sys/types.h>
34 #include <sys/param.h>
35 #include <sys/systm.h>
36 #include <sys/sysmacros.h>
37 #include <sys/signal.h>
38 #include <sys/kmem.h>
39 #include <sys/termios.h>
40 #include <sys/stropts.h>
41 #include <sys/stream.h>
42 #include <sys/strsun.h>
43 #include <sys/tty.h>
44 #include <sys/ptyvar.h>
45 #include <sys/cred.h>
46 #include <sys/user.h>
47 #include <sys/proc.h>
48 #include <sys/file.h>
49 #include <sys/uio.h>
50 #include <sys/buf.h>
51 #include <sys/mkdev.h>
52 #include <sys/cmn_err.h>
53 #include <sys/strtty.h>
54 #include <sys/consdev.h>
55 #include <sys/zsdev.h>
56 #include <sys/ser_async.h>
57 #include <sys/debug.h>
58 #include <sys/kbio.h>
59 #include <sys/conf.h>
60 #include <sys/ddi.h>
61 #include <sys/sunddi.h>
62 #include <sys/promif.h>
63 #include <sys/policy.h>
64
65 /*
66 * PPS (Pulse Per Second) support.
67 */
68 extern void ddi_hardpps(struct timeval *, int);
69 static struct ppsclockev ppsclockev;
70
71 #ifdef PPSCLOCKLED
72 /* XXX Use these to observe PPS latencies and jitter on a scope */
73 #define LED_ON
74 #define LED_OFF
75 #else
76 #define LED_ON
77 #define LED_OFF
78 #endif
79
80 #define ZSA_RCV_SIZE 64
81 #define ZA_KICK_RCV_COUNT 3
82 #define ZSA_GRACE_MIN_FLOW_CONTROL 5
83 #define ZSA_GRACE_MAX_FLOW_CONTROL 20
84
85 int zsasoftdtr = 0; /* if nonzero, softcarrier raises dtr at attach */
86 int zsb134_weird = 0; /* if set, old weird B134 behavior */
87 int g_zsticks = 0; /* if set, becomes the global zsticks value */
88 int g_nocluster = 0; /* if set, disables clustering of received data */
89
90 unsigned int zsa_rstandby = ZSA_MIN_RSTANDBY;
91 unsigned int zsa_rdone = ZSA_RDONE_MIN;
92 unsigned int zsa_grace_flow_control = ZSA_GRACE_MIN_FLOW_CONTROL;
93
94
95 #define NSPEED 18 /* max # of speeds */
96 ushort_t zs_speeds[NSPEED] = {
97 0,
98 ZSPEED(50), /* 1 */
99 ZSPEED(75), /* 2 */
100 ZSPEED(110), /* 3 */
101 #ifdef lint
102 ZSPEED(134), /* 4 */
103 #else
104 ZSPEED(269/2), /* XXX - This is sleazy */
105 #endif
106 ZSPEED(150), /* 5 */
107 ZSPEED(200), /* 6 */
108 ZSPEED(300), /* 7 */
109 ZSPEED(600), /* 8 */
110 ZSPEED(1200), /* 9 */
111 ZSPEED(1800), /* 10 */
112 ZSPEED(2400), /* 11 */
113 ZSPEED(4800), /* 12 */
114 ZSPEED(9600), /* 13 */
115 ZSPEED(19200), /* 14 */
116 ZSPEED(38400), /* 15 */
117 ZSPEED(57680), /* 16 */
118 ZSPEED(76800) /* 17 */
119 };
120
121 ushort_t zsticks[NSPEED] = {
122 3, /* 0 */
123 3, /* 1 */
124 3, /* 2 */
125 3, /* 3 */
126 3, /* 4 */
127 3, /* 5 */
128 3, /* 6 */
129 3, /* 7 */
130 3, /* 8 */
131 3, /* 9 */
132 3, /* 10 */
133 3, /* 11 */
134 3, /* 12 */
135 3, /* 13 */
136 2, /* 14 */
137 1, /* 15 */
138 1, /* 16 */
139 1 /* 17 */
140 };
141
142 #define ztdelay(nsp) (zsdelay[(nsp)]*(hz/100))
143
144 ushort_t zsdelay[NSPEED] = {
145 0,
146 ZDELAY(50), /* 1 */
147 ZDELAY(75), /* 2 */
148 ZDELAY(110), /* 3 */
149 #ifdef lint
150 ZDELAY(134), /* 4 */
151 #else
152 ZDELAY(269/2),
153 #endif
154 ZDELAY(150), /* 5 */
155 ZDELAY(200), /* 6 */
156 ZDELAY(300), /* 7 */
157 ZDELAY(600), /* 8 */
158 ZDELAY(1200), /* 9 */
159 ZDELAY(1800), /* 10 */
160 ZDELAY(2400), /* 11 */
161 ZDELAY(4800), /* 12 */
162 ZDELAY(9600), /* 13 */
163 ZDELAY(19200), /* 14 */
164 ZDELAY(38400), /* 15 */
165 ZDELAY(57600), /* 16 */
166 ZDELAY(76800) /* 17 */
167 };
168
169 ushort_t zslowat[NSPEED] = {
170 3, /* 0 */
171 3, /* 1 */
172 3, /* 2 */
173 3, /* 3 */
174 3, /* 4 */
175 3, /* 5 */
176 3, /* 6 */
177 2, /* 7 */
178 2, /* 8 */
179 2, /* 9 */
180 2, /* 10 */
181 1, /* 11 */
182 1, /* 12 */
183 1, /* 13 */
184 1, /* 14 */
185 1, /* 15 */
186 1, /* 16 */
187 1 /* 17 */
188 };
189
190 ushort_t zshiwat[NSPEED] = {
191 0, /* 0 */
192 1, /* 1 */
193 1, /* 2 */
194 1, /* 3 */
195 1, /* 4 */
196 1, /* 5 */
197 1, /* 6 */
198 1, /* 7 */
199 1, /* 8 */
200 1, /* 9 */
201 1, /* 10 */
202 1, /* 11 */
203 1, /* 12 */
204 3, /* 13 */
205 3, /* 14 */
206 4, /* 15 */
207 4, /* 16 */
208 4 /* 17 */
209 };
210
211 #define SLAVIO_BUG /* this workaround required to fix bug 1102778 */
212
213 #define SPEED(cflag) \
214 ((cflag) & CBAUDEXT) ? \
215 (((cflag) & 0x1) + CBAUD + 1) : ((cflag) & CBAUD)
216
217 /*
218 * Special macros to handle STREAMS operations.
219 * These are required to address memory leakage problems.
220 * WARNING : the macro do NOT call ZSSETSOFT
221 */
222
223 /*
224 * Should be called holding only the adaptive (zs_excl) mutex.
225 */
226 #define ZSA_GETBLOCK(zs, allocbcount) \
227 { \
228 int n = zsa_rstandby; \
229 while (--n >= 0 && allocbcount > 0) { \
230 if (!za->za_rstandby[n]) { \
231 if ((za->za_rstandby[n] = allocb(ZSA_RCV_SIZE, \
232 BPRI_MED)) == NULL) { \
233 if (za->za_bufcid == 0) { \
234 za->za_bufcid = bufcall(ZSA_RCV_SIZE, \
235 BPRI_MED, \
236 zsa_callback, zs); \
237 break; \
238 } \
239 } \
240 allocbcount--; \
241 } \
242 } \
243 if (za->za_ttycommon.t_cflag & CRTSXOFF) { \
244 mutex_enter(zs->zs_excl_hi); \
245 if (!(zs->zs_wreg[5] & ZSWR5_RTS)) { \
246 int usedcnt = 0; \
247 for (n = 0; n < zsa_rstandby; n++) \
248 if (!za->za_rstandby[n]) \
249 usedcnt++; \
250 if ((ushort_t)usedcnt <= \
251 zslowat[SPEED(za->za_ttycommon.t_cflag)]) \
252 SCC_BIS(5, ZSWR5_RTS); \
253 } \
254 mutex_exit(zs->zs_excl_hi); \
255 } \
256 }
257
258 /*
259 * Should be called holding the spin (zs_excl_hi) mutex.
260 */
261 #define ZSA_ALLOCB(mp) \
262 { \
263 int n = zsa_rstandby; \
264 while (--n >= 0) { \
265 if ((mp = za->za_rstandby[n]) != NULL) { \
266 za->za_rstandby[n] = NULL; \
267 break; \
268 } \
269 } \
270 if (za->za_ttycommon.t_cflag & CRTSXOFF) { \
271 if (!mp) { \
272 if (zs->zs_wreg[5] & ZSWR5_RTS) \
273 SCC_BIC(5, ZSWR5_RTS); \
274 cmn_err(CE_WARN, "zs%d: message lost\n", \
275 UNIT(za->za_dev)); \
276 } else if (zs->zs_wreg[5] & ZSWR5_RTS) { \
277 int usedcnt = 0; \
278 for (n = 0; n < zsa_rstandby; n++) \
279 if (!za->za_rstandby[n]) \
280 usedcnt++; \
281 if ((ushort_t)usedcnt >= (zsa_rstandby - \
282 zshiwat[SPEED(za->za_ttycommon.t_cflag)])) \
283 SCC_BIC(5, ZSWR5_RTS); \
284 } \
285 } \
286 }
287
288 /*
289 * Should get the spin (zs_excl_hi) mutex.
290 */
291 #define ZSA_QREPLY(q, mp) \
292 { \
293 mutex_enter(zs->zs_excl_hi); \
294 ZSA_PUTQ(mp); \
295 ZSSETSOFT(zs); \
296 mutex_exit(zs->zs_excl_hi); \
297 }
298
299 /*
300 * Should be called holding the spin (zs_excl_hi) mutex.
301 */
302 #define ZSA_PUTQ(mp) \
303 { \
304 int wptr, rptr; \
305 wptr = za->za_rdone_wptr; \
306 rptr = za->za_rdone_rptr; \
307 za->za_rdone[wptr] = mp; \
308 if ((wptr)+1 == zsa_rdone) { \
309 za->za_rdone_wptr = wptr = 0; \
310 } else \
311 za->za_rdone_wptr = ++wptr; \
312 if (wptr == rptr) { \
313 SCC_BIC(1, ZSWR1_INIT); \
314 cmn_err(CE_WARN, "zs%d disabled: input buffer overflow", \
315 UNIT(za->za_dev)); \
316 } \
317 }
318
319 /*
320 * Should be called holding the spin (zs_excl_hi) mutex.
321 */
322 #define ZSA_KICK_RCV \
323 { \
324 mblk_t *mp = za->za_rcvblk; \
325 if (mp) { \
326 if (zs->zs_rd_cur) { /* M_DATA */ \
327 mp->b_wptr = zs->zs_rd_cur; \
328 zs->zs_rd_cur = NULL; \
329 zs->zs_rd_lim = NULL; \
330 } \
331 za->za_rcvblk = NULL; \
332 ZSA_PUTQ(mp); \
333 ZSSETSOFT(zs); \
334 } \
335 }
336
337 #define ZSA_SEEQ(mp) \
338 { \
339 if (za->za_rdone_rptr != za->za_rdone_wptr) { \
340 mp = za->za_rdone[za->za_rdone_rptr]; \
341 } else { \
342 mp = NULL; \
343 } \
344 }
345
346
347 /*
348 * Should be called holding only the adaptive (zs_excl) mutex.
349 */
350 #define ZSA_GETQ(mp) \
351 { \
352 if (za->za_rdone_rptr != za->za_rdone_wptr) { \
353 mp = za->za_rdone[za->za_rdone_rptr]; \
354 za->za_rdone[za->za_rdone_rptr++] = NULL; \
355 if (za->za_rdone_rptr == zsa_rdone) \
356 za->za_rdone_rptr = 0; \
357 } else { \
358 mp = NULL; \
359 } \
360 }
361
362 /*
363 * Should be called holding only the adaptive (zs_excl) mutex.
364 */
365 #define ZSA_FLUSHQ \
366 { \
367 mblk_t *tmp; \
368 for (;;) { \
369 ZSA_GETQ(tmp); \
370 if (!(tmp)) \
371 break; \
372 freemsg(tmp); \
373 } \
374 }
375
376
377 /*
378 * Logging definitions
379 */
380
381 #ifdef ZSA_DEBUG
382
383 #ifdef ZS_DEBUG_ALL
384
385 extern char zs_h_log[];
386 extern int zs_h_log_n;
387
388 #define zsa_h_log_clear
389
390 #define zsa_h_log_add(c) \
391 { \
392 if (zs_h_log_n >= ZS_H_LOG_MAX) \
393 zs_h_log_n = 0; \
394 zs_h_log[zs_h_log_n++] = 'A' + zs->zs_unit; \
395 zs_h_log[zs_h_log_n++] = c; \
396 zs_h_log[zs_h_log_n] = '\0'; \
397 }
398
399 #else /* ZS_DEBUG_ALL */
400
401 #define ZSA_H_LOG_MAX 0x4000
402 char zsa_h_log[40][ZSA_H_LOG_MAX +10];
403 int zsa_h_log_n[40];
404
405 #define zsa_h_log_add(c) \
406 { \
407 if (zsa_h_log_n[zs->zs_unit] >= ZSA_H_LOG_MAX) \
408 zsa_h_log_n[zs->zs_unit] = 0; \
409 zsa_h_log[zs->zs_unit][zsa_h_log_n[zs->zs_unit]++] = c; \
410 zsa_h_log[zs->zs_unit][zsa_h_log_n[zs->zs_unit]] = '\0'; \
411 }
412
413 #define zsa_h_log_clear \
414 { \
415 char *p; \
416 for (p = &zsa_h_log[zs->zs_unit][ZSA_H_LOG_MAX]; \
417 p >= &zsa_h_log[zs->zs_unit][0]; /* null */) \
418 *p-- = '\0'; \
419 zsa_h_log_n[zs->zs_unit] = 0; \
420 }
421
422 #endif /* ZS_DEBUG_ALL */
423
424 #define ZSA_R0_LOG(r0) \
425 { \
426 if (r0 & ZSRR0_RX_READY) zsa_h_log_add('R'); \
427 if (r0 & ZSRR0_TIMER) zsa_h_log_add('Z'); \
428 if (r0 & ZSRR0_TX_READY) zsa_h_log_add('T'); \
429 if (r0 & ZSRR0_CD) zsa_h_log_add('D'); \
430 if (r0 & ZSRR0_SYNC) zsa_h_log_add('S'); \
431 if (r0 & ZSRR0_CTS) zsa_h_log_add('C'); \
432 if (r0 & ZSRR0_TXUNDER) zsa_h_log_add('U'); \
433 if (r0 & ZSRR0_BREAK) zsa_h_log_add('B'); \
434 }
435
436 #else /* ZSA_DEBUG */
437
438 #define zsa_h_log_clear
439 #define zsa_h_log_add(c)
440 #define ZSA_R0_LOG(r0)
441
442 #endif /* ZSA_DEBUG */
443
444
445
446 static int zsa_open(queue_t *rq, dev_t *dev, int flag, int sflag, cred_t *cr);
447 static int zsa_close(queue_t *q, int flag, cred_t *cr);
448 static int zsa_wput(queue_t *q, mblk_t *mp);
449 static int zsa_rsrv(queue_t *q);
450
451 static struct module_info asyncm_info = {
452 0,
453 "zs",
454 0,
455 INFPSZ,
456 2048,
457 128
458 };
459
460 static struct qinit async_rinit = {
461 putq,
462 zsa_rsrv,
463 zsa_open,
464 zsa_close,
465 NULL,
466 &asyncm_info,
467 NULL
468 };
469
470 static struct qinit async_winit = {
471 zsa_wput,
472 NULL,
473 NULL,
474 NULL,
475 NULL,
476 &asyncm_info,
477 NULL
478 };
479
480 struct streamtab asynctab = {
481 &async_rinit,
482 &async_winit,
483 NULL,
484 NULL,
485 };
486
487 /*
488 * The async interrupt entry points.
489 */
490 static void zsa_txint(struct zscom *zs);
491 static void zsa_xsint(struct zscom *zs);
492 static void zsa_rxint(struct zscom *zs);
493 static void zsa_srint(struct zscom *zs);
494 static int zsa_softint(struct zscom *zs);
495 static int zsa_suspend(struct zscom *zs);
496 static int zsa_resume(struct zscom *zs);
497
498 static void
zsa_null(struct zscom * zs)499 zsa_null(struct zscom *zs)
500 {
501 short c;
502
503 SCC_WRITE0(ZSWR0_RESET_TXINT);
504 SCC_WRITE0(ZSWR0_RESET_STATUS);
505 c = SCC_READDATA();
506 ZSDELAY();
507 SCC_WRITE0(ZSWR0_RESET_ERRORS);
508 }
509
510 /*ARGSUSED*/
511 static int
zsa_null_int(struct zscom * zs)512 zsa_null_int(struct zscom *zs)
513 {
514 return (0);
515 }
516
517 struct zsops zsops_null_async = {
518 zsa_null,
519 zsa_null,
520 zsa_null,
521 zsa_null,
522 zsa_null_int,
523 zsa_null_int,
524 zsa_null_int
525 };
526
527 struct zsops zsops_async = {
528 zsa_txint,
529 zsa_xsint,
530 zsa_rxint,
531 zsa_srint,
532 zsa_softint,
533 zsa_suspend,
534 zsa_resume
535 };
536
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);
548
549 static boolean_t abort_charseq_recognize(uchar_t ch);
550
551 /* ARGSUSED */
552 int
zsc_info(dev_info_t * dip,ddi_info_cmd_t infocmd,void * arg,void ** result)553 zsc_info(dev_info_t *dip, ddi_info_cmd_t infocmd, void *arg,
554 void **result)
555 {
556 dev_t dev = (dev_t)arg;
557 int unit, error;
558 struct zscom *zs;
559
560 if ((unit = UNIT(dev)) >= nzs)
561 return (DDI_FAILURE);
562
563 switch (infocmd) {
564 case DDI_INFO_DEVT2DEVINFO:
565 zs = &zscom[unit];
566 *result = zs->zs_dip;
567 error = DDI_SUCCESS;
568 break;
569 case DDI_INFO_DEVT2INSTANCE:
570 *result = (void *)(uintptr_t)(unit / 2);
571 error = DDI_SUCCESS;
572 break;
573 default:
574 error = DDI_FAILURE;
575 }
576 return (error);
577 }
578
579 /*
580 * The Asynchronous Driver.
581 */
582
583 /*
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.
587 *
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?
592 */
593
594 /*
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:
598 *
599 * PROM (real device) zs minor device
600 *
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
607 *
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, ...".
611 */
612
613 static int zsa_inuse; /* Strictly for debugging */
614
615 int
zsa_channel_is_active_in_rom(dev_info_t * dev,int zsminor)616 zsa_channel_is_active_in_rom(dev_info_t *dev, int zsminor)
617 {
618 char pathname[OBP_MAXPATHLEN];
619 char default_pathname[OBP_MAXPATHLEN];
620 char *stdioname;
621 char minordata[3];
622
623 /*
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).
627 *
628 * We get two forms of the pathname, one complete with the
629 * the channel number, and if the channel is 'a', then
630 * we also deal with the user's ability to default to
631 * channel 'a', by omitting the channel number option.
632 * We then compare these pathnames to both the stdin and
633 * stdout pathnames. If any of these match, then the channel
634 * is in use.
635 */
636
637 (void) ddi_pathname(dev, pathname); /* device pathname */
638 default_pathname[0] = (char)0; /* default pathname if channel 'a' */
639 if ((zsminor & 1) == 0)
640 (void) strcpy(default_pathname, pathname);
641 minordata[0] = ':';
642 minordata[1] = (char)('a' + (zsminor & 1));
643 minordata[2] = (char)0;
644 (void) strcat(pathname, minordata);
645
646 stdioname = prom_stdinpath();
647 if (strcmp(pathname, stdioname) == 0) {
648 zsa_inuse |= (1 << zsminor);
649 return (1);
650 }
651 if (strcmp(default_pathname, stdioname) == 0) {
652 zsa_inuse |= (1 << zsminor);
653 return (1);
654 }
655
656 stdioname = prom_stdoutpath();
657 if (strcmp(pathname, stdioname) == 0) {
658 zsa_inuse |= (1 << zsminor);
659 return (1);
660 }
661 if (strcmp(default_pathname, stdioname) == 0) {
662 zsa_inuse |= (1 << zsminor);
663 return (1);
664 }
665
666 return (0);
667 }
668
669 /*
670 * Initialize zs
671 */
672 void
zsa_init(struct zscom * zs)673 zsa_init(struct zscom *zs)
674 {
675 /*
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.
679 */
680 mutex_enter(zs->zs_excl);
681 mutex_enter(zs->zs_excl_hi);
682
683 /*
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.
689 */
690 if (zsa_channel_is_active_in_rom(zs->zs_dip, zs->zs_unit))
691 (void) zsmctl(zs, ZS_ON, DMSET); /* raise dtr */
692 else if (zsasoftdtr && (zssoftCAR[zs->zs_unit]))
693 (void) zsmctl(zs, ZS_ON, DMSET); /* raise dtr */
694 else
695 (void) zsmctl(zs, ZS_OFF, DMSET); /* drop dtr */
696
697 if (zsa_rstandby > ZSA_MAX_RSTANDBY)
698 zsa_rstandby = ZSA_MAX_RSTANDBY;
699
700 if (zsa_rdone > ZSA_RDONE_MAX)
701 zsa_rdone = ZSA_RDONE_MAX;
702
703 if (zsa_grace_flow_control > ZSA_GRACE_MAX_FLOW_CONTROL)
704 zsa_grace_flow_control = ZSA_GRACE_MAX_FLOW_CONTROL;
705
706 mutex_exit(zs->zs_excl_hi);
707 mutex_exit(zs->zs_excl);
708 }
709
710
711 /*
712 * Open routine.
713 */
714 /*ARGSUSED*/
715 static int
zsa_open(queue_t * rq,dev_t * dev,int flag,int sflag,cred_t * cr)716 zsa_open(queue_t *rq, dev_t *dev, int flag, int sflag, cred_t *cr)
717 {
718 struct zscom *zs;
719 struct asyncline *za;
720 int speed, unit;
721 struct termios *termiosp;
722 int len;
723 int allocbcount = zsa_rstandby;
724 boolean_t set_zsoptinit = B_FALSE;
725
726 unit = UNIT(*dev);
727 if (unit >= nzs)
728 return (ENXIO); /* unit not configured */
729
730 /* zscom is allocated by zsattach, and thus cannot be NULL here */
731 zs = &zscom[unit];
732 if (zs->zs_ops == NULL) {
733 return (ENXIO); /* device not found by autoconfig */
734 }
735
736 mutex_enter(zs->zs_ocexcl);
737 mutex_enter(zs->zs_excl);
738 again:
739 if ((zs->zs_ops != &zsops_null) &&
740 (zs->zs_ops != &zsops_async)) {
741 mutex_exit(zs->zs_excl);
742 mutex_exit(zs->zs_ocexcl);
743 return (EBUSY); /* another protocol got here first */
744 }
745
746 za = (struct asyncline *)&zs->zs_priv_str;
747
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);
754 }
755
756 /* Mark device as busy (for power management) */
757 (void) pm_busy_component(zs->zs_dip, unit%2+1);
758
759 if (zs->zs_ops == &zsops_null) {
760 bzero(za, sizeof (zs->zs_priv_str));
761 za->za_common = zs;
762 if (zssoftCAR[zs->zs_unit])
763 za->za_ttycommon.t_flags |= TS_SOFTCAR;
764 zsopinit(zs, &zsops_async);
765 set_zsoptinit = B_TRUE;
766 za->za_rdone_wptr = 0;
767 za->za_rdone_rptr = 0;
768 }
769
770 zs->zs_priv = (caddr_t)za;
771
772 /*
773 * Block waiting for carrier to come up,
774 * unless this is a no-delay open.
775 */
776 mutex_enter(zs->zs_excl_hi);
777 if (!(za->za_flags & ZAS_ISOPEN)) {
778 /*
779 * Get the default termios settings (cflag).
780 * These are stored as a property in the
781 * "options" node.
782 */
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)) {
788
789 za->za_ttycommon.t_cflag = termiosp->c_cflag;
790 kmem_free(termiosp, len);
791 } else {
792 /*
793 * Gack! Whine about it.
794 */
795 cmn_err(CE_WARN,
796 "zs: Couldn't get ttymodes property!");
797 }
798 mutex_enter(zs->zs_excl_hi);
799 if ((*dev == rconsdev) || (*dev == kbddev) ||
800 (*dev == stdindev)) {
801 speed = zsgetspeed(*dev);
802 za->za_ttycommon.t_cflag &= ~(CBAUD);
803 if (speed > CBAUD) {
804 za->za_ttycommon.t_cflag |= CBAUDEXT;
805 za->za_ttycommon.t_cflag |=
806 ((speed - CBAUD - 1) & CBAUD);
807 } else {
808 za->za_ttycommon.t_cflag &= ~CBAUDEXT;
809 za->za_ttycommon.t_cflag |= (speed & CBAUD);
810 }
811 }
812 za->za_overrun = 0;
813 za->za_ttycommon.t_iflag = 0;
814 za->za_ttycommon.t_iocpending = NULL;
815 za->za_ttycommon.t_size.ws_row = 0;
816 za->za_ttycommon.t_size.ws_col = 0;
817 za->za_ttycommon.t_size.ws_xpixel = 0;
818 za->za_ttycommon.t_size.ws_ypixel = 0;
819 za->za_dev = *dev;
820 za->za_wbufcid = 0;
821 zsa_program(za, za->za_ttycommon.t_cflag & (CIBAUDEXT|CIBAUD));
822 zsa_set_za_rcv_flags_mask(za);
823 } else if ((za->za_ttycommon.t_flags & TS_XCLUDE) &&
824 secpolicy_excl_open(cr) != 0) {
825 mutex_exit(zs->zs_excl_hi);
826 if (set_zsoptinit && !(za->za_flags & ISOPEN))
827 zsopinit(zs, &zsops_null);
828 mutex_exit(zs->zs_excl);
829 mutex_exit(zs->zs_ocexcl);
830 return (EBUSY);
831 } else if ((*dev & OUTLINE) && !(za->za_flags & ZAS_OUT)) {
832 mutex_exit(zs->zs_excl_hi);
833 if (set_zsoptinit && !(za->za_flags & ISOPEN))
834 zsopinit(zs, &zsops_null);
835 mutex_exit(zs->zs_excl);
836 mutex_exit(zs->zs_ocexcl);
837 return (EBUSY);
838 }
839
840 if (*dev & OUTLINE)
841 za->za_flags |= ZAS_OUT;
842 (void) zsmctl(zs, ZS_ON, DMSET);
843
844 /*
845 * Check carrier.
846 */
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);
851
852 /*
853 * If FNDELAY and FNONBLOCK are clear, block until carrier up.
854 * Quit on interrupt.
855 */
856 if (!(flag & (FNDELAY|FNONBLOCK)) &&
857 !(za->za_ttycommon.t_cflag & CLOCAL)) {
858 if (!(za->za_flags & (ZAS_CARR_ON|ZAS_OUT)) ||
859 ((za->za_flags & ZAS_OUT) && !(*dev & OUTLINE))) {
860 za->za_flags |= ZAS_WOPEN;
861 mutex_exit(zs->zs_excl);
862 if (cv_wait_sig(&zs->zs_flags_cv, zs->zs_ocexcl) == 0) {
863 mutex_enter(zs->zs_excl);
864 if (zs->zs_suspended) {
865 mutex_exit(zs->zs_excl);
866 mutex_exit(zs->zs_ocexcl);
867 (void) ddi_dev_is_needed(zs->zs_dip,
868 0, 1);
869 mutex_enter(zs->zs_ocexcl);
870 mutex_enter(zs->zs_excl);
871 }
872 za->za_flags &= ~ZAS_WOPEN;
873 if (set_zsoptinit && !(za->za_flags & ISOPEN))
874 zsopinit(zs, &zsops_null);
875 mutex_exit(zs->zs_excl);
876 mutex_exit(zs->zs_ocexcl);
877 return (EINTR);
878 }
879 mutex_enter(zs->zs_excl);
880 za->za_flags &= ~ZAS_WOPEN;
881 if ((zs->zs_ops == &zsops_null) ||
882 (zs->zs_ops == &zsops_async))
883 goto again;
884 else {
885 if (set_zsoptinit && !(za->za_flags & ISOPEN))
886 zsopinit(zs, &zsops_null);
887 mutex_exit(zs->zs_excl);
888 mutex_exit(zs->zs_ocexcl);
889 return (EBUSY);
890 }
891 }
892 } else if ((za->za_flags & ZAS_OUT) && !(*dev & OUTLINE)) {
893 if (set_zsoptinit && !(za->za_flags & ISOPEN))
894 zsopinit(zs, &zsops_null);
895 mutex_exit(zs->zs_excl);
896 mutex_exit(zs->zs_ocexcl);
897 return (EBUSY);
898 }
899
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;
903
904 za->za_flags |= ZAS_ISOPEN;
905 ZSA_GETBLOCK(zs, allocbcount);
906 qprocson(rq);
907 mutex_exit(zs->zs_excl);
908 mutex_exit(zs->zs_ocexcl);
909 return (0);
910 }
911
912 static void
zs_progress_check(void * arg)913 zs_progress_check(void *arg)
914 {
915 struct asyncline *za = arg;
916 struct zscom *zs = za->za_common;
917 mblk_t *bp;
918
919 /*
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.
923 */
924 mutex_enter(zs->zs_excl);
925 if (!(zs->zs_flags & ZS_PROGRESS) &&
926 !(za->za_flags & (ZAS_BREAK|ZAS_DELAY))) {
927 za->za_flags &= ~ZAS_BUSY;
928 mutex_enter(zs->zs_excl_hi);
929 za->za_rcv_flags_mask &= ~DO_RETRANSMIT;
930 zs->zs_wr_cur = NULL;
931 zs->zs_wr_lim = NULL;
932 bp = za->za_xmitblk;
933 za->za_xmitblk = NULL;
934 mutex_exit(zs->zs_excl_hi);
935 zs->zs_timer = 0;
936 mutex_exit(zs->zs_excl);
937 if (bp != NULL)
938 freeb(bp);
939 /*
940 * Since this timer is running, we know that we're in exit(2).
941 * That means that the user can't possibly be waiting on any
942 * valid ioctl(2) completion anymore, and we should just flush
943 * everything.
944 */
945 flushq(za->za_ttycommon.t_writeq, FLUSHALL);
946 cv_broadcast(&zs->zs_flags_cv);
947 } else {
948 zs->zs_flags &= ~ZS_PROGRESS;
949 zs->zs_timer = timeout(zs_progress_check, za,
950 drv_usectohz(zs_drain_check));
951 mutex_exit(zs->zs_excl);
952 }
953 }
954
955 /*
956 * Close routine.
957 *
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.
962 */
963
964 /*ARGSUSED*/
965 static int
zsa_close(queue_t * q,int flag,cred_t * cr __unused)966 zsa_close(queue_t *q, int flag, cred_t *cr __unused)
967 {
968 struct asyncline *za;
969 struct zscom *zs;
970 int i;
971 mblk_t *bp;
972 timeout_id_t za_zsa_restart_id, za_kick_rcv_id;
973 bufcall_id_t za_bufcid, za_wbufcid;
974 int tmp;
975
976 za = q->q_ptr;
977 ASSERT(za != NULL);
978
979 zs = za->za_common;
980
981 mutex_enter(zs->zs_excl);
982 zs->zs_flags |= ZS_CLOSING;
983
984 /*
985 * There are two flavors of break -- timed (M_BREAK or TCSBRK) and
986 * untimed (TIOCSBRK). For the timed case, these are enqueued on our
987 * write queue and there's a timer running, so we don't have to worry
988 * about them. For the untimed case, though, the user obviously made a
989 * mistake, because these are handled immediately. We'll terminate the
990 * break now and honor their implicit request by discarding the rest of
991 * the data.
992 */
993 if (!(za->za_flags & ZAS_BREAK) && (zs->zs_wreg[5] & ZSWR5_BREAK))
994 goto nodrain;
995
996 /*
997 * If the user told us not to delay the close ("non-blocking"), then
998 * don't bother trying to drain.
999 *
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.
1005 */
1006 if ((flag & (FNDELAY|FNONBLOCK)) || (za->za_flags & ZAS_STOPPED))
1007 goto nodrain;
1008
1009 /*
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.
1016 *
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.
1023 *
1024 * Note that loss of carrier will cause the output queue to be flushed,
1025 * and we'll wake up again and finish normally.
1026 */
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));
1031 }
1032
1033 while (zs->zs_wr_cur != NULL ||
1034 za->za_ttycommon.t_writeq->q_first != NULL ||
1035 (za->za_flags & (ZAS_BUSY|ZAS_DELAY|ZAS_BREAK))) {
1036 if (cv_wait_sig(&zs->zs_flags_cv, zs->zs_excl) == 0)
1037 break;
1038 }
1039
1040 if (zs->zs_timer != 0) {
1041 (void) untimeout(zs->zs_timer);
1042 zs->zs_timer = 0;
1043 }
1044
1045 nodrain:
1046 /*
1047 * If break is in progress, stop it.
1048 */
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;
1053 }
1054
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;
1059
1060 za->za_wbufcid = za->za_bufcid = 0;
1061 za->za_zsa_restart_id = za->za_kick_rcv_id = 0;
1062
1063 /*
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.
1067 */
1068
1069 zsopinit(zs, &zsops_null_async);
1070
1071 /*
1072 * Nobody, zsh or zs can now open this port until
1073 * zsopinit(zs, &zsops_null);
1074 *
1075 */
1076
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))) {
1081 /*
1082 * If DTR is being held high by softcarrier,
1083 * set up the ZS_ON set; if not, hang up.
1084 */
1085 if (zsasoftdtr && (za->za_ttycommon.t_flags & TS_SOFTCAR))
1086 (void) zsmctl(zs, ZS_ON, DMSET);
1087 else
1088 (void) zsmctl(zs, ZS_OFF, DMSET);
1089 mutex_exit(zs->zs_excl_hi);
1090 /*
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.
1094 */
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);
1101 }
1102 if (tmp == 0)
1103 goto out;
1104 mutex_enter(zs->zs_excl_hi);
1105 }
1106
1107 /*
1108 * If nobody's now using it, turn off receiver interrupts.
1109 */
1110 if ((za->za_flags & (ZAS_ISOPEN|ZAS_WOPEN)) == 0)
1111 SCC_BIC(1, ZSWR1_RIE);
1112 mutex_exit(zs->zs_excl_hi);
1113
1114 out:
1115 /*
1116 * Clear out device state.
1117 */
1118 ttycommon_close(&za->za_ttycommon);
1119
1120 za->za_ttycommon.t_readq = NULL;
1121 za->za_ttycommon.t_writeq = NULL;
1122
1123 mutex_enter(zs->zs_excl_hi);
1124 za->za_rcv_flags_mask &= ~DO_RETRANSMIT;
1125 zs->zs_wr_cur = NULL;
1126 zs->zs_wr_lim = NULL;
1127 bp = za->za_xmitblk;
1128 za->za_xmitblk = NULL;
1129 mutex_exit(zs->zs_excl_hi);
1130 if (bp)
1131 freemsg(bp);
1132
1133 mutex_enter(zs->zs_excl_hi);
1134 zs->zs_rd_cur = NULL;
1135 zs->zs_rd_lim = NULL;
1136 bp = za->za_rcvblk;
1137 za->za_rcvblk = NULL;
1138 mutex_exit(zs->zs_excl_hi);
1139 if (bp)
1140 freemsg(bp);
1141
1142 for (i = 0; i < zsa_rstandby; i++) {
1143 mutex_enter(zs->zs_excl_hi);
1144 bp = za->za_rstandby[i];
1145 za->za_rstandby[i] = NULL;
1146 mutex_exit(zs->zs_excl_hi);
1147 if (bp)
1148 freemsg(bp);
1149 }
1150
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);
1155 }
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);
1160 }
1161
1162 ZSA_FLUSHQ;
1163 bzero(za, sizeof (struct asyncline));
1164 qprocsoff(q);
1165 mutex_exit(zs->zs_excl);
1166
1167 /*
1168 * Cancel outstanding "bufcall" request.
1169 */
1170 if (za_wbufcid)
1171 unbufcall(za_wbufcid);
1172 if (za_bufcid)
1173 unbufcall(za_bufcid);
1174
1175 /*
1176 * Cancel outstanding timeout.
1177 */
1178 if (za_zsa_restart_id)
1179 (void) untimeout(za_zsa_restart_id);
1180
1181 if (za_kick_rcv_id)
1182 (void) untimeout(za_kick_rcv_id);
1183
1184 q->q_ptr = WR(q)->q_ptr = NULL;
1185 zsopinit(zs, &zsops_null);
1186 cv_broadcast(&zs->zs_flags_cv);
1187
1188 /* Mark device as available for power management */
1189 (void) pm_idle_component(zs->zs_dip, zs->zs_unit%2+1);
1190 return (0);
1191 }
1192
1193 /*
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.
1203 */
1204 static int
zsa_wput(queue_t * q,mblk_t * mp)1205 zsa_wput(queue_t *q, mblk_t *mp)
1206 {
1207 struct asyncline *za;
1208 struct zscom *zs;
1209 struct copyresp *resp;
1210 mblk_t *bp = NULL;
1211 int error;
1212 struct iocblk *iocp;
1213
1214 za = (struct asyncline *)q->q_ptr;
1215 zs = za->za_common;
1216 if (zs->zs_flags & ZS_NEEDSOFT) {
1217 zs->zs_flags &= ~ZS_NEEDSOFT;
1218 (void) zsa_softint(zs);
1219 }
1220
1221 switch (mp->b_datap->db_type) {
1222
1223 case M_STOP:
1224 /*
1225 * Since we don't do real DMA, we can just let the
1226 * chip coast to a stop after applying the brakes.
1227 */
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;
1239 }
1240 mutex_exit(zs->zs_excl_hi);
1241 if (bp)
1242 (void) putbq(q, bp);
1243 freemsg(mp);
1244 mutex_exit(zs->zs_excl);
1245 break;
1246
1247 case M_START:
1248 mutex_enter(zs->zs_excl);
1249 if (za->za_flags & ZAS_STOPPED) {
1250 za->za_flags &= ~ZAS_STOPPED;
1251 /*
1252 * If an output operation is in progress,
1253 * resume it. Otherwise, prod the start
1254 * routine.
1255 */
1256 zsa_start(zs);
1257 }
1258 freemsg(mp);
1259 mutex_exit(zs->zs_excl);
1260 break;
1261
1262 case M_IOCTL:
1263 mutex_enter(zs->zs_excl);
1264 iocp = (struct iocblk *)mp->b_rptr;
1265
1266 switch (iocp->ioc_cmd) {
1267
1268 case TIOCGPPS:
1269 /*
1270 * Get PPS state.
1271 */
1272 if (mp->b_cont != NULL)
1273 freemsg(mp->b_cont);
1274
1275 mp->b_cont = allocb(sizeof (int), BPRI_HI);
1276 if (mp->b_cont == NULL) {
1277 mp->b_datap->db_type = M_IOCNAK;
1278 iocp->ioc_error = ENOMEM;
1279 ZSA_QREPLY(q, mp);
1280 break;
1281 }
1282 if (za->za_pps)
1283 *(int *)mp->b_cont->b_wptr = 1;
1284 else
1285 *(int *)mp->b_cont->b_wptr = 0;
1286 mp->b_cont->b_wptr += sizeof (int);
1287 mp->b_datap->db_type = M_IOCACK;
1288 iocp->ioc_count = sizeof (int);
1289 ZSA_QREPLY(q, mp);
1290 break;
1291
1292 case TIOCSPPS:
1293 /*
1294 * Set PPS state.
1295 */
1296 error = miocpullup(mp, sizeof (int));
1297 if (error != 0) {
1298 mp->b_datap->db_type = M_IOCNAK;
1299 iocp->ioc_error = error;
1300 ZSA_QREPLY(q, mp);
1301 break;
1302 }
1303
1304 za->za_pps = (*(int *)mp->b_cont->b_rptr != 0);
1305 mp->b_datap->db_type = M_IOCACK;
1306 ZSA_QREPLY(q, mp);
1307 break;
1308
1309 case TIOCGPPSEV:
1310 {
1311 /*
1312 * Get PPS event data.
1313 */
1314 void *buf;
1315 #ifdef _SYSCALL32_IMPL
1316 struct ppsclockev32 p32;
1317 #endif
1318
1319 if (mp->b_cont != NULL) {
1320 freemsg(mp->b_cont);
1321 mp->b_cont = NULL;
1322 }
1323 if (za->za_pps == 0) {
1324 mp->b_datap->db_type = M_IOCNAK;
1325 iocp->ioc_error = ENXIO;
1326 ZSA_QREPLY(q, mp);
1327 break;
1328 }
1329
1330 #ifdef _SYSCALL32_IMPL
1331 if ((iocp->ioc_flag & IOC_MODELS) != IOC_NATIVE) {
1332 TIMEVAL_TO_TIMEVAL32(&p32.tv, &ppsclockev.tv);
1333 p32.serial = ppsclockev.serial;
1334 buf = &p32;
1335 iocp->ioc_count = sizeof (struct ppsclockev32);
1336 } else
1337 #endif
1338 {
1339 buf = &ppsclockev;
1340 iocp->ioc_count = sizeof (struct ppsclockev);
1341 }
1342
1343 if ((bp = allocb(iocp->ioc_count, BPRI_HI)) == NULL) {
1344 mp->b_datap->db_type = M_IOCNAK;
1345 iocp->ioc_error = ENOMEM;
1346 ZSA_QREPLY(q, mp);
1347 break;
1348 }
1349 mp->b_cont = bp;
1350
1351 bcopy(buf, bp->b_wptr, iocp->ioc_count);
1352 bp->b_wptr += iocp->ioc_count;
1353 mp->b_datap->db_type = M_IOCACK;
1354 ZSA_QREPLY(q, mp);
1355 break;
1356 }
1357
1358 case TCSETSW:
1359 case TCSETSF:
1360 case TCSETAW:
1361 case TCSETAF:
1362 case TCSBRK:
1363 /*
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.
1370 */
1371 (void) putq(q, mp);
1372 zsa_start(zs);
1373 break;
1374
1375 default:
1376 /*
1377 * Do it now.
1378 */
1379 zsa_ioctl(za, q, mp);
1380 break;
1381 }
1382 mutex_exit(zs->zs_excl);
1383 break;
1384
1385
1386 case M_IOCDATA:
1387
1388 mutex_enter(zs->zs_excl);
1389 resp = (struct copyresp *)mp->b_rptr;
1390 if (resp->cp_rval) {
1391 /*
1392 * Just free message on failure.
1393 */
1394 freemsg(mp);
1395 mutex_exit(zs->zs_excl);
1396 break;
1397 }
1398 switch (resp->cp_cmd) {
1399
1400 case TIOCMSET:
1401 mutex_enter(zs->zs_excl_hi);
1402 (void) zsmctl(zs, dmtozs(*(int *)mp->b_cont->b_rptr),
1403 DMSET);
1404 mutex_exit(zs->zs_excl_hi);
1405 mioc2ack(mp, NULL, 0, 0);
1406 ZSA_QREPLY(q, mp);
1407 break;
1408
1409 case TIOCMBIS:
1410 mutex_enter(zs->zs_excl_hi);
1411 (void) zsmctl(zs, dmtozs(*(int *)mp->b_cont->b_rptr),
1412 DMBIS);
1413 mutex_exit(zs->zs_excl_hi);
1414 mioc2ack(mp, NULL, 0, 0);
1415 ZSA_QREPLY(q, mp);
1416 break;
1417
1418 case TIOCMBIC:
1419 mutex_enter(zs->zs_excl_hi);
1420 (void) zsmctl(zs, dmtozs(*(int *)mp->b_cont->b_rptr),
1421 DMBIC);
1422 mutex_exit(zs->zs_excl_hi);
1423 mioc2ack(mp, NULL, 0, 0);
1424 ZSA_QREPLY(q, mp);
1425 break;
1426
1427 case TIOCMGET:
1428 mioc2ack(mp, NULL, 0, 0);
1429 ZSA_QREPLY(q, mp);
1430 break;
1431
1432 default:
1433 freemsg(mp);
1434
1435 }
1436 mutex_exit(zs->zs_excl);
1437 break;
1438
1439
1440 case M_FLUSH:
1441 mutex_enter(zs->zs_excl);
1442 if (*mp->b_rptr & FLUSHW) {
1443
1444 /*
1445 * Abort any output in progress.
1446 */
1447 if (za->za_flags & ZAS_BUSY) {
1448 za->za_flags &= ~ZAS_BUSY;
1449 mutex_enter(zs->zs_excl_hi);
1450 za->za_rcv_flags_mask &= ~DO_RETRANSMIT;
1451 zs->zs_wr_cur = NULL;
1452 zs->zs_wr_lim = NULL;
1453 bp = za->za_xmitblk;
1454 za->za_xmitblk = NULL;
1455 mutex_exit(zs->zs_excl_hi);
1456 if (bp)
1457 freemsg(bp);
1458 }
1459 /*
1460 * Flush our write queue.
1461 */
1462 flushq(q, FLUSHDATA); /* XXX doesn't flush M_DELAY */
1463 *mp->b_rptr &= ~FLUSHW; /* it has been flushed */
1464 }
1465 if (*mp->b_rptr & FLUSHR) {
1466 /*
1467 * Flush any data in the temporary receive buffer
1468 */
1469 mutex_enter(zs->zs_excl_hi);
1470 if ((za->za_ttycommon.t_flags & TS_SOFTCAR) ||
1471 (SCC_READ0() & ZSRR0_CD)) {
1472 ZSA_KICK_RCV;
1473 } else {
1474 ZSA_KICK_RCV;
1475 if (!(SCC_READ0() & ZSRR0_RX_READY)) {
1476 /*
1477 * settle time for 1 character shift
1478 */
1479 mutex_exit(zs->zs_excl_hi);
1480 mutex_exit(zs->zs_excl);
1481 delay(ztdelay(SPEED(
1482 za->za_ttycommon.t_cflag))/3 + 1);
1483 mutex_enter(zs->zs_excl);
1484 mutex_enter(zs->zs_excl_hi);
1485 if (!(SCC_READ0() & ZSRR0_CD))
1486 ZSA_KICK_RCV;
1487 }
1488 while ((SCC_READ0() &
1489 (ZSRR0_CD | ZSRR0_RX_READY)) ==
1490 ZSRR0_RX_READY) {
1491 /*
1492 * Empty Receiver
1493 */
1494 (void) SCC_READDATA();
1495 }
1496 }
1497 mutex_exit(zs->zs_excl_hi);
1498 flushq(RD(q), FLUSHDATA);
1499 ZSA_QREPLY(q, mp);
1500 /*
1501 * give the read queues a crack at it
1502 */
1503 } else
1504 freemsg(mp);
1505
1506 /*
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.)
1511 */
1512 zsa_start(zs);
1513 mutex_exit(zs->zs_excl);
1514 break;
1515
1516 case M_BREAK:
1517 case M_DELAY:
1518 case M_DATA:
1519 mutex_enter(zs->zs_excl);
1520 /*
1521 * Queue the message up to be transmitted,
1522 * and poke the start routine.
1523 */
1524 (void) putq(q, mp);
1525 zsa_start(zs);
1526 mutex_exit(zs->zs_excl);
1527 break;
1528
1529 case M_STOPI:
1530 mutex_enter(zs->zs_excl);
1531 mutex_enter(zs->zs_excl_hi);
1532 za->za_flowc = za->za_ttycommon.t_stopc;
1533 if ((zs->zs_wr_cur) != NULL) {
1534 za->za_rcv_flags_mask &= ~DO_RETRANSMIT;
1535 bp = za->za_xmitblk;
1536 bp->b_rptr = zs->zs_wr_cur;
1537 zs->zs_wr_cur = NULL;
1538 zs->zs_wr_lim = NULL;
1539 za->za_xmitblk = NULL;
1540 }
1541 mutex_exit(zs->zs_excl_hi);
1542 if (bp)
1543 (void) putbq(q, bp);
1544 else
1545 zsa_start(zs); /* poke the start routine */
1546 freemsg(mp);
1547 mutex_exit(zs->zs_excl);
1548 break;
1549
1550 case M_STARTI:
1551 mutex_enter(zs->zs_excl);
1552 mutex_enter(zs->zs_excl_hi);
1553 za->za_flowc = za->za_ttycommon.t_startc;
1554 if ((zs->zs_wr_cur) != NULL) {
1555 za->za_rcv_flags_mask &= ~DO_RETRANSMIT;
1556 bp = za->za_xmitblk;
1557 bp->b_rptr = zs->zs_wr_cur;
1558 zs->zs_wr_cur = NULL;
1559 zs->zs_wr_lim = NULL;
1560 za->za_xmitblk = NULL;
1561 }
1562 mutex_exit(zs->zs_excl_hi);
1563 if (bp)
1564 (void) putbq(q, bp);
1565 else
1566 zsa_start(zs); /* poke the start routine */
1567 freemsg(mp);
1568 mutex_exit(zs->zs_excl);
1569 break;
1570
1571 case M_CTL:
1572 if (MBLKL(mp) >= sizeof (struct iocblk) &&
1573 ((struct iocblk *)mp->b_rptr)->ioc_cmd == MC_POSIXQUERY) {
1574 ((struct iocblk *)mp->b_rptr)->ioc_cmd = MC_HAS_POSIX;
1575 qreply(q, mp);
1576 } else {
1577 /*
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.
1583 */
1584 mutex_enter(zs->zs_excl);
1585 switch (*mp->b_rptr) {
1586
1587 case MC_SERVICEIMM:
1588 mutex_enter(zs->zs_excl_hi);
1589 za->za_flags |= ZAS_SERVICEIMM;
1590 mutex_exit(zs->zs_excl_hi);
1591 break;
1592
1593 case MC_SERVICEDEF:
1594 mutex_enter(zs->zs_excl_hi);
1595 za->za_flags &= ~ZAS_SERVICEIMM;
1596 mutex_exit(zs->zs_excl_hi);
1597 break;
1598 }
1599 freemsg(mp);
1600 mutex_exit(zs->zs_excl);
1601 }
1602 break;
1603
1604 default:
1605 /*
1606 * "No, I don't want a subscription to Chain Store Age,
1607 * thank you anyway."
1608 */
1609 freemsg(mp);
1610 break;
1611 }
1612 return (0);
1613 }
1614
1615 /*
1616 * zs read service procedure
1617 */
1618 static int
zsa_rsrv(queue_t * q)1619 zsa_rsrv(queue_t *q)
1620 {
1621 struct asyncline *za;
1622 struct zscom *zs;
1623
1624 if (((za = (struct asyncline *)q->q_ptr) != NULL) &&
1625 (za->za_ttycommon.t_cflag & CRTSXOFF)) {
1626 zs = za->za_common;
1627 mutex_enter(zs->zs_excl_hi);
1628 ZSSETSOFT(zs);
1629 mutex_exit(zs->zs_excl_hi);
1630 }
1631 return (0);
1632 }
1633
1634 /*
1635 * Transmitter interrupt service routine.
1636 * If there's more data to transmit in the current pseudo-DMA block,
1637 * and the transmitter is ready, send the next character if output
1638 * is not stopped or draining.
1639 * Otherwise, queue up a soft interrupt.
1640 */
1641 static void
zsa_txint(struct zscom * zs)1642 zsa_txint(struct zscom *zs)
1643 {
1644 struct asyncline *za = (struct asyncline *)&zs->zs_priv_str;
1645 uchar_t *wr_cur;
1646 uchar_t s0;
1647
1648 s0 = SCC_READ0();
1649
1650 if ((wr_cur = zs->zs_wr_cur) != NULL) {
1651 if (wr_cur < zs->zs_wr_lim) {
1652 if ((za->za_ttycommon.t_cflag & CRTSCTS) &&
1653 !(s0 & ZSRR0_CTS)) {
1654 SCC_WRITE0(ZSWR0_RESET_TXINT);
1655 za->za_rcv_flags_mask |= DO_RETRANSMIT;
1656 return;
1657 }
1658 SCC_WRITEDATA(*wr_cur++);
1659 #ifdef ZSA_DEBUG
1660 za->za_wr++;
1661 #endif
1662 zs->zs_wr_cur = wr_cur;
1663 zs->zs_flags |= ZS_PROGRESS;
1664 return;
1665 } else {
1666 zs->zs_wr_cur = NULL;
1667 zs->zs_wr_lim = NULL;
1668 /*
1669 * Use the rcv_flags_mask as it is set and
1670 * test while holding the zs_excl_hi mutex
1671 */
1672 za->za_rcv_flags_mask |= DO_TRANSMIT;
1673 SCC_WRITE0(ZSWR0_RESET_TXINT);
1674 ZSSETSOFT(zs);
1675 return;
1676 }
1677 }
1678
1679 if (za->za_flowc != '\0' && (!(za->za_flags & ZAS_DRAINING))) {
1680 if ((za->za_ttycommon.t_cflag & CRTSCTS) &&
1681 !(s0 & ZSRR0_CTS)) {
1682 SCC_WRITE0(ZSWR0_RESET_TXINT);
1683 return;
1684 }
1685 SCC_WRITEDATA(za->za_flowc);
1686 za->za_flowc = '\0';
1687 return;
1688 }
1689 SCC_WRITE0(ZSWR0_RESET_TXINT);
1690 /*
1691 * Set DO_TRANSMIT bit so that the soft interrupt can
1692 * test it and unset the ZAS_BUSY in za_flags while holding
1693 * the mutex zs_excl and zs_excl_hi
1694 */
1695 za->za_rcv_flags_mask |= DO_TRANSMIT;
1696 ZSSETSOFT(zs);
1697 }
1698
1699 /*
1700 * External/Status interrupt.
1701 */
1702 static void
zsa_xsint(struct zscom * zs)1703 zsa_xsint(struct zscom *zs)
1704 {
1705 struct asyncline *za = (struct asyncline *)&zs->zs_priv_str;
1706 uchar_t s0, x0;
1707
1708 s0 = SCC_READ0();
1709 ZSA_R0_LOG(s0);
1710 x0 = s0 ^ za->za_rr0;
1711 za->za_rr0 = s0;
1712 SCC_WRITE0(ZSWR0_RESET_STATUS);
1713
1714 /*
1715 * PPS (Pulse Per Second) support.
1716 */
1717 if (za->za_pps && (x0 & ZSRR0_CD) && (s0 & ZSRR0_CD)) {
1718 /*
1719 * This code captures a timestamp at the designated
1720 * transition of the PPS signal (CD asserted). The
1721 * code provides a pointer to the timestamp, as well
1722 * as the hardware counter value at the capture.
1723 *
1724 * Note: the kernel has nano based time values while
1725 * NTP requires micro based, an in-line fast algorithm
1726 * to convert nsec to usec is used here -- see hrt2ts()
1727 * in common/os/timers.c for a full description.
1728 */
1729 struct timeval *tvp = &ppsclockev.tv;
1730 timespec_t ts;
1731 int nsec, usec;
1732
1733 LED_OFF;
1734 gethrestime(&ts);
1735 LED_ON;
1736 nsec = ts.tv_nsec;
1737 usec = nsec + (nsec >> 2);
1738 usec = nsec + (usec >> 1);
1739 usec = nsec + (usec >> 2);
1740 usec = nsec + (usec >> 4);
1741 usec = nsec - (usec >> 3);
1742 usec = nsec + (usec >> 2);
1743 usec = nsec + (usec >> 3);
1744 usec = nsec + (usec >> 4);
1745 usec = nsec + (usec >> 1);
1746 usec = nsec + (usec >> 6);
1747 tvp->tv_usec = usec >> 10;
1748 tvp->tv_sec = ts.tv_sec;
1749
1750 ++ppsclockev.serial;
1751
1752 /*
1753 * Because the kernel keeps a high-resolution time, pass the
1754 * current highres timestamp in tvp and zero in usec.
1755 */
1756 ddi_hardpps(tvp, 0);
1757 }
1758
1759 ZSA_KICK_RCV;
1760
1761 if ((x0 & ZSRR0_BREAK) && (s0 & ZSRR0_BREAK) == 0) {
1762 #ifdef SLAVIO_BUG
1763 /*
1764 * ZSRR0_BREAK turned off. This means that the break sequence
1765 * has completed (i.e., the stop bit finally arrived).
1766 */
1767 if ((s0 & ZSRR0_RX_READY) == 0) {
1768 /*
1769 * SLAVIO will generate a separate STATUS change
1770 * interrupt when the break sequence completes.
1771 * SCC will combine both, taking the higher priority
1772 * one, the receive. Should still see the ext/stat.
1773 * bit in REG3 on SCC. If no ext/stat, it must be
1774 * a SLAVIO.
1775 */
1776 za->za_breakoff = 1;
1777 } else {
1778 /*
1779 * The NUL character in the receiver is part of the
1780 * break sequence; it is discarded.
1781 */
1782 (void) SCC_READDATA(); /* swallow null */
1783 }
1784 #else /* SLAVIO_BUG */
1785 /*
1786 * ZSRR0_BREAK turned off. This means that the break sequence
1787 * has completed (i.e., the stop bit finally arrived). The NUL
1788 * character in the receiver is part of the break sequence;
1789 * it is discarded.
1790 */
1791 (void) SCC_READDATA(); /* swallow null */
1792 #endif /* SLAVIO_BUG */
1793 SCC_WRITE0(ZSWR0_RESET_ERRORS);
1794
1795 /*
1796 * Note: this will cause an abort if a break occurs on
1797 * the "keyboard device", regardless of whether the
1798 * "keyboard device" is a real keyboard or just a
1799 * terminal on a serial line. This permits you to
1800 * abort a workstation by unplugging the keyboard,
1801 * even if the normal abort key sequence isn't working.
1802 */
1803 if ((za->za_dev == kbddev) ||
1804 ((za->za_dev == rconsdev) || (za->za_dev == stdindev)) &&
1805 (abort_enable != KIOCABORTALTERNATE)) {
1806 abort_sequence_enter((char *)NULL);
1807 /*
1808 * We just broke into the monitor or debugger,
1809 * ignore the break in this case so whatever
1810 * random program that was running doesn't get
1811 * a SIGINT.
1812 */
1813 return;
1814 }
1815 za->za_break = 1;
1816 }
1817
1818 /*
1819 * If hardware flow control is enabled, (re)start output
1820 * when CTS is reasserted.
1821 */
1822 if ((za->za_ttycommon.t_cflag & CRTSCTS) &&
1823 (x0 & ZSRR0_CTS) && (s0 & ZSRR0_CTS) &&
1824 (za->za_rcv_flags_mask & DO_RETRANSMIT))
1825 za->za_rcv_flags_mask |= DO_TRANSMIT;
1826
1827 za->za_ext = 1;
1828 ZSSETSOFT(zs);
1829 }
1830
1831 /*
1832 * Receive Interrupt
1833 */
1834 static void
zsa_rxint(struct zscom * zs)1835 zsa_rxint(struct zscom *zs)
1836 {
1837 struct asyncline *za = (struct asyncline *)&zs->zs_priv_str;
1838 uchar_t c;
1839 uchar_t *rd_cur = zs->zs_rd_cur;
1840 uchar_t *rd_lim = zs->zs_rd_lim;
1841 mblk_t *bp;
1842 uint_t fm = za->za_rcv_flags_mask;
1843
1844
1845 #ifdef ZSA_DEBUG
1846 za->za_rd++;
1847 #endif
1848 c = (fm >> 16) & (SCC_READDATA());
1849
1850 /*
1851 * Check for character break sequence
1852 */
1853 if ((abort_enable == KIOCABORTALTERNATE) && (za->za_dev == rconsdev)) {
1854 if (abort_charseq_recognize(c))
1855 abort_sequence_enter((char *)NULL);
1856 }
1857
1858 if (!rd_cur) {
1859 #ifdef SLAVIO_BUG
1860 /*
1861 * SLAVIO generates FE for the start of break and
1862 * during break when parity is set. End of break is
1863 * detected when the first character is received.
1864 * This character is always garbage and is thrown away.
1865 */
1866 if (za->za_slav_break) {
1867 za->za_slav_break = 0;
1868 za->za_rr0 |= ZSRR0_BREAK;
1869 zsa_xsint(zs);
1870 return;
1871 }
1872 #endif /* SLAVIO_BUG */
1873
1874 if (c == 0 && (za->za_rr0 & ZSRR0_BREAK)) {
1875 /*
1876 * A break sequence was under way, and a NUL character
1877 * was received. Discard the NUL character, as it is
1878 * part of the break sequence; if ZSRR0_BREAK turned
1879 * off, indicating that the break sequence has com-
1880 * pleted, call "zsa_xsint" to properly handle the
1881 * error. It would appear that External/Status
1882 * interrupts get lost occasionally, so this ensures
1883 * that one is delivered.
1884 */
1885 c = SCC_READ0();
1886 if (!(c & ZSRR0_BREAK))
1887 zsa_xsint(zs);
1888 return;
1889 }
1890
1891 #ifdef SLAVIO_BUG
1892 if (c == 0 && za->za_breakoff) {
1893 /*
1894 * A break sequence completed, but SLAVIO generates
1895 * the NULL character interrupt late, so we throw the
1896 * NULL away now.
1897 */
1898 return;
1899 }
1900
1901 /*
1902 * make sure it gets cleared.
1903 */
1904 za->za_breakoff = 0;
1905 #endif /* SLAVIO_BUG */
1906
1907 ZSA_KICK_RCV; /* We can have M_BREAK msg */
1908 ZSA_ALLOCB(bp);
1909 if (!bp) {
1910 za->za_sw_overrun++;
1911 ZSSETSOFT(zs);
1912 return;
1913 }
1914 za->za_rcvblk = bp;
1915 zs->zs_rd_cur = rd_cur = bp->b_wptr;
1916 zs->zs_rd_lim = rd_lim = bp->b_datap->db_lim;
1917 if (za->za_kick_rcv_id == 0)
1918 ZSSETSOFT(zs);
1919 }
1920 if (c == 0377 && (fm & DO_ESC)) {
1921 if (rd_lim < rd_cur + 2) {
1922 ZSA_ALLOCB(bp);
1923 ZSA_KICK_RCV;
1924 if (!bp) {
1925 za->za_sw_overrun++;
1926 return;
1927 }
1928 za->za_rcvblk = bp;
1929 zs->zs_rd_cur = rd_cur = bp->b_wptr;
1930 zs->zs_rd_lim = rd_lim = bp->b_datap->db_lim;
1931 }
1932 *rd_cur++ = c;
1933 }
1934
1935
1936 *rd_cur++ = c;
1937 zs->zs_rd_cur = rd_cur;
1938
1939 if (rd_cur == rd_lim) {
1940 ZSA_KICK_RCV;
1941 } else if ((fm & DO_STOPC) && (c == (fm & 0xff))) {
1942 za->za_do_kick_rcv_in_softint = 1;
1943 ZSSETSOFT(zs);
1944 }
1945
1946 if ((za->za_flags & ZAS_SERVICEIMM) || g_nocluster) {
1947 /*
1948 * Send the data up immediately
1949 */
1950 ZSA_KICK_RCV;
1951 }
1952 }
1953
1954 /*
1955 * Special receive condition interrupt handler.
1956 */
1957 static void
zsa_srint(struct zscom * zs)1958 zsa_srint(struct zscom *zs)
1959 {
1960 struct asyncline *za = (struct asyncline *)&zs->zs_priv_str;
1961 short s1;
1962 uchar_t c;
1963 uchar_t c1;
1964 mblk_t *bp = za->za_rcvblk;
1965 uchar_t *rd_cur = zs->zs_rd_cur;
1966
1967 SCC_READ(1, s1);
1968 if (s1 & (ZSRR1_FE | ZSRR1_PE | ZSRR1_DO)) {
1969 c = SCC_READDATA(); /* swallow bad character */
1970 }
1971 #ifdef SLAVIO_BUG
1972 /*
1973 * SLAVIO does not handle breaks properly when parity is enabled.
1974 *
1975 * In general, if a null character is received when a framing
1976 * error occurs then it is a break condition and not a real
1977 * framing error. The null character must be limited to the
1978 * number of bits including the parity bit. For example, a 6
1979 * bit character with parity would be null if the lower 7 bits
1980 * read from the receive fifo were 0. (The higher order bits are
1981 * padded with 1 and/or the stop bits.) The only exception to this
1982 * general rule would be an 8 bit null character with parity being
1983 * a 1 in the parity bit and a framing error. This exception
1984 * can be determined by examining the parity error bit in RREG 1.
1985 *
1986 * A null character, even parity, 8 bits, no parity error,
1987 * (0 0000 0000) with framing error is a break condition.
1988 *
1989 * A null character, even parity, 8 bits, parity error,
1990 * (1 0000 0000) with framing error is a framing error.
1991 *
1992 * A null character, odd parity, 8 bits, parity error
1993 * (0 0000 0000) with framing error is a break condition.
1994 *
1995 * A null character, odd parity, 8 bits, no parity error,
1996 * (1 0000 0000) with framing error is a framing error.
1997 */
1998 if (za->za_ttycommon.t_cflag & PARENB) {
1999 switch (za->za_ttycommon.t_cflag & CSIZE) {
2000
2001 case CS5:
2002 c1 = c & 0x3f;
2003 break;
2004
2005 case CS6:
2006 c1 = c & 0x7f;
2007 break;
2008
2009 case CS7:
2010 c1 = c & 0xff;
2011 break;
2012
2013 case CS8:
2014 if ((za->za_ttycommon.t_cflag & PARODD) &&
2015 !(s1 & ZSRR1_PE))
2016 c1 = 0xff;
2017 else if (!(za->za_ttycommon.t_cflag & PARODD) &&
2018 (s1 & ZSRR1_PE))
2019 c1 = 0xff;
2020 else
2021 c1 = c;
2022 break;
2023 }
2024
2025 /*
2026 * We fake start of break condition.
2027 */
2028 if ((s1 & ZSRR1_FE) && c1 == 0) {
2029 za->za_slav_break = 1;
2030 return;
2031 }
2032 }
2033 #endif /* SLAVIO_BUG */
2034
2035 if (s1 & ZSRR1_PE) {
2036
2037 /*
2038 * Mark the parity error so zsa_process will
2039 * notice it and send it up in an M_BREAK
2040 * message; ldterm will do the actual parity error
2041 * processing
2042 */
2043
2044 if (bp && zs->zs_rd_cur) { /* M_DATA msg */
2045 ZSA_KICK_RCV;
2046 bp = NULL;
2047 }
2048 if (!bp)
2049 ZSA_ALLOCB(bp);
2050 if (!bp) {
2051 za->za_sw_overrun++;
2052 ZSSETSOFT(zs);
2053 } else {
2054 za->za_rcvblk = bp;
2055 zs->zs_rd_cur = rd_cur = bp->b_wptr;
2056 zs->zs_rd_lim = bp->b_datap->db_lim;
2057 *rd_cur++ = c;
2058 zs->zs_rd_cur = rd_cur;
2059 bp->b_datap->db_type = M_BREAK;
2060 if (bp->b_datap->db_lim <= rd_cur)
2061 ZSA_KICK_RCV;
2062 za->za_do_kick_rcv_in_softint = 1;
2063 ZSSETSOFT(zs);
2064
2065 }
2066 }
2067 SCC_WRITE0(ZSWR0_RESET_ERRORS);
2068 if (s1 & ZSRR1_DO) {
2069 za->za_hw_overrun++;
2070 ZSSETSOFT(zs);
2071 }
2072 }
2073
2074 /*
2075 * Process software interrupts (or poll)
2076 * Crucial points:
2077 * 3. BUG - breaks are handled "out-of-band" - their relative position
2078 * among input events is lost, as well as multiple breaks together.
2079 * This is probably not a problem in practice.
2080 */
2081 static int
zsa_softint(struct zscom * zs)2082 zsa_softint(struct zscom *zs)
2083 {
2084 struct asyncline *za = (struct asyncline *)&zs->zs_priv_str;
2085 uchar_t r0;
2086 uchar_t za_kick_active;
2087 int m_error;
2088 int allocbcount = 0;
2089 int do_ttycommon_qfull = 0;
2090 boolean_t hangup = B_FALSE, unhangup = B_FALSE;
2091 boolean_t m_break = B_FALSE, wakeup = B_FALSE;
2092 queue_t *q;
2093 mblk_t *bp;
2094 mblk_t *head = NULL, *tail = NULL;
2095
2096 mutex_enter(zs->zs_excl);
2097 if (zs->zs_suspended || (zs->zs_flags & ZS_CLOSED)) {
2098 mutex_exit(zs->zs_excl);
2099 return (0);
2100 }
2101 q = za->za_ttycommon.t_readq;
2102 if (za->za_flags & ZAS_WOPEN && !q) {
2103 if (za->za_ext) {
2104 mutex_enter(zs->zs_excl_hi);
2105 r0 = SCC_READ0();
2106 za->za_ext = 0;
2107 mutex_exit(zs->zs_excl_hi);
2108 /*
2109 * carrier up?
2110 */
2111 if ((r0 & ZSRR0_CD) ||
2112 (za->za_ttycommon.t_flags & TS_SOFTCAR)) {
2113 /*
2114 * carrier present
2115 */
2116 if ((za->za_flags & ZAS_CARR_ON) == 0) {
2117 za->za_flags |= ZAS_CARR_ON;
2118 mutex_exit(zs->zs_excl);
2119 cv_broadcast(&zs->zs_flags_cv);
2120 return (0);
2121 }
2122 }
2123 }
2124 mutex_exit(zs->zs_excl);
2125 return (0);
2126 }
2127 q = za->za_ttycommon.t_readq;
2128 if (!q) {
2129 mutex_exit(zs->zs_excl);
2130 return (0);
2131 }
2132
2133 m_error = za->za_m_error;
2134 za->za_m_error = 0;
2135
2136 if (za->za_do_kick_rcv_in_softint) {
2137 mutex_enter(zs->zs_excl_hi);
2138 ZSA_KICK_RCV;
2139 za->za_do_kick_rcv_in_softint = 0;
2140 mutex_exit(zs->zs_excl_hi);
2141 }
2142
2143 za_kick_active = za->za_kick_active;
2144
2145 while (!za_kick_active) {
2146 ZSA_SEEQ(bp);
2147 if (!bp)
2148 break;
2149
2150 allocbcount++;
2151
2152 if (bp->b_datap->db_type <= QPCTL) {
2153 if (!(canputnext(q))) {
2154 if (za->za_grace_flow_control >=
2155 zsa_grace_flow_control) {
2156 if (za->za_ttycommon.t_cflag &
2157 CRTSXOFF) {
2158 allocbcount--;
2159 break;
2160 }
2161 ZSA_GETQ(bp);
2162 freemsg(bp);
2163 do_ttycommon_qfull = 1;
2164 continue;
2165 } else
2166 za->za_grace_flow_control++;
2167 } else
2168 za->za_grace_flow_control = 0;
2169 }
2170 ZSA_GETQ(bp);
2171 if (!head) {
2172 head = bp;
2173 } else {
2174 if (!tail)
2175 tail = head;
2176 tail->b_next = bp;
2177 tail = bp;
2178 }
2179 }
2180
2181 if (allocbcount)
2182 ZSA_GETBLOCK(zs, allocbcount);
2183
2184 if (za->za_ext) {
2185 mutex_enter(zs->zs_excl_hi);
2186 r0 = SCC_READ0();
2187 za->za_ext = 0;
2188 /*
2189 * carrier up?
2190 */
2191 if ((r0 & ZSRR0_CD) ||
2192 (za->za_ttycommon.t_flags & TS_SOFTCAR)) {
2193 /*
2194 * carrier present
2195 */
2196 if ((za->za_flags & ZAS_CARR_ON) == 0) {
2197 za->za_flags |= ZAS_CARR_ON;
2198 unhangup = B_TRUE;
2199 wakeup = B_TRUE;
2200 }
2201 } else {
2202 if ((za->za_flags & ZAS_CARR_ON) &&
2203 !(za->za_ttycommon.t_cflag & CLOCAL)) {
2204 /*
2205 * Carrier went away.
2206 * Drop DTR, abort any output in progress,
2207 * indicate that output is not stopped, and
2208 * send a hangup notification upstream.
2209 */
2210 (void) zsmctl(zs, ZSWR5_DTR, DMBIC);
2211 if ((za->za_flags & ZAS_BUSY) &&
2212 (zs->zs_wr_cur != NULL)) {
2213 zs->zs_wr_cur = NULL;
2214 zs->zs_wr_lim = NULL;
2215 }
2216 hangup = B_TRUE;
2217 wakeup = B_TRUE;
2218 za->za_flags &= ~(ZAS_STOPPED | ZAS_CARR_ON |
2219 ZAS_BUSY);
2220 za->za_rcv_flags_mask &= ~(DO_TRANSMIT |
2221 DO_RETRANSMIT);
2222 }
2223 }
2224 mutex_exit(zs->zs_excl_hi);
2225 if (hangup && (bp = za->za_xmitblk) != NULL) {
2226 za->za_xmitblk = NULL;
2227 freeb(bp);
2228 }
2229 }
2230
2231 if (za->za_break != 0) {
2232 mutex_enter(zs->zs_excl_hi);
2233 r0 = SCC_READ0();
2234 mutex_exit(zs->zs_excl_hi);
2235 if ((r0 & ZSRR0_BREAK) == 0) {
2236 za->za_break = 0;
2237 m_break = B_TRUE;
2238 }
2239 }
2240
2241 /*
2242 * If a transmission has finished, indicate that it's
2243 * finished, and start that line up again.
2244 */
2245
2246 mutex_enter(zs->zs_excl_hi);
2247 if (za->za_rcv_flags_mask & DO_TRANSMIT) {
2248 za->za_rcv_flags_mask &= ~DO_TRANSMIT;
2249 za->za_flags &= ~ZAS_BUSY;
2250
2251 if ((za->za_ttycommon.t_cflag & CRTSCTS) &&
2252 (za->za_rcv_flags_mask & DO_RETRANSMIT) &&
2253 zs->zs_wr_cur)
2254 bp = NULL;
2255 else {
2256 za->za_rcv_flags_mask &= ~DO_RETRANSMIT;
2257 bp = za->za_xmitblk;
2258 za->za_xmitblk = 0;
2259 }
2260 mutex_exit(zs->zs_excl_hi);
2261 if (bp)
2262 freemsg(bp);
2263 zsa_start(zs);
2264 /* if we didn't start anything, then notify waiters */
2265 if (!(za->za_flags & ZAS_BUSY))
2266 wakeup = B_TRUE;
2267 } else {
2268 mutex_exit(zs->zs_excl_hi);
2269 }
2270
2271
2272 /*
2273 * A note about these overrun bits: all they do is *tell* someone
2274 * about an error- They do not track multiple errors. In fact,
2275 * you could consider them latched register bits if you like.
2276 * We are only interested in printing the error message once for
2277 * any cluster of overrun errors.
2278 */
2279 if ((!za->za_kick_rcv_id) && (zs->zs_rd_cur || za_kick_active)) {
2280 if (g_zsticks)
2281 za->za_kick_rcv_id = timeout(zsa_kick_rcv, zs,
2282 g_zsticks);
2283 else
2284 za->za_kick_rcv_id = timeout(zsa_kick_rcv, zs,
2285 zsticks[SPEED(za->za_ttycommon.t_cflag)]);
2286 za->za_kick_rcv_count = ZA_KICK_RCV_COUNT;
2287 }
2288 za->za_soft_active = 1;
2289 mutex_exit(zs->zs_excl);
2290
2291 if (!hangup && do_ttycommon_qfull) {
2292 ttycommon_qfull(&za->za_ttycommon, q);
2293 mutex_enter(zs->zs_excl);
2294 zsa_start(zs);
2295 mutex_exit(zs->zs_excl);
2296 }
2297
2298 if (za->za_hw_overrun > 10) {
2299 cmn_err(CE_NOTE, "zs%d: silo overflow\n", UNIT(za->za_dev));
2300 za->za_hw_overrun = 0;
2301 }
2302
2303 if (za->za_sw_overrun > 10) {
2304 cmn_err(CE_NOTE, "zs%d:ring buffer overflow\n",
2305 UNIT(za->za_dev));
2306 za->za_sw_overrun = 0;
2307 }
2308
2309 if (unhangup)
2310 (void) putnextctl(q, M_UNHANGUP);
2311
2312 if (m_break)
2313 (void) putnextctl(q, M_BREAK);
2314
2315 while (head) {
2316 if (!tail) {
2317 putnext(q, head);
2318 break;
2319 }
2320 bp = head;
2321 head = head->b_next;
2322 bp->b_next = NULL;
2323 putnext(q, bp);
2324 }
2325
2326 if (hangup) {
2327 int flushflag;
2328
2329 /*
2330 * If we're in the midst of close, then flush everything. Don't
2331 * leave stale ioctls lying about.
2332 */
2333 flushflag = (zs->zs_flags & ZS_CLOSING) ? FLUSHALL : FLUSHDATA;
2334 flushq(za->za_ttycommon.t_writeq, flushflag);
2335 (void) putnextctl(q, M_HANGUP);
2336 }
2337
2338 if (m_error)
2339 (void) putnextctl1(q, M_ERROR, m_error);
2340
2341 za->za_soft_active = 0;
2342
2343 if (wakeup || (zs->zs_flags & ZS_CLOSED))
2344 cv_broadcast(&zs->zs_flags_cv);
2345
2346 return (0);
2347 }
2348
2349 /*
2350 * Start output on a line, unless it's busy, frozen, or otherwise.
2351 */
2352 static void
zsa_start(struct zscom * zs)2353 zsa_start(struct zscom *zs)
2354 {
2355 struct asyncline *za = (struct asyncline *)&zs->zs_priv_str;
2356 int cc;
2357 queue_t *q;
2358 mblk_t *bp;
2359 uchar_t *rptr, *wptr;
2360
2361 /*
2362 * If the chip is busy (i.e., we're waiting for a break timeout
2363 * to expire, or for the current transmission to finish, or for
2364 * output to finish draining from chip), don't grab anything new.
2365 */
2366 if ((za->za_flags & (ZAS_BREAK|ZAS_BUSY|ZAS_DRAINING)) ||
2367 zs->zs_suspended)
2368 return;
2369
2370 if (za->za_ttycommon.t_cflag & CRTSCTS) {
2371 mutex_enter(zs->zs_excl_hi);
2372 if (za->za_rcv_flags_mask & DO_RETRANSMIT) {
2373 rptr = zs->zs_wr_cur;
2374 wptr = zs->zs_wr_lim;
2375 goto zsa_start_retransmit;
2376
2377 }
2378 mutex_exit(zs->zs_excl_hi);
2379 }
2380
2381 /*
2382 * If we have a flow-control character to transmit, do it now.
2383 */
2384 if (za->za_flowc != '\0') {
2385 mutex_enter(zs->zs_excl_hi);
2386 if (za->za_ttycommon.t_cflag & CRTSCTS) {
2387 if ((SCC_READ0() & (ZSRR0_CTS|ZSRR0_TX_READY)) !=
2388 (ZSRR0_CTS|ZSRR0_TX_READY)) {
2389 mutex_exit(zs->zs_excl_hi);
2390 return;
2391 }
2392 } else if (!(SCC_READ0() & ZSRR0_TX_READY)) {
2393 mutex_exit(zs->zs_excl_hi);
2394 return;
2395 }
2396
2397 ZSDELAY();
2398 SCC_WRITEDATA(za->za_flowc);
2399 za->za_flowc = '\0';
2400 mutex_exit(zs->zs_excl_hi);
2401 return;
2402 }
2403
2404 /*
2405 * If we're waiting for a delay timeout to expire, don't grab
2406 * anything new.
2407 */
2408 if (za->za_flags & ZAS_DELAY)
2409 return;
2410
2411 if ((q = za->za_ttycommon.t_writeq) == NULL)
2412 return; /* not attached to a stream */
2413
2414 zsa_start_again:
2415 for (;;) {
2416 if ((bp = getq(q)) == NULL)
2417 return; /* no data to transmit */
2418
2419 /*
2420 * We have a message block to work on.
2421 * Check whether it's a break, a delay, or an ioctl (the latter
2422 * occurs if the ioctl in question was waiting for the output
2423 * to drain). If it's one of those, process it immediately.
2424 */
2425 switch (bp->b_datap->db_type) {
2426
2427 case M_BREAK:
2428 /*
2429 * Set the break bit, and arrange for "zsa_restart"
2430 * to be called in 1/4 second; it will turn the
2431 * break bit off, and call "zsa_start" to grab
2432 * the next message.
2433 */
2434 mutex_enter(zs->zs_excl_hi);
2435 SCC_BIS(5, ZSWR5_BREAK);
2436 mutex_exit(zs->zs_excl_hi);
2437 if (!za->za_zsa_restart_id) {
2438 za->za_zsa_restart_id =
2439 timeout(zsa_restart, zs, hz/4);
2440 }
2441 za->za_flags |= ZAS_BREAK;
2442 freemsg(bp);
2443 return; /* wait for this to finish */
2444
2445 case M_DELAY:
2446 /*
2447 * Arrange for "zsa_restart" to be called when the
2448 * delay expires; it will turn MTS_DELAY off,
2449 * and call "zsa_start" to grab the next message.
2450 */
2451 if (! za->za_zsa_restart_id) {
2452 za->za_zsa_restart_id = timeout(zsa_restart,
2453 zs,
2454 (int)(*(unsigned char *)bp->b_rptr + 6));
2455 }
2456 za->za_flags |= ZAS_DELAY;
2457 freemsg(bp);
2458 return; /* wait for this to finish */
2459
2460 case M_IOCTL:
2461 /*
2462 * This ioctl was waiting for the output ahead of
2463 * it to drain; obviously, it has. Do it, and
2464 * then grab the next message after it.
2465 */
2466 zsa_ioctl(za, q, bp);
2467 continue;
2468 default: /* M_DATA */
2469 goto zsa_start_transmit;
2470 }
2471
2472 }
2473 zsa_start_transmit:
2474 /*
2475 * We have data to transmit. If output is stopped, put
2476 * it back and try again later.
2477 */
2478 if (za->za_flags & ZAS_STOPPED) {
2479 (void) putbq(q, bp);
2480 return;
2481 }
2482
2483 za->za_xmitblk = bp;
2484 rptr = bp->b_rptr;
2485 wptr = bp->b_wptr;
2486 cc = wptr - rptr;
2487 bp = bp->b_cont;
2488 if (bp != NULL) {
2489 za->za_xmitblk->b_cont = NULL;
2490 (void) putbq(q, bp); /* not done with this message yet */
2491 }
2492
2493 if (rptr >= wptr) {
2494 freeb(za->za_xmitblk);
2495 za->za_xmitblk = NULL;
2496 goto zsa_start_again;
2497 }
2498
2499 /*
2500 * In 5-bit mode, the high order bits are used
2501 * to indicate character sizes less than five,
2502 * so we need to explicitly mask before transmitting
2503 */
2504 if ((za->za_ttycommon.t_cflag & CSIZE) == CS5) {
2505 unsigned char *p = rptr;
2506 int cnt = cc;
2507
2508 while (cnt--)
2509 *p++ &= (unsigned char) 0x1f;
2510 }
2511
2512 /*
2513 * Set up this block for pseudo-DMA.
2514 */
2515
2516 mutex_enter(zs->zs_excl_hi);
2517 zs->zs_wr_cur = rptr;
2518 zs->zs_wr_lim = wptr;
2519
2520 zsa_start_retransmit:
2521 za->za_rcv_flags_mask &= ~DO_TRANSMIT;
2522 if (za->za_ttycommon.t_cflag & CRTSCTS) {
2523 if ((SCC_READ0() & (ZSRR0_CTS|ZSRR0_TX_READY)) !=
2524 (ZSRR0_CTS|ZSRR0_TX_READY)) {
2525 za->za_rcv_flags_mask |= DO_RETRANSMIT;
2526 za->za_flags |= ZAS_BUSY;
2527 mutex_exit(zs->zs_excl_hi);
2528 return;
2529 }
2530 za->za_rcv_flags_mask &= ~DO_RETRANSMIT;
2531 } else {
2532 if (!(SCC_READ0() & ZSRR0_TX_READY)) {
2533 za->za_flags |= ZAS_BUSY;
2534 mutex_exit(zs->zs_excl_hi);
2535 return;
2536 }
2537 }
2538 /*
2539 * If the transmitter is ready, shove the first
2540 * character out.
2541 */
2542 ZSDELAY();
2543 SCC_WRITEDATA(*rptr++);
2544 #ifdef ZSA_DEBUG
2545 za->za_wr++;
2546 #endif
2547 zs->zs_wr_cur = rptr;
2548 za->za_flags |= ZAS_BUSY;
2549 zs->zs_flags |= ZS_PROGRESS;
2550 mutex_exit(zs->zs_excl_hi);
2551 }
2552
2553 /*
2554 * Restart output on a line after a delay or break timer expired.
2555 */
2556 static void
zsa_restart(void * arg)2557 zsa_restart(void *arg)
2558 {
2559 struct zscom *zs = arg;
2560 struct asyncline *za = (struct asyncline *)&zs->zs_priv_str;
2561
2562 /*
2563 * If break timer expired, turn off the break bit.
2564 */
2565 mutex_enter(zs->zs_excl);
2566 if (!za->za_zsa_restart_id) {
2567 mutex_exit(zs->zs_excl);
2568 return;
2569 }
2570 za->za_zsa_restart_id = 0;
2571 if (za->za_flags & ZAS_BREAK) {
2572 mutex_enter(zs->zs_excl_hi);
2573 SCC_BIC(5, ZSWR5_BREAK);
2574 mutex_exit(zs->zs_excl_hi);
2575 }
2576 za->za_flags &= ~(ZAS_DELAY|ZAS_BREAK);
2577 if (za->za_ttycommon.t_writeq != NULL)
2578 zsa_start(zs);
2579 mutex_exit(zs->zs_excl);
2580 cv_broadcast(&zs->zs_flags_cv);
2581 }
2582
2583 /*
2584 * See if the receiver has any data after zs_tick delay
2585 */
2586 static void
zsa_kick_rcv(void * arg)2587 zsa_kick_rcv(void *arg)
2588 {
2589 struct zscom *zs = arg;
2590 struct asyncline *za = (struct asyncline *)&zs->zs_priv_str;
2591 queue_t *q;
2592 int tmp;
2593 mblk_t *mp;
2594 uchar_t za_soft_active, za_kick_active;
2595 int allocbcount = 0;
2596 int do_ttycommon_qfull = 0;
2597 mblk_t *head = NULL, *tail = NULL;
2598
2599 mutex_enter(zs->zs_excl);
2600 if (za->za_kick_rcv_id == 0 || (zs->zs_flags & ZS_CLOSED)) {
2601 mutex_exit(zs->zs_excl);
2602 return;
2603 }
2604 za_soft_active = za->za_soft_active;
2605 za_kick_active = za->za_kick_active;
2606 q = za->za_ttycommon.t_readq;
2607 if (!q) {
2608 mutex_exit(zs->zs_excl);
2609 return;
2610 }
2611 mutex_enter(zs->zs_excl_hi);
2612 if (zs->zs_rd_cur) {
2613 ZSA_KICK_RCV;
2614 za->za_kick_rcv_count = tmp = ZA_KICK_RCV_COUNT;
2615 } else
2616 tmp = --za->za_kick_rcv_count;
2617 if (tmp > 0 || za_soft_active || za_kick_active) {
2618 mutex_exit(zs->zs_excl_hi);
2619 if (g_zsticks)
2620 za->za_kick_rcv_id = timeout(zsa_kick_rcv,
2621 zs, g_zsticks);
2622 else
2623 za->za_kick_rcv_id = timeout(zsa_kick_rcv,
2624 zs, zsticks[SPEED(za->za_ttycommon.t_cflag)]);
2625 if (za_soft_active || za_kick_active) {
2626 mutex_exit(zs->zs_excl);
2627 return;
2628 }
2629 } else {
2630 za->za_kick_rcv_id = 0;
2631 mutex_exit(zs->zs_excl_hi);
2632 }
2633
2634
2635 for (;;) {
2636 ZSA_SEEQ(mp);
2637 if (!mp)
2638 break;
2639
2640 allocbcount++;
2641
2642 if (mp->b_datap->db_type <= QPCTL) {
2643 if (!(canputnext(q))) {
2644 if (za->za_grace_flow_control >=
2645 zsa_grace_flow_control) {
2646 if (za->za_ttycommon.t_cflag &
2647 CRTSXOFF) {
2648 allocbcount--;
2649 break;
2650 }
2651 ZSA_GETQ(mp);
2652 freemsg(mp);
2653 do_ttycommon_qfull = 1;
2654 continue;
2655 } else
2656 za->za_grace_flow_control++;
2657 } else
2658 za->za_grace_flow_control = 0;
2659 }
2660 ZSA_GETQ(mp);
2661 if (!head) {
2662 head = mp;
2663 } else {
2664 if (!tail)
2665 tail = head;
2666 tail->b_next = mp;
2667 tail = mp;
2668 }
2669 }
2670
2671 if (allocbcount)
2672 ZSA_GETBLOCK(zs, allocbcount);
2673
2674 za->za_kick_active = 1;
2675 mutex_exit(zs->zs_excl);
2676
2677 if (do_ttycommon_qfull) {
2678 ttycommon_qfull(&za->za_ttycommon, q);
2679 mutex_enter(zs->zs_excl);
2680 zsa_start(zs);
2681 mutex_exit(zs->zs_excl);
2682 }
2683
2684 while (head) {
2685 if (!tail) {
2686 putnext(q, head);
2687 break;
2688 }
2689 mp = head;
2690 head = head->b_next;
2691 mp->b_next = NULL;
2692 putnext(q, mp);
2693
2694 }
2695 za->za_kick_active = 0;
2696
2697 if (zs->zs_flags & ZS_CLOSED)
2698 cv_broadcast(&zs->zs_flags_cv);
2699 }
2700
2701 /*
2702 * Retry an "ioctl", now that "bufcall" claims we may be able to allocate
2703 * the buffer we need.
2704 */
2705 static void
zsa_reioctl(void * arg)2706 zsa_reioctl(void *arg)
2707 {
2708 struct asyncline *za = arg;
2709 struct zscom *zs = za->za_common;
2710 queue_t *q;
2711 mblk_t *mp;
2712
2713 /*
2714 * The bufcall is no longer pending.
2715 */
2716 mutex_enter(zs->zs_excl);
2717 if (!za->za_wbufcid) {
2718 mutex_exit(zs->zs_excl);
2719 return;
2720 }
2721 za->za_wbufcid = 0;
2722 if ((q = za->za_ttycommon.t_writeq) == NULL) {
2723 mutex_exit(zs->zs_excl);
2724 return;
2725 }
2726 if ((mp = za->za_ttycommon.t_iocpending) != NULL) {
2727 /*
2728 * not pending any more
2729 */
2730 za->za_ttycommon.t_iocpending = NULL;
2731 zsa_ioctl(za, q, mp);
2732 }
2733 mutex_exit(zs->zs_excl);
2734 }
2735
2736 /*
2737 * Process an "ioctl" message sent down to us.
2738 * Note that we don't need to get any locks until we are ready to access
2739 * the hardware. Nothing we access until then is going to be altered
2740 * outside of the STREAMS framework, so we should be safe.
2741 */
2742 static void
zsa_ioctl(struct asyncline * za,queue_t * wq,mblk_t * mp)2743 zsa_ioctl(struct asyncline *za, queue_t *wq, mblk_t *mp)
2744 {
2745 struct zscom *zs = za->za_common;
2746 struct iocblk *iocp;
2747 unsigned datasize;
2748 int error;
2749 mblk_t *tmp;
2750
2751 if (za->za_ttycommon.t_iocpending != NULL) {
2752 /*
2753 * We were holding an "ioctl" response pending the
2754 * availability of an "mblk" to hold data to be passed up;
2755 * another "ioctl" came through, which means that "ioctl"
2756 * must have timed out or been aborted.
2757 */
2758 freemsg(za->za_ttycommon.t_iocpending);
2759 za->za_ttycommon.t_iocpending = NULL;
2760 }
2761
2762 iocp = (struct iocblk *)mp->b_rptr;
2763
2764 /*
2765 * The only way in which "ttycommon_ioctl" can fail is if the "ioctl"
2766 * requires a response containing data to be returned to the user,
2767 * and no mblk could be allocated for the data.
2768 * No such "ioctl" alters our state. Thus, we always go ahead and
2769 * do any state-changes the "ioctl" calls for. If we couldn't allocate
2770 * the data, "ttycommon_ioctl" has stashed the "ioctl" away safely, so
2771 * we just call "bufcall" to request that we be called back when we
2772 * stand a better chance of allocating the data.
2773 */
2774 mutex_exit(zs->zs_excl);
2775 datasize = ttycommon_ioctl(&za->za_ttycommon, wq, mp, &error);
2776 mutex_enter(zs->zs_excl);
2777 if (za->za_ttycommon.t_flags & TS_SOFTCAR)
2778 zssoftCAR[zs->zs_unit] = 1;
2779 else
2780 zssoftCAR[zs->zs_unit] = 0;
2781 if (datasize != 0) {
2782 if (za->za_wbufcid)
2783 unbufcall(za->za_wbufcid);
2784 za->za_wbufcid = bufcall(datasize, BPRI_HI, zsa_reioctl, za);
2785 return;
2786 }
2787
2788
2789 if (error == 0) {
2790 /*
2791 * "ttycommon_ioctl" did most of the work; we just use the
2792 * data it set up.
2793 */
2794 switch (iocp->ioc_cmd) {
2795
2796 case TCSETS:
2797 case TCSETSW:
2798 case TCSETSF:
2799 case TCSETA:
2800 case TCSETAW:
2801 case TCSETAF:
2802 mutex_enter(zs->zs_excl_hi);
2803 zsa_program(za, 1);
2804 zsa_set_za_rcv_flags_mask(za);
2805 mutex_exit(zs->zs_excl_hi);
2806 break;
2807 }
2808 } else if (error < 0) {
2809 /*
2810 * "ttycommon_ioctl" didn't do anything; we process it here.
2811 */
2812 error = 0;
2813
2814 switch (iocp->ioc_cmd) {
2815
2816 case TCSBRK:
2817 error = miocpullup(mp, sizeof (int));
2818 if (error != 0)
2819 break;
2820
2821 if (*(int *)mp->b_cont->b_rptr == 0) {
2822 /*
2823 * The delay ensures that a 3 byte transmit
2824 * fifo is empty.
2825 */
2826 mutex_exit(zs->zs_excl);
2827 delay(ztdelay(SPEED(za->za_ttycommon.t_cflag)));
2828 mutex_enter(zs->zs_excl);
2829
2830 /*
2831 * Set the break bit, and arrange for
2832 * "zsa_restart" to be called in 1/4 second;
2833 * it will turn the break bit off, and call
2834 * "zsa_start" to grab the next message.
2835 */
2836 mutex_enter(zs->zs_excl_hi);
2837 SCC_BIS(5, ZSWR5_BREAK);
2838 if (!za->za_zsa_restart_id) {
2839 mutex_exit(zs->zs_excl_hi);
2840 za->za_zsa_restart_id =
2841 timeout(zsa_restart, zs, hz / 4);
2842 mutex_enter(zs->zs_excl_hi);
2843 }
2844 za->za_flags |= ZAS_BREAK;
2845 mutex_exit(zs->zs_excl_hi);
2846 }
2847 break;
2848
2849 case TIOCSBRK:
2850 mutex_enter(zs->zs_excl_hi);
2851 SCC_BIS(5, ZSWR5_BREAK);
2852 mutex_exit(zs->zs_excl_hi);
2853 mioc2ack(mp, NULL, 0, 0);
2854 break;
2855
2856 case TIOCCBRK:
2857 mutex_enter(zs->zs_excl_hi);
2858 SCC_BIC(5, ZSWR5_BREAK);
2859 mutex_exit(zs->zs_excl_hi);
2860 mioc2ack(mp, NULL, 0, 0);
2861 break;
2862
2863 case TIOCMSET:
2864 case TIOCMBIS:
2865 case TIOCMBIC: {
2866 int mlines;
2867
2868 if (iocp->ioc_count == TRANSPARENT) {
2869 mcopyin(mp, NULL, sizeof (int), NULL);
2870 break;
2871 }
2872
2873 error = miocpullup(mp, sizeof (int));
2874 if (error != 0)
2875 break;
2876
2877 mlines = *(int *)mp->b_cont->b_rptr;
2878
2879 mutex_enter(zs->zs_excl_hi);
2880 switch (iocp->ioc_cmd) {
2881 case TIOCMSET:
2882 (void) zsmctl(zs, dmtozs(mlines), DMSET);
2883 break;
2884 case TIOCMBIS:
2885 (void) zsmctl(zs, dmtozs(mlines), DMBIS);
2886 break;
2887 case TIOCMBIC:
2888 (void) zsmctl(zs, dmtozs(mlines), DMBIC);
2889 break;
2890 }
2891 mutex_exit(zs->zs_excl_hi);
2892
2893 mioc2ack(mp, NULL, 0, 0);
2894 break;
2895 }
2896
2897 case TIOCMGET:
2898 tmp = allocb(sizeof (int), BPRI_MED);
2899 if (tmp == NULL) {
2900 error = EAGAIN;
2901 break;
2902 }
2903 if (iocp->ioc_count != TRANSPARENT)
2904 mioc2ack(mp, tmp, sizeof (int), 0);
2905 else
2906 mcopyout(mp, NULL, sizeof (int), NULL, tmp);
2907
2908 mutex_enter(zs->zs_excl_hi);
2909 *(int *)mp->b_cont->b_rptr =
2910 zstodm(zsmctl(zs, 0, DMGET));
2911 mutex_exit(zs->zs_excl_hi);
2912 /*
2913 * qreply done below
2914 */
2915 break;
2916
2917 default:
2918 /*
2919 * If we don't understand it, it's an error. NAK it.
2920 */
2921 error = EINVAL;
2922 break;
2923 }
2924 }
2925
2926 if (error != 0) {
2927 iocp->ioc_error = error;
2928 mp->b_datap->db_type = M_IOCNAK;
2929 }
2930
2931 ZSA_QREPLY(wq, mp);
2932 }
2933
2934
2935 static int
dmtozs(int bits)2936 dmtozs(int bits)
2937 {
2938 int b = 0;
2939
2940 if (bits & TIOCM_CAR)
2941 b |= ZSRR0_CD;
2942 if (bits & TIOCM_CTS)
2943 b |= ZSRR0_CTS;
2944 if (bits & TIOCM_RTS)
2945 b |= ZSWR5_RTS;
2946 if (bits & TIOCM_DTR)
2947 b |= ZSWR5_DTR;
2948 return (b);
2949 }
2950
2951 static int
zstodm(int bits)2952 zstodm(int bits)
2953 {
2954 int b;
2955
2956 b = 0;
2957 if (bits & ZSRR0_CD)
2958 b |= TIOCM_CAR;
2959 if (bits & ZSRR0_CTS)
2960 b |= TIOCM_CTS;
2961 if (bits & ZSWR5_RTS)
2962 b |= TIOCM_RTS;
2963 if (bits & ZSWR5_DTR)
2964 b |= TIOCM_DTR;
2965 return (b);
2966 }
2967
2968 /*
2969 * Assemble registers and flags necessary to program the port to our liking.
2970 * For async operation, most of this is based on the values of
2971 * the "c_iflag" and "c_cflag" fields supplied to us.
2972 */
2973 static void
zsa_program(struct asyncline * za,int setibaud)2974 zsa_program(struct asyncline *za, int setibaud)
2975 {
2976 struct zscom *zs = za->za_common;
2977 struct zs_prog *zspp;
2978 int wr3, wr4, wr5, wr15, speed, baudrate, flags = 0;
2979
2980 if ((baudrate = SPEED(za->za_ttycommon.t_cflag)) == 0) {
2981 /*
2982 * Hang up line.
2983 */
2984 (void) zsmctl(zs, ZS_OFF, DMSET);
2985 return;
2986 }
2987
2988 /*
2989 * set input speed same as output, as split speed not supported
2990 */
2991 if (setibaud) {
2992 za->za_ttycommon.t_cflag &= ~(CIBAUD);
2993 if (baudrate > CBAUD) {
2994 za->za_ttycommon.t_cflag |= CIBAUDEXT;
2995 za->za_ttycommon.t_cflag |=
2996 (((baudrate - CBAUD - 1) << IBSHIFT) & CIBAUD);
2997 } else {
2998 za->za_ttycommon.t_cflag &= ~CIBAUDEXT;
2999 za->za_ttycommon.t_cflag |=
3000 ((baudrate << IBSHIFT) & CIBAUD);
3001 }
3002 }
3003
3004 /*
3005 * Do not allow the console/keyboard device to have its receiver
3006 * disabled; doing that would mean you couldn't type an abort
3007 * sequence.
3008 */
3009 if ((za->za_dev == rconsdev) || (za->za_dev == kbddev) ||
3010 (za->za_dev == stdindev) || (za->za_ttycommon.t_cflag & CREAD))
3011 wr3 = ZSWR3_RX_ENABLE;
3012 else
3013 wr3 = 0;
3014 wr4 = ZSWR4_X16_CLK;
3015 wr5 = (zs->zs_wreg[5] & (ZSWR5_RTS|ZSWR5_DTR)) | ZSWR5_TX_ENABLE;
3016
3017 if (zsb134_weird && baudrate == B134) { /* what a joke! */
3018 /*
3019 * XXX - should B134 set all this crap in the compatibility
3020 * module, leaving this stuff fairly clean?
3021 */
3022 flags |= ZSP_PARITY_SPECIAL;
3023 wr3 |= ZSWR3_RX_6;
3024 wr4 |= ZSWR4_PARITY_ENABLE | ZSWR4_PARITY_EVEN;
3025 wr4 |= ZSWR4_1_5_STOP;
3026 wr5 |= ZSWR5_TX_6;
3027 } else {
3028
3029 switch (za->za_ttycommon.t_cflag & CSIZE) {
3030
3031 case CS5:
3032 wr3 |= ZSWR3_RX_5;
3033 wr5 |= ZSWR5_TX_5;
3034 break;
3035
3036 case CS6:
3037 wr3 |= ZSWR3_RX_6;
3038 wr5 |= ZSWR5_TX_6;
3039 break;
3040
3041 case CS7:
3042 wr3 |= ZSWR3_RX_7;
3043 wr5 |= ZSWR5_TX_7;
3044 break;
3045
3046 case CS8:
3047 wr3 |= ZSWR3_RX_8;
3048 wr5 |= ZSWR5_TX_8;
3049 break;
3050 }
3051
3052 if (za->za_ttycommon.t_cflag & PARENB) {
3053 /*
3054 * The PARITY_SPECIAL bit causes a special rx
3055 * interrupt on parity errors. Turn it on if
3056 * we're checking the parity of characters.
3057 */
3058 if (za->za_ttycommon.t_iflag & INPCK)
3059 flags |= ZSP_PARITY_SPECIAL;
3060 wr4 |= ZSWR4_PARITY_ENABLE;
3061 if (!(za->za_ttycommon.t_cflag & PARODD))
3062 wr4 |= ZSWR4_PARITY_EVEN;
3063 }
3064 wr4 |= (za->za_ttycommon.t_cflag & CSTOPB) ?
3065 ZSWR4_2_STOP : ZSWR4_1_STOP;
3066 }
3067
3068 #if 0
3069 /*
3070 * The AUTO_CD_CTS flag enables the hardware flow control feature of
3071 * the 8530, which allows the state of CTS and DCD to control the
3072 * enabling of the transmitter and receiver, respectively. The
3073 * receiver and transmitter still must have their enable bits set in
3074 * WR3 and WR5, respectively, for CTS and DCD to be monitored this way.
3075 * Hardware flow control can thus be implemented with no help from
3076 * software.
3077 */
3078 if (za->za_ttycommon.t_cflag & CRTSCTS)
3079 wr3 |= ZSWR3_AUTO_CD_CTS;
3080 #endif
3081 if (za->za_ttycommon.t_cflag & CRTSCTS)
3082 wr15 = ZSR15_BREAK | ZSR15_TX_UNDER | ZSR15_CD | ZSR15_CTS;
3083 else
3084 wr15 = ZSR15_BREAK | ZSR15_TX_UNDER | ZSR15_CD;
3085
3086 speed = zs->zs_wreg[12] + (zs->zs_wreg[13] << 8);
3087
3088 /*
3089 * Here we assemble a set of changes to be passed to zs_program.
3090 * Note: Write Register 15 must be set to enable BREAK and UNDERrun
3091 * interrupts. It must also enable CD interrupts which, although
3092 * not processed by the hardware interrupt handler, will be processed
3093 * by zsa_process, indirectly resulting in a SIGHUP being delivered
3094 * to the controlling process if CD drops. CTS interrupts must NOT
3095 * be enabled. We don't use them at all, and they will hang IPC/IPX
3096 * systems at boot time if synchronous modems that supply transmit
3097 * clock are attached to any of their serial ports.
3098 */
3099 if (((zs->zs_wreg[1] & ZSWR1_PARITY_SPECIAL) &&
3100 !(flags & ZSP_PARITY_SPECIAL)) ||
3101 (!(zs->zs_wreg[1] & ZSWR1_PARITY_SPECIAL) &&
3102 (flags & ZSP_PARITY_SPECIAL)) ||
3103 wr3 != zs->zs_wreg[3] || wr4 != zs->zs_wreg[4] ||
3104 wr5 != zs->zs_wreg[5] || wr15 != zs->zs_wreg[15] ||
3105 speed != zs_speeds[baudrate]) {
3106
3107 za->za_flags |= ZAS_DRAINING;
3108 zspp = &zs_prog[zs->zs_unit];
3109 zspp->zs = zs;
3110 zspp->flags = (uchar_t)flags;
3111 zspp->wr4 = (uchar_t)wr4;
3112 zspp->wr11 = (uchar_t)(ZSWR11_TXCLK_BAUD | ZSWR11_RXCLK_BAUD);
3113
3114 speed = zs_speeds[baudrate];
3115 zspp->wr12 = (uchar_t)(speed & 0xff);
3116 zspp->wr13 = (uchar_t)((speed >> 8) & 0xff);
3117 zspp->wr3 = (uchar_t)wr3;
3118 zspp->wr5 = (uchar_t)wr5;
3119 zspp->wr15 = (uchar_t)wr15;
3120
3121 zs_program(zspp);
3122 za->za_flags &= ~ZAS_DRAINING;
3123 }
3124 }
3125
3126 /*
3127 * Get the current speed of the console and turn it into something
3128 * UNIX knows about - used to preserve console speed when UNIX comes up.
3129 */
3130 int
zsgetspeed(dev_t dev)3131 zsgetspeed(dev_t dev)
3132 {
3133 struct zscom *zs;
3134 int uspeed, zspeed;
3135 uchar_t rr;
3136
3137 zs = &zscom[UNIT(dev)];
3138 SCC_READ(12, zspeed);
3139 SCC_READ(13, rr);
3140 zspeed |= rr << 8;
3141 for (uspeed = 0; uspeed < NSPEED; uspeed++)
3142 if (zs_speeds[uspeed] == zspeed)
3143 return (uspeed);
3144 /*
3145 * 9600 baud if we can't figure it out
3146 */
3147 return (ISPEED);
3148 }
3149
3150 /*
3151 * callback routine when enough memory is available.
3152 */
3153 static void
zsa_callback(void * arg)3154 zsa_callback(void *arg)
3155 {
3156 struct zscom *zs = arg;
3157 struct asyncline *za = (struct asyncline *)&zs->zs_priv_str;
3158 int allocbcount = zsa_rstandby;
3159
3160 mutex_enter(zs->zs_excl);
3161 if (za->za_bufcid) {
3162 za->za_bufcid = 0;
3163 ZSA_GETBLOCK(zs, allocbcount);
3164 }
3165 mutex_exit(zs->zs_excl);
3166 }
3167
3168 /*
3169 * Set the receiver flags
3170 */
3171 static void
zsa_set_za_rcv_flags_mask(struct asyncline * za)3172 zsa_set_za_rcv_flags_mask(struct asyncline *za)
3173 {
3174 uint_t mask;
3175
3176 za->za_rcv_flags_mask &= ~0xFF;
3177 switch (za->za_ttycommon.t_cflag & CSIZE) {
3178 case CS5:
3179 mask = 0x1f;
3180 break;
3181 case CS6:
3182 mask = 0x3f;
3183 break;
3184 case CS7:
3185 mask = 0x7f;
3186 break;
3187 default:
3188 mask = 0xff;
3189 }
3190
3191 za->za_rcv_flags_mask &= ~(0xFF << 16);
3192 za->za_rcv_flags_mask |= mask << 16;
3193
3194 if ((za->za_ttycommon.t_iflag & PARMRK) &&
3195 !(za->za_ttycommon.t_iflag & (IGNPAR|ISTRIP))) {
3196 za->za_rcv_flags_mask |= DO_ESC;
3197 } else
3198 za->za_rcv_flags_mask &= ~DO_ESC;
3199 if (za->za_ttycommon.t_iflag & IXON) {
3200 za->za_rcv_flags_mask |= DO_STOPC;
3201 za->za_rcv_flags_mask &= ~0xFF;
3202 za->za_rcv_flags_mask |= za->za_ttycommon.t_stopc;
3203 } else
3204 za->za_rcv_flags_mask &= ~DO_STOPC;
3205 }
3206
3207 static int
zsa_suspend(struct zscom * zs)3208 zsa_suspend(struct zscom *zs)
3209 {
3210 struct asyncline *za;
3211 queue_t *q;
3212 mblk_t *bp = NULL;
3213 timeout_id_t restart_id, kick_rcv_id;
3214 struct zs_prog *zspp;
3215
3216 za = (struct asyncline *)&zs->zs_priv_str;
3217 mutex_enter(zs->zs_excl);
3218 if (zs->zs_suspended) {
3219 mutex_exit(zs->zs_excl);
3220 return (DDI_SUCCESS);
3221 }
3222 zs->zs_suspended = 1;
3223
3224 /*
3225 * Turn off interrupts and get any bytes in receiver
3226 */
3227 mutex_enter(zs->zs_excl_hi);
3228 SCC_BIC(1, ZSWR1_INIT);
3229 ZSA_KICK_RCV;
3230 restart_id = za->za_zsa_restart_id;
3231 za->za_zsa_restart_id = 0;
3232 kick_rcv_id = za->za_kick_rcv_id;
3233 za->za_kick_rcv_id = 0;
3234 mutex_exit(zs->zs_excl_hi);
3235 mutex_exit(zs->zs_excl);
3236
3237 /*
3238 * Cancel any timeouts
3239 */
3240 if (restart_id)
3241 (void) untimeout(restart_id);
3242 if (kick_rcv_id)
3243 (void) untimeout(kick_rcv_id);
3244
3245 /*
3246 * Since we have turned off interrupts, zsa_txint will not be called
3247 * and no new chars will given to the chip. We just wait for the
3248 * current character(s) to drain.
3249 */
3250 delay(ztdelay(za->za_ttycommon.t_cflag & CBAUD));
3251
3252 /*
3253 * Return remains of partially sent message to queue
3254 */
3255 mutex_enter(zs->zs_excl);
3256 if ((q = za->za_ttycommon.t_writeq) != NULL) {
3257 mutex_enter(zs->zs_excl_hi);
3258 if ((zs->zs_wr_cur) != NULL) {
3259 za->za_flags &= ~ZAS_BUSY;
3260 za->za_rcv_flags_mask &= ~DO_RETRANSMIT;
3261 bp = za->za_xmitblk;
3262 bp->b_rptr = zs->zs_wr_cur;
3263 zs->zs_wr_cur = NULL;
3264 zs->zs_wr_lim = NULL;
3265 za->za_xmitblk = NULL;
3266 }
3267 mutex_exit(zs->zs_excl_hi);
3268 if (bp)
3269 (void) putbq(q, bp);
3270 }
3271
3272 /*
3273 * Stop any breaks in progress.
3274 */
3275 mutex_enter(zs->zs_excl_hi);
3276 if (zs->zs_wreg[5] & ZSWR5_BREAK) {
3277 SCC_BIC(5, ZSWR5_BREAK);
3278 za->za_flags &= ~ZAS_BREAK;
3279 }
3280
3281 /*
3282 * Now get a copy of current registers setting.
3283 */
3284 zspp = &zs_prog[zs->zs_unit];
3285 zspp->zs = zs;
3286 zspp->flags = 0;
3287 zspp->wr3 = zs->zs_wreg[3];
3288 zspp->wr4 = zs->zs_wreg[4];
3289 zspp->wr5 = zs->zs_wreg[5];
3290 zspp->wr11 = zs->zs_wreg[11];
3291 zspp->wr12 = zs->zs_wreg[12];
3292 zspp->wr13 = zs->zs_wreg[13];
3293 zspp->wr15 = zs->zs_wreg[15];
3294 mutex_exit(zs->zs_excl_hi);
3295 mutex_exit(zs->zs_excl);
3296 /*
3297 * We do this on the off chance that zsa_close is waiting on a timed
3298 * break to complete and nothing else.
3299 */
3300 cv_broadcast(&zs->zs_flags_cv);
3301 return (DDI_SUCCESS);
3302 }
3303
3304 static int
zsa_resume(struct zscom * zs)3305 zsa_resume(struct zscom *zs)
3306 {
3307 struct asyncline *za;
3308 struct zs_prog *zspp;
3309
3310 za = (struct asyncline *)&zs->zs_priv_str;
3311 mutex_enter(zs->zs_excl);
3312 if (!(zs->zs_suspended)) {
3313 mutex_exit(zs->zs_excl);
3314 return (DDI_SUCCESS);
3315 }
3316
3317 /*
3318 * Restore H/W state
3319 */
3320 mutex_enter(zs->zs_excl_hi);
3321 zspp = &zs_prog[zs->zs_unit];
3322 zs_program(zspp);
3323
3324 /*
3325 * Enable all interrupts for this chip and delay to let chip settle
3326 */
3327 SCC_WRITE(9, ZSWR9_MASTER_IE | ZSWR9_VECTOR_INCL_STAT);
3328 DELAY(4000);
3329
3330 /*
3331 * Restart receiving and transmitting
3332 */
3333 zs->zs_suspended = 0;
3334 za->za_rcv_flags_mask |= DO_TRANSMIT;
3335 za->za_ext = 1;
3336 ZSSETSOFT(zs);
3337 mutex_exit(zs->zs_excl_hi);
3338 mutex_exit(zs->zs_excl);
3339
3340 return (DDI_SUCCESS);
3341 }
3342
3343 #ifdef ZSA_DEBUG
3344 static void
zsa_print_info(struct zscom * zs)3345 zsa_print_info(struct zscom *zs)
3346 {
3347 struct asyncline *za = (struct asyncline *)&zs->zs_priv_str;
3348 queue_t *q = za->za_ttycommon.t_writeq;
3349
3350 printf(" next q=%s\n", (RD(q))->q_next->q_qinfo->qi_minfo->mi_idname);
3351 printf("unit=%d\n", zs->zs_unit);
3352 printf("tflag:\n");
3353 if (za->za_ttycommon.t_flags & TS_SOFTCAR) printf(" t_fl:TS_SOFTCAR");
3354 if (za->za_ttycommon.t_flags & TS_XCLUDE) printf(" t_fl:TS_XCLUDE");
3355 if (za->za_ttycommon.t_iflag & IGNBRK) printf(" t_ifl:IGNBRK");
3356 if (za->za_ttycommon.t_iflag & BRKINT) printf(" t_ifl:BRKINT");
3357 if (za->za_ttycommon.t_iflag & IGNPAR) printf(" t_ifl:IGNPAR");
3358 if (za->za_ttycommon.t_iflag & PARMRK) printf(" t_ifl:PARMRK");
3359 if (za->za_ttycommon.t_iflag & INPCK) printf(" t_ifl:INPCK");
3360 if (za->za_ttycommon.t_iflag & ISTRIP) printf(" t_ifl:ISTRIP");
3361 if (za->za_ttycommon.t_iflag & INLCR) printf(" t_ifl:INLCR");
3362 if (za->za_ttycommon.t_iflag & IGNCR) printf(" t_ifl:IGNCR");
3363 if (za->za_ttycommon.t_iflag & ICRNL) printf(" t_ifl:ICRNL");
3364 if (za->za_ttycommon.t_iflag & IUCLC) printf(" t_ifl:IUCLC");
3365 if (za->za_ttycommon.t_iflag & IXON) printf(" t_ifl:IXON");
3366 if (za->za_ttycommon.t_iflag & IXOFF) printf(" t_ifl:IXOFF");
3367
3368 printf("\n");
3369
3370
3371 if (za->za_ttycommon.t_cflag & CSIZE == CS5) printf(" t_cfl:CS5");
3372 if (za->za_ttycommon.t_cflag & CSIZE == CS6) printf(" t_cfl:CS6");
3373 if (za->za_ttycommon.t_cflag & CSIZE == CS7) printf(" t_cfl:CS7");
3374 if (za->za_ttycommon.t_cflag & CSIZE == CS8) printf(" t_cfl:CS8");
3375 if (za->za_ttycommon.t_cflag & CSTOPB) printf(" t_cfl:CSTOPB");
3376 if (za->za_ttycommon.t_cflag & CREAD) printf(" t_cfl:CREAD");
3377 if (za->za_ttycommon.t_cflag & PARENB) printf(" t_cfl:PARENB");
3378 if (za->za_ttycommon.t_cflag & PARODD) printf(" t_cfl:PARODD");
3379 if (za->za_ttycommon.t_cflag & HUPCL) printf(" t_cfl:HUPCL");
3380 if (za->za_ttycommon.t_cflag & CLOCAL) printf(" t_cfl:CLOCAL");
3381 printf(" t_stopc=%x", za->za_ttycommon.t_stopc);
3382 printf("\n");
3383 }
3384 #endif
3385
3386 /*
3387 * Check for abort character sequence
3388 */
3389 static boolean_t
abort_charseq_recognize(uchar_t ch)3390 abort_charseq_recognize(uchar_t ch)
3391 {
3392 static int state = 0;
3393 #define CNTRL(c) ((c)&037)
3394 static char sequence[] = { '\r', '~', CNTRL('b') };
3395
3396 if (ch == sequence[state]) {
3397 if (++state >= sizeof (sequence)) {
3398 state = 0;
3399 return (B_TRUE);
3400 }
3401 } else {
3402 state = (ch == sequence[0]) ? 1 : 0;
3403 }
3404 return (B_FALSE);
3405 }
3406