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 2008 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
27 * Serial I/O driver for Z8530 chips
31 #include <sys/types.h>
32 #include <sys/param.h>
33 #include <sys/systm.h>
34 #include <sys/sysmacros.h>
35 #include <sys/stropts.h>
36 #include <sys/stream.h>
38 #include <sys/mkdev.h>
39 #include <sys/cmn_err.h>
40 #include <sys/errno.h>
42 #include <sys/zsdev.h>
43 #include <sys/debug.h>
44 #include <sys/machsystm.h>
47 #include <sys/sunddi.h>
48 #include <sys/errno.h>
52 #include <sys/vtrace.h>
55 * Temp tracepoint definitions
59 #define TR_ZS_H_INT_START 1
60 #define TR_ZS_H_INT_END 2
61 #define TR_ZS_INT_START 3
62 #define TR_ZS_INT_END 4
64 #define TR_FAC_ZS_INT 52
65 #define TR_READ_START 1
68 #endif /* ZSH_TRACING */
70 #define KIOIP KSTAT_INTR_PTR(zs->intrstats)
82 struct zs_prog
*zs_prog
;
84 int zs_watchdog_count
= 10; /* countdown to determine if tx hung */
86 int zs_drain_check
= 15000000; /* tunable: exit drain check time */
89 char zs_h_log
[ZS_H_LOG_MAX
+10];
91 #define zs_h_log_add(c) \
93 if (zs_h_log_n >= ZS_H_LOG_MAX) \
95 zs_h_log[zs_h_log_n++] = c; \
96 zs_h_log[zs_h_log_n] = '\0'; \
99 #else /* NO_ZS_DEBUG */
100 #define zs_h_log_add(c)
101 #endif /* ZS_DEBUG */
108 #define GETPROP(dip, str, defval) \
109 ddi_getprop(DDI_DEV_T_ANY, (dip), DDI_PROP_DONTPASS, (str), (defval))
111 int zs_usec_delay
= 1;
113 ddi_softintr_t zs_softintr_id
;
114 time_t default_dtrlow
= 3; /* hold dtr low nearly this long on close */
115 static ddi_iblock_cookie_t zs_iblock
;
116 static ddi_iblock_cookie_t zs_hi_iblock
;
117 static int zs_addedsoft
= 0;
121 * Driver information for auto-configuration stuff.
124 static int zsprobe(dev_info_t
*dev
);
125 static int zsattach(dev_info_t
*dev
, ddi_attach_cmd_t cmd
);
126 static int zsdetach(dev_info_t
*dev
, ddi_detach_cmd_t cmd
);
127 void zsopinit(struct zscom
*zs
, struct zsops
*zso
);
129 static void zsnull_intr(struct zscom
*zs
);
130 static int zsnull_softint(struct zscom
*zs
);
131 static int zsnull_suspend(struct zscom
*zs
);
132 static int zsnull_resume(struct zscom
*zs
);
134 struct zsops zsops_null
= {
144 extern struct streamtab asynctab
; /* default -- from zs_async.c */
146 uint_t
zs_high_intr(caddr_t argzs
);
147 uint_t
zsintr(caddr_t intarg
);
149 extern int zsc_info(dev_info_t
*dip
, ddi_info_cmd_t infocmd
, void *arg
,
152 extern int ddi_create_internal_pathname(dev_info_t
*dip
, char *name
,
153 int spec_type
, minor_t minor_num
);
155 extern struct streamtab zsstab
;
156 int zssoftpend
; /* soft interrupt pending */
157 kmutex_t zs_soft_lock
; /* adapt.lock,to use to protect data */
158 /* common to sev. streams or ports */
159 kmutex_t zs_curr_lock
; /* lock protecting zscurr */
161 extern kcondvar_t lbolt_cv
;
164 * curently the only spin lock level 12 for all ocasions
167 #define ZSS_CONF_FLAG (D_NEW | D_MP)
169 static struct cb_ops cb_zs_ops
= {
170 nulldev
, /* cb_open */
171 nulldev
, /* cb_close */
172 nodev
, /* cb_strategy */
173 nodev
, /* cb_print */
176 nodev
, /* cb_write */
177 nodev
, /* cb_ioctl */
178 nodev
, /* cb_devmap */
180 nodev
, /* cb_segmap */
181 nochpoll
, /* cb_chpoll */
182 ddi_prop_op
, /* cb_prop_op */
183 &asynctab
, /* cb_stream */
184 (int)(ZSS_CONF_FLAG
) /* cb_flag */
187 struct dev_ops zs_ops
= {
188 DEVO_REV
, /* devo_rev */
190 zsc_info
, /* devo_getinfo */
191 nulldev
, /* devo_identify */
192 zsprobe
, /* devo_probe */
193 zsattach
, /* devo_attach */
194 zsdetach
, /* devo_detach */
195 nodev
, /* devo_reset */
196 &cb_zs_ops
, /* devo_cb_ops */
197 (struct bus_ops
*)NULL
, /* devo_bus_ops */
198 ddi_power
, /* devo_power */
199 ddi_quiesce_not_supported
, /* devo_quiesce */
204 * This is the loadable module wrapper.
207 #include <sys/modctl.h>
210 * Module linkage information for the kernel.
213 extern struct mod_ops mod_driverops
;
215 static struct modldrv modldrv
= {
216 &mod_driverops
, /* Type of module. This one is a driver */
217 "Z8530 serial driver",
218 &zs_ops
, /* driver ops */
221 static struct modlinkage modlinkage
= {
222 MODREV_1
, (void *)&modldrv
, NULL
228 return (mod_install(&modlinkage
));
238 _info(struct modinfo
*modinfop
)
240 return (mod_info(&modlinkage
, modinfop
));
244 zsprobe(dev_info_t
*dev
)
246 struct zscc_device
*zsaddr
;
250 rval
= DDI_PROBE_FAILURE
;
253 * temporarily map in registers
255 if (ddi_map_regs(dev
, 0, (caddr_t
*)&zsaddr
, 0, 0)) {
256 cmn_err(CE_WARN
, "zsprobe: unable to map registers");
261 * NON-DDI Compliant call
266 * get in sync with the chip
269 if (ddi_peek8(dev
, (char *)&zsaddr
->zscc_control
, &c
) != DDI_SUCCESS
) {
275 * The traditional test for the presence of an 8530 has been to write
276 * a 15 (octal 017) to its control register address, then read it back.
277 * A Z8530 will respond to this with the contents of Read-Register 15.
278 * If this address were memory, or something else, we would expect to
279 * see the 15 again. Normally, the contents of RR15 will be entirely
280 * different. A Z8530 does not use the D0 and D2 bits of register 15,
281 * so they should equal zero. Compatable chips should do the same.
282 * Beware of "enhanced" SCC's that do not guarantee this.
284 if (ddi_poke8(dev
, (char *)&zsaddr
->zscc_control
, '\017')
289 if (ddi_peek8(dev
, (char *)&zsaddr
->zscc_control
, &c
) != DDI_SUCCESS
) {
297 rval
= DDI_PROBE_SUCCESS
;
301 * NON-DDI Compliant call
305 ddi_unmap_regs(dev
, 0, (caddr_t
*)&zsaddr
, 0, 0);
311 zsattach(dev_info_t
*dev
, ddi_attach_cmd_t cmd
)
320 int current_chip
= ddi_get_instance(dev
);
321 struct zscc_device
*tmpzs
; /* for mapping purposes */
330 zs
= &zscom
[current_chip
*2];
332 * Try to resume first channel
334 if (!zs
->zs_resume
|| (zs
->zs_resume
)(zs
) != DDI_SUCCESS
)
335 return (DDI_FAILURE
);
337 * And the second channel
340 if (!zs
->zs_resume
|| (zs
->zs_resume
)(zs
) != DDI_SUCCESS
) {
342 if (!zs
->zs_suspend
||
343 (zs
->zs_suspend
)(zs
) != DDI_SUCCESS
)
345 "zs: inconsistent suspend/resume state");
346 return (DDI_FAILURE
);
348 return (DDI_SUCCESS
);
351 return (DDI_FAILURE
);
355 mutex_init(&zs_soft_lock
, NULL
, MUTEX_DRIVER
, (void *)ZS_PL
);
356 mutex_init(&zs_curr_lock
, NULL
, MUTEX_DRIVER
, (void *)ZS_PL_HI
);
357 zscom
= kmem_zalloc(maxzs
* sizeof (struct zscom
), KM_SLEEP
);
358 zs_prog
= kmem_zalloc(maxzs
* sizeof (struct zs_prog
),
360 zssoftCAR
= kmem_zalloc(maxzs
, KM_SLEEP
);
361 /* don't set nzs until arrays are allocated */
364 zscurr
= &zscom
[(current_chip
*2) + 1];
365 zslast
= &zscom
[current_chip
*2];
366 i
= GETPROP(dev
, "zs-usec-delay", 0);
367 zs_usec_delay
= (i
<= 0) ? 1 : i
;
370 if (2 * current_chip
>= maxzs
) {
372 "zs: unable to allocate resources for chip %d.",
374 cmn_err(CE_WARN
, "Change zs:maxzs in /etc/system");
375 return (DDI_FAILURE
);
377 zs
= &zscom
[current_chip
*2];
380 * map in the device registers
382 if (ddi_map_regs(dev
, 0, (caddr_t
*)&zs
->zs_addr
, 0, 0)) {
383 cmn_err(CE_WARN
, "zs%d: unable to map registers\n",
385 return (DDI_FAILURE
);
391 * Non-DDI compliant Sun-Ness specfic call(s)
395 * Stop the monitor's polling interrupt.
397 * I know that this is not exactly obvious. On all sunmon PROM
398 * machines, the PROM has can have a high level periodic clock
399 * interrupt going at this time. It uses this periodic interrupt
400 * to poll the console tty or kbd uart to check for things like
401 * BREAK or L1-A (abort). While we're probing this device out we
402 * have to shut that off so the PROM won't get confused by what
403 * we're doing to the zs. This has caused some pretty funny bugs
406 * For OPENPROM machines, the prom takes level12 interrupts directly,
407 * but we call this routine anyway (I forget why).
412 * Go critical to keep uart from urking.
414 s
= ddi_enter_critical();
417 * We are about to issue a full reset to this chip.
418 * First, now that interrupts are blocked, we will delay up to a
419 * half-second, checking both channels for any stray activity.
420 * Next we will preserve the time constants from both channels,
421 * so that they can be restored after the reset. This is especially
422 * important for the console device. Finally, do the reset and
423 * follow it with an extended recovery while the chip settles down.
425 for (loops
= 0; loops
++ <= 500; DELAY(1000)) {
427 if ((rr
& ZSRR1_ALL_SENT
) == 0) continue;
429 if ((rr
& ZSRR1_ALL_SENT
) == 0) continue;
431 if ((rr
& ZSRR0_TX_READY
) == 0) continue;
433 if ((rr
& ZSRR0_TX_READY
) != 0) break;
436 SCC_READA(12, speed
[0]);
439 SCC_READB(12, speed
[1]);
443 SCC_WRITE(9, ZSWR9_RESET_WORLD
);
447 * Set up the other components of the zscom structs for this chip.
449 for (i
= 0; i
< 2; i
++) {
451 * Property for ignoring DCD.
452 * We switch between 'a' and 'b' ports for this device.
454 static char prop
[] = "port-a-ignore-cd";
457 * For this channel, set the hardware address, allocate the
458 * high-level mutex, and update the zscurr pointer.
459 * The high-level lock is shared by both channels because
460 * 8530 register addressing is non-atomic and asymetrical.
461 * Multiple threads crossing paths during this operation
462 * could trash the chip, and thus, possibly the system console.
464 if (i
== 0) { /* port A */
465 zs
->zs_addr
= (struct zscc_device
*)
466 ((uintptr_t)tmpzs
| ZSOFF
);
467 (zs
+1)->zs_excl_hi
= zs
->zs_excl_hi
= &zs_curr_lock
;
468 } else { /* port B */
470 zs
->zs_addr
= (struct zscc_device
*)
471 ((uintptr_t)tmpzs
& ~ZSOFF
);
474 zs
->zs_unit
= current_chip
* 2 + i
;
476 zs
->zs_excl
= kmem_zalloc(sizeof (kmutex_t
), KM_SLEEP
);
477 mutex_init(zs
->zs_excl
, NULL
, MUTEX_DRIVER
, (void *)ZS_PL
);
478 zs
->zs_ocexcl
= kmem_zalloc(sizeof (kmutex_t
), KM_SLEEP
);
479 mutex_init(zs
->zs_ocexcl
, NULL
, MUTEX_DRIVER
, (void *)ZS_PL
);
481 zsopinit(zs
, &zsops_null
);
484 softcd
= GETPROP((dev_info_t
*)(dev
), prop
, 0);
485 zssoftCAR
[zs
->zs_unit
] = softcd
;
487 rtsdtr_bits
= ZSWR5_RTS
| ZSWR5_DTR
;
489 keyboard_prop
= GETPROP((dev_info_t
*)(zs
->zs_dip
),
492 mutex_enter(&zs_curr_lock
);
495 * Set up the default asynch modes
496 * so the monitor will still work
498 SCC_WRITE(4, ZSWR4_PARITY_EVEN
| ZSWR4_1_STOP
| ZSWR4_X16_CLK
);
499 SCC_WRITE(3, ZSWR3_RX_8
);
500 SCC_WRITE(11, ZSWR11_TXCLK_BAUD
| ZSWR11_RXCLK_BAUD
);
501 SCC_WRITE(12, (speed
[i
] & 0xff));
502 SCC_WRITE(13, (speed
[i
] >> 8) & 0xff);
503 SCC_WRITE(14, ZSWR14_BAUD_FROM_PCLK
);
504 SCC_WRITE(3, ZSWR3_RX_8
| ZSWR3_RX_ENABLE
);
505 SCC_WRITE(5, ZSWR5_TX_ENABLE
| ZSWR5_TX_8
| rtsdtr_bits
);
506 SCC_WRITE(14, ZSWR14_BAUD_ENA
| ZSWR14_BAUD_FROM_PCLK
);
509 * The SYNC pin on the second SCC (keyboard & mouse) may not
510 * be connected and noise creates transitions on this line.
511 * This floods the system with interrupts, unless the
512 * Sync/Hunt Interrupt Enable is cleared. So write
513 * register 15 with everything we need but that one.
516 SCC_WRITE(15, ZSR15_BREAK
| ZSR15_TX_UNDER
|
517 ZSR15_CTS
| ZSR15_CD
);
520 SCC_WRITE0(ZSWR0_RESET_ERRORS
);
521 SCC_WRITE0(ZSWR0_RESET_STATUS
);
522 mutex_exit(&zs_curr_lock
);
524 zs
->zs_dtrlow
= gethrestime_sec() - default_dtrlow
;
525 cv_init(&zs
->zs_flags_cv
, NULL
, CV_DEFAULT
, NULL
);
529 mutex_enter(&zs_curr_lock
);
530 SCC_WRITE(9, ZSWR9_MASTER_IE
| ZSWR9_VECTOR_INCL_STAT
);
532 mutex_exit(&zs_curr_lock
);
535 * Two levels of interrupt - chip interrupts at a high level (12),
536 * (which is seen below as zs_high_intr), and then as a secondary
537 * stage soft interrupt as seen in zsintr below.
539 * Because zs_high_intr does a window save, as well as calls to
540 * other functions, we cannot install it as a "fast" interrupt
541 * that would execute right out of the trap window. Too bad...
543 if (ddi_add_intr(dev
, (uint_t
)0, &zs_hi_iblock
,
544 (ddi_idevice_cookie_t
*)0, zs_high_intr
,
545 (caddr_t
)0) != DDI_SUCCESS
) {
546 cmn_err(CE_PANIC
, "cannot set high level zs interrupt");
550 if (zs_addedsoft
== 0) {
551 if (ddi_add_softintr(dev
, DDI_SOFTINT_HIGH
, &zs_softintr_id
,
552 &zs_iblock
, (ddi_idevice_cookie_t
*)0,
553 zsintr
, (caddr_t
)0) != DDI_SUCCESS
) {
555 "cannot set second stage zs interrupt");
559 zs_addedsoft
++; /* we only need one zsintr! */
565 (void) ddi_exit_critical(s
);
568 * Non-DDI compliant Sun-Ness specific call
570 mon_clock_start(); /* re-enable monitor's polling interrupt */
572 if (!GETPROP(zs
->zs_dip
, "keyboard", 0)) {
573 static char *serial_line
= DDI_NT_SERIAL_MB
;
574 static char *dial_out
= DDI_NT_SERIAL_MB_DO
;
577 * Export names for channel a or b consconfig match...
578 * The names exported to the filesystem include the
579 * designated tty'a' type name and may not match the PROM
581 * Note the special name "obp-console-name" used in these calls.
582 * This keeps the ports and devlinks programs from seeing these
583 * names. (But allows ddi_pathname_to_dev_t to see them.)
584 * We don't need to do this if the instance number is zero,
585 * because we'll create them below, in this case.
588 if (ddi_get_instance(dev
) != 0) {
591 * Select a node type unused by ddi/devfs
593 static char *obp_type
= "obp-console-name";
595 (void) strcpy(name
, "a");
596 if (ddi_create_minor_node(dev
, name
, S_IFCHR
,
597 ddi_get_instance(dev
) * 2,
598 obp_type
, NULL
) == DDI_FAILURE
) {
599 ddi_remove_minor_node(dev
, NULL
);
600 return (DDI_FAILURE
);
602 (void) strcpy(name
, "b");
603 if (ddi_create_minor_node(dev
, name
, S_IFCHR
,
604 (ddi_get_instance(dev
) * 2) + 1,
605 obp_type
, NULL
) == DDI_FAILURE
) {
606 ddi_remove_minor_node(dev
, NULL
);
607 return (DDI_FAILURE
);
612 * Export normal device names...
614 (void) sprintf(name
, "%c", (ddi_get_instance(dev
) + 'a'));
615 if (ddi_create_minor_node(dev
, name
, S_IFCHR
,
616 ddi_get_instance(dev
) * 2,
617 serial_line
, NULL
) == DDI_FAILURE
) {
618 ddi_remove_minor_node(dev
, NULL
);
619 return (DDI_FAILURE
);
621 (void) sprintf(name
, "%c", (ddi_get_instance(dev
) + 'b'));
622 if (ddi_create_minor_node(dev
, name
, S_IFCHR
,
623 (ddi_get_instance(dev
) * 2) + 1,
624 serial_line
, NULL
) == DDI_FAILURE
) {
625 ddi_remove_minor_node(dev
, NULL
);
626 return (DDI_FAILURE
);
628 (void) sprintf(name
, "%c,cu", (ddi_get_instance(dev
) + 'a'));
629 if (ddi_create_minor_node(dev
, name
, S_IFCHR
,
630 (ddi_get_instance(dev
) * 2) | OUTLINE
,
631 dial_out
, NULL
) == DDI_FAILURE
) {
632 ddi_remove_minor_node(dev
, NULL
);
633 return (DDI_FAILURE
);
635 (void) sprintf(name
, "%c,cu", (ddi_get_instance(dev
) + 'b'));
636 if (ddi_create_minor_node(dev
, name
, S_IFCHR
,
637 ((ddi_get_instance(dev
) * 2) + 1) | OUTLINE
,
638 dial_out
, NULL
) == DDI_FAILURE
) {
639 ddi_remove_minor_node(dev
, NULL
);
640 return (DDI_FAILURE
);
645 * Create keyboard and mouse nodes which devfs doesn't see
649 * This set of minor nodes is for use with the consconfig_dacf
650 * module for the sun4u platforms. (See PSARC/1998/212)
652 if (ddi_create_internal_pathname(dev
, "keyboard", S_IFCHR
,
653 ddi_get_instance(dev
) * 2) == DDI_FAILURE
) {
654 ddi_remove_minor_node(dev
, NULL
);
655 return (DDI_FAILURE
);
658 if (ddi_create_internal_pathname(dev
, "mouse", S_IFCHR
,
659 (ddi_get_instance(dev
) * 2) + 1) == DDI_FAILURE
) {
660 ddi_remove_minor_node(dev
, NULL
);
661 return (DDI_FAILURE
);
665 * These minor nodes are for use with pre-sun4u platforms.
666 * Either one set or the other will be opened by consconfig.
668 (void) strcpy(name
, "a");
669 if (ddi_create_internal_pathname(dev
, name
, S_IFCHR
,
670 ddi_get_instance(dev
) * 2) == DDI_FAILURE
) {
671 ddi_remove_minor_node(dev
, NULL
);
672 return (DDI_FAILURE
);
675 (void) strcpy(name
, "b");
676 if (ddi_create_internal_pathname(dev
, name
, S_IFCHR
,
677 (ddi_get_instance(dev
) * 2) + 1) == DDI_FAILURE
) {
678 ddi_remove_minor_node(dev
, NULL
);
679 return (DDI_FAILURE
);
686 * Initialize power management bookkeeping; components are
689 if (pm_create_components(dev
, 3) == DDI_SUCCESS
) {
690 (void) pm_busy_component(dev
, 0);
691 pm_set_normal_power(dev
, 0, 1);
692 pm_set_normal_power(dev
, 1, 1);
693 pm_set_normal_power(dev
, 2, 1);
695 return (DDI_FAILURE
);
698 (void) sprintf(name
, "zsc%d", current_chip
);
699 zs
->intrstats
= kstat_create("zs", current_chip
, name
, "controller",
700 KSTAT_TYPE_INTR
, 1, KSTAT_FLAG_PERSISTENT
);
702 kstat_install(zs
->intrstats
);
705 return (DDI_SUCCESS
);
709 zsdetach(dev_info_t
*dev
, ddi_detach_cmd_t cmd
)
712 int current_chip
= ddi_get_instance(dev
);
716 return (DDI_FAILURE
);
719 zs
= &zscom
[current_chip
*2];
721 * Try to suspend first channel
723 if (!zs
->zs_suspend
|| (zs
->zs_suspend
)(zs
) != DDI_SUCCESS
)
724 return (DDI_FAILURE
);
726 * And the second channel
729 if (!zs
->zs_suspend
|| (zs
->zs_suspend
)(zs
) != DDI_SUCCESS
) {
731 if (!zs
->zs_resume
||
732 (zs
->zs_resume
)(zs
) != DDI_SUCCESS
)
734 "zs: inconsistent suspend/resume state");
735 return (DDI_FAILURE
);
737 return (DDI_SUCCESS
);
740 return (DDI_FAILURE
);
745 * SCC High Level Interrupt Handler
747 * This routine fields the level 12 interrupts generated by the 8530 chips.
748 * When the SCC interrupts the conditions that triggered it are available
749 * for reference in Read Register 3 of the A channel (RR3A). We process
750 * all the pending interrupts before returning. The maximum interrupts
751 * that will be processed before returning is set to 6, which is twice
752 * the size of RX-FIFO.
753 * We keep a pointer to the B side of the most recently interrupting chip
758 * 'argzs' actually 'struct zscom *argzs'
761 #define ZSRR3_INT_PENDING (ZSRR3_IP_B_STAT | ZSRR3_IP_B_TX | ZSRR3_IP_B_RX |\
762 ZSRR3_IP_A_STAT | ZSRR3_IP_A_TX | ZSRR3_IP_A_RX)
764 #define ZSRR1_ANY_ERRORS (ZSRR1_PE | ZSRR1_DO | ZSRR1_FE | ZSRR1_RXEOF)
765 #define ZS_HIGH_INTR_LOOPLIMIT 6
769 zs_high_intr(caddr_t argzs
)
772 uchar_t stat
, isource
, count
;
775 TRACE_0(TR_FAC_ZS
, TR_ZS_H_INT_START
, "zs_h_int start");
776 mutex_enter(&zs_curr_lock
);
777 zs
= zscurr
; /* Points at Channel B */
779 ZSNEXTPOLL(zs
, zscurr
);
781 SCC_READA(3, isource
);
783 count
= ZS_HIGH_INTR_LOOPLIMIT
;
784 while ((isource
& ZSRR3_INT_PENDING
) && (count
--)) {
785 if (isource
& ZSRR3_IP_B_STAT
)
788 if (isource
& ZSRR3_IP_B_TX
)
790 if (isource
& ZSRR3_IP_B_RX
) {
792 if (stat
& ZSRR1_ANY_ERRORS
)
794 else if ((SCC_READ0()) & ZSRR0_RX_READY
)
800 if (isource
& ZSRR3_IP_A_STAT
)
803 if (isource
& ZSRR3_IP_A_TX
)
805 if (isource
& ZSRR3_IP_A_RX
) {
807 if (stat
& ZSRR1_ANY_ERRORS
)
809 else if ((SCC_READ0()) & ZSRR0_RX_READY
)
815 SCC_READA(3, isource
);
818 if (count
== ZS_HIGH_INTR_LOOPLIMIT
) {
819 unit
= (nzs
>> 1) - 1;
821 zs
+= 2; /* Always Channel B */
826 SCC_READA(3, isource
);
827 if (isource
& ZSRR3_INT_PENDING
) {
828 zscurr
= zs
; /* update zscurr and */
833 KIOIP
->intrs
[KSTAT_INTR_HARD
]++;
835 mutex_exit(&zs_curr_lock
);
836 TRACE_0(TR_FAC_ZS
, TR_ZS_H_INT_END
, "zs_h_int end");
837 return (DDI_INTR_UNCLAIMED
); /* Must not be for us. */
840 KIOIP
->intrs
[KSTAT_INTR_HARD
]++;
842 mutex_exit(&zs_curr_lock
); /* we're done with zscurr */
843 TRACE_0(TR_FAC_ZS
, TR_ZS_H_INT_END
, "zs_h_int end");
844 return (DDI_INTR_CLAIMED
);
848 * Handle a second-stage interrupt.
852 zsintr(caddr_t intarg
)
858 * Test and clear soft interrupt.
860 TRACE_0(TR_FAC_ZS
, TR_ZS_INT_START
,
863 mutex_enter(&zs_curr_lock
);
868 mutex_exit(&zs_curr_lock
);
871 for (zs
= &zscom
[0]; zs
<= zslast
; zs
++) {
872 if (zs
->zs_flags
& ZS_NEEDSOFT
) {
873 zs
->zs_flags
&= ~ZS_NEEDSOFT
;
874 (*zs
->zs_ops
->zsop_softint
)(zs
);
876 KIOIP
->intrs
[KSTAT_INTR_SOFT
]++;
881 TRACE_0(TR_FAC_ZS
, TR_ZS_INT_END
,
889 ddi_trigger_softintr(zs_softintr_id
);
893 * Install a new ops vector into low level vector routine addresses
896 zsopinit(struct zscom
*zs
, struct zsops
*zso
)
898 zs
->zs_txint
= zso
->zsop_txint
;
899 zs
->zs_xsint
= zso
->zsop_xsint
;
900 zs
->zs_rxint
= zso
->zsop_rxint
;
901 zs
->zs_srint
= zso
->zsop_srint
;
902 zs
->zs_suspend
= zso
->zsop_suspend
;
903 zs
->zs_resume
= zso
->zsop_resume
;
909 * Set or get the modem control status.
911 * This routine relies on the fact that the bits of interest in RR0 (CD and
912 * CTS) do not overlap the bits of interest in WR5 (RTS and DTR). Thus, they
913 * can be combined into a single 'int' without harm.
916 zsmctl(struct zscom
*zs
, int bits
, int how
)
921 ASSERT(mutex_owned(zs
->zs_excl_hi
));
922 ASSERT(mutex_owned(zs
->zs_excl
));
925 mbits
= zs
->zs_wreg
[5] & (ZSWR5_RTS
|ZSWR5_DTR
);
926 SCC_WRITE0(ZSWR0_RESET_STATUS
);
927 mbits
|= SCC_READ0() & (ZSRR0_CD
|ZSRR0_CTS
);
949 now
= gethrestime_sec();
950 held
= now
- zs
->zs_dtrlow
;
953 * if DTR is going low, stash current time away
955 if (~mbits
& obits
& ZSWR5_DTR
)
959 * if DTR is going high, sleep until it has been low a bit
961 if ((mbits
& ~obits
& ZSWR5_DTR
) && (held
< default_dtrlow
)) {
962 mutex_exit(zs
->zs_excl_hi
);
963 cv_wait(&lbolt_cv
, zs
->zs_excl
);
964 if (zs
->zs_suspended
)
965 (void) ddi_dev_is_needed(zs
->zs_dip
, 0, 1);
966 mutex_enter(zs
->zs_excl_hi
);
970 zs
->zs_wreg
[5] &= ~(ZSWR5_RTS
|ZSWR5_DTR
);
971 SCC_BIS(5, mbits
& (ZSWR5_RTS
|ZSWR5_DTR
));
976 * Program the Z8530 registers.
979 zs_program(struct zs_prog
*zspp
)
981 struct zscom
*zs
= zspp
->zs
;
984 uchar_t wr10
= 0, wr14
= 0;
986 ASSERT(mutex_owned(zs
->zs_excl
));
987 ASSERT(mutex_owned(zs
->zs_excl_hi
));
990 * There are some special cases to account for before reprogramming.
991 * We might be transmitting, so delay 100,000 usec (worst case at 110
992 * baud) for this to finish, then disable the receiver until later,
993 * reset the External Status Change latches and the error bits, and
994 * drain the receive FIFO.
995 * XXX: Doing any kind of reset (WR9) here causes trouble!
997 if (zspp
->flags
& ZSP_SYNC
) {
998 SCC_WRITE(7, SDLCFLAG
);
999 wr10
= ZSWR10_PRESET_ONES
;
1000 if (zspp
->flags
& ZSP_NRZI
)
1001 wr10
|= ZSWR10_NRZI
;
1002 SCC_WRITE(10, wr10
);
1004 for (loops
= 1000; loops
> 0; --loops
) {
1006 if (c
& ZSRR1_ALL_SENT
)
1011 SCC_WRITE0(ZSWR0_RESET_STATUS
);
1012 SCC_WRITE0(ZSWR0_RESET_ERRORS
);
1013 c
= SCC_READDATA(); /* Empty the FIFO */
1019 * Programming the SCC is done in three phases.
1020 * Phase one sets operating modes:
1022 SCC_WRITE(4, zspp
->wr4
);
1023 SCC_WRITE(11, zspp
->wr11
);
1024 SCC_WRITE(12, zspp
->wr12
);
1025 SCC_WRITE(13, zspp
->wr13
);
1026 if (zspp
->flags
& ZSP_PLL
) {
1027 SCC_WRITE(14, ZSWR14_DPLL_SRC_BAUD
);
1028 SCC_WRITE(14, ZSWR14_DPLL_NRZI
);
1030 SCC_WRITE(14, ZSWR14_DPLL_DISABLE
);
1033 * Phase two enables special hardware functions:
1035 wr14
= ZSWR14_BAUD_FROM_PCLK
| ZSWR14_BAUD_ENA
;
1036 if (zspp
->flags
& ZSP_LOOP
)
1037 wr14
|= ZSWR14_LOCAL_LOOPBACK
;
1038 if (zspp
->flags
& ZSP_ECHO
)
1039 wr14
|= ZSWR14_AUTO_ECHO
;
1040 SCC_WRITE(14, wr14
);
1041 SCC_WRITE(3, zspp
->wr3
);
1042 SCC_WRITE(5, zspp
->wr5
);
1044 SCC_WRITE0(ZSWR0_RESET_TXCRC
);
1046 if (zspp
->flags
& ZSP_PARITY_SPECIAL
) {
1047 SCC_WRITE(1, ZSWR1_PARITY_SPECIAL
);
1053 * Phase three enables interrupt sources:
1055 SCC_WRITE(15, zspp
->wr15
);
1056 SCC_WRITE0(ZSWR0_RESET_STATUS
);
1057 SCC_WRITE0(ZSWR0_RESET_ERRORS
);
1058 SCC_BIS(1, ZSWR1_INIT
);
1062 zsnull_intr(struct zscom
*zs
)
1066 SCC_WRITE0(ZSWR0_RESET_TXINT
);
1067 SCC_WRITE0(ZSWR0_RESET_STATUS
);
1073 SCC_WRITE0(ZSWR0_RESET_ERRORS
);
1077 zsnull_softint(struct zscom
*zs
)
1079 cmn_err(CE_WARN
, "zs%d: unexpected soft int\n", zs
->zs_unit
);
1084 * These will be called on suspend/resume for un-opened zs ports.
1087 zsnull_suspend(struct zscom
*zs
)
1089 struct zs_prog
*zspp
= &zs_prog
[zs
->zs_unit
];
1092 * Get a copy of the current registers
1094 mutex_enter(zs
->zs_excl
);
1095 mutex_enter(zs
->zs_excl_hi
);
1098 zspp
->wr3
= zs
->zs_wreg
[3];
1099 zspp
->wr4
= zs
->zs_wreg
[4];
1100 zspp
->wr5
= zs
->zs_wreg
[5];
1101 zspp
->wr11
= zs
->zs_wreg
[11];
1102 zspp
->wr12
= zs
->zs_wreg
[12];
1103 zspp
->wr13
= zs
->zs_wreg
[13];
1104 zspp
->wr15
= zs
->zs_wreg
[15];
1105 mutex_exit(zs
->zs_excl_hi
);
1106 mutex_exit(zs
->zs_excl
);
1108 return (DDI_SUCCESS
);
1112 zsnull_resume(struct zscom
*zs
)
1114 struct zs_prog
*zspp
= &zs_prog
[zs
->zs_unit
];
1119 mutex_enter(zs
->zs_excl
);
1120 mutex_enter(zs
->zs_excl_hi
);
1122 SCC_WRITE(9, ZSWR9_MASTER_IE
);
1124 mutex_exit(zs
->zs_excl_hi
);
1125 mutex_exit(zs
->zs_excl
);
1126 return (DDI_SUCCESS
);