summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorSebastian Reitenbach <sebastia@cvs.openbsd.org>2013-04-21 14:44:17 +0000
committerSebastian Reitenbach <sebastia@cvs.openbsd.org>2013-04-21 14:44:17 +0000
commit841c597229f823f724befaf6a10afab3eddc3f95 (patch)
tree23ef87d27e4d747fb797a6f313890d39739364e6 /sys
parent387b11b6df84ee8d556ce77a94a3c85a312eadaa (diff)
Unify the zs tty driver.
Most of the hard work by mpi@, who provided the initial diff. Fixes for sparc from myself. Tested on sgi and sparc myself. Compiles and detects zstty on my powerbook, compile tested on sparc64 by me. Real testing with zs device on sparc64 by miod@ who also gave a lot of help and feedback. ok miod@, mpi@
Diffstat (limited to 'sys')
-rw-r--r--sys/arch/macppc/conf/files.macppc6
-rw-r--r--sys/arch/macppc/dev/z8530reg.h447
-rw-r--r--sys/arch/macppc/dev/z8530sc.c342
-rw-r--r--sys/arch/macppc/dev/z8530sc.h154
-rw-r--r--sys/arch/macppc/dev/z8530tty.c1576
-rw-r--r--sys/arch/macppc/dev/zs.c3
-rw-r--r--sys/arch/macppc/include/z8530var.h4
-rw-r--r--sys/arch/sgi/hpc/files.hpc6
-rw-r--r--sys/arch/sgi/hpc/z8530sc.c415
-rw-r--r--sys/arch/sgi/hpc/z8530sc.h199
-rw-r--r--sys/arch/sgi/hpc/z8530tty.c1682
-rw-r--r--sys/arch/sgi/include/z8530var.h4
-rw-r--r--sys/arch/solbourne/dev/zsclock.c4
-rw-r--r--sys/arch/solbourne/solbourne/locore.s4
-rw-r--r--sys/arch/sparc/conf/files.sparc6
-rw-r--r--sys/arch/sparc/dev/z8530kbd.c6
-rw-r--r--sys/arch/sparc/dev/z8530reg.h447
-rw-r--r--sys/arch/sparc/dev/z8530sc.c353
-rw-r--r--sys/arch/sparc/dev/z8530sc.h154
-rw-r--r--sys/arch/sparc/dev/z8530tty.c1707
-rw-r--r--sys/arch/sparc/dev/zs.c21
-rw-r--r--sys/arch/sparc/dev/zs_kgdb.c7
-rw-r--r--sys/arch/sparc/include/z8530var.h19
-rw-r--r--sys/arch/sparc64/conf/files.sparc646
-rw-r--r--sys/arch/sparc64/dev/z8530kbd.c4
-rw-r--r--sys/arch/sparc64/dev/z8530reg.h447
-rw-r--r--sys/arch/sparc64/dev/z8530sc.c353
-rw-r--r--sys/arch/sparc64/dev/z8530sc.h154
-rw-r--r--sys/arch/sparc64/dev/z8530tty.c1668
-rw-r--r--sys/arch/sparc64/dev/zs.c4
-rw-r--r--sys/arch/sparc64/include/z8530var.h4
-rw-r--r--sys/dev/ic/z8530sc.c303
-rw-r--r--sys/dev/ic/z8530sc.h116
-rw-r--r--sys/dev/ic/z8530tty.c1817
-rw-r--r--sys/dev/sun/z8530ms.c12
35 files changed, 1462 insertions, 10992 deletions
diff --git a/sys/arch/macppc/conf/files.macppc b/sys/arch/macppc/conf/files.macppc
index dfea2ab76ef..f0b80a5f1d3 100644
--- a/sys/arch/macppc/conf/files.macppc
+++ b/sys/arch/macppc/conf/files.macppc
@@ -1,4 +1,4 @@
-# $OpenBSD: files.macppc,v 1.68 2012/12/04 10:42:04 mpi Exp $
+# $OpenBSD: files.macppc,v 1.69 2013/04/21 14:44:16 sebastia Exp $
#
# macppc-specific configuration info
@@ -145,11 +145,11 @@ file arch/macppc/dev/openpic.c openpic
device zsc {[channel = -1]}
attach zsc at macobio
file arch/macppc/dev/zs.c zsc needs-flag
-file arch/macppc/dev/z8530sc.c zsc
+file dev/ic/z8530sc.c zsc
device zstty: tty
attach zstty at zsc
-file arch/macppc/dev/z8530tty.c zstty needs-flag
+file dev/ic/z8530tty.c zstty needs-flag
device adb {}
attach adb at macobio
diff --git a/sys/arch/macppc/dev/z8530reg.h b/sys/arch/macppc/dev/z8530reg.h
deleted file mode 100644
index 81dc26dac5c..00000000000
--- a/sys/arch/macppc/dev/z8530reg.h
+++ /dev/null
@@ -1,447 +0,0 @@
-/* $OpenBSD: z8530reg.h,v 1.3 2011/09/17 08:38:07 miod Exp $ */
-/* $NetBSD: z8530reg.h,v 1.9 1998/07/31 05:08:38 wrstuden Exp $ */
-
-/*
- * Copyright (c) 1992, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * This software was developed by the Computer Systems Engineering group
- * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
- * contributed to Berkeley.
- *
- * All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Lawrence Berkeley Laboratory.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)zsreg.h 8.1 (Berkeley) 6/11/93
- */
-
-/*
- * Zilog SCC registers, as implemented on the Sun-4c.
- *
- * Each Z8530 implements two channels (called `a' and `b').
- *
- * The damnable chip was designed to fit on Z80 I/O ports, and thus
- * has everything multiplexed out the wazoo. We have to select
- * a register, then read or write the register, and so on. Worse,
- * the parameter bits are scattered all over the register space.
- * This thing is full of `miscellaneous' control registers.
- *
- * Worse yet, the registers have incompatible functions on read
- * and write operations. We describe the registers below according
- * to whether they are `read registers' (RR) or `write registers' (WR).
- * As if this were not enough, some of the channel B status bits show
- * up in channel A, and vice versa. The blasted thing shares write
- * registers 2 and 9 across both channels, and reads registers 2 and 3
- * differently for the two channels. We can, however, ignore this much
- * of the time.
- *
- * This file also includes flags for the Z85C30 and Z85230 enhanced scc.
- * The CMOS 8530 includes extra SDLC functionality, and is used in a
- * number of Macs (often in the Z85C80, an 85C30 combined w/ a SCSI
- * controller). -wrs
- *
- * Some of the names in this files were chosen to make the hsis driver
- * work unchanged (which means that they will match some in SunOS).
- *
- * `S.C.' stands for Special Condition, which is any of these:
- * receiver overrun (aka silo overflow)
- * framing error (missing stop bit, etc)
- * end of frame (in synchronous modes)
- * parity error (when `parity error is S.C.' is set)
- *
- * Registers with only a single `numeric value' get a name.
- * Other registers hold bits and are only numbered; the bit
- * definitions imply the register number (see below).
- *
- * We never use the receive and transmit data registers as
- * indirects (choosing instead the zc_data register), so they
- * are not defined here.
- */
-#define ZSRR_IVEC 2 /* interrupt vector (channel 0) */
-#define ZSRR_IPEND 3 /* interrupt pending (ch. 0 only) */
-#define ZSRR_TXSYNC 6 /* sync transmit char (monosync mode) */
-#define ZSRR_RXSYNC 7 /* sync receive char (monosync mode) */
-#define ZSRR_SYNCLO 6 /* sync low byte (bisync mode) */
-#define ZSRR_SYNCHI 7 /* sync high byte (bisync mode) */
-#define ZSRR_SDLC_ADDR 6 /* SDLC address (SDLC mode) */
-#define ZSRR_SDLC_FLAG 7 /* SDLC flag 0x7E (SDLC mode) */
-#define ZSRR_BAUDLO 12 /* baud rate generator (low half) */
-#define ZSRR_BAUDHI 13 /* baud rate generator (high half) */
-#define ZSRR_ENHANCED 14 /* read address of WR7' - yes, it's not 7!*/
-
-#define ZSWR_IVEC 2 /* interrupt vector (shared) */
-#define ZSWR_TXSYNC 6 /* sync transmit char (monosync mode) */
-#define ZSWR_RXSYNC 7 /* sync receive char (monosync mode) */
-#define ZSWR_SYNCLO 6 /* sync low byte (bisync mode) */
-#define ZSWR_SYNCHI 7 /* sync high byte (bisync mode) */
-#define ZSWR_SDLC_ADDR 6 /* SDLC address (SDLC mode) */
-#define ZSWR_SDLC_FLAG 7 /* SDLC flag 0x7E (SDLC mode) */
-#define ZSWR_BAUDLO 12 /* baud rate generator (low half) */
-#define ZSWR_BAUDHI 13 /* baud rate generator (high half) */
-#define ZSWR_ENHANCED 7 /* write address of WR7' */
-
-/*
- * Registers 0 through 7 may be written with any one of the 8 command
- * modifiers, and/or any one of the 4 reset modifiers, defined below.
- * To write registers 8 through 15, however, the command modifier must
- * always be `point high'. Rather than track this bizzareness all over
- * the driver, we try to avoid using any modifiers, ever (but they are
- * defined here if you want them).
- */
-#define ZSM_RESET_TXUEOM 0xc0 /* reset xmit underrun / eom latch */
-#define ZSM_RESET_TXCRC 0x80 /* reset xmit crc generator */
-#define ZSM_RESET_RXCRC 0x40 /* reset recv crc checker */
-#define ZSM_NULL 0x00 /* nothing special */
-
-#define ZSM_RESET_IUS 0x38 /* reset interrupt under service */
-#define ZSM_RESET_ERR 0x30 /* reset error cond */
-#define ZSM_RESET_TXINT 0x28 /* reset xmit interrupt pending */
-#define ZSM_EI_NEXTRXC 0x20 /* enable int. on next rcvd char */
-#define ZSM_SEND_ABORT 0x18 /* send abort (SDLC) */
-#define ZSM_RESET_STINT 0x10 /* reset external/status interrupt */
-#define ZSM_POINTHIGH 0x08 /* `point high' (use r8-r15) */
-#define ZSM_NULL 0x00 /* nothing special */
-
-/*
- * Commands for Write Register 0 (`Command Register').
- * These are just the command modifiers or'ed with register number 0
- * (which of course equals the command modifier).
- */
-#define ZSWR0_RESET_EOM ZSM_RESET_TXUEOM
-#define ZSWR0_RESET_TXCRC ZSM_RESET_TXCRC
-#define ZSWR0_RESET_RXCRC ZSM_RESET_RXCRC
-#define ZSWR0_CLR_INTR ZSM_RESET_IUS
-#define ZSWR0_RESET_ERRORS ZSM_RESET_ERR
-#define ZSWR0_EI_NEXTRXC ZSM_EI_NEXTRXC
-#define ZSWR0_SEND_ABORT ZSM_SEND_ABORT
-#define ZSWR0_RESET_STATUS ZSM_RESET_STINT
-#define ZSWR0_RESET_TXINT ZSM_RESET_TXINT
-
-/*
- * Bits in Write Register 1 (`Transmit/Receive Interrupt and Data
- * Transfer Mode Definition'). Note that bits 3 and 4 are taken together
- * as a single unit, and bits 5 and 6 are useful only if bit 7 is set.
- */
-#define ZSWR1_REQ_WAIT 0x80 /* WAIT*-REQ* pin gives WAIT* */
-#define ZSWR1_REQ_REQ 0xc0 /* WAIT*-REQ* pin gives REQ* */
-#define ZSWR1_REQ_TX 0x00 /* WAIT*-REQ* pin follows xmit buf */
-#define ZSWR1_REQ_RX 0x20 /* WAIT*-REQ* pin follows recv buf */
-
-#define ZSWR1_RIE_NONE 0x00 /* disable rxint entirely */
-#define ZSWR1_RIE_FIRST 0x08 /* rxint on first char & on S.C. */
-#define ZSWR1_RIE 0x10 /* rxint per char & on S.C. */
-#define ZSWR1_RIE_SPECIAL_ONLY 0x18 /* rxint on S.C. only */
-
-#define ZSWR1_PE_SC 0x04 /* parity error is special condition */
-#define ZSWR1_TIE 0x02 /* transmit interrupt enable */
-#define ZSWR1_SIE 0x01 /* external/status interrupt enable */
-
-#define ZSWR1_IMASK 0x1F /* mask of all itr. enable bits. */
-
-/* HSIS compat */
-#define ZSWR1_REQ_ENABLE (ZSWR1_REQ_WAIT | ZSWR1_REQ_TX)
-
-/*
- * Bits in Write Register 3 (`Receive Parameters and Control').
- * Bits 7 and 6 are taken as a unit. Note that the receive bits
- * per character ordering is insane.
- *
- * Here `hardware flow control' means CTS enables the transmitter
- * and DCD enables the receiver. The latter is neither interesting
- * nor useful, and gets in our way, making it almost unusable.
- */
-#define ZSWR3_RX_5 0x00 /* receive 5 bits per char */
-#define ZSWR3_RX_7 0x40 /* receive 7 bits per char */
-#define ZSWR3_RX_6 0x80 /* receive 6 bits per char */
-#define ZSWR3_RX_8 0xc0 /* receive 8 bits per char */
-#define ZSWR3_RXSIZE 0xc0 /* receive char size mask */
-
-#define ZSWR3_HFC 0x20 /* hardware flow control */
-#define ZSWR3_HUNT 0x10 /* enter hunt mode */
-#define ZSWR3_RXCRC_ENABLE 0x08 /* enable recv crc calculation */
-#define ZSWR3_ADDR_SEARCH_MODE 0x04 /* address search mode (SDLC only) */
-#define ZSWR3_SDLC_SHORT_ADDR 0x02 /* short address mode (SDLC only) */
-#define ZSWR3_SYNC_LOAD_INH 0x02 /* sync character load inhibit */
-#define ZSWR3_RX_ENABLE 0x01 /* receiver enable */
-
-/*
- * Bits in Write Register 4 (`Transmit/Receive Miscellaneous Parameters
- * and Modes'). Bits 7&6, 5&4, and 3&2 are taken as units.
- */
-#define ZSWR4_CLK_X1 0x00 /* clock divisor = 1 */
-#define ZSWR4_CLK_X16 0x40 /* clock divisor = 16 */
-#define ZSWR4_CLK_X32 0x80 /* clock divisor = 32 */
-#define ZSWR4_CLK_X64 0xc0 /* clock divisor = 64 */
-#define ZSWR4_CLK_MASK 0xc0 /* clock divisor mask */
-
-#define ZSWR4_MONOSYNC 0x00 /* 8 bit sync char (sync only) */
-#define ZSWR4_BISYNC 0x10 /* 16 bit sync char (sync only) */
-#define ZSWR4_SDLC 0x20 /* SDLC mode */
-#define ZSWR4_EXTSYNC 0x30 /* external sync mode */
-#define ZSWR4_SYNC_MASK 0x30 /* sync mode bit mask */
-
-#define ZSWR4_SYNCMODE 0x00 /* no stop bit (sync mode only) */
-#define ZSWR4_ONESB 0x04 /* 1 stop bit */
-#define ZSWR4_1P5SB 0x08 /* 1.5 stop bits (clk cannot be 1x) */
-#define ZSWR4_TWOSB 0x0c /* 2 stop bits */
-#define ZSWR4_SBMASK 0x0c /* mask of all stop bits */
-
-#define ZSWR4_EVENP 0x02 /* check for even parity */
-#define ZSWR4_PARENB 0x01 /* enable parity checking */
-#define ZSWR4_PARMASK 0x03 /* mask of all parity bits */
-
-/*
- * Bits in Write Register 5 (`Transmit Parameter and Controls').
- * Bits 6 and 5 are taken as a unit; the ordering is, as with RX
- * bits per char, not sensible.
- */
-#define ZSWR5_DTR 0x80 /* assert (set to -12V) DTR */
-
-#define ZSWR5_TX_5 0x00 /* transmit 5 or fewer bits */
-#define ZSWR5_TX_7 0x20 /* transmit 7 bits */
-#define ZSWR5_TX_6 0x40 /* transmit 6 bits */
-#define ZSWR5_TX_8 0x60 /* transmit 8 bits */
-#define ZSWR5_TXSIZE 0x60 /* transmit char size mask */
-
-#define ZSWR5_BREAK 0x10 /* send break (continuous 0s) */
-#define ZSWR5_TX_ENABLE 0x08 /* enable transmitter */
-#define ZSWR5_CRC16 0x04 /* use CRC16 (off => use SDLC) */
-#define ZSWR5_RTS 0x02 /* assert RTS */
-#define ZSWR5_TXCRC_ENABLE 0x01 /* enable xmit crc calculation */
-
-#ifdef not_done_here
-/*
- * Bits in Write Register 7 when the chip is in SDLC mode.
- */
-#define ZSWR7_SDLCFLAG 0x7e /* this value makes SDLC mode work */
-#endif
-
-/*
- * Bits in Write Register 7' (ZSWR_ENHANCED above). This register is
- * only available on the 85230. Dispite the fact it contains flags
- * and not a single value, the register was named as it is read
- * via RR14. Weird.
- */
- /* 0x80 unused */
-#define ZSWR7P_EXTEND_READ 0x40 /* modify read map; make most regs readable */
-#define ZSWR7P_TX_FIFO 0x20 /* change level for Tx FIFO empty int */
-#define ZSWR7P_DTR_TIME 0x10 /* modifies deact. speed of /DTR//REQ */
-#define ZSWR7P_RX_FIFO 0x08 /* Rx FIFO int on 1/2 full? */
-#define ZSWR7P_RTS_DEACT 0x04 /* automatically deassert RTS */
-#define ZSWR7P_AUTO_EOM_RESET 0x02 /* automatically reset EMO/Tx Underrun */
-#define ZSWR7P_AUTO_TX_FLAG 0x01 /* Auto send SDLC flag at transmit start */
-
-/*
- * Bits in Write Register 9 (`Master Interrupt Control'). Bits 7 & 6
- * are taken as a unit and indicate the type of reset; 00 means no reset
- * (and is not defined here).
- */
-#define ZSWR9_HARD_RESET 0xc0 /* force hardware reset */
-#define ZSWR9_A_RESET 0x80 /* reset channel A (0) */
-#define ZSWR9_B_RESET 0x40 /* reset channel B (1) */
-#define ZSWR9_SOFT_INTAC 0x20 /* Not in NMOS version */
-
-#define ZSWR9_STATUS_HIGH 0x10 /* status in high bits of intr vec */
-#define ZSWR9_MASTER_IE 0x08 /* master interrupt enable */
-#define ZSWR9_DLC 0x04 /* disable lower chain */
-#define ZSWR9_NO_VECTOR 0x02 /* no vector */
-#define ZSWR9_VECTOR_INCL_STAT 0x01 /* vector includes status */
-
-/*
- * Bits in Write Register 10 (`Miscellaneous Transmitter/Receiver Control
- * Bits'). Bits 6 & 5 are taken as a unit, and some of the bits are
- * meaningful only in certain modes. Bleah.
- */
-#define ZSWR10_PRESET_ONES 0x80 /* preset CRC to all 1 (else all 0) */
-
-#define ZSWR10_NRZ 0x00 /* NRZ encoding */
-#define ZSWR10_NRZI 0x20 /* NRZI encoding */
-#define ZSWR10_FM1 0x40 /* FM1 encoding */
-#define ZSWR10_FM0 0x60 /* FM0 encoding */
-
-#define ZSWR10_GA_ON_POLL 0x10 /* go active on poll (loop mode) */
-#define ZSWR10_MARK_IDLE 0x08 /* all 1s (vs flag) when idle (SDLC) */
-#define ZSWR10_ABORT_ON_UNDERRUN 0x4 /* abort on xmit underrun (SDLC) */
-#define ZSWR10_LOOP_MODE 0x02 /* loop mode (SDLC) */
-#define ZSWR10_6_BIT_SYNC 0x01 /* 6 bits per sync char (sync modes) */
-
-/*
- * Bits in Write Register 11 (`Clock Mode Control'). Bits 6&5, 4&3, and
- * 1&0 are taken as units. Various bits depend on other bits in complex
- * ways; see the Zilog manual.
- */
-#define ZSWR11_XTAL 0x80 /* have xtal between RTxC* and SYNC* */
- /* (else have TTL oscil. on RTxC*) */
-#define ZSWR11_RXCLK_RTXC 0x00 /* recv clock taken from RTxC* pin */
-#define ZSWR11_RXCLK_TRXC 0x20 /* recv clock taken from TRxC* pin */
-#define ZSWR11_RXCLK_BAUD 0x40 /* recv clock taken from BRG */
-#define ZSWR11_RXCLK_DPLL 0x60 /* recv clock taken from DPLL */
-
-#define ZSWR11_TXCLK_RTXC 0x00 /* xmit clock taken from RTxC* pin */
-#define ZSWR11_TXCLK_TRXC 0x08 /* xmit clock taken from TRxC* pin */
-#define ZSWR11_TXCLK_BAUD 0x10 /* xmit clock taken from BRG */
-#define ZSWR11_TXCLK_DPLL 0x18 /* xmit clock taken from DPLL */
-
-#define ZSWR11_TRXC_OUT_ENA 0x04 /* TRxC* pin will be an output */
- /* (unless it is being used above) */
-#define ZSWR11_TRXC_XTAL 0x00 /* TRxC output from xtal oscillator */
-#define ZSWR11_TRXC_XMIT 0x01 /* TRxC output from xmit clock */
-#define ZSWR11_TRXC_BAUD 0x02 /* TRxC output from BRG */
-#define ZSWR11_TRXC_DPLL 0x03 /* TRxC output from DPLL */
-
-/*
- * Formula for Write Registers 12 and 13 (`Lower Byte of Baud Rate
- * Generator Time Constant' and `Upper Byte of ...'). Inputs:
- *
- * f BRG input clock frequency (in Hz) AFTER division
- * by 1, 16, 32, or 64 (per clock divisor in WR4)
- * bps desired rate in bits per second (9600, etc)
- *
- * We want
- *
- * f
- * ----- + 0.5 - 2
- * 2 bps
- *
- * rounded down to an integer. This can be computed entirely
- * in integer arithmetic as:
- *
- * f + bps
- * ------- - 2
- * 2 bps
- */
-#define BPS_TO_TCONST(f, bps) ((((f) + (bps)) / (2 * (bps))) - 2)
-
-/* inverse of above: given a BRG Time Constant, return Bits Per Second */
-#define TCONST_TO_BPS(f, tc) ((f) / 2 / ((tc) + 2))
-
-/*
- * Bits in Write Register 14 (`Miscellaneous Control Bits').
- * Bits 7 through 5 are taken as a unit and make up a `DPLL command'.
- */
-#define ZSWR14_DPLL_NOOP 0x00 /* leave DPLL alone */
-#define ZSWR14_DPLL_SEARCH 0x20 /* enter search mode */
-#define ZSWR14_DPLL_RESET_CM 0x40 /* reset `clock missing' in RR10 */
-#define ZSWR14_DPLL_DISABLE 0x60 /* disable DPLL (continuous search) */
-#define ZSWR14_DPLL_SRC_BAUD 0x80 /* set DPLL src = BRG */
-#define ZSWR14_DPLL_SRC_RTXC 0xa0 /* set DPLL src = RTxC* or xtal osc */
-#define ZSWR14_DPLL_FM 0xc0 /* operate in FM mode */
-#define ZSWR14_DPLL_NRZI 0xe0 /* operate in NRZI mode */
-
-#define ZSWR14_LOCAL_LOOPBACK 0x10 /* set local loopback mode */
-#define ZSWR14_AUTO_ECHO 0x08 /* set auto echo mode */
-#define ZSWR14_DTR_REQ 0x04 /* DTR* / REQ* pin gives REQ* */
-#define ZSWR14_BAUD_FROM_PCLK 0x02 /* BRG clock taken from PCLK */
- /* (else from RTxC* pin or xtal osc) */
-#define ZSWR14_BAUD_ENA 0x01 /* enable BRG countdown */
-
-/*
- * Bits in Write Register 15 (`External/Status Interrupt Control').
- * Most of these cause status interrupts whenever the corresponding
- * bit or pin changes state (i.e., any rising or falling edge).
- *
- * NOTE: ZSWR15_SDLC_FIFO & ZSWR15_ENABLE_ENHANCED should not be
- * set on an NMOS 8530. Also, ZSWR15_ENABLE_ENHANCED is only
- * available on the 85230.
- */
-#define ZSWR15_BREAK_IE 0x80 /* enable break/abort status int */
-#define ZSWR15_TXUEOM_IE 0x40 /* enable TX underrun/EOM status int */
-#define ZSWR15_CTS_IE 0x20 /* enable CTS* pin status int */
-#define ZSWR15_SYNCHUNT_IE 0x10 /* enable SYNC* pin/hunt status int */
-#define ZSWR15_DCD_IE 0x08 /* enable DCD* pin status int */
-#define ZSWR15_SDLC_FIFO 0x04 /* enable SDLC FIFO enhancements */
-#define ZSWR15_ZERO_COUNT_IE 0x02 /* enable BRG-counter = 0 status int */
-#define ZSWR15_ENABLE_ENHANCED 0x01 /* enable writing WR7' at reg 7 */
-
-/*
- * Bits in Read Register 0 (`Transmit/Receive Buffer Status and External
- * Status').
- */
-#define ZSRR0_BREAK 0x80 /* break/abort detected */
-#define ZSRR0_TXUNDER 0x40 /* transmit underrun/EOM (sync) */
-#define ZSRR0_CTS 0x20 /* clear to send */
-#define ZSRR0_SYNC_HUNT 0x10 /* sync/hunt (sync mode) */
-#define ZSRR0_DCD 0x08 /* data carrier detect */
-#define ZSRR0_TX_READY 0x04 /* transmit buffer empty */
-#define ZSRR0_ZERO_COUNT 0x02 /* zero count in baud clock */
-#define ZSRR0_RX_READY 0x01 /* received character ready */
-
-/*
- * Bits in Read Register 1 (the Zilog book does not name this one).
- */
-#define ZSRR1_EOF 0x80 /* end of frame (SDLC mode) */
-#define ZSRR1_FE 0x40 /* CRC/framing error */
-#define ZSRR1_DO 0x20 /* data (receiver) overrun */
-#define ZSRR1_PE 0x10 /* parity error */
-#define ZSRR1_RC0 0x08 /* residue code 0 (SDLC mode) */
-#define ZSRR1_RC1 0x04 /* residue code 1 (SDLC mode) */
-#define ZSRR1_RC2 0x02 /* residue code 2 (SDLC mode) */
-#define ZSRR1_ALL_SENT 0x01 /* all chars out of xmitter (async) */
-
-/*
- * Read Register 2 in B channel contains status bits if VECTOR_INCL_STAT
- * is set.
- */
-
-/*
- * Bits in Read Register 3 (`Interrupt Pending'). Only channel A
- * has an RR3.
- */
- /* 0x80 unused, returned as 0 */
- /* 0x40 unused, returned as 0 */
-#define ZSRR3_IP_A_RX 0x20 /* channel A recv int pending */
-#define ZSRR3_IP_A_TX 0x10 /* channel A xmit int pending */
-#define ZSRR3_IP_A_STAT 0x08 /* channel A status int pending */
-#define ZSRR3_IP_B_RX 0x04 /* channel B recv int pending */
-#define ZSRR3_IP_B_TX 0x02 /* channel B xmit int pending */
-#define ZSRR3_IP_B_STAT 0x01 /* channel B status int pending */
-
-/*
- * Bits in Read Register 10 (`contains some miscellaneous status bits').
- */
-#define ZSRR10_1_CLOCK_MISSING 0x80 /* 1 clock edge missing (FM mode) */
-#define ZSRR10_2_CLOCKS_MISSING 0x40 /* 2 clock edges missing (FM mode) */
- /* 0x20 unused */
-#define ZSRR10_LOOP_SENDING 0x10 /* xmitter controls loop (SDLC loop) */
- /* 0x08 unused */
- /* 0x04 unused */
-#define ZSRR10_ON_LOOP 0x02 /* SCC is on loop (SDLC/X.21 modes) */
-
-/*
- * Bits in Read Register 15. This register is one of the few that
- * simply reads back the corresponding Write Register.
- */
-#define ZSRR15_BREAK_IE 0x80 /* break/abort status int enable */
-#define ZSRR15_TXUEOM_IE 0x40 /* TX underrun/EOM status int enable */
-#define ZSRR15_CTS_IE 0x20 /* CTS* pin status int enable */
-#define ZSRR15_SYNCHUNT_IE 0x10 /* SYNC* pin/hunt status int enable */
-#define ZSRR15_DCD_IE 0x08 /* DCD* pin status int enable */
- /* 0x04 unused, returned as zero */
-#define ZSRR15_ZERO_COUNT_IE 0x02 /* BRG-counter = 0 status int enable */
- /* 0x01 unused, returned as zero */
diff --git a/sys/arch/macppc/dev/z8530sc.c b/sys/arch/macppc/dev/z8530sc.c
deleted file mode 100644
index 1a5e19f075f..00000000000
--- a/sys/arch/macppc/dev/z8530sc.c
+++ /dev/null
@@ -1,342 +0,0 @@
-/* $OpenBSD: z8530sc.c,v 1.3 2003/10/16 03:31:25 drahn Exp $ */
-/* $NetBSD: z8530sc.c,v 1.4 1996/05/17 19:30:34 gwr Exp $ */
-
-/*
- * Copyright (c) 1994 Gordon W. Ross
- * Copyright (c) 1992, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * This software was developed by the Computer Systems Engineering group
- * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
- * contributed to Berkeley.
- *
- * All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Lawrence Berkeley Laboratory.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)zs.c 8.1 (Berkeley) 7/19/93
- */
-
-/*
- * Zilog Z8530 Dual UART driver (common part)
- *
- * This file contains the machine-independent parts of the
- * driver common to tty and keyboard/mouse sub-drivers.
- */
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/proc.h>
-#include <sys/device.h>
-#include <sys/conf.h>
-#include <sys/file.h>
-#include <sys/ioctl.h>
-#include <sys/tty.h>
-#include <sys/time.h>
-#include <sys/kernel.h>
-#include <sys/syslog.h>
-
-#include <macppc/dev/z8530reg.h>
-#include <machine/z8530var.h>
-
-void
-zs_break(struct zs_chanstate *cs, int set)
-{
-
- if (set) {
- cs->cs_preg[5] |= ZSWR5_BREAK;
- cs->cs_creg[5] |= ZSWR5_BREAK;
- } else {
- cs->cs_preg[5] &= ~ZSWR5_BREAK;
- cs->cs_creg[5] &= ~ZSWR5_BREAK;
- }
- zs_write_reg(cs, 5, cs->cs_creg[5]);
-}
-
-
-/*
- * drain on-chip fifo
- */
-void
-zs_iflush(struct zs_chanstate *cs)
-{
- u_char c, rr0, rr1;
- int i;
-
- /*
- * Count how many times we loop. Some systems, such as some
- * Apple PowerBooks, claim to have SCC's which they really don't.
- */
- for (i = 0; i < 32; i++) {
- /* Is there input available? */
- rr0 = zs_read_csr(cs);
- if ((rr0 & ZSRR0_RX_READY) == 0)
- break;
-
- /*
- * First read the status, because reading the data
- * destroys the status of this char.
- */
- rr1 = zs_read_reg(cs, 1);
- c = zs_read_data(cs);
-
- if (rr1 & (ZSRR1_FE | ZSRR1_DO | ZSRR1_PE)) {
- /* Clear the receive error. */
- zs_write_csr(cs, ZSWR0_RESET_ERRORS);
- }
- }
-}
-
-
-/*
- * Write the given register set to the given zs channel in the proper order.
- * The channel must not be transmitting at the time. The receiver will
- * be disabled for the time it takes to write all the registers.
- * Call this with interrupts disabled.
- */
-void
-zs_loadchannelregs(struct zs_chanstate *cs)
-{
- u_char *reg;
-
- zs_write_csr(cs, ZSM_RESET_ERR); /* XXX: reset error condition */
-
-#if 1
- /*
- * XXX: Is this really a good idea?
- * XXX: Should go elsewhere! -gwr
- */
- zs_iflush(cs); /* XXX */
-#endif
-
- if (memcmp((caddr_t)cs->cs_preg, (caddr_t)cs->cs_creg, 16) == 0)
- return; /* only change if values are different */
-
- /* Copy "pending" regs to "current" */
- memcpy((caddr_t)cs->cs_creg, (caddr_t)cs->cs_preg, 16);
- reg = cs->cs_creg; /* current regs */
-
- /* disable interrupts */
- zs_write_reg(cs, 1, reg[1] & ~ZSWR1_IMASK);
-
- /* baud clock divisor, stop bits, parity */
- zs_write_reg(cs, 4, reg[4]);
-
- /* misc. TX/RX control bits */
- zs_write_reg(cs, 10, reg[10]);
-
- /* char size, enable (RX/TX) */
- zs_write_reg(cs, 3, reg[3] & ~ZSWR3_RX_ENABLE);
- zs_write_reg(cs, 5, reg[5] & ~ZSWR5_TX_ENABLE);
-
- /* synchronous mode stuff */
- zs_write_reg(cs, 6, reg[6]);
- zs_write_reg(cs, 7, reg[7]);
-
-#if 0
- /*
- * Registers 2 and 9 are special because they are
- * actually common to both channels, but must be
- * programmed through channel A. The "zsc" attach
- * function takes care of setting these registers
- * and they should not be touched thereafter.
- */
- /* interrupt vector */
- zs_write_reg(cs, 2, reg[2]);
- /* master interrupt control */
- zs_write_reg(cs, 9, reg[9]);
-#endif
-
- /* Shut down the BRG */
- zs_write_reg(cs, 14, reg[14] & ~ZSWR14_BAUD_ENA);
-
-#ifdef ZS_MD_SETCLK
- /* Let the MD code setup any external clock. */
- ZS_MD_SETCLK(cs);
-#endif /* ZS_MD_SETCLK */
-
- /* clock mode control */
- zs_write_reg(cs, 11, reg[11]);
-
- /* baud rate (lo/hi) */
- zs_write_reg(cs, 12, reg[12]);
- zs_write_reg(cs, 13, reg[13]);
-
- /* Misc. control bits */
- zs_write_reg(cs, 14, reg[14]);
-
- /* which lines cause status interrupts */
- zs_write_reg(cs, 15, reg[15]);
-
- /*
- * Zilog docs recommend resetting external status twice at this
- * point. Mainly as the status bits are latched, and the first
- * interrupt clear might unlatch them to new values, generating
- * a second interrupt request.
- */
- zs_write_csr(cs, ZSM_RESET_STINT);
- zs_write_csr(cs, ZSM_RESET_STINT);
-
- /* char size, enable (RX/TX)*/
- zs_write_reg(cs, 3, reg[3]);
- zs_write_reg(cs, 5, reg[5]);
-
- /* interrupt enables: TX, TX, STATUS */
- zs_write_reg(cs, 1, reg[1]);
-}
-
-
-/*
- * ZS hardware interrupt. Scan all ZS channels. NB: we know here that
- * channels are kept in (A,B) pairs.
- *
- * Do just a little, then get out; set a software interrupt if more
- * work is needed.
- *
- * We deliberately ignore the vectoring Zilog gives us, and match up
- * only the number of `reset interrupt under service' operations, not
- * the order.
- */
-int
-zsc_intr_hard(void *arg)
-{
- struct zsc_softc *zsc = arg;
- struct zs_chanstate *cs;
- u_char rr3;
-
- /* First look at channel A. */
- cs = zsc->zsc_cs[0];
- /* Note: only channel A has an RR3 */
- rr3 = zs_read_reg(cs, 3);
-
- /*
- * Clear interrupt first to avoid a race condition.
- * If a new interrupt condition happens while we are
- * servicing this one, we will get another interrupt
- * shortly. We can NOT just sit here in a loop, or
- * we will cause horrible latency for other devices
- * on this interrupt level (i.e. sun3x floppy disk).
- */
- if (rr3 & (ZSRR3_IP_A_RX | ZSRR3_IP_A_TX | ZSRR3_IP_A_STAT)) {
- zs_write_csr(cs, ZSWR0_CLR_INTR);
- if (rr3 & ZSRR3_IP_A_RX)
- (*cs->cs_ops->zsop_rxint)(cs);
- if (rr3 & ZSRR3_IP_A_STAT)
- (*cs->cs_ops->zsop_stint)(cs, 0);
- if (rr3 & ZSRR3_IP_A_TX)
- (*cs->cs_ops->zsop_txint)(cs);
- }
-
- /* Now look at channel B. */
- cs = zsc->zsc_cs[1];
- if (rr3 & (ZSRR3_IP_B_RX | ZSRR3_IP_B_TX | ZSRR3_IP_B_STAT)) {
- zs_write_csr(cs, ZSWR0_CLR_INTR);
- if (rr3 & ZSRR3_IP_B_RX)
- (*cs->cs_ops->zsop_rxint)(cs);
- if (rr3 & ZSRR3_IP_B_STAT)
- (*cs->cs_ops->zsop_stint)(cs, 0);
- if (rr3 & ZSRR3_IP_B_TX)
- (*cs->cs_ops->zsop_txint)(cs);
- }
-
- /* Note: caller will check cs_x->cs_softreq and DTRT. */
- return (rr3);
-}
-
-
-/*
- * ZS software interrupt. Scan all channels for deferred interrupts.
- */
-int
-zsc_intr_soft(void *arg)
-{
- struct zsc_softc *zsc = arg;
- struct zs_chanstate *cs;
- int rval, chan;
-
- rval = 0;
- for (chan = 0; chan < 2; chan++) {
- cs = zsc->zsc_cs[chan];
-
- /*
- * The softint flag can be safely cleared once
- * we have decided to call the softint routine.
- * (No need to do splzs() first.)
- */
- if (cs->cs_softreq) {
- cs->cs_softreq = 0;
- (*cs->cs_ops->zsop_softint)(cs);
- rval++;
- }
- }
- return (rval);
-}
-
-/*
- * Provide a null zs "ops" vector.
- */
-
-void zsnull_rxint(struct zs_chanstate *);
-void zsnull_stint(struct zs_chanstate *, int);
-void zsnull_txint(struct zs_chanstate *);
-void zsnull_softint(struct zs_chanstate *);
-
-void
-zsnull_rxint(struct zs_chanstate *cs)
-{
- /* Ask for softint() call. */
- cs->cs_softreq = 1;
-}
-
-void
-zsnull_stint(struct zs_chanstate *cs, int force)
-{
- /* Ask for softint() call. */
- cs->cs_softreq = 1;
-}
-
-void
-zsnull_txint(struct zs_chanstate *cs)
-{
- /* Ask for softint() call. */
- cs->cs_softreq = 1;
-}
-
-void
-zsnull_softint(struct zs_chanstate *cs)
-{
- zs_write_reg(cs, 1, 0);
- zs_write_reg(cs, 15, 0);
-}
-
-struct zsops zsops_null = {
- zsnull_rxint, /* receive char available */
- zsnull_stint, /* external/status */
- zsnull_txint, /* xmit buffer empty */
- zsnull_softint, /* process software interrupt */
-};
diff --git a/sys/arch/macppc/dev/z8530sc.h b/sys/arch/macppc/dev/z8530sc.h
deleted file mode 100644
index bc2fcfb9c78..00000000000
--- a/sys/arch/macppc/dev/z8530sc.h
+++ /dev/null
@@ -1,154 +0,0 @@
-/* $OpenBSD: z8530sc.h,v 1.2 2003/06/02 23:27:49 millert Exp $ */
-/* $NetBSD: z8530sc.h,v 1.15 2001/05/11 01:40:48 thorpej Exp $ */
-
-/*
- * Copyright (c) 1994 Gordon W. Ross
- * Copyright (c) 1992, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * This software was developed by the Computer Systems Engineering group
- * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
- * contributed to Berkeley.
- *
- * All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Lawrence Berkeley Laboratory.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)zsvar.h 8.1 (Berkeley) 6/11/93
- */
-
-
-/*
- * Function vector - per channel
- */
-struct zs_chanstate;
-struct zsops {
- void (*zsop_rxint)(struct zs_chanstate *);
- /* receive char available */
- void (*zsop_stint)(struct zs_chanstate *, int);
- /* external/status */
- void (*zsop_txint)(struct zs_chanstate *);
- /* xmit buffer empty */
- void (*zsop_softint)(struct zs_chanstate *);
- /* process software interrupt */
-};
-
-extern struct zsops zsops_null;
-
-
-/*
- * Software state, per zs channel.
- */
-struct zs_chanstate {
-
- /* Pointers to the device registers. */
- volatile u_char *cs_reg_csr; /* ctrl, status, and reg. number. */
- volatile u_char *cs_reg_data; /* data or numbered register */
-
- int cs_channel; /* sub-unit number */
- void *cs_private; /* sub-driver data pointer */
- struct zsops *cs_ops;
-
- int cs_brg_clk; /* BAUD Rate Generator clock
- * (usually PCLK / 16) */
- int cs_defspeed; /* default baud rate */
- int cs_defcflag; /* default cflag */
-
- /*
- * We must keep a copy of the write registers as they are
- * mostly write-only and we sometimes need to set and clear
- * individual bits (e.g., in WR3). Not all of these are
- * needed but 16 bytes is cheap and this makes the addressing
- * simpler. Unfortunately, we can only write to some registers
- * when the chip is not actually transmitting, so whenever
- * we are expecting a `transmit done' interrupt the preg array
- * is allowed to `get ahead' of the current values. In a
- * few places we must change the current value of a register,
- * rather than (or in addition to) the pending value; for these
- * cs_creg[] contains the current value.
- */
- u_char cs_creg[16]; /* current values */
- u_char cs_preg[16]; /* pending values */
- int cs_heldchange; /* change pending (creg != preg) */
-
- u_char cs_rr0; /* last rr0 processed */
- u_char cs_rr0_delta; /* rr0 changes at status intr. */
- u_char cs_rr0_mask; /* rr0 bits that stop output */
- u_char cs_rr0_dcd; /* which bit to read as DCD */
- u_char cs_rr0_cts; /* which bit to read as CTS */
- u_char cs_rr0_pps; /* which bit to use for PPS */
- /* the above is set only while CRTSCTS is enabled. */
-
- u_char cs_wr5_dtr; /* which bit to write as DTR */
- u_char cs_wr5_rts; /* which bit to write as RTS */
- /* the above is set only while CRTSCTS is enabled. */
-
- char cs_softreq; /* need soft interrupt call */
- char cs_spare1; /* (for skippy :) */
-
- /* power management hooks */
- int (*enable)(struct zs_chanstate *);
- void (*disable)(struct zs_chanstate *);
- int enabled;
-
- /* MD code might define a larger variant of this. */
-};
-
-struct consdev;
-struct zsc_attach_args {
- char *type; /* type name 'serial', 'keyboard', 'mouse' */
- int channel; /* two serial channels per zsc */
- int hwflags; /* see definitions below */
- /* `consdev' is only valid if ZS_HWFLAG_USE_CONSDEV is set */
- struct consdev *consdev;
-};
-/* In case of split console devices, use these: */
-#define ZS_HWFLAG_CONSOLE_INPUT 1
-#define ZS_HWFLAG_CONSOLE_OUTPUT 2
-#define ZS_HWFLAG_CONSOLE \
- (ZS_HWFLAG_CONSOLE_INPUT | ZS_HWFLAG_CONSOLE_OUTPUT)
-#define ZS_HWFLAG_NO_DCD 4 /* Ignore the DCD bit */
-#define ZS_HWFLAG_NO_CTS 8 /* Ignore the CTS bit */
-#define ZS_HWFLAG_RAW 16 /* advise raw mode */
-#define ZS_HWFLAG_USE_CONSDEV 32 /* Use console ops from `consdev' */
-#define ZS_HWFLAG_NORESET 64 /* Don't reset at attach time */
-
-int zsc_intr_soft(void *);
-int zsc_intr_hard(void *);
-
-void zs_abort(struct zs_chanstate *);
-void zs_break(struct zs_chanstate *, int);
-void zs_iflush(struct zs_chanstate *);
-void zs_loadchannelregs(struct zs_chanstate *);
-int zs_set_speed(struct zs_chanstate *, int);
-int zs_set_modes(struct zs_chanstate *, int);
-
-extern int zs_major;
-
-int zs_check_kgdb(struct zs_chanstate *, int);
-
diff --git a/sys/arch/macppc/dev/z8530tty.c b/sys/arch/macppc/dev/z8530tty.c
deleted file mode 100644
index 08ec3910d61..00000000000
--- a/sys/arch/macppc/dev/z8530tty.c
+++ /dev/null
@@ -1,1576 +0,0 @@
-/* $OpenBSD: z8530tty.c,v 1.15 2010/07/05 10:41:35 blambert Exp $ */
-/* $NetBSD: z8530tty.c,v 1.13 1996/10/16 20:42:14 gwr Exp $ */
-
-/*-
- * Copyright (c) 1993, 1994, 1995, 1996, 1997, 1998, 1999
- * Charles M. Hannum. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Charles M. Hannum.
- * 4. The name of the author may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * Copyright (c) 1994 Gordon W. Ross
- * Copyright (c) 1992, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * This software was developed by the Computer Systems Engineering group
- * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
- * contributed to Berkeley.
- *
- * All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Lawrence Berkeley Laboratory.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)zs.c 8.1 (Berkeley) 7/19/93
- */
-
-/*
- * Zilog Z8530 Dual UART driver (tty interface)
- *
- * This is the "slave" driver that will be attached to
- * the "zsc" driver for plain "tty" async. serial lines.
- *
- * Credits, history:
- *
- * The original version of this code was the sparc/dev/zs.c driver
- * as distributed with the Berkeley 4.4 Lite release. Since then,
- * Gordon Ross reorganized the code into the current parent/child
- * driver scheme, separating the Sun keyboard and mouse support
- * into independent child drivers.
- *
- * RTS/CTS flow-control support was a collaboration of:
- * Gordon Ross <gwr@netbsd.org>,
- * Bill Studenmund <wrstuden@loki.stanford.edu>
- * Ian Dall <Ian.Dall@dsto.defence.gov.au>
- *
- * The driver was massively overhauled in November 1997 by Charles Hannum,
- * fixing *many* bugs, and substantially improving performance.
- */
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/proc.h>
-#include <sys/device.h>
-#include <sys/conf.h>
-#include <sys/file.h>
-#include <sys/ioctl.h>
-#include <sys/malloc.h>
-#include <sys/tty.h>
-#include <sys/time.h>
-#include <sys/kernel.h>
-#include <sys/syslog.h>
-
-#include <macppc/dev/z8530reg.h>
-#include <machine/z8530var.h>
-
-#include <dev/cons.h>
-
-#ifdef KGDB
-extern int zs_check_kgdb();
-#endif
-
-/*
- * Allow the MD var.h to override the default CFLAG so that
- * console messages during boot come out with correct parity.
- */
-#ifndef ZSTTY_DEF_CFLAG
-#define ZSTTY_DEF_CFLAG TTYDEF_CFLAG
-#endif
-
-/*
- * How many input characters we can buffer.
- * The port-specific var.h may override this.
- * Note: must be a power of two!
- */
-#ifndef ZSTTY_RING_SIZE
-#define ZSTTY_RING_SIZE 2048
-#endif
-
-/*
- * Make this an option variable one can patch.
- * But be warned: this must be a power of 2!
- */
-u_int zstty_rbuf_size = ZSTTY_RING_SIZE;
-
-/* Stop input when 3/4 of the ring is full; restart when only 1/4 is full. */
-u_int zstty_rbuf_hiwat = (ZSTTY_RING_SIZE * 1) / 4;
-u_int zstty_rbuf_lowat = (ZSTTY_RING_SIZE * 3) / 4;
-
-struct zstty_softc {
- struct device zst_dev; /* required first: base device */
- struct tty *zst_tty;
- struct zs_chanstate *zst_cs;
-
- struct timeout zst_diag_ch;
-
- u_int zst_overflows,
- zst_floods,
- zst_errors;
-
- int zst_hwflags, /* see z8530var.h */
- zst_swflags; /* TIOCFLAG_SOFTCAR, ... <ttycom.h> */
-
- u_int zst_r_hiwat,
- zst_r_lowat;
- u_char *volatile zst_rbget,
- *volatile zst_rbput;
- volatile u_int zst_rbavail;
- u_char *zst_rbuf,
- *zst_ebuf;
-
- /*
- * The transmit byte count and address are used for pseudo-DMA
- * output in the hardware interrupt code. PDMA can be suspended
- * to get pending changes done; heldtbc is used for this. It can
- * also be stopped for ^S; this sets TS_TTSTOP in tp->t_state.
- */
- u_char *zst_tba; /* transmit buffer address */
- u_int zst_tbc, /* transmit byte count */
- zst_heldtbc; /* held tbc while xmission stopped */
-
- /* Flags to communicate with zstty_softint() */
- volatile u_char zst_rx_flags, /* receiver blocked */
-#define RX_TTY_BLOCKED 0x01
-#define RX_TTY_OVERFLOWED 0x02
-#define RX_IBUF_BLOCKED 0x04
-#define RX_IBUF_OVERFLOWED 0x08
-#define RX_ANY_BLOCK 0x0f
- zst_tx_busy, /* working on an output chunk */
- zst_tx_done, /* done with one output chunk */
- zst_tx_stopped, /* H/W level stop (lost CTS) */
- zst_st_check, /* got a status interrupt */
- zst_rx_ready;
-
- /* PPS signal on DCD, with or without inkernel clock disciplining */
- u_char zst_ppsmask; /* pps signal mask */
- u_char zst_ppsassert; /* pps leading edge */
- u_char zst_ppsclear; /* pps trailing edge */
-};
-
-
-/* Definition of the driver for autoconfig. */
-int zstty_match(struct device *, void *, void *);
-void zstty_attach(struct device *, struct device *, void *);
-
-struct cfattach zstty_ca = {
- sizeof(struct zstty_softc), zstty_match, zstty_attach
-};
-
-struct cfdriver zstty_cd = {
- NULL, "zstty", DV_TTY
-};
-
-struct zsops zsops_tty;
-
-/* Routines called from other code. */
-cdev_decl(zs); /* open, close, read, write, ioctl, stop, ... */
-
-void zs_shutdown(struct zstty_softc *);
-void zsstart(struct tty *);
-int zsparam(struct tty *, struct termios *);
-void zs_modem(struct zstty_softc *, int);
-void tiocm_to_zs(struct zstty_softc *, u_long, int);
-int zs_to_tiocm(struct zstty_softc *);
-int zshwiflow(struct tty *, int);
-void zs_hwiflow(struct zstty_softc *);
-void zs_maskintr(struct zstty_softc *);
-
-/* Low-level routines. */
-void zstty_rxint(struct zs_chanstate *);
-void zstty_stint(struct zs_chanstate *, int);
-void zstty_txint(struct zs_chanstate *);
-void zstty_softint(struct zs_chanstate *);
-void zstty_diag(void *);
-
-#define ZSUNIT(x) (minor(x) & 0x7ffff)
-#define ZSDIALOUT(x) (minor(x) & 0x80000)
-
-/*
- * zstty_match: how is this zs channel configured?
- */
-int
-zstty_match(struct device *parent, void *match, void *aux)
-{
- struct cfdata *cf = match;
- struct zsc_attach_args *args = aux;
-
- /* Exact match is better than wildcard. */
- if (cf->cf_loc[ZSCCF_CHANNEL] == args->channel)
- return 2;
-
- /* This driver accepts wildcard. */
- if (cf->cf_loc[ZSCCF_CHANNEL] == ZSCCF_CHANNEL_DEFAULT)
- return 1;
-
- return 0;
-}
-
-void
-zstty_attach(struct device *parent, struct device *self, void *aux)
-{
- struct zsc_softc *zsc = (void *) parent;
- struct zstty_softc *zst = (void *) self;
- struct zsc_attach_args *args = aux;
- struct zs_chanstate *cs;
- struct cfdata *cf;
- struct tty *tp;
- int channel, s, tty_unit;
- dev_t dev;
- char *i, *o;
- int maj;
-
- cf = zst->zst_dev.dv_cfdata;
-
- timeout_set(&zst->zst_diag_ch, zstty_diag, zst);
-
- tty_unit = zst->zst_dev.dv_unit;
- channel = args->channel;
- cs = zsc->zsc_cs[channel];
- cs->cs_private = zst;
- cs->cs_ops = &zsops_tty;
-
- zst->zst_cs = cs;
- zst->zst_swflags = cf->cf_flags; /* softcar, etc. */
- zst->zst_hwflags = args->hwflags;
- /* locate the major number */
- for (maj = 0; maj < nchrdev; maj++)
- if (cdevsw[maj].d_open == zsopen)
- break;
-
- dev = makedev(maj, tty_unit);
-
- if (zst->zst_swflags)
- printf(" flags 0x%x", zst->zst_swflags);
-
- /*
- * Check whether we serve as a console device.
- * XXX - split console input/output channels aren't
- * supported yet on /dev/console
- */
- i = o = NULL;
- if ((zst->zst_hwflags & ZS_HWFLAG_CONSOLE_INPUT) != 0) {
- i = " input";
- if ((args->hwflags & ZS_HWFLAG_USE_CONSDEV) != 0) {
- args->consdev->cn_dev = dev;
- cn_tab->cn_pollc = args->consdev->cn_pollc;
- cn_tab->cn_getc = args->consdev->cn_getc;
- }
- cn_tab->cn_dev = dev;
- /* Set console magic to BREAK */
- }
- if ((zst->zst_hwflags & ZS_HWFLAG_CONSOLE_OUTPUT) != 0) {
- o = " output";
- if ((args->hwflags & ZS_HWFLAG_USE_CONSDEV) != 0) {
- cn_tab->cn_putc = args->consdev->cn_putc;
- }
- cn_tab->cn_dev = dev;
- }
- if (i != NULL || o != NULL)
- printf(": console%s", i ? (o ? "" : i) : o);
-
-#ifdef KGDB
- /*
- * Allow kgdb to "take over" this port. If this port is
- * NOT the kgdb port, zs_check_kgdb() will return zero.
- * If it IS the kgdb port, it will print "kgdb,...\n"
- * and then return non-zero.
- */
- if (zs_check_kgdb(cs, dev)) {
- printf(" (kgdb)\n");
- /*
- * This is the kgdb port (exclusive use)
- * so skip the normal attach code.
- */
- return;
- }
-#endif
-
- if (strcmp(args->type, "keyboard") == 0 ||
- strcmp(args->type, "mouse") == 0)
- printf(": %s", args->type);
-
- printf("\n");
-
- tp = ttymalloc(0);
- tp->t_dev = dev;
- tp->t_oproc = zsstart;
- tp->t_param = zsparam;
- tp->t_hwiflow = zshwiflow;
-
- zst->zst_tty = tp;
- zst->zst_rbuf = malloc(zstty_rbuf_size << 1, M_DEVBUF, M_WAITOK);
- zst->zst_ebuf = zst->zst_rbuf + (zstty_rbuf_size << 1);
- /* Disable the high water mark. */
- zst->zst_r_hiwat = 0;
- zst->zst_r_lowat = 0;
- zst->zst_rbget = zst->zst_rbput = zst->zst_rbuf;
- zst->zst_rbavail = zstty_rbuf_size;
-
- /* if there are no enable/disable functions, assume the device
- is always enabled */
- if (!cs->enable)
- cs->enabled = 1;
-
- /*
- * Hardware init
- */
- if (ISSET(zst->zst_hwflags, ZS_HWFLAG_CONSOLE)) {
- /* Call zsparam similar to open. */
- struct termios t;
-
- /* Wait a while for previous console output to complete */
- DELAY(10000);
-
- /* Setup the "new" parameters in t. */
- t.c_ispeed = 0;
- t.c_ospeed = cs->cs_defspeed;
- t.c_cflag = cs->cs_defcflag;
-
- s = splzs();
-
- /*
- * Turn on receiver and status interrupts.
- * We defer the actual write of the register to zsparam(),
- * but we must make sure status interrupts are turned on by
- * the time zsparam() reads the initial rr0 state.
- */
- SET(cs->cs_preg[1], ZSWR1_RIE | ZSWR1_SIE);
-
- splx(s);
-
- /* Make sure zsparam will see changes. */
- tp->t_ospeed = 0;
- (void) zsparam(tp, &t);
-
- s = splzs();
-
- /* Make sure DTR is on now. */
- zs_modem(zst, 1);
-
- splx(s);
- } else if (!ISSET(zst->zst_hwflags, ZS_HWFLAG_NORESET)) {
- /* Not the console; may need reset. */
- int reset;
-
- reset = (channel == 0) ? ZSWR9_A_RESET : ZSWR9_B_RESET;
-
- s = splzs();
-
- zs_write_reg(cs, 9, reset);
-
- /* Will raise DTR in open. */
- zs_modem(zst, 0);
-
- splx(s);
- }
-}
-
-
-/*
- * Return pointer to our tty.
- */
-struct tty *
-zstty(dev_t dev)
-{
- struct zstty_softc *zst;
- int unit = minor(dev);
-
-#ifdef DIAGNOSTIC
- if (unit >= zstty_cd.cd_ndevs)
- panic("zstty");
-#endif
- zst = zstty_cd.cd_devs[unit];
- return (zst->zst_tty);
-}
-
-
-void
-zs_shutdown(struct zstty_softc *zst)
-{
- struct zs_chanstate *cs = zst->zst_cs;
- struct tty *tp = zst->zst_tty;
- int s;
-
- s = splzs();
-
- /* If we were asserting flow control, then deassert it. */
- SET(zst->zst_rx_flags, RX_IBUF_BLOCKED);
- zs_hwiflow(zst);
-
- /* Clear any break condition set with TIOCSBRK. */
- zs_break(cs, 0);
-
- /* Turn off PPS capture on last close. */
- zst->zst_ppsmask = 0;
-
- /*
- * Hang up if necessary. Wait a bit, so the other side has time to
- * notice even if we immediately open the port again.
- */
- if (ISSET(tp->t_cflag, HUPCL)) {
- zs_modem(zst, 0);
- (void) tsleep(cs, TTIPRI, ttclos, hz);
- }
-
- /* Turn off interrupts if not the console. */
- if (!ISSET(zst->zst_hwflags, ZS_HWFLAG_CONSOLE)) {
- CLR(cs->cs_preg[1], ZSWR1_RIE | ZSWR1_SIE);
- cs->cs_creg[1] = cs->cs_preg[1];
- zs_write_reg(cs, 1, cs->cs_creg[1]);
- }
-
-/* Call the power management hook. */
- if (cs->disable) {
-#ifdef DIAGNOSTIC
- if (!cs->enabled)
- panic("zs_shutdown: not enabled?");
-#endif
- (*cs->disable)(zst->zst_cs);
- }
-
- splx(s);
-}
-
-/*
- * Open a zs serial (tty) port.
- */
-int
-zsopen(dev_t dev, int flags, int mode, struct proc *p)
-{
- struct tty *tp;
- struct zs_chanstate *cs;
- struct zstty_softc *zst;
- int s, s2;
- int error, unit;
-
- unit = minor(dev);
- if (unit >= zstty_cd.cd_ndevs)
- return (ENXIO);
- zst = zstty_cd.cd_devs[unit];
- if (zst == NULL)
- return (ENXIO);
- tp = zst->zst_tty;
- cs = zst->zst_cs;
-
- /* If KGDB took the line, then tp==NULL */
- if (tp == NULL)
- return (EBUSY);
-
- if (ISSET(tp->t_state, TS_ISOPEN) &&
- ISSET(tp->t_state, TS_XCLUDE) &&
- suser(p, 0) != 0)
- return (EBUSY);
-
- s = spltty();
-
- /*
- * Do the following iff this is a first open.
- */
- if (!ISSET(tp->t_state, TS_ISOPEN)) {
- struct termios t;
-
- tp->t_dev = dev;
-
- /* Call the power management hook. */
- if (cs->enable) {
- if ((*cs->enable)(cs)) {
- splx(s);
- printf("%s: device enable failed\n",
- zst->zst_dev.dv_xname);
- return (EIO);
- }
- }
-
- /*
- * Initialize the termios status to the defaults. Add in the
- * sticky bits from TIOCSFLAGS.
- */
- t.c_ispeed = 0;
- t.c_ospeed = cs->cs_defspeed;
- t.c_cflag = cs->cs_defcflag;
- if (ISSET(zst->zst_swflags, TIOCFLAG_CLOCAL))
- SET(t.c_cflag, CLOCAL);
- if (ISSET(zst->zst_swflags, TIOCFLAG_CRTSCTS))
- SET(t.c_cflag, CRTSCTS);
- if (ISSET(zst->zst_swflags, TIOCFLAG_MDMBUF))
- SET(t.c_cflag, MDMBUF);
-
- s2 = splzs();
-
- /*
- * Turn on receiver and status interrupts.
- * We defer the actual write of the register to zsparam(),
- * but we must make sure status interrupts are turned on by
- * the time zsparam() reads the initial rr0 state.
- */
- SET(cs->cs_preg[1], ZSWR1_RIE | ZSWR1_SIE);
-
- /* Clear PPS capture state on first open. */
- zst->zst_ppsmask = 0;
-
- splx(s2);
-
- /* Make sure zsparam will see changes. */
- tp->t_ospeed = 0;
- (void) zsparam(tp, &t);
-
- /*
- * Note: zsparam has done: cflag, ispeed, ospeed
- * so we just need to do: iflag, oflag, lflag, cc
- * For "raw" mode, just leave all zeros.
- */
- if (!ISSET(zst->zst_hwflags, ZS_HWFLAG_RAW)) {
- tp->t_iflag = TTYDEF_IFLAG;
- tp->t_oflag = TTYDEF_OFLAG;
- tp->t_lflag = TTYDEF_LFLAG;
- } else {
- tp->t_iflag = 0;
- tp->t_oflag = 0;
- tp->t_lflag = 0;
- }
- ttychars(tp);
- ttsetwater(tp);
-
- s2 = splzs();
-
- /*
- * Turn on DTR. We must always do this, even if carrier is not
- * present, because otherwise we'd have to use TIOCSDTR
- * immediately after setting CLOCAL, which applications do not
- * expect. We always assert DTR while the device is open
- * unless explicitly requested to deassert it.
- */
- zs_modem(zst, 1);
-
- /* Clear the input ring, and unblock. */
- zst->zst_rbget = zst->zst_rbput = zst->zst_rbuf;
- zst->zst_rbavail = zstty_rbuf_size;
- zs_iflush(cs);
- CLR(zst->zst_rx_flags, RX_ANY_BLOCK);
- zs_hwiflow(zst);
-
- splx(s2);
- }
-
- splx(s);
-
- error = ((*linesw[tp->t_line].l_open)(dev, tp, p));
- if (error)
- goto bad;
-
- return (0);
-
-bad:
- if (!ISSET(tp->t_state, TS_ISOPEN)) {
- /*
- * We failed to open the device, and nobody else had it opened.
- * Clean up the state as appropriate.
- */
- zs_shutdown(zst);
- }
-
- return (error);
-}
-
-/*
- * Close a zs serial port.
- */
-int
-zsclose(dev_t dev, int flags, int mode, struct proc *p)
-{
- struct zstty_softc *zst;
- struct zs_chanstate *cs;
- struct tty *tp;
-
- zst = zstty_cd.cd_devs[minor(dev)];
- cs = zst->zst_cs;
- tp = zst->zst_tty;
-
- /* XXX This is for cons.c. */
- if (!ISSET(tp->t_state, TS_ISOPEN))
- return 0;
-
- (*linesw[tp->t_line].l_close)(tp, flags, p);
- ttyclose(tp);
-
- if (!ISSET(tp->t_state, TS_ISOPEN)) {
- /*
- * Although we got a last close, the device may still be in
- * use; e.g. if this was the dialout node, and there are still
- * processes waiting for carrier on the non-dialout node.
- */
- zs_shutdown(zst);
- }
-
- return (0);
-}
-
-/*
- * Read/write zs serial port.
- */
-int
-zsread(dev_t dev, struct uio *uio, int flags)
-{
- struct zstty_softc *zst;
- struct tty *tp;
-
- zst = zstty_cd.cd_devs[minor(dev)];
- tp = zst->zst_tty;
-
- return (*linesw[tp->t_line].l_read)(tp, uio, flags);
-}
-
-int
-zswrite(dev_t dev, struct uio *uio, int flags)
-{
- struct zstty_softc *zst;
- struct tty *tp;
-
- zst = zstty_cd.cd_devs[minor(dev)];
- tp = zst->zst_tty;
-
- return (*linesw[tp->t_line].l_write)(tp, uio, flags);
-}
-
-#define TIOCFLAG_ALL (TIOCFLAG_SOFTCAR | TIOCFLAG_CLOCAL | \
- TIOCFLAG_CRTSCTS | TIOCFLAG_MDMBUF )
-
-int
-zsioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
-{
- struct zstty_softc *zst;
- struct zs_chanstate *cs;
- struct tty *tp;
- int error;
- int s;
-
- zst = zstty_cd.cd_devs[minor(dev)];
- cs = zst->zst_cs;
- tp = zst->zst_tty;
-
- error = ((*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag, p));
- if (error >= 0)
- return (error);
-
- error = ttioctl(tp, cmd, data, flag, p);
- if (error >= 0)
- return (error);
-
-#ifdef ZS_MD_IOCTL
- error = ZS_MD_IOCTL;
- if (error >= 0)
- return (error);
-#endif /* ZS_MD_IOCTL */
-
- error = 0;
-
- s = splzs();
-
- switch (cmd) {
- case TIOCSBRK:
- zs_break(cs, 1);
- break;
-
- case TIOCCBRK:
- zs_break(cs, 0);
- break;
-
- case TIOCGFLAGS:
- *(int *)data = zst->zst_swflags;
- break;
-
- case TIOCSFLAGS:
- error = suser(p, 0);
- if (error != 0)
- break;
- zst->zst_swflags = *(int *)data;
- break;
-
- case TIOCSDTR:
- zs_modem(zst, 1);
- break;
-
- case TIOCCDTR:
- zs_modem(zst, 0);
- break;
-
- case TIOCMSET:
- case TIOCMBIS:
- case TIOCMBIC:
- tiocm_to_zs(zst, cmd, *(int *)data);
- break;
-
- case TIOCMGET:
- *(int *)data = zs_to_tiocm(zst);
- break;
-
- default:
- error = ENOTTY;
- break;
- }
-
- splx(s);
-
- return (error);
-}
-
-/*
- * Start or restart transmission.
- */
-void
-zsstart(struct tty *tp)
-{
- struct zstty_softc *zst;
- struct zs_chanstate *cs;
- int s;
-
- zst = zstty_cd.cd_devs[minor(tp->t_dev)];
- cs = zst->zst_cs;
-
- s = spltty();
- if (ISSET(tp->t_state, TS_BUSY | TS_TIMEOUT | TS_TTSTOP))
- goto out;
- if (zst->zst_tx_stopped)
- goto out;
-
- ttwakeupwr(tp);
- if (tp->t_outq.c_cc == 0)
- goto out;
-
- /* Grab the first contiguous region of buffer space. */
- {
- u_char *tba;
- int tbc;
-
- tba = tp->t_outq.c_cf;
- tbc = ndqb(&tp->t_outq, 0);
-
- (void) splzs();
-
- zst->zst_tba = tba;
- zst->zst_tbc = tbc;
- }
-
- SET(tp->t_state, TS_BUSY);
- zst->zst_tx_busy = 1;
-
- /* Enable transmit completion interrupts if necessary. */
- if (!ISSET(cs->cs_preg[1], ZSWR1_TIE)) {
- SET(cs->cs_preg[1], ZSWR1_TIE);
- cs->cs_creg[1] = cs->cs_preg[1];
- zs_write_reg(cs, 1, cs->cs_creg[1]);
- }
-
- /* Output the first character of the contiguous buffer. */
- zs_write_data(cs, *zst->zst_tba);
- zst->zst_tbc--;
- zst->zst_tba++;
-out:
- splx(s);
-}
-
-/*
- * Stop output, e.g., for ^S or output flush.
- */
-int
-zsstop(struct tty *tp, int flag)
-{
- struct zstty_softc *zst;
- struct zs_chanstate *cs;
- int s;
-
- zst = zstty_cd.cd_devs[minor(tp->t_dev)];
- cs = zst->zst_cs;
-
- s = splzs();
- if (ISSET(tp->t_state, TS_BUSY)) {
- /* Stop transmitting at the next chunk. */
- zst->zst_tbc = 0;
- zst->zst_heldtbc = 0;
- if (!ISSET(tp->t_state, TS_TTSTOP))
- SET(tp->t_state, TS_FLUSH);
- }
- splx(s);
- return (0);
-}
-
-/*
- * Set ZS tty parameters from termios.
- * XXX - Should just copy the whole termios after
- * making sure all the changes could be done.
- */
-int
-zsparam(struct tty *tp, struct termios *t)
-{
- struct zstty_softc *zst;
- struct zs_chanstate *cs;
- int ospeed, cflag;
- u_char tmp3, tmp4, tmp5;
- int s, error;
-
- zst = zstty_cd.cd_devs[minor(tp->t_dev)];
- cs = zst->zst_cs;
-
- ospeed = t->c_ospeed;
- cflag = t->c_cflag;
-
- /* Check requested parameters. */
- if (ospeed < 0)
- return (EINVAL);
- if (t->c_ispeed && t->c_ispeed != ospeed)
- return (EINVAL);
-
- /*
- * For the console, always force CLOCAL and !HUPCL, so that the port
- * is always active.
- */
- if (ISSET(zst->zst_swflags, TIOCFLAG_SOFTCAR) ||
- ISSET(zst->zst_hwflags, ZS_HWFLAG_CONSOLE)) {
- SET(cflag, CLOCAL);
- CLR(cflag, HUPCL);
- }
-
- /*
- * Only whack the UART when params change.
- * Some callers need to clear tp->t_ospeed
- * to make sure initialization gets done.
- */
- if (tp->t_ospeed == ospeed &&
- tp->t_cflag == cflag)
- return (0);
-
- /*
- * Call MD functions to deal with changed
- * clock modes or H/W flow control modes.
- * The BRG divisor is set now. (reg 12,13)
- */
- error = zs_set_speed(cs, ospeed);
- if (error)
- return (error);
- error = zs_set_modes(cs, cflag);
- if (error)
- return (error);
-
- /*
- * Block interrupts so that state will not
- * be altered until we are done setting it up.
- *
- * Initial values in cs_preg are set before
- * our attach routine is called. The master
- * interrupt enable is handled by zsc.c
- */
- s = splzs();
-
- /*
- * Recalculate which status ints to enable.
- */
- zs_maskintr(zst);
-
- /* Recompute character size bits. */
- tmp3 = cs->cs_preg[3];
- tmp5 = cs->cs_preg[5];
- CLR(tmp3, ZSWR3_RXSIZE);
- CLR(tmp5, ZSWR5_TXSIZE);
- switch (ISSET(cflag, CSIZE)) {
- case CS5:
- SET(tmp3, ZSWR3_RX_5);
- SET(tmp5, ZSWR5_TX_5);
- break;
- case CS6:
- SET(tmp3, ZSWR3_RX_6);
- SET(tmp5, ZSWR5_TX_6);
- break;
- case CS7:
- SET(tmp3, ZSWR3_RX_7);
- SET(tmp5, ZSWR5_TX_7);
- break;
- case CS8:
- SET(tmp3, ZSWR3_RX_8);
- SET(tmp5, ZSWR5_TX_8);
- break;
- }
- cs->cs_preg[3] = tmp3;
- cs->cs_preg[5] = tmp5;
-
- /*
- * Recompute the stop bits and parity bits. Note that
- * zs_set_speed() may have set clock selection bits etc.
- * in wr4, so those must preserved.
- */
- tmp4 = cs->cs_preg[4];
- CLR(tmp4, ZSWR4_SBMASK | ZSWR4_PARMASK);
- if (ISSET(cflag, CSTOPB))
- SET(tmp4, ZSWR4_TWOSB);
- else
- SET(tmp4, ZSWR4_ONESB);
- if (!ISSET(cflag, PARODD))
- SET(tmp4, ZSWR4_EVENP);
- if (ISSET(cflag, PARENB))
- SET(tmp4, ZSWR4_PARENB);
- cs->cs_preg[4] = tmp4;
-
- /* And copy to tty. */
- tp->t_ispeed = 0;
- tp->t_ospeed = ospeed;
- tp->t_cflag = cflag;
-
- /*
- * If nothing is being transmitted, set up new current values,
- * else mark them as pending.
- */
- if (!cs->cs_heldchange) {
- if (zst->zst_tx_busy) {
- zst->zst_heldtbc = zst->zst_tbc;
- zst->zst_tbc = 0;
- cs->cs_heldchange = 1;
- } else
- zs_loadchannelregs(cs);
- }
-
- /*
- * If hardware flow control is disabled, turn off the buffer water
- * marks and unblock any soft flow control state. Otherwise, enable
- * the water marks.
- */
- if (!ISSET(cflag, CHWFLOW)) {
- zst->zst_r_hiwat = 0;
- zst->zst_r_lowat = 0;
- if (ISSET(zst->zst_rx_flags, RX_TTY_OVERFLOWED)) {
- CLR(zst->zst_rx_flags, RX_TTY_OVERFLOWED);
- zst->zst_rx_ready = 1;
- cs->cs_softreq = 1;
- }
- if (ISSET(zst->zst_rx_flags, RX_TTY_BLOCKED|RX_IBUF_BLOCKED)) {
- CLR(zst->zst_rx_flags, RX_TTY_BLOCKED|RX_IBUF_BLOCKED);
- zs_hwiflow(zst);
- }
- } else {
- zst->zst_r_hiwat = zstty_rbuf_hiwat;
- zst->zst_r_lowat = zstty_rbuf_lowat;
- }
-
- /*
- * Force a recheck of the hardware carrier and flow control status,
- * since we may have changed which bits we're looking at.
- */
- zstty_stint(cs, 1);
-
- splx(s);
-
- /*
- * If hardware flow control is disabled, unblock any hard flow control
- * state.
- */
- if (!ISSET(cflag, CHWFLOW)) {
- if (zst->zst_tx_stopped) {
- zst->zst_tx_stopped = 0;
- zsstart(tp);
- }
- }
-
- zstty_softint(cs);
-
- return (0);
-}
-
-/*
- * Compute interrupt enable bits and set in the pending bits. Called both
- * in zsparam() and when PPS (pulse per second timing) state changes.
- * Must be called at splzs().
- */
-void
-zs_maskintr(struct zstty_softc *zst)
-{
- struct zs_chanstate *cs = zst->zst_cs;
- int tmp15;
-
- cs->cs_rr0_mask = cs->cs_rr0_cts | cs->cs_rr0_dcd;
- if (zst->zst_ppsmask != 0)
- cs->cs_rr0_mask |= cs->cs_rr0_pps;
- tmp15 = cs->cs_preg[15];
- if (ISSET(cs->cs_rr0_mask, ZSRR0_DCD))
- SET(tmp15, ZSWR15_DCD_IE);
- else
- CLR(tmp15, ZSWR15_DCD_IE);
- if (ISSET(cs->cs_rr0_mask, ZSRR0_CTS))
- SET(tmp15, ZSWR15_CTS_IE);
- else
- CLR(tmp15, ZSWR15_CTS_IE);
- cs->cs_preg[15] = tmp15;
-}
-
-/*
- * Raise or lower modem control (DTR/RTS) signals. If a character is
- * in transmission, the change is deferred.
- */
-void
-zs_modem(struct zstty_softc *zst, int onoff)
-{
- struct zs_chanstate *cs = zst->zst_cs;
-
- if (cs->cs_wr5_dtr == 0)
- return;
-
- if (onoff)
- SET(cs->cs_preg[5], cs->cs_wr5_dtr);
- else
- CLR(cs->cs_preg[5], cs->cs_wr5_dtr);
-
- if (!cs->cs_heldchange) {
- if (zst->zst_tx_busy) {
- zst->zst_heldtbc = zst->zst_tbc;
- zst->zst_tbc = 0;
- cs->cs_heldchange = 1;
- } else
- zs_loadchannelregs(cs);
- }
-}
-
-void
-tiocm_to_zs(struct zstty_softc *zst, u_long how, int ttybits)
-{
- struct zs_chanstate *cs = zst->zst_cs;
- u_char zsbits;
-
- zsbits = 0;
- if (ISSET(ttybits, TIOCM_DTR))
- SET(zsbits, ZSWR5_DTR);
- if (ISSET(ttybits, TIOCM_RTS))
- SET(zsbits, ZSWR5_RTS);
-
- switch (how) {
- case TIOCMBIC:
- CLR(cs->cs_preg[5], zsbits);
- break;
-
- case TIOCMBIS:
- SET(cs->cs_preg[5], zsbits);
- break;
-
- case TIOCMSET:
- CLR(cs->cs_preg[5], ZSWR5_RTS | ZSWR5_DTR);
- SET(cs->cs_preg[5], zsbits);
- break;
- }
-
- if (!cs->cs_heldchange) {
- if (zst->zst_tx_busy) {
- zst->zst_heldtbc = zst->zst_tbc;
- zst->zst_tbc = 0;
- cs->cs_heldchange = 1;
- } else
- zs_loadchannelregs(cs);
- }
-}
-
-int
-zs_to_tiocm(struct zstty_softc *zst)
-{
- struct zs_chanstate *cs = zst->zst_cs;
- u_char zsbits;
- int ttybits = 0;
-
- zsbits = cs->cs_preg[5];
- if (ISSET(zsbits, ZSWR5_DTR))
- SET(ttybits, TIOCM_DTR);
- if (ISSET(zsbits, ZSWR5_RTS))
- SET(ttybits, TIOCM_RTS);
-
- zsbits = cs->cs_rr0;
- if (ISSET(zsbits, ZSRR0_DCD))
- SET(ttybits, TIOCM_CD);
- if (ISSET(zsbits, ZSRR0_CTS))
- SET(ttybits, TIOCM_CTS);
-
- return (ttybits);
-}
-
-/*
- * Try to block or unblock input using hardware flow-control.
- * This is called by kern/tty.c if MDMBUF|CRTSCTS is set, and
- * if this function returns non-zero, the TS_TBLOCK flag will
- * be set or cleared according to the "block" arg passed.
- */
-int
-zshwiflow(struct tty *tp, int block)
-{
- struct zstty_softc *zst;
- struct zs_chanstate *cs;
- int s;
-
- zst = zstty_cd.cd_devs[minor(tp->t_dev)];
- cs = zst->zst_cs;
-
- if (cs->cs_wr5_rts == 0)
- return (0);
-
- s = splzs();
- if (block) {
- if (!ISSET(zst->zst_rx_flags, RX_TTY_BLOCKED)) {
- SET(zst->zst_rx_flags, RX_TTY_BLOCKED);
- zs_hwiflow(zst);
- }
- } else {
- if (ISSET(zst->zst_rx_flags, RX_TTY_OVERFLOWED)) {
- CLR(zst->zst_rx_flags, RX_TTY_OVERFLOWED);
- zst->zst_rx_ready = 1;
- cs->cs_softreq = 1;
- }
- if (ISSET(zst->zst_rx_flags, RX_TTY_BLOCKED)) {
- CLR(zst->zst_rx_flags, RX_TTY_BLOCKED);
- zs_hwiflow(zst);
- }
- }
- splx(s);
- return (1);
-}
-
-/*
- * Internal version of zshwiflow
- * called at splzs
- */
-void
-zs_hwiflow(struct zstty_softc *zst)
-{
- struct zs_chanstate *cs = zst->zst_cs;
-
- if (cs->cs_wr5_rts == 0)
- return;
-
- if (ISSET(zst->zst_rx_flags, RX_ANY_BLOCK)) {
- CLR(cs->cs_preg[5], cs->cs_wr5_rts);
- CLR(cs->cs_creg[5], cs->cs_wr5_rts);
- } else {
- SET(cs->cs_preg[5], cs->cs_wr5_rts);
- SET(cs->cs_creg[5], cs->cs_wr5_rts);
- }
- zs_write_reg(cs, 5, cs->cs_creg[5]);
-}
-
-
-/****************************************************************
- * Interface to the lower layer (zscc)
- ****************************************************************/
-
-void zstty_rxsoft(struct zstty_softc *, struct tty *);
-void zstty_txsoft(struct zstty_softc *, struct tty *);
-void zstty_stsoft(struct zstty_softc *, struct tty *);
-
-/*
- * receiver ready interrupt.
- * called at splzs
- */
-void
-zstty_rxint(struct zs_chanstate *cs)
-{
- struct zstty_softc *zst = cs->cs_private;
- u_char *put, *end;
- u_int cc;
- u_char rr0, rr1, c;
-
- end = zst->zst_ebuf;
- put = zst->zst_rbput;
- cc = zst->zst_rbavail;
-
- while (cc > 0) {
- /*
- * First read the status, because reading the received char
- * destroys the status of this char.
- */
- rr1 = zs_read_reg(cs, 1);
- c = zs_read_data(cs);
-
- if (ISSET(rr1, ZSRR1_FE | ZSRR1_DO | ZSRR1_PE)) {
- /* Clear the receive error. */
- zs_write_csr(cs, ZSWR0_RESET_ERRORS);
- }
-
- put[0] = c;
- put[1] = rr1;
- put += 2;
- if (put >= end)
- put = zst->zst_rbuf;
- cc--;
-
- rr0 = zs_read_csr(cs);
- if (!ISSET(rr0, ZSRR0_RX_READY))
- break;
- }
-
- /*
- * Current string of incoming characters ended because
- * no more data was available or we ran out of space.
- * Schedule a receive event if any data was received.
- * If we're out of space, turn off receive interrupts.
- */
- zst->zst_rbput = put;
- zst->zst_rbavail = cc;
- if (!ISSET(zst->zst_rx_flags, RX_TTY_OVERFLOWED)) {
- zst->zst_rx_ready = 1;
- cs->cs_softreq = 1;
- }
-
- /*
- * See if we are in danger of overflowing a buffer. If
- * so, use hardware flow control to ease the pressure.
- */
- if (!ISSET(zst->zst_rx_flags, RX_IBUF_BLOCKED) &&
- cc < zst->zst_r_hiwat) {
- SET(zst->zst_rx_flags, RX_IBUF_BLOCKED);
- zs_hwiflow(zst);
- }
-
- /*
- * If we're out of space, disable receive interrupts
- * until the queue has drained a bit.
- */
- if (!cc) {
- SET(zst->zst_rx_flags, RX_IBUF_OVERFLOWED);
- CLR(cs->cs_preg[1], ZSWR1_RIE);
- cs->cs_creg[1] = cs->cs_preg[1];
- zs_write_reg(cs, 1, cs->cs_creg[1]);
- }
-}
-
-/*
- * transmitter ready interrupt. (splzs)
- */
-void
-zstty_txint(struct zs_chanstate *cs)
-{
- struct zstty_softc *zst = cs->cs_private;
-
- /*
- * If we've delayed a parameter change, do it now, and restart
- * output.
- */
- if (cs->cs_heldchange) {
- zs_loadchannelregs(cs);
- cs->cs_heldchange = 0;
- zst->zst_tbc = zst->zst_heldtbc;
- zst->zst_heldtbc = 0;
- }
-
- /* Output the next character in the buffer, if any. */
- if (zst->zst_tbc > 0) {
- zs_write_data(cs, *zst->zst_tba);
- zst->zst_tbc--;
- zst->zst_tba++;
- } else {
- /* Disable transmit completion interrupts if necessary. */
- if (ISSET(cs->cs_preg[1], ZSWR1_TIE)) {
- CLR(cs->cs_preg[1], ZSWR1_TIE);
- cs->cs_creg[1] = cs->cs_preg[1];
- zs_write_reg(cs, 1, cs->cs_creg[1]);
- }
- if (zst->zst_tx_busy) {
- zst->zst_tx_busy = 0;
- zst->zst_tx_done = 1;
- cs->cs_softreq = 1;
- }
- }
-}
-
-#ifdef DDB
-#include <ddb/db_var.h>
-#define DB_CONSOLE db_console
-#else
-#define DB_CONSOLE 1
-#endif
-
-/*
- * status change interrupt. (splzs)
- */
-void
-zstty_stint(struct zs_chanstate *cs, int force)
-{
- struct zstty_softc *zst = cs->cs_private;
- u_char rr0, delta;
-
- rr0 = zs_read_csr(cs);
- zs_write_csr(cs, ZSWR0_RESET_STATUS);
-
- /*
- * Check here for console break, so that we can abort
- * even when interrupts are locking up the machine.
- */
- if ((zst->zst_hwflags & ZS_HWFLAG_CONSOLE_INPUT) &&
- ISSET(rr0, ZSRR0_BREAK) && DB_CONSOLE)
- zs_abort(cs);
-
- if (!force)
- delta = rr0 ^ cs->cs_rr0;
- else
- delta = cs->cs_rr0_mask;
- cs->cs_rr0 = rr0;
-
- if (ISSET(delta, cs->cs_rr0_mask)) {
- SET(cs->cs_rr0_delta, delta);
-
- /*
- * Stop output immediately if we lose the output
- * flow control signal or carrier detect.
- */
- if (ISSET(~rr0, cs->cs_rr0_mask)) {
- zst->zst_tbc = 0;
- zst->zst_heldtbc = 0;
- }
-
- zst->zst_st_check = 1;
- cs->cs_softreq = 1;
- }
-}
-
-void
-zstty_diag(void *arg)
-{
- struct zstty_softc *zst = arg;
- int overflows, floods;
- int s;
-
- s = splzs();
- overflows = zst->zst_overflows;
- zst->zst_overflows = 0;
- floods = zst->zst_floods;
- zst->zst_floods = 0;
- zst->zst_errors = 0;
- splx(s);
-
- log(LOG_WARNING, "%s: %d silo overflow%s, %d ibuf flood%s\n",
- zst->zst_dev.dv_xname,
- overflows, overflows == 1 ? "" : "s",
- floods, floods == 1 ? "" : "s");
-}
-
-void
-zstty_rxsoft(struct zstty_softc *zst, struct tty *tp)
-{
- struct zs_chanstate *cs = zst->zst_cs;
- int (*rint)(int c, struct tty *tp) = linesw[tp->t_line].l_rint;
- u_char *get, *end;
- u_int cc, scc;
- u_char rr1;
- int code;
- int s;
-
- end = zst->zst_ebuf;
- get = zst->zst_rbget;
- scc = cc = zstty_rbuf_size - zst->zst_rbavail;
-
- if (cc == zstty_rbuf_size) {
- zst->zst_floods++;
- if (zst->zst_errors++ == 0)
- timeout_add_sec(&zst->zst_diag_ch, 60);
- }
-
- /* If not yet open, drop the entire buffer content here */
- if (!ISSET(tp->t_state, TS_ISOPEN)) {
- get += cc << 1;
- if (get >= end)
- get -= zstty_rbuf_size << 1;
- cc = 0;
- }
- while (cc) {
- code = get[0];
- rr1 = get[1];
- if (ISSET(rr1, ZSRR1_DO | ZSRR1_FE | ZSRR1_PE)) {
- if (ISSET(rr1, ZSRR1_DO)) {
- zst->zst_overflows++;
- if (zst->zst_errors++ == 0)
- timeout_add_sec(&zst->zst_diag_ch, 60);
- }
- if (ISSET(rr1, ZSRR1_FE))
- SET(code, TTY_FE);
- if (ISSET(rr1, ZSRR1_PE))
- SET(code, TTY_PE);
- }
- if ((*rint)(code, tp) == -1) {
- /*
- * The line discipline's buffer is out of space.
- */
- if (!ISSET(zst->zst_rx_flags, RX_TTY_BLOCKED)) {
- /*
- * We're either not using flow control, or the
- * line discipline didn't tell us to block for
- * some reason. Either way, we have no way to
- * know when there's more space available, so
- * just drop the rest of the data.
- */
- get += cc << 1;
- if (get >= end)
- get -= zstty_rbuf_size << 1;
- cc = 0;
- } else {
- /*
- * Don't schedule any more receive processing
- * until the line discipline tells us there's
- * space available (through comhwiflow()).
- * Leave the rest of the data in the input
- * buffer.
- */
- SET(zst->zst_rx_flags, RX_TTY_OVERFLOWED);
- }
- break;
- }
- get += 2;
- if (get >= end)
- get = zst->zst_rbuf;
- cc--;
- }
-
- if (cc != scc) {
- zst->zst_rbget = get;
- s = splzs();
- cc = zst->zst_rbavail += scc - cc;
- /* Buffers should be ok again, release possible block. */
- if (cc >= zst->zst_r_lowat) {
- if (ISSET(zst->zst_rx_flags, RX_IBUF_OVERFLOWED)) {
- CLR(zst->zst_rx_flags, RX_IBUF_OVERFLOWED);
- SET(cs->cs_preg[1], ZSWR1_RIE);
- cs->cs_creg[1] = cs->cs_preg[1];
- zs_write_reg(cs, 1, cs->cs_creg[1]);
- }
- if (ISSET(zst->zst_rx_flags, RX_IBUF_BLOCKED)) {
- CLR(zst->zst_rx_flags, RX_IBUF_BLOCKED);
- zs_hwiflow(zst);
- }
- }
- splx(s);
- }
-}
-
-void
-zstty_txsoft(struct zstty_softc *zst, struct tty *tp)
-{
- CLR(tp->t_state, TS_BUSY);
- if (ISSET(tp->t_state, TS_FLUSH))
- CLR(tp->t_state, TS_FLUSH);
- else
- ndflush(&tp->t_outq, (int)(zst->zst_tba - tp->t_outq.c_cf));
- (*linesw[tp->t_line].l_start)(tp);
-}
-
-void
-zstty_stsoft(struct zstty_softc *zst, struct tty *tp)
-{
- struct zs_chanstate *cs = zst->zst_cs;
- u_char rr0, delta;
- int s;
-
- s = splzs();
- rr0 = cs->cs_rr0;
- delta = cs->cs_rr0_delta;
- cs->cs_rr0_delta = 0;
- splx(s);
-
- if (ISSET(delta, cs->cs_rr0_dcd)) {
- /*
- * Inform the tty layer that carrier detect changed.
- */
- (void) (*linesw[tp->t_line].l_modem)(tp, ISSET(rr0, ZSRR0_DCD));
- }
-
- if (ISSET(delta, cs->cs_rr0_cts)) {
- /* Block or unblock output according to flow control. */
- if (ISSET(rr0, cs->cs_rr0_cts)) {
- zst->zst_tx_stopped = 0;
- (*linesw[tp->t_line].l_start)(tp);
- } else {
- zst->zst_tx_stopped = 1;
- }
- }
-}
-
-/*
- * Software interrupt. Called at zssoft
- *
- * The main job to be done here is to empty the input ring
- * by passing its contents up to the tty layer. The ring is
- * always emptied during this operation, therefore the ring
- * must not be larger than the space after "high water" in
- * the tty layer, or the tty layer might drop our input.
- *
- * Note: an "input blockage" condition is assumed to exist if
- * EITHER the TS_TBLOCK flag or zst_rx_blocked flag is set.
- */
-void
-zstty_softint(struct zs_chanstate *cs)
-{
- struct zstty_softc *zst = cs->cs_private;
- struct tty *tp = zst->zst_tty;
- int s;
-
- s = spltty();
-
- if (zst->zst_rx_ready) {
- zst->zst_rx_ready = 0;
- zstty_rxsoft(zst, tp);
- }
-
- if (zst->zst_st_check) {
- zst->zst_st_check = 0;
- zstty_stsoft(zst, tp);
- }
-
- if (zst->zst_tx_done) {
- zst->zst_tx_done = 0;
- zstty_txsoft(zst, tp);
- }
-
- splx(s);
-}
-
-struct zsops zsops_tty = {
- zstty_rxint, /* receive char available */
- zstty_stint, /* external/status */
- zstty_txint, /* xmit buffer empty */
- zstty_softint, /* process software interrupt */
-};
diff --git a/sys/arch/macppc/dev/zs.c b/sys/arch/macppc/dev/zs.c
index 26fe41e94e5..0a5367593b7 100644
--- a/sys/arch/macppc/dev/zs.c
+++ b/sys/arch/macppc/dev/zs.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: zs.c,v 1.20 2010/11/22 21:09:32 miod Exp $ */
+/* $OpenBSD: zs.c,v 1.21 2013/04/21 14:44:16 sebastia Exp $ */
/* $NetBSD: zs.c,v 1.17 2001/06/19 13:42:15 wiz Exp $ */
/*
@@ -85,6 +85,7 @@
* Some warts needed by z8530tty.c -
*/
int zs_def_cflag = (CREAD | CS8 | HUPCL);
+int zs_major = 7;
/*
* abort detection on console will now timeout after iterating on a loop
diff --git a/sys/arch/macppc/include/z8530var.h b/sys/arch/macppc/include/z8530var.h
index f778e7e56e9..8d909b9b8b0 100644
--- a/sys/arch/macppc/include/z8530var.h
+++ b/sys/arch/macppc/include/z8530var.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: z8530var.h,v 1.8 2009/10/01 20:19:18 kettenis Exp $ */
+/* $OpenBSD: z8530var.h,v 1.9 2013/04/21 14:44:16 sebastia Exp $ */
/* $NetBSD: z8530var.h,v 1.5 2002/03/17 19:40:45 atatat Exp $ */
/*
@@ -42,7 +42,7 @@
* @(#)zsvar.h 8.1 (Berkeley) 6/11/93
*/
-#include <macppc/dev/z8530sc.h>
+#include <dev/ic/z8530sc.h>
#include <macppc/dev/dbdma.h>
/*
diff --git a/sys/arch/sgi/hpc/files.hpc b/sys/arch/sgi/hpc/files.hpc
index 70008de4fd0..02a1522057c 100644
--- a/sys/arch/sgi/hpc/files.hpc
+++ b/sys/arch/sgi/hpc/files.hpc
@@ -1,4 +1,4 @@
-# $OpenBSD: files.hpc,v 1.3 2012/05/02 18:43:44 miod Exp $
+# $OpenBSD: files.hpc,v 1.4 2013/04/21 14:44:16 sebastia Exp $
# $NetBSD: files.hpc,v 1.14 2009/05/14 01:10:19 macallan Exp $
# IP20 RTC
@@ -29,11 +29,11 @@ file arch/sgi/hpc/haltwo.c haltwo
device zs {[channel = -1]}
attach zs at hpc with zs_hpc
file arch/sgi/hpc/zs.c zs needs-flag
-file arch/sgi/hpc/z8530sc.c zs
+file dev/ic/z8530sc.c zs
device zstty: tty
attach zstty at zs
-file arch/sgi/hpc/z8530tty.c zstty needs-flag
+file dev/ic/z8530tty.c zstty needs-flag
device zskbd: wskbddev
attach zskbd at zs
diff --git a/sys/arch/sgi/hpc/z8530sc.c b/sys/arch/sgi/hpc/z8530sc.c
deleted file mode 100644
index 35b5ad73497..00000000000
--- a/sys/arch/sgi/hpc/z8530sc.c
+++ /dev/null
@@ -1,415 +0,0 @@
-/* $OpenBSD: z8530sc.c,v 1.2 2012/04/29 09:01:38 miod Exp $ */
-/* $NetBSD: z8530sc.c,v 1.30 2009/05/22 03:51:30 mrg Exp $ */
-
-/*
- * Copyright (c) 1992, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * This software was developed by the Computer Systems Engineering group
- * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
- * contributed to Berkeley.
- *
- * All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Lawrence Berkeley Laboratory.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)zs.c 8.1 (Berkeley) 7/19/93
- */
-
-/*
- * Copyright (c) 1994 Gordon W. Ross
- *
- * This software was developed by the Computer Systems Engineering group
- * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
- * contributed to Berkeley.
- *
- * All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Lawrence Berkeley Laboratory.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)zs.c 8.1 (Berkeley) 7/19/93
- */
-
-/*
- * Zilog Z8530 Dual UART driver (common part)
- *
- * This file contains the machine-independent parts of the
- * driver common to tty and keyboard/mouse sub-drivers.
- */
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/proc.h>
-#include <sys/device.h>
-#include <sys/conf.h>
-#include <sys/file.h>
-#include <sys/ioctl.h>
-#include <sys/tty.h>
-#include <sys/time.h>
-#include <sys/kernel.h>
-#include <sys/syslog.h>
-
-#include <dev/ic/z8530reg.h>
-#include <machine/z8530var.h>
-
-void
-zs_break(struct zs_chanstate *cs, int set)
-{
-
- if (set) {
- cs->cs_preg[5] |= ZSWR5_BREAK;
- cs->cs_creg[5] |= ZSWR5_BREAK;
- } else {
- cs->cs_preg[5] &= ~ZSWR5_BREAK;
- cs->cs_creg[5] &= ~ZSWR5_BREAK;
- }
- zs_write_reg(cs, 5, cs->cs_creg[5]);
-}
-
-
-/*
- * drain on-chip fifo
- */
-void
-zs_iflush(struct zs_chanstate *cs)
-{
- uint8_t c, rr0, rr1;
- int i;
-
- /*
- * Count how many times we loop. Some systems, such as some
- * Apple PowerBooks, claim to have SCC's which they really don't.
- */
- for (i = 0; i < 32; i++) {
- /* Is there input available? */
- rr0 = zs_read_csr(cs);
- if ((rr0 & ZSRR0_RX_READY) == 0)
- break;
-
- /*
- * First read the status, because reading the data
- * destroys the status of this char.
- */
- rr1 = zs_read_reg(cs, 1);
- c = zs_read_data(cs);
-
- if (rr1 & (ZSRR1_FE | ZSRR1_DO | ZSRR1_PE)) {
- /* Clear the receive error. */
- zs_write_csr(cs, ZSWR0_RESET_ERRORS);
- }
- }
-}
-
-
-/*
- * Write the given register set to the given zs channel in the proper order.
- * The channel must not be transmitting at the time. The receiver will
- * be disabled for the time it takes to write all the registers.
- * Call this with interrupts disabled.
- */
-void
-zs_loadchannelregs(struct zs_chanstate *cs)
-{
- uint8_t *reg, v;
-
- zs_write_csr(cs, ZSM_RESET_ERR); /* XXX: reset error condition */
-
-#if 1
- /*
- * XXX: Is this really a good idea?
- * XXX: Should go elsewhere! -gwr
- */
- zs_iflush(cs); /* XXX */
-#endif
-
- if (cs->cs_ctl_chan != NULL)
- v = ((cs->cs_ctl_chan->cs_creg[5] & (ZSWR5_RTS | ZSWR5_DTR)) !=
- (cs->cs_ctl_chan->cs_preg[5] & (ZSWR5_RTS | ZSWR5_DTR)));
- else
- v = 0;
-
- if (memcmp((void *)cs->cs_preg, (void *)cs->cs_creg, 16) == 0 && !v)
- return; /* only change if values are different */
-
- /* Copy "pending" regs to "current" */
- memcpy((void *)cs->cs_creg, (void *)cs->cs_preg, 16);
- reg = cs->cs_creg; /* current regs */
-
- /* disable interrupts */
- zs_write_reg(cs, 1, reg[1] & ~ZSWR1_IMASK);
-
- /* baud clock divisor, stop bits, parity */
- zs_write_reg(cs, 4, reg[4]);
-
- /* misc. TX/RX control bits */
- zs_write_reg(cs, 10, reg[10]);
-
- /* char size, enable (RX/TX) */
- zs_write_reg(cs, 3, reg[3] & ~ZSWR3_RX_ENABLE);
- zs_write_reg(cs, 5, reg[5] & ~ZSWR5_TX_ENABLE);
-
- /* synchronous mode stuff */
- zs_write_reg(cs, 6, reg[6]);
- if (reg[15] & ZSWR15_ENABLE_ENHANCED)
- zs_write_reg(cs, 15, 0);
- zs_write_reg(cs, 7, reg[7]);
-
-#if 0
- /*
- * Registers 2 and 9 are special because they are
- * actually common to both channels, but must be
- * programmed through channel A. The "zsc" attach
- * function takes care of setting these registers
- * and they should not be touched thereafter.
- */
- /* interrupt vector */
- zs_write_reg(cs, 2, reg[2]);
- /* master interrupt control */
- zs_write_reg(cs, 9, reg[9]);
-#endif
-
- /* Shut down the BRG */
- zs_write_reg(cs, 14, reg[14] & ~ZSWR14_BAUD_ENA);
-
-#ifdef ZS_MD_SETCLK
- /* Let the MD code setup any external clock. */
- ZS_MD_SETCLK(cs);
-#endif /* ZS_MD_SETCLK */
-
- /* clock mode control */
- zs_write_reg(cs, 11, reg[11]);
-
- /* baud rate (lo/hi) */
- zs_write_reg(cs, 12, reg[12]);
- zs_write_reg(cs, 13, reg[13]);
-
- /* Misc. control bits */
- zs_write_reg(cs, 14, reg[14]);
-
- /* which lines cause status interrupts */
- zs_write_reg(cs, 15, reg[15]);
-
- /*
- * Zilog docs recommend resetting external status twice at this
- * point. Mainly as the status bits are latched, and the first
- * interrupt clear might unlatch them to new values, generating
- * a second interrupt request.
- */
- zs_write_csr(cs, ZSM_RESET_STINT);
- zs_write_csr(cs, ZSM_RESET_STINT);
-
- /* char size, enable (RX/TX)*/
- zs_write_reg(cs, 3, reg[3]);
- zs_write_reg(cs, 5, reg[5]);
-
- /* Write the status bits on the alternate channel also. */
- if (cs->cs_ctl_chan != NULL) {
- v = cs->cs_ctl_chan->cs_preg[5];
- cs->cs_ctl_chan->cs_creg[5] = v;
- zs_write_reg(cs->cs_ctl_chan, 5, v);
- }
-
- /* Register 7' if applicable */
- if (reg[15] & ZSWR15_ENABLE_ENHANCED)
- zs_write_reg(cs, 7, reg[16]);
-
- /* interrupt enables: RX, TX, STATUS */
- zs_write_reg(cs, 1, reg[1]);
-}
-
-/*
- * ZS hardware interrupt. Scan all ZS channels. NB: we know here that
- * channels are kept in (A,B) pairs.
- *
- * Do just a little, then get out; set a software interrupt if more
- * work is needed.
- *
- * We deliberately ignore the vectoring Zilog gives us, and match up
- * only the number of `reset interrupt under service' operations, not
- * the order.
- */
-int
-zsc_intr_hard(void *arg)
-{
- struct zsc_softc *zsc = arg;
- struct zs_chanstate *cs0, *cs1;
- int handled;
- uint8_t rr3;
-
- handled = 0;
-
- /* First look at channel A. */
- cs0 = zsc->zsc_cs[0];
- cs1 = zsc->zsc_cs[1];
-
- /*
- * We have to clear interrupt first to avoid a race condition,
- * but it will be done in each MD handler.
- */
- for (;;) {
- /* Note: only channel A has an RR3 */
- rr3 = zs_read_reg(cs0, 3);
-
- if ((rr3 & (ZSRR3_IP_A_RX | ZSRR3_IP_A_TX | ZSRR3_IP_A_STAT |
- ZSRR3_IP_B_RX | ZSRR3_IP_B_TX | ZSRR3_IP_B_STAT)) == 0) {
- break;
- }
- handled = 1;
-
- /* First look at channel A. */
- if (rr3 & (ZSRR3_IP_A_RX | ZSRR3_IP_A_TX | ZSRR3_IP_A_STAT))
- zs_write_csr(cs0, ZSWR0_CLR_INTR);
-
- if (rr3 & ZSRR3_IP_A_RX)
- (*cs0->cs_ops->zsop_rxint)(cs0);
- if (rr3 & ZSRR3_IP_A_STAT)
- (*cs0->cs_ops->zsop_stint)(cs0, 0);
- if (rr3 & ZSRR3_IP_A_TX)
- (*cs0->cs_ops->zsop_txint)(cs0);
-
- /* Now look at channel B. */
- if (rr3 & (ZSRR3_IP_B_RX | ZSRR3_IP_B_TX | ZSRR3_IP_B_STAT))
- zs_write_csr(cs1, ZSWR0_CLR_INTR);
-
- if (rr3 & ZSRR3_IP_B_RX)
- (*cs1->cs_ops->zsop_rxint)(cs1);
- if (rr3 & ZSRR3_IP_B_STAT)
- (*cs1->cs_ops->zsop_stint)(cs1, 0);
- if (rr3 & ZSRR3_IP_B_TX)
- (*cs1->cs_ops->zsop_txint)(cs1);
- }
-
- /* Note: caller will check cs_x->cs_softreq and DTRT. */
- return handled;
-}
-
-
-/*
- * ZS software interrupt. Scan all channels for deferred interrupts.
- */
-int
-zsc_intr_soft(void *arg)
-{
- struct zsc_softc *zsc = arg;
- struct zs_chanstate *cs;
- int rval, chan;
-
- rval = 0;
- for (chan = 0; chan < 2; chan++) {
- cs = zsc->zsc_cs[chan];
-
- /*
- * The softint flag can be safely cleared once
- * we have decided to call the softint routine.
- * (No need to do splzs() first.)
- */
- if (cs->cs_softreq) {
- cs->cs_softreq = 0;
- (*cs->cs_ops->zsop_softint)(cs);
- rval++;
- }
- }
- return (rval);
-}
-
-/*
- * Provide a null zs "ops" vector.
- */
-
-static void zsnull_rxint (struct zs_chanstate *);
-static void zsnull_stint (struct zs_chanstate *, int);
-static void zsnull_txint (struct zs_chanstate *);
-static void zsnull_softint(struct zs_chanstate *);
-
-static void
-zsnull_rxint(struct zs_chanstate *cs)
-{
-
- /* Ask for softint() call. */
- cs->cs_softreq = 1;
-}
-
-static void
-zsnull_stint(struct zs_chanstate *cs, int force)
-{
-
- /* Ask for softint() call. */
- cs->cs_softreq = 1;
-}
-
-static void
-zsnull_txint(struct zs_chanstate *cs)
-{
-
- /* Ask for softint() call. */
- cs->cs_softreq = 1;
-}
-
-static void
-zsnull_softint(struct zs_chanstate *cs)
-{
-
- zs_write_reg(cs, 1, 0);
- zs_write_reg(cs, 15, 0);
-}
-
-struct zsops zsops_null = {
- zsnull_rxint, /* receive char available */
- zsnull_stint, /* external/status */
- zsnull_txint, /* xmit buffer empty */
- zsnull_softint, /* process software interrupt */
-};
diff --git a/sys/arch/sgi/hpc/z8530sc.h b/sys/arch/sgi/hpc/z8530sc.h
deleted file mode 100644
index 8a99b1869e3..00000000000
--- a/sys/arch/sgi/hpc/z8530sc.h
+++ /dev/null
@@ -1,199 +0,0 @@
-/* $OpenBSD: z8530sc.h,v 1.2 2012/04/29 09:01:38 miod Exp $ */
-/* $NetBSD: z8530sc.h,v 1.26 2009/05/22 03:51:30 mrg Exp $ */
-
-/*
- * Copyright (c) 1992, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * This software was developed by the Computer Systems Engineering group
- * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
- * contributed to Berkeley.
- *
- * All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Lawrence Berkeley Laboratory.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)zsvar.h 8.1 (Berkeley) 6/11/93
- */
-
-/*
- * Copyright (c) 1994 Gordon W. Ross
- *
- * This software was developed by the Computer Systems Engineering group
- * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
- * contributed to Berkeley.
- *
- * All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Lawrence Berkeley Laboratory.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)zsvar.h 8.1 (Berkeley) 6/11/93
- */
-
-/*
- * Function vector - per channel
- */
-struct zs_chanstate;
-struct zsops {
- void (*zsop_rxint)(struct zs_chanstate *);
- /* receive char available */
- void (*zsop_stint)(struct zs_chanstate *, int);
- /* external/status */
- void (*zsop_txint)(struct zs_chanstate *);
- /* xmit buffer empty */
- void (*zsop_softint)(struct zs_chanstate *);
- /* process software interrupt */
-};
-
-extern struct zsops zsops_null;
-
-
-/*
- * Software state, per zs channel.
- */
-struct zs_chanstate {
-
- /* Pointers to the device registers. */
- volatile uint8_t *cs_reg_csr; /* ctrl, status, and reg. number. */
- volatile uint8_t *cs_reg_data; /* data or numbered register */
-
- int cs_channel; /* sub-unit number */
- void *cs_private; /* sub-driver data pointer */
- struct zsops *cs_ops;
-
- int cs_brg_clk; /* BAUD Rate Generator clock
- * (usually PCLK / 16) */
- int cs_defspeed; /* default baud rate */
- int cs_defcflag; /* default cflag */
-
- /*
- * We must keep a copy of the write registers as they are
- * mostly write-only and we sometimes need to set and clear
- * individual bits (e.g., in WR3). Not all of these are
- * needed but 16 bytes is cheap and this makes the addressing
- * simpler. Unfortunately, we can only write to some registers
- * when the chip is not actually transmitting, so whenever
- * we are expecting a `transmit done' interrupt the preg array
- * is allowed to `get ahead' of the current values. In a
- * few places we must change the current value of a register,
- * rather than (or in addition to) the pending value; for these
- * cs_creg[] contains the current value.
- */
- uint8_t cs_creg[17]; /* current values */
- uint8_t cs_preg[17]; /* pending values */
- int cs_heldchange; /* change pending (creg != preg) */
-
- uint8_t cs_rr0; /* last rr0 processed */
- uint8_t cs_rr0_delta; /* rr0 changes at status intr. */
- uint8_t cs_rr0_mask; /* rr0 bits that stop output */
- uint8_t cs_rr0_dcd; /* which bit to read as DCD */
- uint8_t cs_rr0_cts; /* which bit to read as CTS */
- uint8_t cs_rr0_pps; /* which bit to use for PPS */
- /* the above is set only while CRTSCTS is enabled. */
-
- uint8_t cs_wr5_dtr; /* which bit to write as DTR */
- uint8_t cs_wr5_rts; /* which bit to write as RTS */
- /* the above is set only while CRTSCTS is enabled. */
-
- volatile uint8_t cs_softreq; /* need soft interrupt call */
- char cs_cua; /* CUA mode flag */
-
- /*
- * For strange systems that have oddly wired serial ports, we
- * provide a pointer to the channel state of the port that has
- * our status lines on it.
- */
- struct zs_chanstate *cs_ctl_chan;
-
- /* power management hooks */
- int (*enable)(struct zs_chanstate *);
- void (*disable)(struct zs_chanstate *);
- int enabled;
-
- /* MD code might define a larger variant of this. */
-};
-
-struct consdev;
-struct zsc_attach_args {
- int channel; /* two serial channels per zsc */
- int hwflags; /* see definitions below */
- /* `consdev' is only valid if ZS_HWFLAG_USE_CONSDEV is set */
- struct consdev *consdev;
-};
-
-/* In case of split console devices, use these: */
-#define ZS_HWFLAG_CONSOLE_INPUT 1
-#define ZS_HWFLAG_CONSOLE_OUTPUT 2
-#define ZS_HWFLAG_CONSOLE \
- (ZS_HWFLAG_CONSOLE_INPUT | ZS_HWFLAG_CONSOLE_OUTPUT)
-#define ZS_HWFLAG_NO_DCD 4 /* Ignore the DCD bit */
-#define ZS_HWFLAG_NO_CTS 8 /* Ignore the CTS bit */
-#define ZS_HWFLAG_RAW 16 /* advise raw mode */
-#define ZS_HWFLAG_USE_CONSDEV 32 /* Use console ops from `consdev' */
-#define ZS_HWFLAG_NORESET 64 /* Don't reset at attach time */
-
-extern int zs_major;
-
-int zsc_intr_soft(void *);
-int zsc_intr_hard(void *);
-
-void zs_abort(struct zs_chanstate *);
-void zs_break(struct zs_chanstate *, int);
-void zs_iflush(struct zs_chanstate *);
-void zs_loadchannelregs(struct zs_chanstate *);
-int zs_set_speed(struct zs_chanstate *, int);
-int zs_set_modes(struct zs_chanstate *, int);
diff --git a/sys/arch/sgi/hpc/z8530tty.c b/sys/arch/sgi/hpc/z8530tty.c
deleted file mode 100644
index 21e82209a0b..00000000000
--- a/sys/arch/sgi/hpc/z8530tty.c
+++ /dev/null
@@ -1,1682 +0,0 @@
-/* $OpenBSD: z8530tty.c,v 1.3 2012/04/29 09:01:38 miod Exp $ */
-/* $NetBSD: z8530tty.c,v 1.128 2011/04/24 16:27:00 rmind Exp $ */
-
-/*-
- * Copyright (c) 1993, 1994, 1995, 1996, 1997, 1998, 1999
- * Charles M. Hannum. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Charles M. Hannum.
- * 4. The name of the author may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * Copyright (c) 1992, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * This software was developed by the Computer Systems Engineering group
- * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
- * contributed to Berkeley.
- *
- * All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Lawrence Berkeley Laboratory.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)zs.c 8.1 (Berkeley) 7/19/93
- */
-
-/*
- * Copyright (c) 1994 Gordon W. Ross
- *
- * This software was developed by the Computer Systems Engineering group
- * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
- * contributed to Berkeley.
- *
- * All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Lawrence Berkeley Laboratory.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)zs.c 8.1 (Berkeley) 7/19/93
- */
-
-/*
- * Zilog Z8530 Dual UART driver (tty interface)
- *
- * This is the "slave" driver that will be attached to
- * the "zsc" driver for plain "tty" async. serial lines.
- *
- * Credits, history:
- *
- * The original version of this code was the sparc/dev/zs.c driver
- * as distributed with the Berkeley 4.4 Lite release. Since then,
- * Gordon Ross reorganized the code into the current parent/child
- * driver scheme, separating the Sun keyboard and mouse support
- * into independent child drivers.
- *
- * RTS/CTS flow-control support was a collaboration of:
- * Gordon Ross <gwr@NetBSD.org>,
- * Bill Studenmund <wrstuden@loki.stanford.edu>
- * Ian Dall <Ian.Dall@dsto.defence.gov.au>
- *
- * The driver was massively overhauled in November 1997 by Charles Hannum,
- * fixing *many* bugs, and substantially improving performance.
- */
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/proc.h>
-#include <sys/device.h>
-#include <sys/conf.h>
-#include <sys/file.h>
-#include <sys/ioctl.h>
-#include <sys/malloc.h>
-#include <sys/tty.h>
-#include <sys/time.h>
-#include <sys/kernel.h>
-#include <sys/syslog.h>
-
-#include <dev/ic/z8530reg.h>
-#include <machine/z8530var.h>
-
-#include <dev/cons.h>
-
-/*
- * How many input characters we can buffer.
- * The port-specific var.h may override this.
- * Note: must be a power of two!
- */
-#ifndef ZSTTY_RING_SIZE
-#define ZSTTY_RING_SIZE 2048
-#endif
-
-struct cfdriver zstty_cd = {
- NULL, "zstty", DV_TTY
-};
-
-/*
- * Make this an option variable one can patch.
- * But be warned: this must be a power of 2!
- */
-u_int zstty_rbuf_size = ZSTTY_RING_SIZE;
-
-/* Stop input when 3/4 of the ring is full; restart when only 1/4 is full. */
-u_int zstty_rbuf_hiwat = (ZSTTY_RING_SIZE * 1) / 4;
-u_int zstty_rbuf_lowat = (ZSTTY_RING_SIZE * 3) / 4;
-
-struct zstty_softc {
- struct device zst_dev; /* required first: base device */
- struct tty *zst_tty;
- struct zs_chanstate *zst_cs;
-
- struct timeout zst_diag_ch;
-
- u_int zst_overflows,
- zst_floods,
- zst_errors;
-
- int zst_hwflags, /* see z8530var.h */
- zst_swflags; /* TIOCFLAG_SOFTCAR, ... <ttycom.h> */
-
- u_int zst_r_hiwat,
- zst_r_lowat;
- uint8_t *volatile zst_rbget,
- *volatile zst_rbput;
- volatile u_int zst_rbavail;
- uint8_t *zst_rbuf,
- *zst_ebuf;
-
- /*
- * The transmit byte count and address are used for pseudo-DMA
- * output in the hardware interrupt code. PDMA can be suspended
- * to get pending changes done; heldtbc is used for this. It can
- * also be stopped for ^S; this sets TS_TTSTOP in tp->t_state.
- */
- uint8_t *zst_tba; /* transmit buffer address */
- u_int zst_tbc, /* transmit byte count */
- zst_heldtbc; /* held tbc while xmission stopped */
-
- /* Flags to communicate with zstty_softint() */
- volatile uint8_t zst_rx_flags, /* receiver blocked */
-#define RX_TTY_BLOCKED 0x01
-#define RX_TTY_OVERFLOWED 0x02
-#define RX_IBUF_BLOCKED 0x04
-#define RX_IBUF_OVERFLOWED 0x08
-#define RX_ANY_BLOCK 0x0f
- zst_tx_busy, /* working on an output chunk */
- zst_tx_done, /* done with one output chunk */
- zst_tx_stopped, /* H/W level stop (lost CTS) */
- zst_st_check, /* got a status interrupt */
- zst_rx_ready;
-
- /* PPS signal on DCD, with or without inkernel clock disciplining */
- uint8_t zst_ppsmask; /* pps signal mask */
- uint8_t zst_ppsassert; /* pps leading edge */
- uint8_t zst_ppsclear; /* pps trailing edge */
-};
-
-/* Definition of the driver for autoconfig. */
-int zstty_match(struct device *, void *, void *);
-void zstty_attach(struct device *, struct device *, void *);
-
-const struct cfattach zstty_ca = {
- sizeof(struct zstty_softc), zstty_match, zstty_attach
-};
-
-cdev_decl(zs);
-
-struct zsops zsops_tty;
-
-void zs_shutdown(struct zstty_softc *);
-void zsstart(struct tty *);
-int zsparam(struct tty *, struct termios *);
-void zs_modem(struct zstty_softc *, int);
-void tiocm_to_zs(struct zstty_softc *, u_long, int);
-int zs_to_tiocm(struct zstty_softc *);
-int zshwiflow(struct tty *, int);
-void zs_hwiflow(struct zstty_softc *);
-void zs_maskintr(struct zstty_softc *);
-
-struct zstty_softc *zs_device_lookup(struct cfdriver *, int);
-
-/* Low-level routines. */
-void zstty_rxint (struct zs_chanstate *);
-void zstty_stint (struct zs_chanstate *, int);
-void zstty_txint (struct zs_chanstate *);
-void zstty_softint(struct zs_chanstate *);
-void zstty_diag(void *);
-
-#define ZSUNIT(x) (minor(x) & 0x7f)
-#define ZSDIALOUT(x) (minor(x) & 0x80)
-
-struct zstty_softc *
-zs_device_lookup(struct cfdriver *cf, int unit)
-{
- return (struct zstty_softc *)device_lookup(cf, unit);
-}
-
-/*
- * zstty_match: how is this zs channel configured?
- */
-int
-zstty_match(struct device *parent, void *vcf, void *aux)
-{
- struct cfdata *cf = vcf;
- struct zsc_attach_args *args = aux;
-
- /* Exact match is better than wildcard. */
- if (cf->cf_loc[0] == args->channel)
- return 2;
-
- /* This driver accepts wildcard. */
- if (cf->cf_loc[0] == -1)
- return 1;
-
- return 0;
-}
-
-void
-zstty_attach(struct device *parent, struct device *self, void *aux)
-{
- struct zsc_softc *zsc = (struct zsc_softc *)parent;
- struct zstty_softc *zst = (struct zstty_softc *)self;
- struct cfdata *cf = self->dv_cfdata;
- struct zsc_attach_args *args = aux;
- struct zs_chanstate *cs;
- struct tty *tp;
- int channel, s, tty_unit;
- dev_t dev;
- const char *i, *o;
- int dtr_on;
- int resetbit;
-
- timeout_set(&zst->zst_diag_ch, zstty_diag, zst);
-
- tty_unit = zst->zst_dev.dv_unit;
- channel = args->channel;
- cs = zsc->zsc_cs[channel];
- cs->cs_private = zst;
- cs->cs_ops = &zsops_tty;
-
- zst->zst_cs = cs;
- zst->zst_swflags = cf->cf_flags; /* softcar, etc. */
- zst->zst_hwflags = args->hwflags;
- dev = makedev(zs_major, tty_unit);
-
- if (zst->zst_swflags)
- printf(" flags 0x%x", zst->zst_swflags);
-
- /*
- * Check whether we serve as a console device.
- * XXX - split console input/output channels aren't
- * supported yet on /dev/console
- */
- i = o = NULL;
- if ((zst->zst_hwflags & ZS_HWFLAG_CONSOLE_INPUT) != 0) {
- i = " input";
- if ((args->hwflags & ZS_HWFLAG_USE_CONSDEV) != 0) {
- args->consdev->cn_dev = dev;
- cn_tab->cn_pollc = args->consdev->cn_pollc;
- cn_tab->cn_getc = args->consdev->cn_getc;
- }
- cn_tab->cn_dev = dev;
- }
- if ((zst->zst_hwflags & ZS_HWFLAG_CONSOLE_OUTPUT) != 0) {
- o = " output";
- if ((args->hwflags & ZS_HWFLAG_USE_CONSDEV) != 0) {
- cn_tab->cn_putc = args->consdev->cn_putc;
- }
- cn_tab->cn_dev = dev;
- }
- if (i != NULL || o != NULL)
- printf(": console%s", i ? (o ? "" : i) : o);
-
-#ifdef KGDB
- if (zs_check_kgdb(cs, dev)) {
- /*
- * Allow kgdb to "take over" this port. Returns true
- * if this serial port is in-use by kgdb.
- */
- printf(" (kgdb)\n");
- /*
- * This is the kgdb port (exclusive use)
- * so skip the normal attach code.
- */
- return;
- }
-#endif
-
- printf("\n");
-
- tp = ttymalloc(0);
- tp->t_dev = dev;
- tp->t_oproc = zsstart;
- tp->t_param = zsparam;
- tp->t_hwiflow = zshwiflow;
-
- zst->zst_tty = tp;
- zst->zst_rbuf = malloc(zstty_rbuf_size << 1, M_DEVBUF, M_WAITOK);
- zst->zst_ebuf = zst->zst_rbuf + (zstty_rbuf_size << 1);
- /* Disable the high water mark. */
- zst->zst_r_hiwat = 0;
- zst->zst_r_lowat = 0;
- zst->zst_rbget = zst->zst_rbput = zst->zst_rbuf;
- zst->zst_rbavail = zstty_rbuf_size;
-
- /* if there are no enable/disable functions, assume the device
- is always enabled */
- if (!cs->enable)
- cs->enabled = 1;
-
- /*
- * Hardware init
- */
- dtr_on = 0;
- resetbit = 0;
- if (ISSET(zst->zst_hwflags, ZS_HWFLAG_CONSOLE)) {
- /* Call zsparam similar to open. */
- struct termios t;
-
- /* Wait a while for previous console output to complete */
- DELAY(10000);
-
- /* Setup the "new" parameters in t. */
- t.c_ispeed = 0;
- t.c_ospeed = cs->cs_defspeed;
- t.c_cflag = cs->cs_defcflag;
-
- s = splzs();
-
- /*
- * Turn on receiver and status interrupts.
- * We defer the actual write of the register to zsparam(),
- * but we must make sure status interrupts are turned on by
- * the time zsparam() reads the initial rr0 state.
- */
- SET(cs->cs_preg[1], ZSWR1_RIE | ZSWR1_TIE | ZSWR1_SIE);
-
- splx(s);
-
- /* Make sure zsparam will see changes. */
- tp->t_ospeed = 0;
- (void)zsparam(tp, &t);
-
- /* Make sure DTR is on now. */
- dtr_on = 1;
- } else if (!ISSET(zst->zst_hwflags, ZS_HWFLAG_NORESET)) {
- /* Not the console; may need reset. */
- resetbit = (channel == 0) ? ZSWR9_A_RESET : ZSWR9_B_RESET;
- }
-
- s = splzs();
- if (resetbit)
- zs_write_reg(cs, 9, resetbit);
- zs_modem(zst, dtr_on);
- splx(s);
-}
-
-
-/*
- * Return pointer to our tty.
- */
-struct tty *
-zstty(dev_t dev)
-{
- struct zstty_softc *zst = zs_device_lookup(&zstty_cd, ZSUNIT(dev));
-
- return (zst->zst_tty);
-}
-
-
-void
-zs_shutdown(struct zstty_softc *zst)
-{
- struct zs_chanstate *cs = zst->zst_cs;
- struct tty *tp = zst->zst_tty;
- int s;
-
- s = splzs();
-
- /* If we were asserting flow control, then deassert it. */
- SET(zst->zst_rx_flags, RX_IBUF_BLOCKED);
- zs_hwiflow(zst);
-
- /* Clear any break condition set with TIOCSBRK. */
- zs_break(cs, 0);
-
- /* Turn off PPS capture on last close. */
- zst->zst_ppsmask = 0;
-
- /*
- * Hang up if necessary. Wait a bit, so the other side has time to
- * notice even if we immediately open the port again.
- */
- if (ISSET(tp->t_cflag, HUPCL) || ISSET(tp->t_state, TS_WOPEN)) {
- zs_modem(zst, 0);
- /* hold low for 1 second */
- (void)tsleep(cs, TTIPRI, ttclos, hz);
- }
-
- /* Turn off interrupts if not the console. */
- if (!ISSET(zst->zst_hwflags, ZS_HWFLAG_CONSOLE)) {
- CLR(cs->cs_preg[1], ZSWR1_RIE | ZSWR1_TIE | ZSWR1_SIE);
- cs->cs_creg[1] = cs->cs_preg[1];
- zs_write_reg(cs, 1, cs->cs_creg[1]);
- }
-
- /* Call the power management hook. */
- if (cs->disable) {
-#ifdef DIAGNOSTIC
- if (!cs->enabled)
- panic("%s: not enabled?", __func__);
-#endif
- (*cs->disable)(zst->zst_cs);
- }
-
- splx(s);
-}
-
-/*
- * Open a zs serial (tty) port.
- */
-int
-zsopen(dev_t dev, int flags, int mode, struct proc *p)
-{
- struct zstty_softc *zst;
- struct zs_chanstate *cs;
- struct tty *tp;
- int s;
-#if IPL_ZS != IPL_TTY
- int s2;
-#endif
- int error;
-
- zst = zs_device_lookup(&zstty_cd, ZSUNIT(dev));
- if (zst == NULL)
- return (ENXIO);
-
- tp = zst->zst_tty;
- cs = zst->zst_cs;
-
- /* If KGDB took the line, then tp==NULL */
- if (tp == NULL)
- return (EBUSY);
-
- if (ISSET(tp->t_state, TS_ISOPEN) &&
- ISSET(tp->t_state, TS_XCLUDE) &&
- suser(p, 0) != 0)
- return (EBUSY);
-
- s = spltty();
-
- /*
- * Do the following iff this is a first open.
- */
- if (!ISSET(tp->t_state, TS_ISOPEN)) {
- struct termios t;
-
- tp->t_dev = dev;
-
- /* Call the power management hook. */
- if (cs->enable) {
- if ((*cs->enable)(cs)) {
- splx(s);
- printf("%s: device enable failed\n",
- zst->zst_dev.dv_xname);
- return (EIO);
- }
- }
-
- /*
- * Initialize the termios status to the defaults. Add in the
- * sticky bits from TIOCSFLAGS.
- */
- t.c_ispeed = 0;
- t.c_ospeed = cs->cs_defspeed;
- t.c_cflag = cs->cs_defcflag;
- if (ISSET(zst->zst_swflags, TIOCFLAG_CLOCAL))
- SET(t.c_cflag, CLOCAL);
- if (ISSET(zst->zst_swflags, TIOCFLAG_CRTSCTS))
- SET(t.c_cflag, CRTSCTS);
- if (ISSET(zst->zst_swflags, TIOCFLAG_MDMBUF))
- SET(t.c_cflag, MDMBUF);
-
-#if IPL_ZS != IPL_TTY
- s2 = splzs();
-#endif
-
- /*
- * Turn on receiver and status interrupts.
- * We defer the actual write of the register to zsparam(),
- * but we must make sure status interrupts are turned on by
- * the time zsparam() reads the initial rr0 state.
- */
- SET(cs->cs_preg[1], ZSWR1_RIE | ZSWR1_TIE | ZSWR1_SIE);
-
- /* Clear PPS capture state on first open. */
- zst->zst_ppsmask = 0;
-
-#if IPL_ZS != IPL_TTY
- splx(s2);
-#endif
-
- /* Make sure zsparam will see changes. */
- tp->t_ospeed = 0;
- (void)zsparam(tp, &t);
-
- /*
- * Note: zsparam has done: cflag, ispeed, ospeed
- * so we just need to do: iflag, oflag, lflag, cc
- * For "raw" mode, just leave all zeros.
- */
- if (!ISSET(zst->zst_hwflags, ZS_HWFLAG_RAW)) {
- tp->t_iflag = TTYDEF_IFLAG;
- tp->t_oflag = TTYDEF_OFLAG;
- tp->t_lflag = TTYDEF_LFLAG;
- } else {
- tp->t_iflag = 0;
- tp->t_oflag = 0;
- tp->t_lflag = 0;
- }
- ttychars(tp);
- ttsetwater(tp);
-
- if (ZSDIALOUT(dev))
- SET(tp->t_state, TS_CARR_ON);
- else
- CLR(tp->t_state, TS_CARR_ON);
-
-#if IPL_ZS != IPL_TTY
- s2 = splzs();
-#endif
-
- /* Clear the input ring, and unblock. */
- zst->zst_rbget = zst->zst_rbput = zst->zst_rbuf;
- zst->zst_rbavail = zstty_rbuf_size;
- zs_iflush(cs);
- CLR(zst->zst_rx_flags, RX_ANY_BLOCK);
- zs_hwiflow(zst);
-
-#if IPL_ZS != IPL_TTY
- splx(s2);
-#endif
- }
-
- if (ZSDIALOUT(dev)) {
- if (ISSET(tp->t_state, TS_ISOPEN)) {
- /* someone already is dialed in... */
- splx(s);
- return EBUSY;
- }
- cs->cs_cua = 1;
- }
-
- error = 0;
- /* wait for carrier if necessary */
- if (ISSET(flags, O_NONBLOCK)) {
- if (!ZSDIALOUT(dev) && cs->cs_cua) {
- /* Opening TTY non-blocking... but the CUA is busy */
- error = EBUSY;
- }
- } else
- while (cs->cs_cua ||
- (!ISSET(tp->t_cflag, CLOCAL) && !ISSET(tp->t_state, TS_CARR_ON))) {
- int rr0;
-
- error = 0;
- SET(tp->t_state, TS_WOPEN);
-
- if (!ZSDIALOUT(dev) && !cs->cs_cua) {
- /*
- * Turn on DTR. We must always do this on non-CUA
- * devices, even if carrier is not present, because
- * otherwise we'd have to use TIOCSDTR immediately
- * after setting CLOCAL, which applications do not
- * expect. We always assert DTR while the device is
- * open unless explicitly requested to deassert it.
- */
-#if IPL_ZS != IPL_TTY
- s2 = splzs();
-#endif
- zs_modem(zst, 1);
- rr0 = zs_read_csr(cs);
-#if IPL_ZS != IPL_TTY
- splx(s2);
-#endif
-
- /* loop, turning on the device, until carrier present */
- if (ISSET(rr0, ZSRR0_DCD) ||
- ISSET(zst->zst_swflags, TIOCFLAG_SOFTCAR))
- SET(tp->t_state, TS_CARR_ON);
- }
-
- if ((ISSET(tp->t_cflag, CLOCAL) ||
- ISSET(tp->t_state, TS_CARR_ON)) && !cs->cs_cua)
- break;
-
- error = ttysleep(tp, (caddr_t)&tp->t_rawq, TTIPRI | PCATCH,
- ttopen, 0);
-
- if (!ZSDIALOUT(dev) && cs->cs_cua && error == EINTR) {
- error = 0;
- continue;
- }
-
- if (error) {
- if (!ISSET(tp->t_state, TS_ISOPEN)) {
-#if IPL_ZS != IPL_TTY
- s2 = splzs();
-#endif
- zs_modem(zst, 0);
-#if IPL_ZS != IPL_TTY
- splx(s2);
-#endif
- CLR(tp->t_state, TS_WOPEN);
- ttwakeup(tp);
- }
- if (ZSDIALOUT(dev))
- cs->cs_cua = 0;
- CLR(tp->t_state, TS_WOPEN);
- break;
- }
- if (!ZSDIALOUT(dev) && cs->cs_cua)
- continue;
- }
-
- splx(s);
-
- if (error == 0)
- error = ((*linesw[tp->t_line].l_open)(dev, tp, p));
- if (error)
- goto bad;
-
- return (0);
-
-bad:
- if (!ISSET(tp->t_state, TS_ISOPEN)) {
- /*
- * We failed to open the device, and nobody else had it opened.
- * Clean up the state as appropriate.
- */
- zs_shutdown(zst);
- }
-
- return (error);
-}
-
-/*
- * Close a zs serial port.
- */
-int
-zsclose(dev_t dev, int flags, int mode, struct proc *p)
-{
- struct zstty_softc *zst = zs_device_lookup(&zstty_cd, ZSUNIT(dev));
- struct zs_chanstate *cs = zst->zst_cs;
- struct tty *tp = zst->zst_tty;
- int s;
-
- /* XXX This is for cons.c. */
- if (!ISSET(tp->t_state, TS_ISOPEN))
- return 0;
-
- (*linesw[tp->t_line].l_close)(tp, flags, p);
-
- s = spltty();
- cs->cs_cua = 0;
- ttyclose(tp);
- splx(s);
-
- if (!ISSET(tp->t_state, TS_ISOPEN)) {
- /*
- * Although we got a last close, the device may still be in
- * use; e.g. if this was the dialout node, and there are still
- * processes waiting for carrier on the non-dialout node.
- */
- zs_shutdown(zst);
- }
-
- return (0);
-}
-
-/*
- * Read/write zs serial port.
- */
-int
-zsread(dev_t dev, struct uio *uio, int flags)
-{
- struct zstty_softc *zst = zs_device_lookup(&zstty_cd, ZSUNIT(dev));
- struct tty *tp = zst->zst_tty;
-
- return (*linesw[tp->t_line].l_read)(tp, uio, flags);
-}
-
-int
-zswrite(dev_t dev, struct uio *uio, int flags)
-{
- struct zstty_softc *zst = zs_device_lookup(&zstty_cd, ZSUNIT(dev));
- struct tty *tp = zst->zst_tty;
-
- return (*linesw[tp->t_line].l_write)(tp, uio, flags);
-}
-
-int
-zsioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
-{
- struct zstty_softc *zst = zs_device_lookup(&zstty_cd, ZSUNIT(dev));
- struct zs_chanstate *cs = zst->zst_cs;
- struct tty *tp = zst->zst_tty;
- int error;
- int s;
-
- error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag, p);
- if (error >= 0)
- return (error);
-
- error = ttioctl(tp, cmd, data, flag, p);
- if (error >= 0)
- return (error);
-
-#ifdef ZS_MD_IOCTL
- error = ZS_MD_IOCTL;
- if (error >= 0)
- return (error);
-#endif /* ZS_MD_IOCTL */
-
- error = 0;
-
- s = splzs();
-
- switch (cmd) {
- case TIOCSBRK:
- zs_break(cs, 1);
- break;
-
- case TIOCCBRK:
- zs_break(cs, 0);
- break;
-
- case TIOCGFLAGS:
- *(int *)data = zst->zst_swflags;
- break;
-
- case TIOCSFLAGS:
- error = suser(p, 0);
- if (error)
- break;
- zst->zst_swflags = *(int *)data;
- break;
-
- case TIOCSDTR:
- zs_modem(zst, 1);
- break;
-
- case TIOCCDTR:
- zs_modem(zst, 0);
- break;
-
- case TIOCMSET:
- case TIOCMBIS:
- case TIOCMBIC:
- tiocm_to_zs(zst, cmd, *(int *)data);
- break;
-
- case TIOCMGET:
- *(int *)data = zs_to_tiocm(zst);
- break;
-
- default:
- error = ENOTTY;
- break;
- }
-
- splx(s);
-
- return (error);
-}
-
-/*
- * Start or restart transmission.
- */
-void
-zsstart(struct tty *tp)
-{
- struct zstty_softc *zst = zs_device_lookup(&zstty_cd, ZSUNIT(tp->t_dev));
- struct zs_chanstate *cs = zst->zst_cs;
- u_char *tba;
- int tbc, rr0;
- int s;
-
- s = spltty();
- if (ISSET(tp->t_state, TS_BUSY | TS_TIMEOUT | TS_TTSTOP))
- goto out;
- if (zst->zst_tx_stopped)
- goto out;
-
- ttwakeupwr(tp);
- if (tp->t_outq.c_cc == 0)
- goto out;
-
- /* Grab the first contiguous region of buffer space. */
- tba = tp->t_outq.c_cf;
- tbc = ndqb(&tp->t_outq, 0);
-
-#if IPL_ZS != IPL_TTY
- (void)splzs();
-#endif
-
- zst->zst_tba = tba;
- zst->zst_tbc = tbc;
- SET(tp->t_state, TS_BUSY);
- zst->zst_tx_busy = 1;
-
- do {
- rr0 = zs_read_csr(cs);
- if ((rr0 & ZSRR0_TX_READY) == 0)
- break;
-
- zs_write_data(cs, *zst->zst_tba);
- zst->zst_tbc--;
- zst->zst_tba++;
- } while (zst->zst_tbc > 0);
-
-out:
- splx(s);
-}
-
-/*
- * Stop output, e.g., for ^S or output flush.
- */
-int
-zsstop(struct tty *tp, int flag)
-{
- struct zstty_softc *zst = zs_device_lookup(&zstty_cd, ZSUNIT(tp->t_dev));
- int s;
-
- s = splzs();
- if (ISSET(tp->t_state, TS_BUSY)) {
- /* Stop transmitting at the next chunk. */
- zst->zst_tbc = 0;
- zst->zst_heldtbc = 0;
- if (!ISSET(tp->t_state, TS_TTSTOP))
- SET(tp->t_state, TS_FLUSH);
- }
- splx(s);
- return 0;
-}
-
-/*
- * Set ZS tty parameters from termios.
- * XXX - Should just copy the whole termios after
- * making sure all the changes could be done.
- */
-int
-zsparam(struct tty *tp, struct termios *t)
-{
- struct zstty_softc *zst = zs_device_lookup(&zstty_cd, ZSUNIT(tp->t_dev));
- struct zs_chanstate *cs = zst->zst_cs;
- int ospeed;
- tcflag_t cflag;
- uint8_t tmp3, tmp4, tmp5;
- int s, error;
-
- ospeed = t->c_ospeed;
- cflag = t->c_cflag;
-
- /* Check requested parameters. */
- if (ospeed < 0)
- return (EINVAL);
- if (t->c_ispeed && t->c_ispeed != ospeed)
- return (EINVAL);
-
- /*
- * For the console, always force CLOCAL and !HUPCL, so that the port
- * is always active.
- */
- if (ISSET(zst->zst_swflags, TIOCFLAG_SOFTCAR) ||
- ISSET(zst->zst_hwflags, ZS_HWFLAG_CONSOLE)) {
- SET(cflag, CLOCAL);
- CLR(cflag, HUPCL);
- }
-
- /*
- * Only whack the UART when params change.
- * Some callers need to clear tp->t_ospeed
- * to make sure initialization gets done.
- */
- if (tp->t_ospeed == ospeed &&
- tp->t_cflag == cflag)
- return (0);
-
- /*
- * Call MD functions to deal with changed
- * clock modes or H/W flow control modes.
- * The BRG divisor is set now. (reg 12,13)
- */
- error = zs_set_speed(cs, ospeed);
- if (error)
- return (error);
- error = zs_set_modes(cs, cflag);
- if (error)
- return (error);
-
- /*
- * Block interrupts so that state will not
- * be altered until we are done setting it up.
- *
- * Initial values in cs_preg are set before
- * our attach routine is called. The master
- * interrupt enable is handled by zsc.c
- *
- */
- s = splzs();
-
- /*
- * Recalculate which status ints to enable.
- */
- zs_maskintr(zst);
-
- /* Recompute character size bits. */
- tmp3 = cs->cs_preg[3];
- tmp5 = cs->cs_preg[5];
- CLR(tmp3, ZSWR3_RXSIZE);
- CLR(tmp5, ZSWR5_TXSIZE);
- switch (ISSET(cflag, CSIZE)) {
- case CS5:
- SET(tmp3, ZSWR3_RX_5);
- SET(tmp5, ZSWR5_TX_5);
- break;
- case CS6:
- SET(tmp3, ZSWR3_RX_6);
- SET(tmp5, ZSWR5_TX_6);
- break;
- case CS7:
- SET(tmp3, ZSWR3_RX_7);
- SET(tmp5, ZSWR5_TX_7);
- break;
- case CS8:
- SET(tmp3, ZSWR3_RX_8);
- SET(tmp5, ZSWR5_TX_8);
- break;
- }
- cs->cs_preg[3] = tmp3;
- cs->cs_preg[5] = tmp5;
-
- /*
- * Recompute the stop bits and parity bits. Note that
- * zs_set_speed() may have set clock selection bits etc.
- * in wr4, so those must preserved.
- */
- tmp4 = cs->cs_preg[4];
- CLR(tmp4, ZSWR4_SBMASK | ZSWR4_PARMASK);
- if (ISSET(cflag, CSTOPB))
- SET(tmp4, ZSWR4_TWOSB);
- else
- SET(tmp4, ZSWR4_ONESB);
- if (!ISSET(cflag, PARODD))
- SET(tmp4, ZSWR4_EVENP);
- if (ISSET(cflag, PARENB))
- SET(tmp4, ZSWR4_PARENB);
- cs->cs_preg[4] = tmp4;
-
- /* And copy to tty. */
- tp->t_ispeed = 0;
- tp->t_ospeed = ospeed;
- tp->t_cflag = cflag;
-
- /*
- * If nothing is being transmitted, set up new current values,
- * else mark them as pending.
- */
- if (!cs->cs_heldchange) {
- if (zst->zst_tx_busy) {
- zst->zst_heldtbc = zst->zst_tbc;
- zst->zst_tbc = 0;
- cs->cs_heldchange = 1;
- } else
- zs_loadchannelregs(cs);
- }
-
- /*
- * If hardware flow control is disabled, turn off the buffer water
- * marks and unblock any soft flow control state. Otherwise, enable
- * the water marks.
- */
- if (!ISSET(cflag, CHWFLOW)) {
- zst->zst_r_hiwat = 0;
- zst->zst_r_lowat = 0;
- if (ISSET(zst->zst_rx_flags, RX_TTY_OVERFLOWED)) {
- CLR(zst->zst_rx_flags, RX_TTY_OVERFLOWED);
- zst->zst_rx_ready = 1;
- cs->cs_softreq = 1;
- }
- if (ISSET(zst->zst_rx_flags, RX_TTY_BLOCKED|RX_IBUF_BLOCKED)) {
- CLR(zst->zst_rx_flags, RX_TTY_BLOCKED|RX_IBUF_BLOCKED);
- zs_hwiflow(zst);
- }
- } else {
- zst->zst_r_hiwat = zstty_rbuf_hiwat;
- zst->zst_r_lowat = zstty_rbuf_lowat;
- }
-
- /*
- * Force a recheck of the hardware carrier and flow control status,
- * since we may have changed which bits we're looking at.
- */
- zstty_stint(cs, 1);
-
- splx(s);
-
- /*
- * If hardware flow control is disabled, unblock any hard flow control
- * state.
- */
- if (!ISSET(cflag, CHWFLOW)) {
- if (zst->zst_tx_stopped) {
- zst->zst_tx_stopped = 0;
- zsstart(tp);
- }
- }
-
- zstty_softint(cs);
-
- return (0);
-}
-
-/*
- * Compute interrupt enable bits and set in the pending bits. Called both
- * in zsparam() and when PPS (pulse per second timing) state changes.
- * Must be called at splzs().
- */
-void
-zs_maskintr(struct zstty_softc *zst)
-{
- struct zs_chanstate *cs = zst->zst_cs;
- uint8_t tmp15;
-
- cs->cs_rr0_mask = cs->cs_rr0_cts | cs->cs_rr0_dcd;
- if (zst->zst_ppsmask != 0)
- cs->cs_rr0_mask |= cs->cs_rr0_pps;
- tmp15 = cs->cs_preg[15];
- if (ISSET(cs->cs_rr0_mask, ZSRR0_DCD))
- SET(tmp15, ZSWR15_DCD_IE);
- else
- CLR(tmp15, ZSWR15_DCD_IE);
- if (ISSET(cs->cs_rr0_mask, ZSRR0_CTS))
- SET(tmp15, ZSWR15_CTS_IE);
- else
- CLR(tmp15, ZSWR15_CTS_IE);
- cs->cs_preg[15] = tmp15;
-}
-
-
-/*
- * Raise or lower modem control (DTR/RTS) signals. If a character is
- * in transmission, the change is deferred.
- * Called at splzs().
- */
-void
-zs_modem(struct zstty_softc *zst, int onoff)
-{
- struct zs_chanstate *cs = zst->zst_cs, *ccs;
-
- if (cs->cs_wr5_dtr == 0)
- return;
-
- ccs = (cs->cs_ctl_chan != NULL ? cs->cs_ctl_chan : cs);
-
- if (onoff)
- SET(ccs->cs_preg[5], cs->cs_wr5_dtr);
- else
- CLR(ccs->cs_preg[5], cs->cs_wr5_dtr);
-
- if (!cs->cs_heldchange) {
- if (zst->zst_tx_busy) {
- zst->zst_heldtbc = zst->zst_tbc;
- zst->zst_tbc = 0;
- cs->cs_heldchange = 1;
- } else
- zs_loadchannelregs(cs);
- }
-}
-
-/*
- * Set modem bits.
- * Called at splzs().
- */
-void
-tiocm_to_zs(struct zstty_softc *zst, u_long how, int ttybits)
-{
- struct zs_chanstate *cs = zst->zst_cs, *ccs;
- uint8_t zsbits;
-
- ccs = (cs->cs_ctl_chan != NULL ? cs->cs_ctl_chan : cs);
-
- zsbits = 0;
- if (ISSET(ttybits, TIOCM_DTR))
- SET(zsbits, ZSWR5_DTR);
- if (ISSET(ttybits, TIOCM_RTS))
- SET(zsbits, ZSWR5_RTS);
-
- switch (how) {
- case TIOCMBIC:
- CLR(ccs->cs_preg[5], zsbits);
- break;
-
- case TIOCMBIS:
- SET(ccs->cs_preg[5], zsbits);
- break;
-
- case TIOCMSET:
- CLR(ccs->cs_preg[5], ZSWR5_RTS | ZSWR5_DTR);
- SET(ccs->cs_preg[5], zsbits);
- break;
- }
-
- if (!cs->cs_heldchange) {
- if (zst->zst_tx_busy) {
- zst->zst_heldtbc = zst->zst_tbc;
- zst->zst_tbc = 0;
- cs->cs_heldchange = 1;
- } else
- zs_loadchannelregs(cs);
- }
-}
-
-/*
- * Get modem bits.
- * Called at splzs().
- */
-int
-zs_to_tiocm(struct zstty_softc *zst)
-{
- struct zs_chanstate *cs = zst->zst_cs, *ccs;
- uint8_t zsbits;
- int ttybits = 0;
-
- ccs = (cs->cs_ctl_chan != NULL ? cs->cs_ctl_chan : cs);
-
- zsbits = ccs->cs_preg[5];
- if (ISSET(zsbits, ZSWR5_DTR))
- SET(ttybits, TIOCM_DTR);
- if (ISSET(zsbits, ZSWR5_RTS))
- SET(ttybits, TIOCM_RTS);
-
- zsbits = cs->cs_rr0;
- if (ISSET(zsbits, ZSRR0_DCD))
- SET(ttybits, TIOCM_CD);
- if (ISSET(zsbits, ZSRR0_CTS))
- SET(ttybits, TIOCM_CTS);
-
- return (ttybits);
-}
-
-/*
- * Try to block or unblock input using hardware flow-control.
- * This is called by kern/tty.c if MDMBUF|CRTSCTS is set, and
- * if this function returns non-zero, the TS_TBLOCK flag will
- * be set or cleared according to the "block" arg passed.
- */
-int
-zshwiflow(struct tty *tp, int block)
-{
- struct zstty_softc *zst = zs_device_lookup(&zstty_cd, ZSUNIT(tp->t_dev));
- struct zs_chanstate *cs = zst->zst_cs;
- int s;
-
- if (cs->cs_wr5_rts == 0)
- return (0);
-
- s = splzs();
- if (block) {
- if (!ISSET(zst->zst_rx_flags, RX_TTY_BLOCKED)) {
- SET(zst->zst_rx_flags, RX_TTY_BLOCKED);
- zs_hwiflow(zst);
- }
- } else {
- if (ISSET(zst->zst_rx_flags, RX_TTY_OVERFLOWED)) {
- CLR(zst->zst_rx_flags, RX_TTY_OVERFLOWED);
- zst->zst_rx_ready = 1;
- cs->cs_softreq = 1;
- }
- if (ISSET(zst->zst_rx_flags, RX_TTY_BLOCKED)) {
- CLR(zst->zst_rx_flags, RX_TTY_BLOCKED);
- zs_hwiflow(zst);
- }
- }
- splx(s);
- return (1);
-}
-
-/*
- * Internal version of zshwiflow
- * Called at splzs()
- */
-void
-zs_hwiflow(struct zstty_softc *zst)
-{
- struct zs_chanstate *cs = zst->zst_cs, *ccs;
-
- if (cs->cs_wr5_rts == 0)
- return;
-
- ccs = (cs->cs_ctl_chan != NULL ? cs->cs_ctl_chan : cs);
-
- if (ISSET(zst->zst_rx_flags, RX_ANY_BLOCK)) {
- CLR(ccs->cs_preg[5], cs->cs_wr5_rts);
- CLR(ccs->cs_creg[5], cs->cs_wr5_rts);
- } else {
- SET(ccs->cs_preg[5], cs->cs_wr5_rts);
- SET(ccs->cs_creg[5], cs->cs_wr5_rts);
- }
- zs_write_reg(ccs, 5, ccs->cs_creg[5]);
-}
-
-
-/****************************************************************
- * Interface to the lower layer (zscc)
- ****************************************************************/
-
-#define integrate static inline
-integrate void zstty_rxsoft(struct zstty_softc *, struct tty *);
-integrate void zstty_txsoft(struct zstty_softc *, struct tty *);
-integrate void zstty_stsoft(struct zstty_softc *, struct tty *);
-void zstty_diag(void *);
-
-/*
- * Receiver Ready interrupt.
- * Called at splzs().
- */
-void
-zstty_rxint(struct zs_chanstate *cs)
-{
- struct zstty_softc *zst = cs->cs_private;
- uint8_t *put, *end;
- u_int cc;
- uint8_t rr0, rr1, c;
-
- end = zst->zst_ebuf;
- put = zst->zst_rbput;
- cc = zst->zst_rbavail;
-
- while (cc > 0) {
- /*
- * First read the status, because reading the received char
- * destroys the status of this char.
- */
- rr1 = zs_read_reg(cs, 1);
- c = zs_read_data(cs);
-
- if (ISSET(rr1, ZSRR1_FE | ZSRR1_DO | ZSRR1_PE)) {
- /* Clear the receive error. */
- zs_write_csr(cs, ZSWR0_RESET_ERRORS);
- }
-
- put[0] = c;
- put[1] = rr1;
- put += 2;
- if (put >= end)
- put = zst->zst_rbuf;
- cc--;
-
- rr0 = zs_read_csr(cs);
- if (!ISSET(rr0, ZSRR0_RX_READY))
- break;
- }
-
- /*
- * Current string of incoming characters ended because
- * no more data was available or we ran out of space.
- * Schedule a receive event if any data was received.
- * If we're out of space, turn off receive interrupts.
- */
- zst->zst_rbput = put;
- zst->zst_rbavail = cc;
- if (!ISSET(zst->zst_rx_flags, RX_TTY_OVERFLOWED)) {
- zst->zst_rx_ready = 1;
- cs->cs_softreq = 1;
- }
-
- /*
- * See if we are in danger of overflowing a buffer. If
- * so, use hardware flow control to ease the pressure.
- */
- if (!ISSET(zst->zst_rx_flags, RX_IBUF_BLOCKED) &&
- cc < zst->zst_r_hiwat) {
- SET(zst->zst_rx_flags, RX_IBUF_BLOCKED);
- zs_hwiflow(zst);
- }
-
- /*
- * If we're out of space, disable receive interrupts
- * until the queue has drained a bit.
- */
- if (!cc) {
- SET(zst->zst_rx_flags, RX_IBUF_OVERFLOWED);
- CLR(cs->cs_preg[1], ZSWR1_RIE);
- cs->cs_creg[1] = cs->cs_preg[1];
- zs_write_reg(cs, 1, cs->cs_creg[1]);
- }
-}
-
-/*
- * Transmitter Ready interrupt.
- * Called at splzs().
- */
-void
-zstty_txint(struct zs_chanstate *cs)
-{
- struct zstty_softc *zst = cs->cs_private;
- int rr0;
-
- zs_write_csr(cs, ZSWR0_RESET_TXINT);
-
- /*
- * If we've delayed a parameter change, do it now, and restart
- * output.
- */
- if (cs->cs_heldchange) {
- zs_loadchannelregs(cs);
- cs->cs_heldchange = 0;
- zst->zst_tbc = zst->zst_heldtbc;
- zst->zst_heldtbc = 0;
- }
-
- while (zst->zst_tbc > 0) {
- rr0 = zs_read_csr(cs);
- if ((rr0 & ZSRR0_TX_READY) == 0)
- break;
-
- zs_write_data(cs, *zst->zst_tba);
- zst->zst_tbc--;
- zst->zst_tba++;
- }
-
- if (zst->zst_tbc == 0) {
- if (zst->zst_tx_busy) {
- zst->zst_tx_busy = 0;
- zst->zst_tx_done = 1;
- cs->cs_softreq = 1;
- }
- }
-}
-
-#ifdef DDB
-#include <ddb/db_var.h>
-#define DB_CONSOLE db_console
-#else
-#define DB_CONSOLE 0
-#endif
-
-/*
- * Status Change interrupt.
- * Called at splzs().
- */
-void
-zstty_stint(struct zs_chanstate *cs, int force)
-{
- struct zstty_softc *zst = cs->cs_private;
- struct tty *tp = zst->zst_tty;
- uint8_t rr0, delta;
-
- rr0 = zs_read_csr(cs);
- zs_write_csr(cs, ZSWR0_RESET_STATUS);
-
- /*
- * Check here for console break, so that we can abort
- * even when interrupts are locking up the machine.
- */
- if ((zst->zst_hwflags & ZS_HWFLAG_CONSOLE_INPUT) &&
- ISSET(rr0, ZSRR0_BREAK) && DB_CONSOLE)
- zs_abort(cs);
-
- if (!force)
- delta = rr0 ^ cs->cs_rr0;
- else
- delta = cs->cs_rr0_mask;
-
- ttytstamp(tp, cs->cs_rr0 & ZSRR0_CTS, rr0 & ZSRR0_CTS,
- cs->cs_rr0 & ZSRR0_DCD, rr0 & ZSRR0_DCD);
-
- cs->cs_rr0 = rr0;
-
- if (ISSET(delta, cs->cs_rr0_mask)) {
- SET(cs->cs_rr0_delta, delta);
-
- /*
- * Stop output immediately if we lose the output
- * flow control signal or carrier detect.
- */
- if (ISSET(~rr0, cs->cs_rr0_mask)) {
- zst->zst_tbc = 0;
- zst->zst_heldtbc = 0;
- }
-
- zst->zst_st_check = 1;
- cs->cs_softreq = 1;
- }
-}
-
-void
-zstty_diag(void *arg)
-{
- struct zstty_softc *zst = arg;
- int overflows, floods;
- int s;
-
- s = splzs();
- overflows = zst->zst_overflows;
- zst->zst_overflows = 0;
- floods = zst->zst_floods;
- zst->zst_floods = 0;
- zst->zst_errors = 0;
- splx(s);
-
- log(LOG_WARNING, "%s: %d silo overflow%s, %d ibuf flood%s\n",
- zst->zst_dev.dv_xname,
- overflows, overflows == 1 ? "" : "s",
- floods, floods == 1 ? "" : "s");
-}
-
-integrate void
-zstty_rxsoft(struct zstty_softc *zst, struct tty *tp)
-{
- struct zs_chanstate *cs = zst->zst_cs;
- int (*rint)(int, struct tty *) = linesw[tp->t_line].l_rint;
- uint8_t *get, *end;
- u_int cc, scc;
- uint8_t rr1;
- int code;
- int s;
-
- end = zst->zst_ebuf;
- get = zst->zst_rbget;
- scc = cc = zstty_rbuf_size - zst->zst_rbavail;
-
- if (cc == zstty_rbuf_size) {
- zst->zst_floods++;
- if (zst->zst_errors++ == 0)
- timeout_add_sec(&zst->zst_diag_ch, 60);
- }
-
- /* If not yet open, drop the entire buffer content here */
- if (!ISSET(tp->t_state, TS_ISOPEN)) {
- get += cc << 1;
- if (get >= end)
- get -= zstty_rbuf_size << 1;
- cc = 0;
- }
- while (cc) {
- code = get[0];
- rr1 = get[1];
- if (ISSET(rr1, ZSRR1_DO | ZSRR1_FE | ZSRR1_PE)) {
- if (ISSET(rr1, ZSRR1_DO)) {
- zst->zst_overflows++;
- if (zst->zst_errors++ == 0)
- timeout_add_sec(&zst->zst_diag_ch, 60);
- }
- if (ISSET(rr1, ZSRR1_FE))
- SET(code, TTY_FE);
- if (ISSET(rr1, ZSRR1_PE))
- SET(code, TTY_PE);
- }
- if ((*rint)(code, tp) == -1) {
- /*
- * The line discipline's buffer is out of space.
- */
- if (!ISSET(zst->zst_rx_flags, RX_TTY_BLOCKED)) {
- /*
- * We're either not using flow control, or the
- * line discipline didn't tell us to block for
- * some reason. Either way, we have no way to
- * know when there's more space available, so
- * just drop the rest of the data.
- */
- get += cc << 1;
- if (get >= end)
- get -= zstty_rbuf_size << 1;
- cc = 0;
- } else {
- /*
- * Don't schedule any more receive processing
- * until the line discipline tells us there's
- * space available (through comhwiflow()).
- * Leave the rest of the data in the input
- * buffer.
- */
- SET(zst->zst_rx_flags, RX_TTY_OVERFLOWED);
- }
- break;
- }
- get += 2;
- if (get >= end)
- get = zst->zst_rbuf;
- cc--;
- }
-
- if (cc != scc) {
- zst->zst_rbget = get;
- s = splzs();
- cc = zst->zst_rbavail += scc - cc;
- /* Buffers should be ok again, release possible block. */
- if (cc >= zst->zst_r_lowat) {
- if (ISSET(zst->zst_rx_flags, RX_IBUF_OVERFLOWED)) {
- CLR(zst->zst_rx_flags, RX_IBUF_OVERFLOWED);
- SET(cs->cs_preg[1], ZSWR1_RIE);
- cs->cs_creg[1] = cs->cs_preg[1];
- zs_write_reg(cs, 1, cs->cs_creg[1]);
- }
- if (ISSET(zst->zst_rx_flags, RX_IBUF_BLOCKED)) {
- CLR(zst->zst_rx_flags, RX_IBUF_BLOCKED);
- zs_hwiflow(zst);
- }
- }
- splx(s);
- }
-}
-
-integrate void
-zstty_txsoft(struct zstty_softc *zst, struct tty *tp)
-{
- int s;
-
- CLR(tp->t_state, TS_BUSY);
- if (ISSET(tp->t_state, TS_FLUSH))
- CLR(tp->t_state, TS_FLUSH);
- else {
- s = splzs();
- ndflush(&tp->t_outq, (int)(zst->zst_tba - tp->t_outq.c_cf));
- splx(s);
- }
- (*linesw[tp->t_line].l_start)(tp);
-}
-
-integrate void
-zstty_stsoft(struct zstty_softc *zst, struct tty *tp)
-{
- struct zs_chanstate *cs = zst->zst_cs;
- uint8_t rr0, delta;
- int s;
-
- s = splzs();
- rr0 = cs->cs_rr0;
- delta = cs->cs_rr0_delta;
- cs->cs_rr0_delta = 0;
- splx(s);
-
- if (ISSET(delta, cs->cs_rr0_dcd)) {
- /*
- * Inform the tty layer that carrier detect changed.
- */
- (void)(*linesw[tp->t_line].l_modem)(tp, ISSET(rr0, ZSRR0_DCD));
- }
-
- if (ISSET(delta, cs->cs_rr0_cts)) {
- /* Block or unblock output according to flow control. */
- if (ISSET(rr0, cs->cs_rr0_cts)) {
- zst->zst_tx_stopped = 0;
- (*linesw[tp->t_line].l_start)(tp);
- } else {
- zst->zst_tx_stopped = 1;
- }
- }
-}
-
-/*
- * Software interrupt. Called at zssoft
- *
- * The main job to be done here is to empty the input ring
- * by passing its contents up to the tty layer. The ring is
- * always emptied during this operation, therefore the ring
- * must not be larger than the space after "high water" in
- * the tty layer, or the tty layer might drop our input.
- *
- * Note: an "input blockage" condition is assumed to exist if
- * EITHER the TS_TBLOCK flag or zst_rx_blocked flag is set.
- */
-void
-zstty_softint(struct zs_chanstate *cs)
-{
- struct zstty_softc *zst = cs->cs_private;
- struct tty *tp = zst->zst_tty;
- int s;
-
- s = spltty();
-
- if (zst->zst_rx_ready) {
- zst->zst_rx_ready = 0;
- zstty_rxsoft(zst, tp);
- }
-
- if (zst->zst_st_check) {
- zst->zst_st_check = 0;
- zstty_stsoft(zst, tp);
- }
-
- if (zst->zst_tx_done) {
- zst->zst_tx_done = 0;
- zstty_txsoft(zst, tp);
- }
-
- splx(s);
-}
-
-struct zsops zsops_tty = {
- zstty_rxint, /* receive char available */
- zstty_stint, /* external/status */
- zstty_txint, /* xmit buffer empty */
- zstty_softint, /* process software interrupt */
-};
diff --git a/sys/arch/sgi/include/z8530var.h b/sys/arch/sgi/include/z8530var.h
index 487913357af..ec176226ca2 100644
--- a/sys/arch/sgi/include/z8530var.h
+++ b/sys/arch/sgi/include/z8530var.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: z8530var.h,v 1.3 2012/05/12 16:47:44 miod Exp $ */
+/* $OpenBSD: z8530var.h,v 1.4 2013/04/21 14:44:16 sebastia Exp $ */
/* $NetBSD: z8530var.h,v 1.10 2011/07/01 21:00:21 dyoung Exp $ */
/*
@@ -85,7 +85,7 @@
*/
#include <machine/bus.h>
-#include <sgi/hpc/z8530sc.h>
+#include <dev/ic/z8530sc.h>
struct zs_channel {
struct zs_chanstate cs_zscs; /* Required: soft state */
diff --git a/sys/arch/solbourne/dev/zsclock.c b/sys/arch/solbourne/dev/zsclock.c
index 66ae045ecda..9753fc82894 100644
--- a/sys/arch/solbourne/dev/zsclock.c
+++ b/sys/arch/solbourne/dev/zsclock.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: zsclock.c,v 1.2 2005/04/20 01:43:51 miod Exp $ */
+/* $OpenBSD: zsclock.c,v 1.3 2013/04/21 14:44:16 sebastia Exp $ */
/* $NetBSD: clock.c,v 1.11 1995/05/16 07:30:46 phil Exp $ */
/*-
@@ -57,7 +57,7 @@
#include <sys/ioctl.h>
#include <sys/kernel.h>
-#include <sparc/dev/z8530reg.h>
+#include <dev/ic/z8530reg.h>
#include <machine/z8530var.h>
#include <machine/autoconf.h>
diff --git a/sys/arch/solbourne/solbourne/locore.s b/sys/arch/solbourne/solbourne/locore.s
index 01caf9b931d..855d7b94420 100644
--- a/sys/arch/solbourne/solbourne/locore.s
+++ b/sys/arch/solbourne/solbourne/locore.s
@@ -1,4 +1,4 @@
-/* $OpenBSD: locore.s,v 1.16 2011/07/04 22:53:53 tedu Exp $ */
+/* $OpenBSD: locore.s,v 1.17 2013/04/21 14:44:16 sebastia Exp $ */
/* OpenBSD: locore.s,v 1.64 2005/04/17 18:47:50 miod Exp */
/*
@@ -91,7 +91,7 @@
#include <machine/signal.h>
#include <machine/trap.h>
-#include <sparc/dev/z8530reg.h>
+#include <dev/ic/z8530reg.h>
/*
* GNU assembler does not understand `.empty' directive; Sun assembler
diff --git a/sys/arch/sparc/conf/files.sparc b/sys/arch/sparc/conf/files.sparc
index 2cc9c9385ea..6e0a5886ac5 100644
--- a/sys/arch/sparc/conf/files.sparc
+++ b/sys/arch/sparc/conf/files.sparc
@@ -1,4 +1,4 @@
-# $OpenBSD: files.sparc,v 1.91 2011/09/04 08:03:32 miod Exp $
+# $OpenBSD: files.sparc,v 1.92 2013/04/21 14:44:16 sebastia Exp $
# $NetBSD: files.sparc,v 1.44 1997/08/31 21:29:16 pk Exp $
# @(#)files.sparc 8.1 (Berkeley) 7/19/93
@@ -64,7 +64,7 @@ file arch/sparc/sparc/memreg.c
device zs {[channel = -1]}
attach zs at mainbus, obio
file arch/sparc/dev/zs.c zs needs-flag
-file arch/sparc/dev/z8530sc.c zs
+file dev/ic/z8530sc.c zs
device fdc {}
attach fdc at mainbus, obio
@@ -87,7 +87,7 @@ include "dev/sun/files.sun"
device zstty: tty
attach zstty at zs
-file arch/sparc/dev/z8530tty.c zstty needs-flag
+file dev/ic/z8530tty.c zstty needs-flag
file arch/sparc/dev/zs_kgdb.c kgdb
device zskbd: wskbddev, sunkbd
diff --git a/sys/arch/sparc/dev/z8530kbd.c b/sys/arch/sparc/dev/z8530kbd.c
index 94d0efa2394..0a9c36439c0 100644
--- a/sys/arch/sparc/dev/z8530kbd.c
+++ b/sys/arch/sparc/dev/z8530kbd.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: z8530kbd.c,v 1.15 2011/03/18 21:01:17 miod Exp $ */
+/* $OpenBSD: z8530kbd.c,v 1.16 2013/04/21 14:44:16 sebastia Exp $ */
/* $NetBSD: z8530tty.c,v 1.77 2001/05/30 15:24:24 lukem Exp $ */
/*-
@@ -117,7 +117,7 @@
#include <dev/sun/sunkbdreg.h>
#include <dev/sun/sunkbdvar.h>
-#include <sparc/dev/z8530reg.h>
+#include <dev/ic/z8530reg.h>
#include <machine/z8530var.h>
#include <dev/cons.h>
@@ -304,7 +304,7 @@ zskbd_attach(parent, self, aux)
tty_unit = ss->sc_dev.dv_unit;
channel = args->channel;
- cs = &zsc->zsc_cs[channel];
+ cs = zsc->zsc_cs[channel];
cs->cs_private = zst;
cs->cs_ops = &zsops_kbd;
diff --git a/sys/arch/sparc/dev/z8530reg.h b/sys/arch/sparc/dev/z8530reg.h
deleted file mode 100644
index 81dc26dac5c..00000000000
--- a/sys/arch/sparc/dev/z8530reg.h
+++ /dev/null
@@ -1,447 +0,0 @@
-/* $OpenBSD: z8530reg.h,v 1.3 2011/09/17 08:38:07 miod Exp $ */
-/* $NetBSD: z8530reg.h,v 1.9 1998/07/31 05:08:38 wrstuden Exp $ */
-
-/*
- * Copyright (c) 1992, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * This software was developed by the Computer Systems Engineering group
- * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
- * contributed to Berkeley.
- *
- * All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Lawrence Berkeley Laboratory.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)zsreg.h 8.1 (Berkeley) 6/11/93
- */
-
-/*
- * Zilog SCC registers, as implemented on the Sun-4c.
- *
- * Each Z8530 implements two channels (called `a' and `b').
- *
- * The damnable chip was designed to fit on Z80 I/O ports, and thus
- * has everything multiplexed out the wazoo. We have to select
- * a register, then read or write the register, and so on. Worse,
- * the parameter bits are scattered all over the register space.
- * This thing is full of `miscellaneous' control registers.
- *
- * Worse yet, the registers have incompatible functions on read
- * and write operations. We describe the registers below according
- * to whether they are `read registers' (RR) or `write registers' (WR).
- * As if this were not enough, some of the channel B status bits show
- * up in channel A, and vice versa. The blasted thing shares write
- * registers 2 and 9 across both channels, and reads registers 2 and 3
- * differently for the two channels. We can, however, ignore this much
- * of the time.
- *
- * This file also includes flags for the Z85C30 and Z85230 enhanced scc.
- * The CMOS 8530 includes extra SDLC functionality, and is used in a
- * number of Macs (often in the Z85C80, an 85C30 combined w/ a SCSI
- * controller). -wrs
- *
- * Some of the names in this files were chosen to make the hsis driver
- * work unchanged (which means that they will match some in SunOS).
- *
- * `S.C.' stands for Special Condition, which is any of these:
- * receiver overrun (aka silo overflow)
- * framing error (missing stop bit, etc)
- * end of frame (in synchronous modes)
- * parity error (when `parity error is S.C.' is set)
- *
- * Registers with only a single `numeric value' get a name.
- * Other registers hold bits and are only numbered; the bit
- * definitions imply the register number (see below).
- *
- * We never use the receive and transmit data registers as
- * indirects (choosing instead the zc_data register), so they
- * are not defined here.
- */
-#define ZSRR_IVEC 2 /* interrupt vector (channel 0) */
-#define ZSRR_IPEND 3 /* interrupt pending (ch. 0 only) */
-#define ZSRR_TXSYNC 6 /* sync transmit char (monosync mode) */
-#define ZSRR_RXSYNC 7 /* sync receive char (monosync mode) */
-#define ZSRR_SYNCLO 6 /* sync low byte (bisync mode) */
-#define ZSRR_SYNCHI 7 /* sync high byte (bisync mode) */
-#define ZSRR_SDLC_ADDR 6 /* SDLC address (SDLC mode) */
-#define ZSRR_SDLC_FLAG 7 /* SDLC flag 0x7E (SDLC mode) */
-#define ZSRR_BAUDLO 12 /* baud rate generator (low half) */
-#define ZSRR_BAUDHI 13 /* baud rate generator (high half) */
-#define ZSRR_ENHANCED 14 /* read address of WR7' - yes, it's not 7!*/
-
-#define ZSWR_IVEC 2 /* interrupt vector (shared) */
-#define ZSWR_TXSYNC 6 /* sync transmit char (monosync mode) */
-#define ZSWR_RXSYNC 7 /* sync receive char (monosync mode) */
-#define ZSWR_SYNCLO 6 /* sync low byte (bisync mode) */
-#define ZSWR_SYNCHI 7 /* sync high byte (bisync mode) */
-#define ZSWR_SDLC_ADDR 6 /* SDLC address (SDLC mode) */
-#define ZSWR_SDLC_FLAG 7 /* SDLC flag 0x7E (SDLC mode) */
-#define ZSWR_BAUDLO 12 /* baud rate generator (low half) */
-#define ZSWR_BAUDHI 13 /* baud rate generator (high half) */
-#define ZSWR_ENHANCED 7 /* write address of WR7' */
-
-/*
- * Registers 0 through 7 may be written with any one of the 8 command
- * modifiers, and/or any one of the 4 reset modifiers, defined below.
- * To write registers 8 through 15, however, the command modifier must
- * always be `point high'. Rather than track this bizzareness all over
- * the driver, we try to avoid using any modifiers, ever (but they are
- * defined here if you want them).
- */
-#define ZSM_RESET_TXUEOM 0xc0 /* reset xmit underrun / eom latch */
-#define ZSM_RESET_TXCRC 0x80 /* reset xmit crc generator */
-#define ZSM_RESET_RXCRC 0x40 /* reset recv crc checker */
-#define ZSM_NULL 0x00 /* nothing special */
-
-#define ZSM_RESET_IUS 0x38 /* reset interrupt under service */
-#define ZSM_RESET_ERR 0x30 /* reset error cond */
-#define ZSM_RESET_TXINT 0x28 /* reset xmit interrupt pending */
-#define ZSM_EI_NEXTRXC 0x20 /* enable int. on next rcvd char */
-#define ZSM_SEND_ABORT 0x18 /* send abort (SDLC) */
-#define ZSM_RESET_STINT 0x10 /* reset external/status interrupt */
-#define ZSM_POINTHIGH 0x08 /* `point high' (use r8-r15) */
-#define ZSM_NULL 0x00 /* nothing special */
-
-/*
- * Commands for Write Register 0 (`Command Register').
- * These are just the command modifiers or'ed with register number 0
- * (which of course equals the command modifier).
- */
-#define ZSWR0_RESET_EOM ZSM_RESET_TXUEOM
-#define ZSWR0_RESET_TXCRC ZSM_RESET_TXCRC
-#define ZSWR0_RESET_RXCRC ZSM_RESET_RXCRC
-#define ZSWR0_CLR_INTR ZSM_RESET_IUS
-#define ZSWR0_RESET_ERRORS ZSM_RESET_ERR
-#define ZSWR0_EI_NEXTRXC ZSM_EI_NEXTRXC
-#define ZSWR0_SEND_ABORT ZSM_SEND_ABORT
-#define ZSWR0_RESET_STATUS ZSM_RESET_STINT
-#define ZSWR0_RESET_TXINT ZSM_RESET_TXINT
-
-/*
- * Bits in Write Register 1 (`Transmit/Receive Interrupt and Data
- * Transfer Mode Definition'). Note that bits 3 and 4 are taken together
- * as a single unit, and bits 5 and 6 are useful only if bit 7 is set.
- */
-#define ZSWR1_REQ_WAIT 0x80 /* WAIT*-REQ* pin gives WAIT* */
-#define ZSWR1_REQ_REQ 0xc0 /* WAIT*-REQ* pin gives REQ* */
-#define ZSWR1_REQ_TX 0x00 /* WAIT*-REQ* pin follows xmit buf */
-#define ZSWR1_REQ_RX 0x20 /* WAIT*-REQ* pin follows recv buf */
-
-#define ZSWR1_RIE_NONE 0x00 /* disable rxint entirely */
-#define ZSWR1_RIE_FIRST 0x08 /* rxint on first char & on S.C. */
-#define ZSWR1_RIE 0x10 /* rxint per char & on S.C. */
-#define ZSWR1_RIE_SPECIAL_ONLY 0x18 /* rxint on S.C. only */
-
-#define ZSWR1_PE_SC 0x04 /* parity error is special condition */
-#define ZSWR1_TIE 0x02 /* transmit interrupt enable */
-#define ZSWR1_SIE 0x01 /* external/status interrupt enable */
-
-#define ZSWR1_IMASK 0x1F /* mask of all itr. enable bits. */
-
-/* HSIS compat */
-#define ZSWR1_REQ_ENABLE (ZSWR1_REQ_WAIT | ZSWR1_REQ_TX)
-
-/*
- * Bits in Write Register 3 (`Receive Parameters and Control').
- * Bits 7 and 6 are taken as a unit. Note that the receive bits
- * per character ordering is insane.
- *
- * Here `hardware flow control' means CTS enables the transmitter
- * and DCD enables the receiver. The latter is neither interesting
- * nor useful, and gets in our way, making it almost unusable.
- */
-#define ZSWR3_RX_5 0x00 /* receive 5 bits per char */
-#define ZSWR3_RX_7 0x40 /* receive 7 bits per char */
-#define ZSWR3_RX_6 0x80 /* receive 6 bits per char */
-#define ZSWR3_RX_8 0xc0 /* receive 8 bits per char */
-#define ZSWR3_RXSIZE 0xc0 /* receive char size mask */
-
-#define ZSWR3_HFC 0x20 /* hardware flow control */
-#define ZSWR3_HUNT 0x10 /* enter hunt mode */
-#define ZSWR3_RXCRC_ENABLE 0x08 /* enable recv crc calculation */
-#define ZSWR3_ADDR_SEARCH_MODE 0x04 /* address search mode (SDLC only) */
-#define ZSWR3_SDLC_SHORT_ADDR 0x02 /* short address mode (SDLC only) */
-#define ZSWR3_SYNC_LOAD_INH 0x02 /* sync character load inhibit */
-#define ZSWR3_RX_ENABLE 0x01 /* receiver enable */
-
-/*
- * Bits in Write Register 4 (`Transmit/Receive Miscellaneous Parameters
- * and Modes'). Bits 7&6, 5&4, and 3&2 are taken as units.
- */
-#define ZSWR4_CLK_X1 0x00 /* clock divisor = 1 */
-#define ZSWR4_CLK_X16 0x40 /* clock divisor = 16 */
-#define ZSWR4_CLK_X32 0x80 /* clock divisor = 32 */
-#define ZSWR4_CLK_X64 0xc0 /* clock divisor = 64 */
-#define ZSWR4_CLK_MASK 0xc0 /* clock divisor mask */
-
-#define ZSWR4_MONOSYNC 0x00 /* 8 bit sync char (sync only) */
-#define ZSWR4_BISYNC 0x10 /* 16 bit sync char (sync only) */
-#define ZSWR4_SDLC 0x20 /* SDLC mode */
-#define ZSWR4_EXTSYNC 0x30 /* external sync mode */
-#define ZSWR4_SYNC_MASK 0x30 /* sync mode bit mask */
-
-#define ZSWR4_SYNCMODE 0x00 /* no stop bit (sync mode only) */
-#define ZSWR4_ONESB 0x04 /* 1 stop bit */
-#define ZSWR4_1P5SB 0x08 /* 1.5 stop bits (clk cannot be 1x) */
-#define ZSWR4_TWOSB 0x0c /* 2 stop bits */
-#define ZSWR4_SBMASK 0x0c /* mask of all stop bits */
-
-#define ZSWR4_EVENP 0x02 /* check for even parity */
-#define ZSWR4_PARENB 0x01 /* enable parity checking */
-#define ZSWR4_PARMASK 0x03 /* mask of all parity bits */
-
-/*
- * Bits in Write Register 5 (`Transmit Parameter and Controls').
- * Bits 6 and 5 are taken as a unit; the ordering is, as with RX
- * bits per char, not sensible.
- */
-#define ZSWR5_DTR 0x80 /* assert (set to -12V) DTR */
-
-#define ZSWR5_TX_5 0x00 /* transmit 5 or fewer bits */
-#define ZSWR5_TX_7 0x20 /* transmit 7 bits */
-#define ZSWR5_TX_6 0x40 /* transmit 6 bits */
-#define ZSWR5_TX_8 0x60 /* transmit 8 bits */
-#define ZSWR5_TXSIZE 0x60 /* transmit char size mask */
-
-#define ZSWR5_BREAK 0x10 /* send break (continuous 0s) */
-#define ZSWR5_TX_ENABLE 0x08 /* enable transmitter */
-#define ZSWR5_CRC16 0x04 /* use CRC16 (off => use SDLC) */
-#define ZSWR5_RTS 0x02 /* assert RTS */
-#define ZSWR5_TXCRC_ENABLE 0x01 /* enable xmit crc calculation */
-
-#ifdef not_done_here
-/*
- * Bits in Write Register 7 when the chip is in SDLC mode.
- */
-#define ZSWR7_SDLCFLAG 0x7e /* this value makes SDLC mode work */
-#endif
-
-/*
- * Bits in Write Register 7' (ZSWR_ENHANCED above). This register is
- * only available on the 85230. Dispite the fact it contains flags
- * and not a single value, the register was named as it is read
- * via RR14. Weird.
- */
- /* 0x80 unused */
-#define ZSWR7P_EXTEND_READ 0x40 /* modify read map; make most regs readable */
-#define ZSWR7P_TX_FIFO 0x20 /* change level for Tx FIFO empty int */
-#define ZSWR7P_DTR_TIME 0x10 /* modifies deact. speed of /DTR//REQ */
-#define ZSWR7P_RX_FIFO 0x08 /* Rx FIFO int on 1/2 full? */
-#define ZSWR7P_RTS_DEACT 0x04 /* automatically deassert RTS */
-#define ZSWR7P_AUTO_EOM_RESET 0x02 /* automatically reset EMO/Tx Underrun */
-#define ZSWR7P_AUTO_TX_FLAG 0x01 /* Auto send SDLC flag at transmit start */
-
-/*
- * Bits in Write Register 9 (`Master Interrupt Control'). Bits 7 & 6
- * are taken as a unit and indicate the type of reset; 00 means no reset
- * (and is not defined here).
- */
-#define ZSWR9_HARD_RESET 0xc0 /* force hardware reset */
-#define ZSWR9_A_RESET 0x80 /* reset channel A (0) */
-#define ZSWR9_B_RESET 0x40 /* reset channel B (1) */
-#define ZSWR9_SOFT_INTAC 0x20 /* Not in NMOS version */
-
-#define ZSWR9_STATUS_HIGH 0x10 /* status in high bits of intr vec */
-#define ZSWR9_MASTER_IE 0x08 /* master interrupt enable */
-#define ZSWR9_DLC 0x04 /* disable lower chain */
-#define ZSWR9_NO_VECTOR 0x02 /* no vector */
-#define ZSWR9_VECTOR_INCL_STAT 0x01 /* vector includes status */
-
-/*
- * Bits in Write Register 10 (`Miscellaneous Transmitter/Receiver Control
- * Bits'). Bits 6 & 5 are taken as a unit, and some of the bits are
- * meaningful only in certain modes. Bleah.
- */
-#define ZSWR10_PRESET_ONES 0x80 /* preset CRC to all 1 (else all 0) */
-
-#define ZSWR10_NRZ 0x00 /* NRZ encoding */
-#define ZSWR10_NRZI 0x20 /* NRZI encoding */
-#define ZSWR10_FM1 0x40 /* FM1 encoding */
-#define ZSWR10_FM0 0x60 /* FM0 encoding */
-
-#define ZSWR10_GA_ON_POLL 0x10 /* go active on poll (loop mode) */
-#define ZSWR10_MARK_IDLE 0x08 /* all 1s (vs flag) when idle (SDLC) */
-#define ZSWR10_ABORT_ON_UNDERRUN 0x4 /* abort on xmit underrun (SDLC) */
-#define ZSWR10_LOOP_MODE 0x02 /* loop mode (SDLC) */
-#define ZSWR10_6_BIT_SYNC 0x01 /* 6 bits per sync char (sync modes) */
-
-/*
- * Bits in Write Register 11 (`Clock Mode Control'). Bits 6&5, 4&3, and
- * 1&0 are taken as units. Various bits depend on other bits in complex
- * ways; see the Zilog manual.
- */
-#define ZSWR11_XTAL 0x80 /* have xtal between RTxC* and SYNC* */
- /* (else have TTL oscil. on RTxC*) */
-#define ZSWR11_RXCLK_RTXC 0x00 /* recv clock taken from RTxC* pin */
-#define ZSWR11_RXCLK_TRXC 0x20 /* recv clock taken from TRxC* pin */
-#define ZSWR11_RXCLK_BAUD 0x40 /* recv clock taken from BRG */
-#define ZSWR11_RXCLK_DPLL 0x60 /* recv clock taken from DPLL */
-
-#define ZSWR11_TXCLK_RTXC 0x00 /* xmit clock taken from RTxC* pin */
-#define ZSWR11_TXCLK_TRXC 0x08 /* xmit clock taken from TRxC* pin */
-#define ZSWR11_TXCLK_BAUD 0x10 /* xmit clock taken from BRG */
-#define ZSWR11_TXCLK_DPLL 0x18 /* xmit clock taken from DPLL */
-
-#define ZSWR11_TRXC_OUT_ENA 0x04 /* TRxC* pin will be an output */
- /* (unless it is being used above) */
-#define ZSWR11_TRXC_XTAL 0x00 /* TRxC output from xtal oscillator */
-#define ZSWR11_TRXC_XMIT 0x01 /* TRxC output from xmit clock */
-#define ZSWR11_TRXC_BAUD 0x02 /* TRxC output from BRG */
-#define ZSWR11_TRXC_DPLL 0x03 /* TRxC output from DPLL */
-
-/*
- * Formula for Write Registers 12 and 13 (`Lower Byte of Baud Rate
- * Generator Time Constant' and `Upper Byte of ...'). Inputs:
- *
- * f BRG input clock frequency (in Hz) AFTER division
- * by 1, 16, 32, or 64 (per clock divisor in WR4)
- * bps desired rate in bits per second (9600, etc)
- *
- * We want
- *
- * f
- * ----- + 0.5 - 2
- * 2 bps
- *
- * rounded down to an integer. This can be computed entirely
- * in integer arithmetic as:
- *
- * f + bps
- * ------- - 2
- * 2 bps
- */
-#define BPS_TO_TCONST(f, bps) ((((f) + (bps)) / (2 * (bps))) - 2)
-
-/* inverse of above: given a BRG Time Constant, return Bits Per Second */
-#define TCONST_TO_BPS(f, tc) ((f) / 2 / ((tc) + 2))
-
-/*
- * Bits in Write Register 14 (`Miscellaneous Control Bits').
- * Bits 7 through 5 are taken as a unit and make up a `DPLL command'.
- */
-#define ZSWR14_DPLL_NOOP 0x00 /* leave DPLL alone */
-#define ZSWR14_DPLL_SEARCH 0x20 /* enter search mode */
-#define ZSWR14_DPLL_RESET_CM 0x40 /* reset `clock missing' in RR10 */
-#define ZSWR14_DPLL_DISABLE 0x60 /* disable DPLL (continuous search) */
-#define ZSWR14_DPLL_SRC_BAUD 0x80 /* set DPLL src = BRG */
-#define ZSWR14_DPLL_SRC_RTXC 0xa0 /* set DPLL src = RTxC* or xtal osc */
-#define ZSWR14_DPLL_FM 0xc0 /* operate in FM mode */
-#define ZSWR14_DPLL_NRZI 0xe0 /* operate in NRZI mode */
-
-#define ZSWR14_LOCAL_LOOPBACK 0x10 /* set local loopback mode */
-#define ZSWR14_AUTO_ECHO 0x08 /* set auto echo mode */
-#define ZSWR14_DTR_REQ 0x04 /* DTR* / REQ* pin gives REQ* */
-#define ZSWR14_BAUD_FROM_PCLK 0x02 /* BRG clock taken from PCLK */
- /* (else from RTxC* pin or xtal osc) */
-#define ZSWR14_BAUD_ENA 0x01 /* enable BRG countdown */
-
-/*
- * Bits in Write Register 15 (`External/Status Interrupt Control').
- * Most of these cause status interrupts whenever the corresponding
- * bit or pin changes state (i.e., any rising or falling edge).
- *
- * NOTE: ZSWR15_SDLC_FIFO & ZSWR15_ENABLE_ENHANCED should not be
- * set on an NMOS 8530. Also, ZSWR15_ENABLE_ENHANCED is only
- * available on the 85230.
- */
-#define ZSWR15_BREAK_IE 0x80 /* enable break/abort status int */
-#define ZSWR15_TXUEOM_IE 0x40 /* enable TX underrun/EOM status int */
-#define ZSWR15_CTS_IE 0x20 /* enable CTS* pin status int */
-#define ZSWR15_SYNCHUNT_IE 0x10 /* enable SYNC* pin/hunt status int */
-#define ZSWR15_DCD_IE 0x08 /* enable DCD* pin status int */
-#define ZSWR15_SDLC_FIFO 0x04 /* enable SDLC FIFO enhancements */
-#define ZSWR15_ZERO_COUNT_IE 0x02 /* enable BRG-counter = 0 status int */
-#define ZSWR15_ENABLE_ENHANCED 0x01 /* enable writing WR7' at reg 7 */
-
-/*
- * Bits in Read Register 0 (`Transmit/Receive Buffer Status and External
- * Status').
- */
-#define ZSRR0_BREAK 0x80 /* break/abort detected */
-#define ZSRR0_TXUNDER 0x40 /* transmit underrun/EOM (sync) */
-#define ZSRR0_CTS 0x20 /* clear to send */
-#define ZSRR0_SYNC_HUNT 0x10 /* sync/hunt (sync mode) */
-#define ZSRR0_DCD 0x08 /* data carrier detect */
-#define ZSRR0_TX_READY 0x04 /* transmit buffer empty */
-#define ZSRR0_ZERO_COUNT 0x02 /* zero count in baud clock */
-#define ZSRR0_RX_READY 0x01 /* received character ready */
-
-/*
- * Bits in Read Register 1 (the Zilog book does not name this one).
- */
-#define ZSRR1_EOF 0x80 /* end of frame (SDLC mode) */
-#define ZSRR1_FE 0x40 /* CRC/framing error */
-#define ZSRR1_DO 0x20 /* data (receiver) overrun */
-#define ZSRR1_PE 0x10 /* parity error */
-#define ZSRR1_RC0 0x08 /* residue code 0 (SDLC mode) */
-#define ZSRR1_RC1 0x04 /* residue code 1 (SDLC mode) */
-#define ZSRR1_RC2 0x02 /* residue code 2 (SDLC mode) */
-#define ZSRR1_ALL_SENT 0x01 /* all chars out of xmitter (async) */
-
-/*
- * Read Register 2 in B channel contains status bits if VECTOR_INCL_STAT
- * is set.
- */
-
-/*
- * Bits in Read Register 3 (`Interrupt Pending'). Only channel A
- * has an RR3.
- */
- /* 0x80 unused, returned as 0 */
- /* 0x40 unused, returned as 0 */
-#define ZSRR3_IP_A_RX 0x20 /* channel A recv int pending */
-#define ZSRR3_IP_A_TX 0x10 /* channel A xmit int pending */
-#define ZSRR3_IP_A_STAT 0x08 /* channel A status int pending */
-#define ZSRR3_IP_B_RX 0x04 /* channel B recv int pending */
-#define ZSRR3_IP_B_TX 0x02 /* channel B xmit int pending */
-#define ZSRR3_IP_B_STAT 0x01 /* channel B status int pending */
-
-/*
- * Bits in Read Register 10 (`contains some miscellaneous status bits').
- */
-#define ZSRR10_1_CLOCK_MISSING 0x80 /* 1 clock edge missing (FM mode) */
-#define ZSRR10_2_CLOCKS_MISSING 0x40 /* 2 clock edges missing (FM mode) */
- /* 0x20 unused */
-#define ZSRR10_LOOP_SENDING 0x10 /* xmitter controls loop (SDLC loop) */
- /* 0x08 unused */
- /* 0x04 unused */
-#define ZSRR10_ON_LOOP 0x02 /* SCC is on loop (SDLC/X.21 modes) */
-
-/*
- * Bits in Read Register 15. This register is one of the few that
- * simply reads back the corresponding Write Register.
- */
-#define ZSRR15_BREAK_IE 0x80 /* break/abort status int enable */
-#define ZSRR15_TXUEOM_IE 0x40 /* TX underrun/EOM status int enable */
-#define ZSRR15_CTS_IE 0x20 /* CTS* pin status int enable */
-#define ZSRR15_SYNCHUNT_IE 0x10 /* SYNC* pin/hunt status int enable */
-#define ZSRR15_DCD_IE 0x08 /* DCD* pin status int enable */
- /* 0x04 unused, returned as zero */
-#define ZSRR15_ZERO_COUNT_IE 0x02 /* BRG-counter = 0 status int enable */
- /* 0x01 unused, returned as zero */
diff --git a/sys/arch/sparc/dev/z8530sc.c b/sys/arch/sparc/dev/z8530sc.c
deleted file mode 100644
index e5afc853816..00000000000
--- a/sys/arch/sparc/dev/z8530sc.c
+++ /dev/null
@@ -1,353 +0,0 @@
-/* $OpenBSD: z8530sc.c,v 1.2 2003/06/02 23:27:54 millert Exp $ */
-/* $NetBSD: z8530sc.c,v 1.4 1996/05/17 19:30:34 gwr Exp $ */
-
-/*
- * Copyright (c) 1994 Gordon W. Ross
- * Copyright (c) 1992, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * This software was developed by the Computer Systems Engineering group
- * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
- * contributed to Berkeley.
- *
- * All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Lawrence Berkeley Laboratory.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)zs.c 8.1 (Berkeley) 7/19/93
- */
-
-/*
- * Zilog Z8530 Dual UART driver (common part)
- *
- * This file contains the machine-independent parts of the
- * driver common to tty and keyboard/mouse sub-drivers.
- */
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/proc.h>
-#include <sys/device.h>
-#include <sys/conf.h>
-#include <sys/file.h>
-#include <sys/ioctl.h>
-#include <sys/tty.h>
-#include <sys/time.h>
-#include <sys/kernel.h>
-#include <sys/syslog.h>
-
-#include <sparc/dev/z8530reg.h>
-#include <machine/z8530var.h>
-
-void
-zs_break(cs, set)
- struct zs_chanstate *cs;
- int set;
-{
-
- if (set) {
- cs->cs_preg[5] |= ZSWR5_BREAK;
- cs->cs_creg[5] |= ZSWR5_BREAK;
- } else {
- cs->cs_preg[5] &= ~ZSWR5_BREAK;
- cs->cs_creg[5] &= ~ZSWR5_BREAK;
- }
- zs_write_reg(cs, 5, cs->cs_creg[5]);
-}
-
-
-/*
- * drain on-chip fifo
- */
-void
-zs_iflush(cs)
- struct zs_chanstate *cs;
-{
- u_char c, rr0, rr1;
- int i;
-
- /*
- * Count how many times we loop. Some systems, such as some
- * Apple PowerBooks, claim to have SCC's which they really don't.
- */
- for (i = 0; i < 32; i++) {
- /* Is there input available? */
- rr0 = zs_read_csr(cs);
- if ((rr0 & ZSRR0_RX_READY) == 0)
- break;
-
- /*
- * First read the status, because reading the data
- * destroys the status of this char.
- */
- rr1 = zs_read_reg(cs, 1);
- c = zs_read_data(cs);
-
- if (rr1 & (ZSRR1_FE | ZSRR1_DO | ZSRR1_PE)) {
- /* Clear the receive error. */
- zs_write_csr(cs, ZSWR0_RESET_ERRORS);
- }
- }
-}
-
-
-/*
- * Write the given register set to the given zs channel in the proper order.
- * The channel must not be transmitting at the time. The receiver will
- * be disabled for the time it takes to write all the registers.
- * Call this with interrupts disabled.
- */
-void
-zs_loadchannelregs(cs)
- struct zs_chanstate *cs;
-{
- u_char *reg;
-
- zs_write_csr(cs, ZSM_RESET_ERR); /* XXX: reset error condition */
-
-#if 1
- /*
- * XXX: Is this really a good idea?
- * XXX: Should go elsewhere! -gwr
- */
- zs_iflush(cs); /* XXX */
-#endif
-
- if (memcmp((caddr_t)cs->cs_preg, (caddr_t)cs->cs_creg, 16) == 0)
- return; /* only change if values are different */
-
- /* Copy "pending" regs to "current" */
- memcpy((caddr_t)cs->cs_creg, (caddr_t)cs->cs_preg, 16);
- reg = cs->cs_creg; /* current regs */
-
- /* disable interrupts */
- zs_write_reg(cs, 1, reg[1] & ~ZSWR1_IMASK);
-
- /* baud clock divisor, stop bits, parity */
- zs_write_reg(cs, 4, reg[4]);
-
- /* misc. TX/RX control bits */
- zs_write_reg(cs, 10, reg[10]);
-
- /* char size, enable (RX/TX) */
- zs_write_reg(cs, 3, reg[3] & ~ZSWR3_RX_ENABLE);
- zs_write_reg(cs, 5, reg[5] & ~ZSWR5_TX_ENABLE);
-
- /* synchronous mode stuff */
- zs_write_reg(cs, 6, reg[6]);
- zs_write_reg(cs, 7, reg[7]);
-
-#if 0
- /*
- * Registers 2 and 9 are special because they are
- * actually common to both channels, but must be
- * programmed through channel A. The "zsc" attach
- * function takes care of setting these registers
- * and they should not be touched thereafter.
- */
- /* interrupt vector */
- zs_write_reg(cs, 2, reg[2]);
- /* master interrupt control */
- zs_write_reg(cs, 9, reg[9]);
-#endif
-
- /* Shut down the BRG */
- zs_write_reg(cs, 14, reg[14] & ~ZSWR14_BAUD_ENA);
-
-#ifdef ZS_MD_SETCLK
- /* Let the MD code setup any external clock. */
- ZS_MD_SETCLK(cs);
-#endif /* ZS_MD_SETCLK */
-
- /* clock mode control */
- zs_write_reg(cs, 11, reg[11]);
-
- /* baud rate (lo/hi) */
- zs_write_reg(cs, 12, reg[12]);
- zs_write_reg(cs, 13, reg[13]);
-
- /* Misc. control bits */
- zs_write_reg(cs, 14, reg[14]);
-
- /* which lines cause status interrupts */
- zs_write_reg(cs, 15, reg[15]);
-
- /*
- * Zilog docs recommend resetting external status twice at this
- * point. Mainly as the status bits are latched, and the first
- * interrupt clear might unlatch them to new values, generating
- * a second interrupt request.
- */
- zs_write_csr(cs, ZSM_RESET_STINT);
- zs_write_csr(cs, ZSM_RESET_STINT);
-
- /* char size, enable (RX/TX)*/
- zs_write_reg(cs, 3, reg[3]);
- zs_write_reg(cs, 5, reg[5]);
-
- /* interrupt enables: TX, TX, STATUS */
- zs_write_reg(cs, 1, reg[1]);
-}
-
-
-/*
- * ZS hardware interrupt. Scan all ZS channels. NB: we know here that
- * channels are kept in (A,B) pairs.
- *
- * Do just a little, then get out; set a software interrupt if more
- * work is needed.
- *
- * We deliberately ignore the vectoring Zilog gives us, and match up
- * only the number of `reset interrupt under service' operations, not
- * the order.
- */
-int
-zsc_intr_hard(arg)
- void *arg;
-{
- struct zsc_softc *zsc = arg;
- struct zs_chanstate *cs;
- u_char rr3;
-
- /* First look at channel A. */
- cs = &zsc->zsc_cs[0];
- /* Note: only channel A has an RR3 */
- rr3 = zs_read_reg(cs, 3);
-
- /*
- * Clear interrupt first to avoid a race condition.
- * If a new interrupt condition happens while we are
- * servicing this one, we will get another interrupt
- * shortly. We can NOT just sit here in a loop, or
- * we will cause horrible latency for other devices
- * on this interrupt level (i.e. sun3x floppy disk).
- */
- if (rr3 & (ZSRR3_IP_A_RX | ZSRR3_IP_A_TX | ZSRR3_IP_A_STAT)) {
- zs_write_csr(cs, ZSWR0_CLR_INTR);
- if (rr3 & ZSRR3_IP_A_RX)
- (*cs->cs_ops->zsop_rxint)(cs);
- if (rr3 & ZSRR3_IP_A_STAT)
- (*cs->cs_ops->zsop_stint)(cs, 0);
- if (rr3 & ZSRR3_IP_A_TX)
- (*cs->cs_ops->zsop_txint)(cs);
- }
-
- /* Now look at channel B. */
- cs = &zsc->zsc_cs[1];
- if (rr3 & (ZSRR3_IP_B_RX | ZSRR3_IP_B_TX | ZSRR3_IP_B_STAT)) {
- zs_write_csr(cs, ZSWR0_CLR_INTR);
- if (rr3 & ZSRR3_IP_B_RX)
- (*cs->cs_ops->zsop_rxint)(cs);
- if (rr3 & ZSRR3_IP_B_STAT)
- (*cs->cs_ops->zsop_stint)(cs, 0);
- if (rr3 & ZSRR3_IP_B_TX)
- (*cs->cs_ops->zsop_txint)(cs);
- }
-
- /* Note: caller will check cs_x->cs_softreq and DTRT. */
- return (rr3);
-}
-
-
-/*
- * ZS software interrupt. Scan all channels for deferred interrupts.
- */
-int
-zsc_intr_soft(arg)
- void *arg;
-{
- struct zsc_softc *zsc = arg;
- struct zs_chanstate *cs;
- int rval, chan;
-
- rval = 0;
- for (chan = 0; chan < 2; chan++) {
- cs = &zsc->zsc_cs[chan];
-
- /*
- * The softint flag can be safely cleared once
- * we have decided to call the softint routine.
- * (No need to do splzs() first.)
- */
- if (cs->cs_softreq) {
- cs->cs_softreq = 0;
- (*cs->cs_ops->zsop_softint)(cs);
- rval++;
- }
- }
- return (rval);
-}
-
-/*
- * Provide a null zs "ops" vector.
- */
-
-void zsnull_rxint(struct zs_chanstate *);
-void zsnull_stint(struct zs_chanstate *, int);
-void zsnull_txint(struct zs_chanstate *);
-void zsnull_softint(struct zs_chanstate *);
-
-void
-zsnull_rxint(cs)
- struct zs_chanstate *cs;
-{
- /* Ask for softint() call. */
- cs->cs_softreq = 1;
-}
-
-void
-zsnull_stint(cs, force)
- struct zs_chanstate *cs;
- int force;
-{
- /* Ask for softint() call. */
- cs->cs_softreq = 1;
-}
-
-void
-zsnull_txint(cs)
- struct zs_chanstate *cs;
-{
- /* Ask for softint() call. */
- cs->cs_softreq = 1;
-}
-
-void
-zsnull_softint(cs)
- struct zs_chanstate *cs;
-{
- zs_write_reg(cs, 1, 0);
- zs_write_reg(cs, 15, 0);
-}
-
-struct zsops zsops_null = {
- zsnull_rxint, /* receive char available */
- zsnull_stint, /* external/status */
- zsnull_txint, /* xmit buffer empty */
- zsnull_softint, /* process software interrupt */
-};
diff --git a/sys/arch/sparc/dev/z8530sc.h b/sys/arch/sparc/dev/z8530sc.h
deleted file mode 100644
index 9d6c37ad46c..00000000000
--- a/sys/arch/sparc/dev/z8530sc.h
+++ /dev/null
@@ -1,154 +0,0 @@
-/* $OpenBSD: z8530sc.h,v 1.3 2010/03/03 20:13:32 miod Exp $ */
-/* $NetBSD: z8530sc.h,v 1.15 2001/05/11 01:40:48 thorpej Exp $ */
-
-/*
- * Copyright (c) 1994 Gordon W. Ross
- * Copyright (c) 1992, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * This software was developed by the Computer Systems Engineering group
- * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
- * contributed to Berkeley.
- *
- * All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Lawrence Berkeley Laboratory.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)zsvar.h 8.1 (Berkeley) 6/11/93
- */
-
-
-/*
- * Function vector - per channel
- */
-struct zs_chanstate;
-struct zsops {
- void (*zsop_rxint)(struct zs_chanstate *);
- /* receive char available */
- void (*zsop_stint)(struct zs_chanstate *, int);
- /* external/status */
- void (*zsop_txint)(struct zs_chanstate *);
- /* xmit buffer empty */
- void (*zsop_softint)(struct zs_chanstate *);
- /* process software interrupt */
-};
-
-extern struct zsops zsops_null;
-
-
-/*
- * Software state, per zs channel.
- */
-struct zs_chanstate {
-
- /* Pointers to the device registers. */
- volatile u_char *cs_reg_csr; /* ctrl, status, and reg. number. */
- volatile u_char *cs_reg_data; /* data or numbered register */
-
- int cs_channel; /* sub-unit number */
- void *cs_private; /* sub-driver data pointer */
- struct zsops *cs_ops;
-
- int cs_brg_clk; /* BAUD Rate Generator clock
- * (usually PCLK / 16) */
- int cs_defspeed; /* default baud rate */
- int cs_defcflag; /* default cflag */
-
- /*
- * We must keep a copy of the write registers as they are
- * mostly write-only and we sometimes need to set and clear
- * individual bits (e.g., in WR3). Not all of these are
- * needed but 16 bytes is cheap and this makes the addressing
- * simpler. Unfortunately, we can only write to some registers
- * when the chip is not actually transmitting, so whenever
- * we are expecting a `transmit done' interrupt the preg array
- * is allowed to `get ahead' of the current values. In a
- * few places we must change the current value of a register,
- * rather than (or in addition to) the pending value; for these
- * cs_creg[] contains the current value.
- */
- u_char cs_creg[16]; /* current values */
- u_char cs_preg[16]; /* pending values */
- int cs_heldchange; /* change pending (creg != preg) */
-
- u_char cs_rr0; /* last rr0 processed */
- u_char cs_rr0_delta; /* rr0 changes at status intr. */
- u_char cs_rr0_mask; /* rr0 bits that stop output */
- u_char cs_rr0_dcd; /* which bit to read as DCD */
- u_char cs_rr0_cts; /* which bit to read as CTS */
- u_char cs_rr0_pps; /* which bit to use for PPS */
- /* the above is set only while CRTSCTS is enabled. */
-
- u_char cs_wr5_dtr; /* which bit to write as DTR */
- u_char cs_wr5_rts; /* which bit to write as RTS */
- /* the above is set only while CRTSCTS is enabled. */
-
- char cs_softreq; /* need soft interrupt call */
- char cs_cua; /* CUA mode flag */
-
- /* power management hooks */
- int (*enable)(struct zs_chanstate *);
- void (*disable)(struct zs_chanstate *);
- int enabled;
-
- /* MD code might define a larger variant of this. */
-};
-
-struct consdev;
-struct zsc_attach_args {
- char *type; /* type name 'serial', 'keyboard', 'mouse' */
- int channel; /* two serial channels per zsc */
- int hwflags; /* see definitions below */
- /* `consdev' is only valid if ZS_HWFLAG_USE_CONSDEV is set */
- struct consdev *consdev;
-};
-/* In case of split console devices, use these: */
-#define ZS_HWFLAG_CONSOLE_INPUT 1
-#define ZS_HWFLAG_CONSOLE_OUTPUT 2
-#define ZS_HWFLAG_CONSOLE \
- (ZS_HWFLAG_CONSOLE_INPUT | ZS_HWFLAG_CONSOLE_OUTPUT)
-#define ZS_HWFLAG_NO_DCD 4 /* Ignore the DCD bit */
-#define ZS_HWFLAG_NO_CTS 8 /* Ignore the CTS bit */
-#define ZS_HWFLAG_RAW 16 /* advise raw mode */
-#define ZS_HWFLAG_USE_CONSDEV 32 /* Use console ops from `consdev' */
-#define ZS_HWFLAG_NORESET 64 /* Don't reset at attach time */
-
-int zsc_intr_soft(void *);
-int zsc_intr_hard(void *);
-
-void zs_abort(struct zs_chanstate *);
-void zs_break(struct zs_chanstate *, int);
-void zs_iflush(struct zs_chanstate *);
-void zs_loadchannelregs(struct zs_chanstate *);
-int zs_set_speed(struct zs_chanstate *, int);
-int zs_set_modes(struct zs_chanstate *, int);
-
-extern int zs_major;
-
-int zs_check_kgdb(struct zs_chanstate *, int);
-
diff --git a/sys/arch/sparc/dev/z8530tty.c b/sys/arch/sparc/dev/z8530tty.c
deleted file mode 100644
index bfb68082ec4..00000000000
--- a/sys/arch/sparc/dev/z8530tty.c
+++ /dev/null
@@ -1,1707 +0,0 @@
-/* $OpenBSD: z8530tty.c,v 1.17 2010/07/02 17:27:01 nicm Exp $ */
-/* $NetBSD: z8530tty.c,v 1.13 1996/10/16 20:42:14 gwr Exp $ */
-
-/*-
- * Copyright (c) 1993, 1994, 1995, 1996, 1997, 1998, 1999
- * Charles M. Hannum. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Charles M. Hannum.
- * 4. The name of the author may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * Copyright (c) 1994 Gordon W. Ross
- * Copyright (c) 1992, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * This software was developed by the Computer Systems Engineering group
- * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
- * contributed to Berkeley.
- *
- * All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Lawrence Berkeley Laboratory.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)zs.c 8.1 (Berkeley) 7/19/93
- */
-
-/*
- * Zilog Z8530 Dual UART driver (tty interface)
- *
- * This is the "slave" driver that will be attached to
- * the "zsc" driver for plain "tty" async. serial lines.
- *
- * Credits, history:
- *
- * The original version of this code was the sparc/dev/zs.c driver
- * as distributed with the Berkeley 4.4 Lite release. Since then,
- * Gordon Ross reorganized the code into the current parent/child
- * driver scheme, separating the Sun keyboard and mouse support
- * into independent child drivers.
- *
- * RTS/CTS flow-control support was a collaboration of:
- * Gordon Ross <gwr@netbsd.org>,
- * Bill Studenmund <wrstuden@loki.stanford.edu>
- * Ian Dall <Ian.Dall@dsto.defence.gov.au>
- *
- * The driver was massively overhauled in November 1997 by Charles Hannum,
- * fixing *many* bugs, and substantially improving performance.
- */
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/proc.h>
-#include <sys/device.h>
-#include <sys/conf.h>
-#include <sys/file.h>
-#include <sys/ioctl.h>
-#include <sys/malloc.h>
-#include <sys/tty.h>
-#include <sys/time.h>
-#include <sys/kernel.h>
-#include <sys/syslog.h>
-
-#include <sparc/dev/z8530reg.h>
-#include <machine/z8530var.h>
-
-#include <dev/cons.h>
-
-#ifdef KGDB
-extern int zs_check_kgdb(struct zs_chanstate *, int);
-#endif
-
-/*
- * Allow the MD var.h to override the default CFLAG so that
- * console messages during boot come out with correct parity.
- */
-#ifndef ZSTTY_DEF_CFLAG
-#define ZSTTY_DEF_CFLAG TTYDEF_CFLAG
-#endif
-
-/*
- * How many input characters we can buffer.
- * The port-specific var.h may override this.
- * Note: must be a power of two!
- */
-#ifndef ZSTTY_RING_SIZE
-#define ZSTTY_RING_SIZE 2048
-#endif
-
-/*
- * Make this an option variable one can patch.
- * But be warned: this must be a power of 2!
- */
-u_int zstty_rbuf_size = ZSTTY_RING_SIZE;
-
-/* Stop input when 3/4 of the ring is full; restart when only 1/4 is full. */
-u_int zstty_rbuf_hiwat = (ZSTTY_RING_SIZE * 1) / 4;
-u_int zstty_rbuf_lowat = (ZSTTY_RING_SIZE * 3) / 4;
-
-struct zstty_softc {
- struct device zst_dev; /* required first: base device */
- struct tty *zst_tty;
- struct zs_chanstate *zst_cs;
-
- struct timeout zst_diag_ch;
-
- u_int zst_overflows,
- zst_floods,
- zst_errors;
-
- int zst_hwflags, /* see z8530var.h */
- zst_swflags; /* TIOCFLAG_SOFTCAR, ... <ttycom.h> */
-
- u_int zst_r_hiwat,
- zst_r_lowat;
- u_char *volatile zst_rbget,
- *volatile zst_rbput;
- volatile u_int zst_rbavail;
- u_char *zst_rbuf,
- *zst_ebuf;
-
- /*
- * The transmit byte count and address are used for pseudo-DMA
- * output in the hardware interrupt code. PDMA can be suspended
- * to get pending changes done; heldtbc is used for this. It can
- * also be stopped for ^S; this sets TS_TTSTOP in tp->t_state.
- */
- u_char *zst_tba; /* transmit buffer address */
- u_int zst_tbc, /* transmit byte count */
- zst_heldtbc; /* held tbc while xmission stopped */
-
- /* Flags to communicate with zstty_softint() */
- volatile u_char zst_rx_flags, /* receiver blocked */
-#define RX_TTY_BLOCKED 0x01
-#define RX_TTY_OVERFLOWED 0x02
-#define RX_IBUF_BLOCKED 0x04
-#define RX_IBUF_OVERFLOWED 0x08
-#define RX_ANY_BLOCK 0x0f
- zst_tx_busy, /* working on an output chunk */
- zst_tx_done, /* done with one output chunk */
- zst_tx_stopped, /* H/W level stop (lost CTS) */
- zst_st_check, /* got a status interrupt */
- zst_rx_ready;
-
- /* PPS signal on DCD, with or without inkernel clock disciplining */
- u_char zst_ppsmask; /* pps signal mask */
- u_char zst_ppsassert; /* pps leading edge */
- u_char zst_ppsclear; /* pps trailing edge */
-};
-
-
-/* Definition of the driver for autoconfig. */
-int zstty_match(struct device *, void *, void *);
-void zstty_attach(struct device *, struct device *, void *);
-
-struct cfattach zstty_ca = {
- sizeof(struct zstty_softc), zstty_match, zstty_attach
-};
-
-struct cfdriver zstty_cd = {
- NULL, "zstty", DV_TTY
-};
-
-struct zsops zsops_tty;
-
-/* Routines called from other code. */
-cdev_decl(zs); /* open, close, read, write, ioctl, stop, ... */
-
-void zs_shutdown(struct zstty_softc *);
-void zsstart(struct tty *);
-int zsparam(struct tty *, struct termios *);
-void zs_modem(struct zstty_softc *, int);
-void tiocm_to_zs(struct zstty_softc *, u_long, int);
-int zs_to_tiocm(struct zstty_softc *);
-int zshwiflow(struct tty *, int);
-void zs_hwiflow(struct zstty_softc *);
-void zs_maskintr(struct zstty_softc *);
-
-/* Low-level routines. */
-void zstty_rxint(struct zs_chanstate *);
-void zstty_stint(struct zs_chanstate *, int);
-void zstty_txint(struct zs_chanstate *);
-void zstty_softint(struct zs_chanstate *);
-void zstty_diag(void *);
-
-#define ZSUNIT(x) (minor(x) & 0x7f)
-#define ZSDIALOUT(x) (minor(x) & 0x80)
-
-/*
- * zstty_match: how is this zs channel configured?
- */
-int
-zstty_match(parent, match, aux)
- struct device *parent;
- void *match, *aux;
-{
- struct cfdata *cf = match;
- struct zsc_attach_args *args = aux;
-
- /* Exact match is better than wildcard. */
- if (cf->cf_loc[ZSCCF_CHANNEL] == args->channel)
- return 2;
-
- /* This driver accepts wildcard. */
- if (cf->cf_loc[ZSCCF_CHANNEL] == ZSCCF_CHANNEL_DEFAULT)
- return 1;
-
- return 0;
-}
-
-void
-zstty_attach(parent, self, aux)
- struct device *parent, *self;
- void *aux;
-
-{
- struct zsc_softc *zsc = (void *) parent;
- struct zstty_softc *zst = (void *) self;
- struct zsc_attach_args *args = aux;
- struct zs_chanstate *cs;
- struct cfdata *cf;
- struct tty *tp;
- int channel, s, tty_unit;
- dev_t dev;
- char *i, *o;
-
- cf = zst->zst_dev.dv_cfdata;
-
- timeout_set(&zst->zst_diag_ch, zstty_diag, zst);
-
- tty_unit = zst->zst_dev.dv_unit;
- channel = args->channel;
- cs = &zsc->zsc_cs[channel];
- cs->cs_private = zst;
- cs->cs_ops = &zsops_tty;
-
- zst->zst_cs = cs;
- zst->zst_swflags = cf->cf_flags; /* softcar, etc. */
- zst->zst_hwflags = args->hwflags;
- dev = makedev(zs_major, tty_unit);
-
- if (zst->zst_swflags)
- printf(" flags 0x%x", zst->zst_swflags);
-
- /*
- * Check whether we serve as a console device.
- * XXX - split console input/output channels aren't
- * supported yet on /dev/console
- */
- i = o = NULL;
- if ((zst->zst_hwflags & ZS_HWFLAG_CONSOLE_INPUT) != 0) {
- i = " input";
- if ((args->hwflags & ZS_HWFLAG_USE_CONSDEV) != 0) {
- args->consdev->cn_dev = dev;
- cn_tab->cn_pollc = args->consdev->cn_pollc;
- cn_tab->cn_getc = args->consdev->cn_getc;
- }
- cn_tab->cn_dev = dev;
- /* Set console magic to BREAK */
- }
- if ((zst->zst_hwflags & ZS_HWFLAG_CONSOLE_OUTPUT) != 0) {
- o = " output";
- if ((args->hwflags & ZS_HWFLAG_USE_CONSDEV) != 0) {
- cn_tab->cn_putc = args->consdev->cn_putc;
- }
- cn_tab->cn_dev = dev;
- }
- if (i != NULL || o != NULL)
- printf(": console%s", i ? (o ? "" : i) : o);
-
-#ifdef KGDB
- /*
- * Allow kgdb to "take over" this port. If this port is
- * NOT the kgdb port, zs_check_kgdb() will return zero.
- * If it IS the kgdb port, it will print "kgdb,...\n"
- * and then return non-zero.
- */
- if (zs_check_kgdb(cs, dev)) {
- printf(" (kgdb)\n");
- /*
- * This is the kgdb port (exclusive use)
- * so skip the normal attach code.
- */
- return;
- }
-#endif
-
- if (strcmp(args->type, "keyboard") == 0 ||
- strcmp(args->type, "mouse") == 0)
- printf(": %s", args->type);
-
- printf("\n");
-
- tp = ttymalloc(0);
- tp->t_dev = dev;
- tp->t_oproc = zsstart;
- tp->t_param = zsparam;
- tp->t_hwiflow = zshwiflow;
-
- zst->zst_tty = tp;
- zst->zst_rbuf = malloc(zstty_rbuf_size << 1, M_DEVBUF, M_WAITOK);
- zst->zst_ebuf = zst->zst_rbuf + (zstty_rbuf_size << 1);
- /* Disable the high water mark. */
- zst->zst_r_hiwat = 0;
- zst->zst_r_lowat = 0;
- zst->zst_rbget = zst->zst_rbput = zst->zst_rbuf;
- zst->zst_rbavail = zstty_rbuf_size;
-
- /* if there are no enable/disable functions, assume the device
- is always enabled */
- if (!cs->enable)
- cs->enabled = 1;
-
- /*
- * Hardware init
- */
- if (ISSET(zst->zst_hwflags, ZS_HWFLAG_CONSOLE)) {
- /* Call zsparam similar to open. */
- struct termios t;
-
- /* Wait a while for previous console output to complete */
- DELAY(10000);
-
- /* Setup the "new" parameters in t. */
- t.c_ispeed = 0;
- t.c_ospeed = cs->cs_defspeed;
- t.c_cflag = cs->cs_defcflag;
-
- s = splzs();
-
- /*
- * Turn on receiver and status interrupts.
- * We defer the actual write of the register to zsparam(),
- * but we must make sure status interrupts are turned on by
- * the time zsparam() reads the initial rr0 state.
- */
- SET(cs->cs_preg[1], ZSWR1_RIE | ZSWR1_SIE);
-
- splx(s);
-
- /* Make sure zsparam will see changes. */
- tp->t_ospeed = 0;
- (void) zsparam(tp, &t);
-
- s = splzs();
-
- /* Make sure DTR is on now. */
- zs_modem(zst, 1);
-
- splx(s);
- } else if (!ISSET(zst->zst_hwflags, ZS_HWFLAG_NORESET)) {
- /* Not the console; may need reset. */
- int reset;
-
- reset = (channel == 0) ? ZSWR9_A_RESET : ZSWR9_B_RESET;
-
- s = splzs();
-
- zs_write_reg(cs, 9, reset);
-
- /* Will raise DTR in open. */
- zs_modem(zst, 0);
-
- splx(s);
- }
-}
-
-
-/*
- * Return pointer to our tty.
- */
-struct tty *
-zstty(dev)
- dev_t dev;
-{
- struct zstty_softc *zst;
- int unit = ZSUNIT(dev);
-
-#ifdef DIAGNOSTIC
- if (unit >= zstty_cd.cd_ndevs)
- panic("zstty");
-#endif
- zst = zstty_cd.cd_devs[unit];
- return (zst->zst_tty);
-}
-
-
-void
-zs_shutdown(zst)
- struct zstty_softc *zst;
-{
- struct zs_chanstate *cs = zst->zst_cs;
- struct tty *tp = zst->zst_tty;
- int s;
-
- s = splzs();
-
- /* If we were asserting flow control, then deassert it. */
- SET(zst->zst_rx_flags, RX_IBUF_BLOCKED);
- zs_hwiflow(zst);
-
- /* Clear any break condition set with TIOCSBRK. */
- zs_break(cs, 0);
-
- /* Turn off PPS capture on last close. */
- zst->zst_ppsmask = 0;
-
- /*
- * Hang up if necessary. Wait a bit, so the other side has time to
- * notice even if we immediately open the port again.
- */
- if (ISSET(tp->t_cflag, HUPCL) || ISSET(tp->t_state, TS_WOPEN)) {
- zs_modem(zst, 0);
- /* hold low for 1 second */
- (void) tsleep(cs, TTIPRI, ttclos, hz);
- }
-
- /* Turn off interrupts if not the console. */
- if (!ISSET(zst->zst_hwflags, ZS_HWFLAG_CONSOLE)) {
- CLR(cs->cs_preg[1], ZSWR1_RIE | ZSWR1_SIE);
- cs->cs_creg[1] = cs->cs_preg[1];
- zs_write_reg(cs, 1, cs->cs_creg[1]);
- }
-
-/* Call the power management hook. */
- if (cs->disable) {
-#ifdef DIAGNOSTIC
- if (!cs->enabled)
- panic("zs_shutdown: not enabled?");
-#endif
- (*cs->disable)(zst->zst_cs);
- }
-
- splx(s);
-}
-
-/*
- * Open a zs serial (tty) port.
- */
-int
-zsopen(dev, flags, mode, p)
- dev_t dev;
- int flags;
- int mode;
- struct proc *p;
-{
- register struct tty *tp;
- register struct zs_chanstate *cs;
- struct zstty_softc *zst;
- int s, s2;
- int error, unit;
-
- unit = ZSUNIT(dev);
- if (unit >= zstty_cd.cd_ndevs)
- return (ENXIO);
- zst = zstty_cd.cd_devs[unit];
- if (zst == NULL)
- return (ENXIO);
- tp = zst->zst_tty;
- cs = zst->zst_cs;
-
- /* If KGDB took the line, then tp==NULL */
- if (tp == NULL)
- return (EBUSY);
-
- if (ISSET(tp->t_state, TS_ISOPEN) &&
- ISSET(tp->t_state, TS_XCLUDE) &&
- suser(p, 0) != 0)
- return (EBUSY);
-
- s = spltty();
-
- /*
- * Do the following iff this is a first open.
- */
- if (!ISSET(tp->t_state, TS_ISOPEN)) {
- struct termios t;
-
- tp->t_dev = dev;
-
- /* Call the power management hook. */
- if (cs->enable) {
- if ((*cs->enable)(cs)) {
- splx(s);
- printf("%s: device enable failed\n",
- zst->zst_dev.dv_xname);
- return (EIO);
- }
- }
-
- /*
- * Initialize the termios status to the defaults. Add in the
- * sticky bits from TIOCSFLAGS.
- */
- t.c_ispeed = 0;
- t.c_ospeed = cs->cs_defspeed;
- t.c_cflag = cs->cs_defcflag;
- if (ISSET(zst->zst_swflags, TIOCFLAG_CLOCAL))
- SET(t.c_cflag, CLOCAL);
- if (ISSET(zst->zst_swflags, TIOCFLAG_CRTSCTS))
- SET(t.c_cflag, CRTSCTS);
- if (ISSET(zst->zst_swflags, TIOCFLAG_MDMBUF))
- SET(t.c_cflag, MDMBUF);
-
- s2 = splzs();
-
- /*
- * Turn on receiver and status interrupts.
- * We defer the actual write of the register to zsparam(),
- * but we must make sure status interrupts are turned on by
- * the time zsparam() reads the initial rr0 state.
- */
- SET(cs->cs_preg[1], ZSWR1_RIE | ZSWR1_SIE);
-
- /* Clear PPS capture state on first open. */
- zst->zst_ppsmask = 0;
-
- splx(s2);
-
- /* Make sure zsparam will see changes. */
- tp->t_ospeed = 0;
- (void) zsparam(tp, &t);
-
- /*
- * Note: zsparam has done: cflag, ispeed, ospeed
- * so we just need to do: iflag, oflag, lflag, cc
- * For "raw" mode, just leave all zeros.
- */
- if (!ISSET(zst->zst_hwflags, ZS_HWFLAG_RAW)) {
- tp->t_iflag = TTYDEF_IFLAG;
- tp->t_oflag = TTYDEF_OFLAG;
- tp->t_lflag = TTYDEF_LFLAG;
- } else {
- tp->t_iflag = 0;
- tp->t_oflag = 0;
- tp->t_lflag = 0;
- }
- ttychars(tp);
- ttsetwater(tp);
-
- if (ZSDIALOUT(dev))
- SET(tp->t_state, TS_CARR_ON);
- else
- CLR(tp->t_state, TS_CARR_ON);
-
- s2 = splzs();
-
- /* Clear the input ring, and unblock. */
- zst->zst_rbget = zst->zst_rbput = zst->zst_rbuf;
- zst->zst_rbavail = zstty_rbuf_size;
- zs_iflush(cs);
- CLR(zst->zst_rx_flags, RX_ANY_BLOCK);
- zs_hwiflow(zst);
-
- splx(s2);
- }
-
- if (ZSDIALOUT(dev)) {
- if (ISSET(tp->t_state, TS_ISOPEN)) {
- /* someone already is dialed in... */
- splx(s);
- return EBUSY;
- }
- cs->cs_cua = 1;
- }
-
- error = 0;
- /* wait for carrier if necessary */
- if (ISSET(flags, O_NONBLOCK)) {
- if (!ZSDIALOUT(dev) && cs->cs_cua) {
- /* Opening TTY non-blocking... but the CUA is busy */
- error = EBUSY;
- }
- } else
- while (cs->cs_cua ||
- (!ISSET(tp->t_cflag, CLOCAL) && !ISSET(tp->t_state, TS_CARR_ON))) {
- int rr0;
-
- error = 0;
- SET(tp->t_state, TS_WOPEN);
-
- if (!ZSDIALOUT(dev) && !cs->cs_cua) {
- /*
- * Turn on DTR. We must always do this on non-CUA
- * devices, even if carrier is not present, because
- * otherwise we'd have to use TIOCSDTR immediately
- * after setting CLOCAL, which applications do not
- * expect. We always assert DTR while the device is
- * open unless explicitly requested to deassert it.
- */
- s2 = splzs();
- zs_modem(zst, 1);
- rr0 = zs_read_csr(cs);
- splx(s2);
-
- /* loop, turning on the device, until carrier present */
- if (ISSET(rr0, ZSRR0_DCD) ||
- ISSET(zst->zst_swflags, TIOCFLAG_SOFTCAR))
- SET(tp->t_state, TS_CARR_ON);
- }
-
- if ((ISSET(tp->t_cflag, CLOCAL) ||
- ISSET(tp->t_state, TS_CARR_ON)) && !cs->cs_cua)
- break;
-
- error = ttysleep(tp, (caddr_t)&tp->t_rawq, TTIPRI | PCATCH,
- ttopen, 0);
-
- if (!ZSDIALOUT(dev) && cs->cs_cua && error == EINTR) {
- error = 0;
- continue;
- }
-
- if (error) {
- if (!ISSET(tp->t_state, TS_ISOPEN)) {
- s2 = splzs();
- zs_modem(zst, 0);
- splx(s2);
- CLR(tp->t_state, TS_WOPEN);
- ttwakeup(tp);
- }
- if (ZSDIALOUT(dev))
- cs->cs_cua = 0;
- CLR(tp->t_state, TS_WOPEN);
- break;
- }
- if (!ZSDIALOUT(dev) && cs->cs_cua)
- continue;
- }
-
- splx(s);
-
- if (error == 0)
- error = ((*linesw[tp->t_line].l_open)(dev, tp, p));
- if (error)
- goto bad;
-
- return (0);
-
-bad:
- if (!ISSET(tp->t_state, TS_ISOPEN)) {
- /*
- * We failed to open the device, and nobody else had it opened.
- * Clean up the state as appropriate.
- */
- zs_shutdown(zst);
- }
-
- return (error);
-}
-
-/*
- * Close a zs serial port.
- */
-int
-zsclose(dev, flags, mode, p)
- dev_t dev;
- int flags;
- int mode;
- struct proc *p;
-{
- struct zstty_softc *zst;
- struct zs_chanstate *cs;
- struct tty *tp;
- int s;
-
- zst = zstty_cd.cd_devs[ZSUNIT(dev)];
- cs = zst->zst_cs;
- tp = zst->zst_tty;
-
- /* XXX This is for cons.c. */
- if (!ISSET(tp->t_state, TS_ISOPEN))
- return 0;
-
- (*linesw[tp->t_line].l_close)(tp, flags, p);
-
- s = spltty();
- cs->cs_cua = 0;
- ttyclose(tp);
- splx(s);
-
- if (!ISSET(tp->t_state, TS_ISOPEN)) {
- /*
- * Although we got a last close, the device may still be in
- * use; e.g. if this was the dialout node, and there are still
- * processes waiting for carrier on the non-dialout node.
- */
- zs_shutdown(zst);
- }
-
- return (0);
-}
-
-/*
- * Read/write zs serial port.
- */
-int
-zsread(dev, uio, flags)
- dev_t dev;
- struct uio *uio;
- int flags;
-{
- struct zstty_softc *zst;
- struct tty *tp;
-
- zst = zstty_cd.cd_devs[ZSUNIT(dev)];
- tp = zst->zst_tty;
-
- return (*linesw[tp->t_line].l_read)(tp, uio, flags);
-}
-
-int
-zswrite(dev, uio, flags)
- dev_t dev;
- struct uio *uio;
- int flags;
-{
- struct zstty_softc *zst;
- struct tty *tp;
-
- zst = zstty_cd.cd_devs[ZSUNIT(dev)];
- tp = zst->zst_tty;
-
- return (*linesw[tp->t_line].l_write)(tp, uio, flags);
-}
-
-#define TIOCFLAG_ALL (TIOCFLAG_SOFTCAR | TIOCFLAG_CLOCAL | \
- TIOCFLAG_CRTSCTS | TIOCFLAG_MDMBUF )
-
-int
-zsioctl(dev, cmd, data, flag, p)
- dev_t dev;
- u_long cmd;
- caddr_t data;
- int flag;
- struct proc *p;
-{
- struct zstty_softc *zst;
- struct zs_chanstate *cs;
- struct tty *tp;
- int error;
- int s;
-
- zst = zstty_cd.cd_devs[ZSUNIT(dev)];
- cs = zst->zst_cs;
- tp = zst->zst_tty;
-
- error = ((*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag, p));
- if (error >= 0)
- return (error);
-
- error = ttioctl(tp, cmd, data, flag, p);
- if (error >= 0)
- return (error);
-
-#ifdef ZS_MD_IOCTL
- error = ZS_MD_IOCTL;
- if (error >= 0)
- return (error);
-#endif /* ZS_MD_IOCTL */
-
- error = 0;
-
- s = splzs();
-
- switch (cmd) {
- case TIOCSBRK:
- zs_break(cs, 1);
- break;
-
- case TIOCCBRK:
- zs_break(cs, 0);
- break;
-
- case TIOCGFLAGS:
- *(int *)data = zst->zst_swflags;
- break;
-
- case TIOCSFLAGS:
- error = suser(p, 0);
- if (error != 0)
- break;
- zst->zst_swflags = *(int *)data;
- break;
-
- case TIOCSDTR:
- zs_modem(zst, 1);
- break;
-
- case TIOCCDTR:
- zs_modem(zst, 0);
- break;
-
- case TIOCMSET:
- case TIOCMBIS:
- case TIOCMBIC:
- tiocm_to_zs(zst, cmd, *(int *)data);
- break;
-
- case TIOCMGET:
- *(int *)data = zs_to_tiocm(zst);
- break;
-
- default:
- error = ENOTTY;
- break;
- }
-
- splx(s);
-
- return (error);
-}
-
-/*
- * Start or restart transmission.
- */
-void
-zsstart(tp)
- struct tty *tp;
-{
- struct zstty_softc *zst;
- struct zs_chanstate *cs;
- int s;
-
- zst = zstty_cd.cd_devs[ZSUNIT(tp->t_dev)];
- cs = zst->zst_cs;
-
- s = spltty();
- if (ISSET(tp->t_state, TS_BUSY | TS_TIMEOUT | TS_TTSTOP))
- goto out;
- if (zst->zst_tx_stopped)
- goto out;
-
- ttwakeupwr(tp);
- if (tp->t_outq.c_cc == 0)
- goto out;
-
- /* Grab the first contiguous region of buffer space. */
- {
- u_char *tba;
- int tbc;
-
- tba = tp->t_outq.c_cf;
- tbc = ndqb(&tp->t_outq, 0);
-
- (void) splzs();
-
- zst->zst_tba = tba;
- zst->zst_tbc = tbc;
- }
-
- SET(tp->t_state, TS_BUSY);
- zst->zst_tx_busy = 1;
-
- /* Enable transmit completion interrupts if necessary. */
- if (!ISSET(cs->cs_preg[1], ZSWR1_TIE)) {
- SET(cs->cs_preg[1], ZSWR1_TIE);
- cs->cs_creg[1] = cs->cs_preg[1];
- zs_write_reg(cs, 1, cs->cs_creg[1]);
- }
-
- /* Output the first character of the contiguous buffer. */
- {
- zs_write_data(cs, *zst->zst_tba);
- zst->zst_tbc--;
- zst->zst_tba++;
- }
-out:
- splx(s);
-}
-
-/*
- * Stop output, e.g., for ^S or output flush.
- */
-int
-zsstop(tp, flag)
- struct tty *tp;
- int flag;
-{
- struct zstty_softc *zst;
- struct zs_chanstate *cs;
- int s;
-
- zst = zstty_cd.cd_devs[ZSUNIT(tp->t_dev)];
- cs = zst->zst_cs;
-
- s = splzs();
- if (ISSET(tp->t_state, TS_BUSY)) {
- /* Stop transmitting at the next chunk. */
- zst->zst_tbc = 0;
- zst->zst_heldtbc = 0;
- if (!ISSET(tp->t_state, TS_TTSTOP))
- SET(tp->t_state, TS_FLUSH);
- }
- splx(s);
- return (0);
-}
-
-/*
- * Set ZS tty parameters from termios.
- * XXX - Should just copy the whole termios after
- * making sure all the changes could be done.
- */
-int
-zsparam(tp, t)
- struct tty *tp;
- struct termios *t;
-{
- struct zstty_softc *zst;
- struct zs_chanstate *cs;
- int ospeed, cflag;
- u_char tmp3, tmp4, tmp5;
- int s, error;
-
- zst = zstty_cd.cd_devs[ZSUNIT(tp->t_dev)];
- cs = zst->zst_cs;
-
- ospeed = t->c_ospeed;
- cflag = t->c_cflag;
-
- /* Check requested parameters. */
- if (ospeed < 0)
- return (EINVAL);
- if (t->c_ispeed && t->c_ispeed != ospeed)
- return (EINVAL);
-
- /*
- * For the console, always force CLOCAL and !HUPCL, so that the port
- * is always active.
- */
- if (ISSET(zst->zst_swflags, TIOCFLAG_SOFTCAR) ||
- ISSET(zst->zst_hwflags, ZS_HWFLAG_CONSOLE)) {
- SET(cflag, CLOCAL);
- CLR(cflag, HUPCL);
- }
-
- /*
- * Only whack the UART when params change.
- * Some callers need to clear tp->t_ospeed
- * to make sure initialization gets done.
- */
- if (tp->t_ospeed == ospeed &&
- tp->t_cflag == cflag)
- return (0);
-
- /*
- * Call MD functions to deal with changed
- * clock modes or H/W flow control modes.
- * The BRG divisor is set now. (reg 12,13)
- */
- error = zs_set_speed(cs, ospeed);
- if (error)
- return (error);
- error = zs_set_modes(cs, cflag);
- if (error)
- return (error);
-
- /*
- * Block interrupts so that state will not
- * be altered until we are done setting it up.
- *
- * Initial values in cs_preg are set before
- * our attach routine is called. The master
- * interrupt enable is handled by zsc.c
- */
- s = splzs();
-
- /*
- * Recalculate which status ints to enable.
- */
- zs_maskintr(zst);
-
- /* Recompute character size bits. */
- tmp3 = cs->cs_preg[3];
- tmp5 = cs->cs_preg[5];
- CLR(tmp3, ZSWR3_RXSIZE);
- CLR(tmp5, ZSWR5_TXSIZE);
- switch (ISSET(cflag, CSIZE)) {
- case CS5:
- SET(tmp3, ZSWR3_RX_5);
- SET(tmp5, ZSWR5_TX_5);
- break;
- case CS6:
- SET(tmp3, ZSWR3_RX_6);
- SET(tmp5, ZSWR5_TX_6);
- break;
- case CS7:
- SET(tmp3, ZSWR3_RX_7);
- SET(tmp5, ZSWR5_TX_7);
- break;
- case CS8:
- SET(tmp3, ZSWR3_RX_8);
- SET(tmp5, ZSWR5_TX_8);
- break;
- }
- cs->cs_preg[3] = tmp3;
- cs->cs_preg[5] = tmp5;
-
- /*
- * Recompute the stop bits and parity bits. Note that
- * zs_set_speed() may have set clock selection bits etc.
- * in wr4, so those must preserved.
- */
- tmp4 = cs->cs_preg[4];
- CLR(tmp4, ZSWR4_SBMASK | ZSWR4_PARMASK);
- if (ISSET(cflag, CSTOPB))
- SET(tmp4, ZSWR4_TWOSB);
- else
- SET(tmp4, ZSWR4_ONESB);
- if (!ISSET(cflag, PARODD))
- SET(tmp4, ZSWR4_EVENP);
- if (ISSET(cflag, PARENB))
- SET(tmp4, ZSWR4_PARENB);
- cs->cs_preg[4] = tmp4;
-
- /* And copy to tty. */
- tp->t_ispeed = 0;
- tp->t_ospeed = ospeed;
- tp->t_cflag = cflag;
-
- /*
- * If nothing is being transmitted, set up new current values,
- * else mark them as pending.
- */
- if (!cs->cs_heldchange) {
- if (zst->zst_tx_busy) {
- zst->zst_heldtbc = zst->zst_tbc;
- zst->zst_tbc = 0;
- cs->cs_heldchange = 1;
- } else
- zs_loadchannelregs(cs);
- }
-
- /*
- * If hardware flow control is disabled, turn off the buffer water
- * marks and unblock any soft flow control state. Otherwise, enable
- * the water marks.
- */
- if (!ISSET(cflag, CHWFLOW)) {
- zst->zst_r_hiwat = 0;
- zst->zst_r_lowat = 0;
- if (ISSET(zst->zst_rx_flags, RX_TTY_OVERFLOWED)) {
- CLR(zst->zst_rx_flags, RX_TTY_OVERFLOWED);
- zst->zst_rx_ready = 1;
- cs->cs_softreq = 1;
- }
- if (ISSET(zst->zst_rx_flags, RX_TTY_BLOCKED|RX_IBUF_BLOCKED)) {
- CLR(zst->zst_rx_flags, RX_TTY_BLOCKED|RX_IBUF_BLOCKED);
- zs_hwiflow(zst);
- }
- } else {
- zst->zst_r_hiwat = zstty_rbuf_hiwat;
- zst->zst_r_lowat = zstty_rbuf_lowat;
- }
-
- /*
- * Force a recheck of the hardware carrier and flow control status,
- * since we may have changed which bits we're looking at.
- */
- zstty_stint(cs, 1);
-
- splx(s);
-
- /*
- * If hardware flow control is disabled, unblock any hard flow control
- * state.
- */
- if (!ISSET(cflag, CHWFLOW)) {
- if (zst->zst_tx_stopped) {
- zst->zst_tx_stopped = 0;
- zsstart(tp);
- }
- }
-
- zstty_softint(cs);
-
- return (0);
-}
-
-/*
- * Compute interrupt enable bits and set in the pending bits. Called both
- * in zsparam() and when PPS (pulse per second timing) state changes.
- * Must be called at splzs().
- */
-void
-zs_maskintr(zst)
- struct zstty_softc *zst;
-{
- struct zs_chanstate *cs = zst->zst_cs;
- int tmp15;
-
- cs->cs_rr0_mask = cs->cs_rr0_cts | cs->cs_rr0_dcd;
- if (zst->zst_ppsmask != 0)
- cs->cs_rr0_mask |= cs->cs_rr0_pps;
- tmp15 = cs->cs_preg[15];
- if (ISSET(cs->cs_rr0_mask, ZSRR0_DCD))
- SET(tmp15, ZSWR15_DCD_IE);
- else
- CLR(tmp15, ZSWR15_DCD_IE);
- if (ISSET(cs->cs_rr0_mask, ZSRR0_CTS))
- SET(tmp15, ZSWR15_CTS_IE);
- else
- CLR(tmp15, ZSWR15_CTS_IE);
- cs->cs_preg[15] = tmp15;
-}
-
-/*
- * Raise or lower modem control (DTR/RTS) signals. If a character is
- * in transmission, the change is deferred.
- */
-void
-zs_modem(zst, onoff)
- struct zstty_softc *zst;
- int onoff;
-{
- struct zs_chanstate *cs = zst->zst_cs;
-
- if (cs->cs_wr5_dtr == 0)
- return;
-
- if (onoff)
- SET(cs->cs_preg[5], cs->cs_wr5_dtr);
- else
- CLR(cs->cs_preg[5], cs->cs_wr5_dtr);
-
- if (!cs->cs_heldchange) {
- if (zst->zst_tx_busy) {
- zst->zst_heldtbc = zst->zst_tbc;
- zst->zst_tbc = 0;
- cs->cs_heldchange = 1;
- } else
- zs_loadchannelregs(cs);
- }
-}
-
-void
-tiocm_to_zs(zst, how, ttybits)
- struct zstty_softc *zst;
- u_long how;
- int ttybits;
-{
- struct zs_chanstate *cs = zst->zst_cs;
- u_char zsbits;
-
- zsbits = 0;
- if (ISSET(ttybits, TIOCM_DTR))
- SET(zsbits, ZSWR5_DTR);
- if (ISSET(ttybits, TIOCM_RTS))
- SET(zsbits, ZSWR5_RTS);
-
- switch (how) {
- case TIOCMBIC:
- CLR(cs->cs_preg[5], zsbits);
- break;
-
- case TIOCMBIS:
- SET(cs->cs_preg[5], zsbits);
- break;
-
- case TIOCMSET:
- CLR(cs->cs_preg[5], ZSWR5_RTS | ZSWR5_DTR);
- SET(cs->cs_preg[5], zsbits);
- break;
- }
-
- if (!cs->cs_heldchange) {
- if (zst->zst_tx_busy) {
- zst->zst_heldtbc = zst->zst_tbc;
- zst->zst_tbc = 0;
- cs->cs_heldchange = 1;
- } else
- zs_loadchannelregs(cs);
- }
-}
-
-int
-zs_to_tiocm(zst)
- struct zstty_softc *zst;
-{
- struct zs_chanstate *cs = zst->zst_cs;
- u_char zsbits;
- int ttybits = 0;
-
- zsbits = cs->cs_preg[5];
- if (ISSET(zsbits, ZSWR5_DTR))
- SET(ttybits, TIOCM_DTR);
- if (ISSET(zsbits, ZSWR5_RTS))
- SET(ttybits, TIOCM_RTS);
-
- zsbits = cs->cs_rr0;
- if (ISSET(zsbits, ZSRR0_DCD))
- SET(ttybits, TIOCM_CD);
- if (ISSET(zsbits, ZSRR0_CTS))
- SET(ttybits, TIOCM_CTS);
-
- return (ttybits);
-}
-
-/*
- * Try to block or unblock input using hardware flow-control.
- * This is called by kern/tty.c if MDMBUF|CRTSCTS is set, and
- * if this function returns non-zero, the TS_TBLOCK flag will
- * be set or cleared according to the "block" arg passed.
- */
-int
-zshwiflow(tp, block)
- struct tty *tp;
- int block;
-{
- struct zstty_softc *zst;
- struct zs_chanstate *cs;
- int s;
-
- zst = zstty_cd.cd_devs[ZSUNIT(tp->t_dev)];
- cs = zst->zst_cs;
-
- if (cs->cs_wr5_rts == 0)
- return (0);
-
- s = splzs();
- if (block) {
- if (!ISSET(zst->zst_rx_flags, RX_TTY_BLOCKED)) {
- SET(zst->zst_rx_flags, RX_TTY_BLOCKED);
- zs_hwiflow(zst);
- }
- } else {
- if (ISSET(zst->zst_rx_flags, RX_TTY_OVERFLOWED)) {
- CLR(zst->zst_rx_flags, RX_TTY_OVERFLOWED);
- zst->zst_rx_ready = 1;
- cs->cs_softreq = 1;
- }
- if (ISSET(zst->zst_rx_flags, RX_TTY_BLOCKED)) {
- CLR(zst->zst_rx_flags, RX_TTY_BLOCKED);
- zs_hwiflow(zst);
- }
- }
- splx(s);
- return (1);
-}
-
-/*
- * Internal version of zshwiflow
- * called at splzs
- */
-void
-zs_hwiflow(zst)
- struct zstty_softc *zst;
-{
- struct zs_chanstate *cs = zst->zst_cs;
-
- if (cs->cs_wr5_rts == 0)
- return;
-
- if (ISSET(zst->zst_rx_flags, RX_ANY_BLOCK)) {
- CLR(cs->cs_preg[5], cs->cs_wr5_rts);
- CLR(cs->cs_creg[5], cs->cs_wr5_rts);
- } else {
- SET(cs->cs_preg[5], cs->cs_wr5_rts);
- SET(cs->cs_creg[5], cs->cs_wr5_rts);
- }
- zs_write_reg(cs, 5, cs->cs_creg[5]);
-}
-
-
-/****************************************************************
- * Interface to the lower layer (zscc)
- ****************************************************************/
-
-void zstty_rxsoft(struct zstty_softc *, struct tty *);
-void zstty_txsoft(struct zstty_softc *, struct tty *);
-void zstty_stsoft(struct zstty_softc *, struct tty *);
-
-/*
- * receiver ready interrupt.
- * called at splzs
- */
-void
-zstty_rxint(cs)
- struct zs_chanstate *cs;
-{
- struct zstty_softc *zst = cs->cs_private;
- u_char *put, *end;
- u_int cc;
- u_char rr0, rr1, c;
-
- end = zst->zst_ebuf;
- put = zst->zst_rbput;
- cc = zst->zst_rbavail;
-
- while (cc > 0) {
- /*
- * First read the status, because reading the received char
- * destroys the status of this char.
- */
- rr1 = zs_read_reg(cs, 1);
- c = zs_read_data(cs);
-
- if (ISSET(rr1, ZSRR1_FE | ZSRR1_DO | ZSRR1_PE)) {
- /* Clear the receive error. */
- zs_write_csr(cs, ZSWR0_RESET_ERRORS);
- }
-
- put[0] = c;
- put[1] = rr1;
- put += 2;
- if (put >= end)
- put = zst->zst_rbuf;
- cc--;
-
- rr0 = zs_read_csr(cs);
- if (!ISSET(rr0, ZSRR0_RX_READY))
- break;
- }
-
- /*
- * Current string of incoming characters ended because
- * no more data was available or we ran out of space.
- * Schedule a receive event if any data was received.
- * If we're out of space, turn off receive interrupts.
- */
- zst->zst_rbput = put;
- zst->zst_rbavail = cc;
- if (!ISSET(zst->zst_rx_flags, RX_TTY_OVERFLOWED)) {
- zst->zst_rx_ready = 1;
- cs->cs_softreq = 1;
- }
-
- /*
- * See if we are in danger of overflowing a buffer. If
- * so, use hardware flow control to ease the pressure.
- */
- if (!ISSET(zst->zst_rx_flags, RX_IBUF_BLOCKED) &&
- cc < zst->zst_r_hiwat) {
- SET(zst->zst_rx_flags, RX_IBUF_BLOCKED);
- zs_hwiflow(zst);
- }
-
- /*
- * If we're out of space, disable receive interrupts
- * until the queue has drained a bit.
- */
- if (!cc) {
- SET(zst->zst_rx_flags, RX_IBUF_OVERFLOWED);
- CLR(cs->cs_preg[1], ZSWR1_RIE);
- cs->cs_creg[1] = cs->cs_preg[1];
- zs_write_reg(cs, 1, cs->cs_creg[1]);
- }
-}
-
-/*
- * transmitter ready interrupt. (splzs)
- */
-void
-zstty_txint(cs)
- struct zs_chanstate *cs;
-{
- struct zstty_softc *zst = cs->cs_private;
-
- /*
- * If we've delayed a parameter change, do it now, and restart
- * output.
- */
- if (cs->cs_heldchange) {
- zs_loadchannelregs(cs);
- cs->cs_heldchange = 0;
- zst->zst_tbc = zst->zst_heldtbc;
- zst->zst_heldtbc = 0;
- }
-
- /* Output the next character in the buffer, if any. */
- if (zst->zst_tbc > 0) {
- zs_write_data(cs, *zst->zst_tba);
- zst->zst_tbc--;
- zst->zst_tba++;
- } else {
- /* Disable transmit completion interrupts if necessary. */
- if (ISSET(cs->cs_preg[1], ZSWR1_TIE)) {
- CLR(cs->cs_preg[1], ZSWR1_TIE);
- cs->cs_creg[1] = cs->cs_preg[1];
- zs_write_reg(cs, 1, cs->cs_creg[1]);
- }
- if (zst->zst_tx_busy) {
- zst->zst_tx_busy = 0;
- zst->zst_tx_done = 1;
- cs->cs_softreq = 1;
- }
- }
-}
-
-#ifdef DDB
-#include <ddb/db_var.h>
-#define DB_CONSOLE db_console
-#else
-#define DB_CONSOLE 1
-#endif
-
-/*
- * status change interrupt. (splzs)
- */
-void
-zstty_stint(cs, force)
- struct zs_chanstate *cs;
- int force;
-{
- struct zstty_softc *zst = cs->cs_private;
- struct tty *tp = zst->zst_tty;
- u_char rr0, delta;
-
- rr0 = zs_read_csr(cs);
- zs_write_csr(cs, ZSWR0_RESET_STATUS);
-
- /*
- * Check here for console break, so that we can abort
- * even when interrupts are locking up the machine.
- */
- if ((zst->zst_hwflags & ZS_HWFLAG_CONSOLE_INPUT) &&
- ISSET(rr0, ZSRR0_BREAK) && DB_CONSOLE)
- zs_abort(cs);
-
- if (!force)
- delta = rr0 ^ cs->cs_rr0;
- else
- delta = cs->cs_rr0_mask;
-
- ttytstamp(tp, cs->cs_rr0 & ZSRR0_CTS, rr0 & ZSRR0_CTS,
- cs->cs_rr0 & ZSRR0_DCD, rr0 & ZSRR0_DCD);
-
- cs->cs_rr0 = rr0;
-
- if (ISSET(delta, cs->cs_rr0_mask)) {
- SET(cs->cs_rr0_delta, delta);
-
- /*
- * Stop output immediately if we lose the output
- * flow control signal or carrier detect.
- */
- if (ISSET(~rr0, cs->cs_rr0_mask)) {
- zst->zst_tbc = 0;
- zst->zst_heldtbc = 0;
- }
-
- zst->zst_st_check = 1;
- cs->cs_softreq = 1;
- }
-}
-
-void
-zstty_diag(arg)
- void *arg;
-{
- struct zstty_softc *zst = arg;
- int overflows, floods;
- int s;
-
- s = splzs();
- overflows = zst->zst_overflows;
- zst->zst_overflows = 0;
- floods = zst->zst_floods;
- zst->zst_floods = 0;
- zst->zst_errors = 0;
- splx(s);
-
- log(LOG_WARNING, "%s: %d silo overflow%s, %d ibuf flood%s\n",
- zst->zst_dev.dv_xname,
- overflows, overflows == 1 ? "" : "s",
- floods, floods == 1 ? "" : "s");
-}
-
-void
-zstty_rxsoft(zst, tp)
- struct zstty_softc *zst;
- struct tty *tp;
-{
- struct zs_chanstate *cs = zst->zst_cs;
- int (*rint)(int c, struct tty *tp) = linesw[tp->t_line].l_rint;
- u_char *get, *end;
- u_int cc, scc;
- u_char rr1;
- int code;
- int s;
-
- end = zst->zst_ebuf;
- get = zst->zst_rbget;
- scc = cc = zstty_rbuf_size - zst->zst_rbavail;
-
- if (cc == zstty_rbuf_size) {
- zst->zst_floods++;
- if (zst->zst_errors++ == 0)
- timeout_add_sec(&zst->zst_diag_ch, 60);
- }
-
- /* If not yet open, drop the entire buffer content here */
- if (!ISSET(tp->t_state, TS_ISOPEN)) {
- get += cc << 1;
- if (get >= end)
- get -= zstty_rbuf_size << 1;
- cc = 0;
- }
- while (cc) {
- code = get[0];
- rr1 = get[1];
- if (ISSET(rr1, ZSRR1_DO | ZSRR1_FE | ZSRR1_PE)) {
- if (ISSET(rr1, ZSRR1_DO)) {
- zst->zst_overflows++;
- if (zst->zst_errors++ == 0)
- timeout_add_sec(&zst->zst_diag_ch, 60);
- }
- if (ISSET(rr1, ZSRR1_FE))
- SET(code, TTY_FE);
- if (ISSET(rr1, ZSRR1_PE))
- SET(code, TTY_PE);
- }
- if ((*rint)(code, tp) == -1) {
- /*
- * The line discipline's buffer is out of space.
- */
- if (!ISSET(zst->zst_rx_flags, RX_TTY_BLOCKED)) {
- /*
- * We're either not using flow control, or the
- * line discipline didn't tell us to block for
- * some reason. Either way, we have no way to
- * know when there's more space available, so
- * just drop the rest of the data.
- */
- get += cc << 1;
- if (get >= end)
- get -= zstty_rbuf_size << 1;
- cc = 0;
- } else {
- /*
- * Don't schedule any more receive processing
- * until the line discipline tells us there's
- * space available (through comhwiflow()).
- * Leave the rest of the data in the input
- * buffer.
- */
- SET(zst->zst_rx_flags, RX_TTY_OVERFLOWED);
- }
- break;
- }
- get += 2;
- if (get >= end)
- get = zst->zst_rbuf;
- cc--;
- }
-
- if (cc != scc) {
- zst->zst_rbget = get;
- s = splzs();
- cc = zst->zst_rbavail += scc - cc;
- /* Buffers should be ok again, release possible block. */
- if (cc >= zst->zst_r_lowat) {
- if (ISSET(zst->zst_rx_flags, RX_IBUF_OVERFLOWED)) {
- CLR(zst->zst_rx_flags, RX_IBUF_OVERFLOWED);
- SET(cs->cs_preg[1], ZSWR1_RIE);
- cs->cs_creg[1] = cs->cs_preg[1];
- zs_write_reg(cs, 1, cs->cs_creg[1]);
- }
- if (ISSET(zst->zst_rx_flags, RX_IBUF_BLOCKED)) {
- CLR(zst->zst_rx_flags, RX_IBUF_BLOCKED);
- zs_hwiflow(zst);
- }
- }
- splx(s);
- }
-}
-
-void
-zstty_txsoft(zst, tp)
- struct zstty_softc *zst;
- struct tty *tp;
-{
-
- CLR(tp->t_state, TS_BUSY);
- if (ISSET(tp->t_state, TS_FLUSH))
- CLR(tp->t_state, TS_FLUSH);
- else
- ndflush(&tp->t_outq, (int)(zst->zst_tba - tp->t_outq.c_cf));
- (*linesw[tp->t_line].l_start)(tp);
-}
-
-void
-zstty_stsoft(zst, tp)
- struct zstty_softc *zst;
- struct tty *tp;
-{
- struct zs_chanstate *cs = zst->zst_cs;
- u_char rr0, delta;
- int s;
-
- s = splzs();
- rr0 = cs->cs_rr0;
- delta = cs->cs_rr0_delta;
- cs->cs_rr0_delta = 0;
- splx(s);
-
- if (ISSET(delta, cs->cs_rr0_dcd)) {
- /*
- * Inform the tty layer that carrier detect changed.
- */
- (void) (*linesw[tp->t_line].l_modem)(tp, ISSET(rr0, ZSRR0_DCD));
- }
-
- if (ISSET(delta, cs->cs_rr0_cts)) {
- /* Block or unblock output according to flow control. */
- if (ISSET(rr0, cs->cs_rr0_cts)) {
- zst->zst_tx_stopped = 0;
- (*linesw[tp->t_line].l_start)(tp);
- } else {
- zst->zst_tx_stopped = 1;
- }
- }
-}
-
-/*
- * Software interrupt. Called at zssoft
- *
- * The main job to be done here is to empty the input ring
- * by passing its contents up to the tty layer. The ring is
- * always emptied during this operation, therefore the ring
- * must not be larger than the space after "high water" in
- * the tty layer, or the tty layer might drop our input.
- *
- * Note: an "input blockage" condition is assumed to exist if
- * EITHER the TS_TBLOCK flag or zst_rx_blocked flag is set.
- */
-void
-zstty_softint(cs)
- struct zs_chanstate *cs;
-{
- struct zstty_softc *zst = cs->cs_private;
- struct tty *tp = zst->zst_tty;
- int s;
-
- s = spltty();
-
- if (zst->zst_rx_ready) {
- zst->zst_rx_ready = 0;
- zstty_rxsoft(zst, tp);
- }
-
- if (zst->zst_st_check) {
- zst->zst_st_check = 0;
- zstty_stsoft(zst, tp);
- }
-
- if (zst->zst_tx_done) {
- zst->zst_tx_done = 0;
- zstty_txsoft(zst, tp);
- }
-
- splx(s);
-}
-
-struct zsops zsops_tty = {
- zstty_rxint, /* receive char available */
- zstty_stint, /* external/status */
- zstty_txint, /* xmit buffer empty */
- zstty_softint, /* process software interrupt */
-};
diff --git a/sys/arch/sparc/dev/zs.c b/sys/arch/sparc/dev/zs.c
index 49468c319fa..34f52252f84 100644
--- a/sys/arch/sparc/dev/zs.c
+++ b/sys/arch/sparc/dev/zs.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: zs.c,v 1.49 2012/05/25 17:11:40 miod Exp $ */
+/* $OpenBSD: zs.c,v 1.50 2013/04/21 14:44:16 sebastia Exp $ */
/* $NetBSD: zs.c,v 1.50 1997/10/18 00:00:40 gwr Exp $ */
/*-
@@ -62,7 +62,7 @@
#include <machine/z8530var.h>
#include <dev/cons.h>
-#include <sparc/dev/z8530reg.h>
+#include <dev/ic/z8530reg.h>
#include <sparc/sparc/vaddrs.h>
#include <sparc/sparc/auxioreg.h>
@@ -285,18 +285,17 @@ zs_attach(parent, self, aux)
zsc_args.channel = channel;
zsc_args.hwflags = zs_hwflags[zs_unit][channel];
- cs = &zsc->zsc_cs[channel];
+ cs = zsc->zsc_cs[channel] =
+ (struct zs_chanstate *)&zsc->zsc_cs_store[channel];
cs->cs_channel = channel;
cs->cs_private = NULL;
cs->cs_ops = &zsops_null;
cs->cs_brg_clk = PCLK / 16;
-
zc = zs_get_chan_addr(zs_unit, channel);
cs->cs_reg_csr = &zc->zc_csr;
cs->cs_reg_data = &zc->zc_data;
-
bcopy(zs_init_reg, cs->cs_creg, 16);
bcopy(zs_init_reg, cs->cs_preg, 16);
@@ -355,7 +354,7 @@ zs_attach(parent, self, aux)
* Set the master interrupt enable and interrupt vector.
* (common to both channels, do it on A)
*/
- cs = &zsc->zsc_cs[0];
+ cs = zsc->zsc_cs[0];
s = splhigh();
/* interrupt vector */
zs_write_reg(cs, 2, zs_init_reg[2]);
@@ -368,7 +367,7 @@ zs_attach(parent, self, aux)
if (CPU_ISSUN4M) {
if (getpropint(ra->ra_node, "pwr-on-auxio2", 0))
for (channel = 0; channel < 2; channel++) {
- cs = &zsc->zsc_cs[channel];
+ cs = zsc->zsc_cs[channel];
cs->disable = zs_disable;
cs->enable = zs_enable;
cs->enabled = 0;
@@ -427,7 +426,7 @@ zshard(arg)
if (rr3) {
rval |= rr3;
}
- if (zsc->zsc_cs[0].cs_softreq || zsc->zsc_cs[1].cs_softreq)
+ if (zsc->zsc_cs[0]->cs_softreq || zsc->zsc_cs[1]->cs_softreq)
softintr_schedule(zsc->zsc_softih);
}
@@ -1156,7 +1155,11 @@ setup_console:
return;
}
zs_conschan = zc;
- zs_hwflags[zs_unit][channel] = ZS_HWFLAG_CONSOLE;
+ /* hardcoded: console is only on unit 0,
+ * unit 1 is keyboard/mouse, see zs_attach
+ */
+ if (zs_unit == 0)
+ zs_hwflags[zs_unit][channel] = ZS_HWFLAG_CONSOLE;
/* switch to selected console */
cn_tab = console;
(*cn_tab->cn_probe)(cn_tab);
diff --git a/sys/arch/sparc/dev/zs_kgdb.c b/sys/arch/sparc/dev/zs_kgdb.c
index 6dc0e40183c..f2d8b00d58d 100644
--- a/sys/arch/sparc/dev/zs_kgdb.c
+++ b/sys/arch/sparc/dev/zs_kgdb.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: zs_kgdb.c,v 1.4 2010/07/10 19:32:24 miod Exp $ */
+/* $OpenBSD: zs_kgdb.c,v 1.5 2013/04/21 14:44:16 sebastia Exp $ */
/* $NetBSD: zs_kgdb.c,v 1.1 1997/10/18 00:00:51 gwr Exp $ */
/*-
@@ -36,7 +36,8 @@
* To use this, build a kernel with: option KGDB, and
* boot that kernel with "-d". (The kernel will call
* zs_kgdb_init, kgdb_connect.) When the console prints
- * "kgdb waiting..." you run "gdb -k kernel" and do:
+ * "kgdb waiting..." you run "gdb /path/to/bsd.gdb" on
+ * the remote machine and do:
* (gdb) set remotebaud 19200
* (gdb) target remote /dev/ttyb
*/
@@ -51,7 +52,7 @@
#include <sys/syslog.h>
#include <sys/kgdb.h>
-#include <sparc/dev/z8530reg.h>
+#include <dev/ic/z8530reg.h>
#include <machine/z8530var.h>
#include <sparc/dev/cons.h>
diff --git a/sys/arch/sparc/include/z8530var.h b/sys/arch/sparc/include/z8530var.h
index 05469563496..4a389af3704 100644
--- a/sys/arch/sparc/include/z8530var.h
+++ b/sys/arch/sparc/include/z8530var.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: z8530var.h,v 1.4 2009/04/10 20:53:54 miod Exp $ */
+/* $OpenBSD: z8530var.h,v 1.5 2013/04/21 14:44:16 sebastia Exp $ */
/* $NetBSD: z8530var.h,v 1.1 1997/10/18 00:01:30 gwr Exp $ */
/*
@@ -41,12 +41,21 @@
* @(#)zsvar.h 8.1 (Berkeley) 6/11/93
*/
-#include <sparc/dev/z8530sc.h>
+#include <dev/ic/z8530sc.h>
+
+/*
+ * sparc64 and sgi use the same structure, but with more members
+ * use it here too, just for more consistency.
+ */
+struct zs_channel {
+ struct zs_chanstate cs_zscs; /* Required: soft state */
+};
struct zsc_softc {
- struct device zsc_dev; /* required first: base device */
- void *zsc_softih; /* softintr cookie */
- struct zs_chanstate zsc_cs[2]; /* channel A and B soft state */
+ struct device zsc_dev; /* required first: base device */
+ void *zsc_softih; /* softintr cookie */
+ struct zs_chanstate *zsc_cs[2]; /* channel A and B soft state */
+ struct zs_channel zsc_cs_store[2];
};
/*
diff --git a/sys/arch/sparc64/conf/files.sparc64 b/sys/arch/sparc64/conf/files.sparc64
index f7e5dd320bc..62f2f9e91fc 100644
--- a/sys/arch/sparc64/conf/files.sparc64
+++ b/sys/arch/sparc64/conf/files.sparc64
@@ -1,4 +1,4 @@
-# $OpenBSD: files.sparc64,v 1.139 2012/12/08 20:38:10 kettenis Exp $
+# $OpenBSD: files.sparc64,v 1.140 2013/04/21 14:44:16 sebastia Exp $
# $NetBSD: files.sparc64,v 1.50 2001/08/10 20:53:50 eeh Exp $
# maxpartitions must be first item in files.${ARCH}
@@ -278,12 +278,12 @@ file arch/sparc64/dev/lpt_ebus.c lpt_ebus
attach zs at sbus with zs_sbus
attach zs at fhc with zs_fhc
file arch/sparc64/dev/zs.c zs needs-flag
-file arch/sparc64/dev/z8530sc.c zs
+file dev/ic/z8530sc.c zs
define zstty {}
device zstty: tty
attach zstty at zs
-file arch/sparc64/dev/z8530tty.c zstty needs-flag
+file dev/ic/z8530tty.c zstty needs-flag
device zskbd: wskbddev, sunkbd
attach zskbd at zs
diff --git a/sys/arch/sparc64/dev/z8530kbd.c b/sys/arch/sparc64/dev/z8530kbd.c
index 63426e0f466..e9855447e4f 100644
--- a/sys/arch/sparc64/dev/z8530kbd.c
+++ b/sys/arch/sparc64/dev/z8530kbd.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: z8530kbd.c,v 1.24 2011/03/18 21:01:17 miod Exp $ */
+/* $OpenBSD: z8530kbd.c,v 1.25 2013/04/21 14:44:16 sebastia Exp $ */
/* $NetBSD: z8530tty.c,v 1.77 2001/05/30 15:24:24 lukem Exp $ */
/*-
@@ -116,7 +116,7 @@
#include <dev/sun/sunkbdreg.h>
#include <dev/sun/sunkbdvar.h>
-#include <sparc64/dev/z8530reg.h>
+#include <dev/ic/z8530reg.h>
#include <machine/z8530var.h>
#include <dev/cons.h>
diff --git a/sys/arch/sparc64/dev/z8530reg.h b/sys/arch/sparc64/dev/z8530reg.h
deleted file mode 100644
index 8dc43bdc4d5..00000000000
--- a/sys/arch/sparc64/dev/z8530reg.h
+++ /dev/null
@@ -1,447 +0,0 @@
-/* $OpenBSD: z8530reg.h,v 1.3 2011/09/17 08:38:08 miod Exp $ */
-/* $NetBSD: z8530reg.h,v 1.9 1998/07/31 05:08:38 wrstuden Exp $ */
-
-/*
- * Copyright (c) 1992, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * This software was developed by the Computer Systems Engineering group
- * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
- * contributed to Berkeley.
- *
- * All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Lawrence Berkeley Laboratory.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)zsreg.h 8.1 (Berkeley) 6/11/93
- */
-
-/*
- * Zilog SCC registers, as implemented on the Sun-4c.
- *
- * Each Z8530 implements two channels (called `a' and `b').
- *
- * The damnable chip was designed to fit on Z80 I/O ports, and thus
- * has everything multiplexed out the wazoo. We have to select
- * a register, then read or write the register, and so on. Worse,
- * the parameter bits are scattered all over the register space.
- * This thing is full of `miscellaneous' control registers.
- *
- * Worse yet, the registers have incompatible functions on read
- * and write operations. We describe the registers below according
- * to whether they are `read registers' (RR) or `write registers' (WR).
- * As if this were not enough, some of the channel B status bits show
- * up in channel A, and vice versa. The blasted thing shares write
- * registers 2 and 9 across both channels, and reads registers 2 and 3
- * differently for the two channels. We can, however, ignore this much
- * of the time.
- *
- * This file also includes flags for the Z85C30 and Z85230 enhanced scc.
- * The CMOS 8530 includes extra SDLC functionality, and is used in a
- * number of Macs (often in the Z85C80, an 85C30 combined w/ a SCSI
- * controller). -wrs
- *
- * Some of the names in this files were chosen to make the hsis driver
- * work unchanged (which means that they will match some in SunOS).
- *
- * `S.C.' stands for Special Condition, which is any of these:
- * receiver overrun (aka silo overflow)
- * framing error (missing stop bit, etc)
- * end of frame (in synchronous modes)
- * parity error (when `parity error is S.C.' is set)
- *
- * Registers with only a single `numeric value' get a name.
- * Other registers hold bits and are only numbered; the bit
- * definitions imply the register number (see below).
- *
- * We never use the receive and transmit data registers as
- * indirects (choosing instead the zc_data register), so they
- * are not defined here.
- */
-#define ZSRR_IVEC 2 /* interrupt vector (channel 0) */
-#define ZSRR_IPEND 3 /* interrupt pending (ch. 0 only) */
-#define ZSRR_TXSYNC 6 /* sync transmit char (monosync mode) */
-#define ZSRR_RXSYNC 7 /* sync receive char (monosync mode) */
-#define ZSRR_SYNCLO 6 /* sync low byte (bisync mode) */
-#define ZSRR_SYNCHI 7 /* sync high byte (bisync mode) */
-#define ZSRR_SDLC_ADDR 6 /* SDLC address (SDLC mode) */
-#define ZSRR_SDLC_FLAG 7 /* SDLC flag 0x7E (SDLC mode) */
-#define ZSRR_BAUDLO 12 /* baud rate generator (low half) */
-#define ZSRR_BAUDHI 13 /* baud rate generator (high half) */
-#define ZSRR_ENHANCED 14 /* read address of WR7' - yes, it's not 7!*/
-
-#define ZSWR_IVEC 2 /* interrupt vector (shared) */
-#define ZSWR_TXSYNC 6 /* sync transmit char (monosync mode) */
-#define ZSWR_RXSYNC 7 /* sync receive char (monosync mode) */
-#define ZSWR_SYNCLO 6 /* sync low byte (bisync mode) */
-#define ZSWR_SYNCHI 7 /* sync high byte (bisync mode) */
-#define ZSWR_SDLC_ADDR 6 /* SDLC address (SDLC mode) */
-#define ZSWR_SDLC_FLAG 7 /* SDLC flag 0x7E (SDLC mode) */
-#define ZSWR_BAUDLO 12 /* baud rate generator (low half) */
-#define ZSWR_BAUDHI 13 /* baud rate generator (high half) */
-#define ZSWR_ENHANCED 7 /* write address of WR7' */
-
-/*
- * Registers 0 through 7 may be written with any one of the 8 command
- * modifiers, and/or any one of the 4 reset modifiers, defined below.
- * To write registers 8 through 15, however, the command modifier must
- * always be `point high'. Rather than track this bizzareness all over
- * the driver, we try to avoid using any modifiers, ever (but they are
- * defined here if you want them).
- */
-#define ZSM_RESET_TXUEOM 0xc0 /* reset xmit underrun / eom latch */
-#define ZSM_RESET_TXCRC 0x80 /* reset xmit crc generator */
-#define ZSM_RESET_RXCRC 0x40 /* reset recv crc checker */
-#define ZSM_NULL 0x00 /* nothing special */
-
-#define ZSM_RESET_IUS 0x38 /* reset interrupt under service */
-#define ZSM_RESET_ERR 0x30 /* reset error cond */
-#define ZSM_RESET_TXINT 0x28 /* reset xmit interrupt pending */
-#define ZSM_EI_NEXTRXC 0x20 /* enable int. on next rcvd char */
-#define ZSM_SEND_ABORT 0x18 /* send abort (SDLC) */
-#define ZSM_RESET_STINT 0x10 /* reset external/status interrupt */
-#define ZSM_POINTHIGH 0x08 /* `point high' (use r8-r15) */
-#define ZSM_NULL 0x00 /* nothing special */
-
-/*
- * Commands for Write Register 0 (`Command Register').
- * These are just the command modifiers or'ed with register number 0
- * (which of course equals the command modifier).
- */
-#define ZSWR0_RESET_EOM ZSM_RESET_TXUEOM
-#define ZSWR0_RESET_TXCRC ZSM_RESET_TXCRC
-#define ZSWR0_RESET_RXCRC ZSM_RESET_RXCRC
-#define ZSWR0_CLR_INTR ZSM_RESET_IUS
-#define ZSWR0_RESET_ERRORS ZSM_RESET_ERR
-#define ZSWR0_EI_NEXTRXC ZSM_EI_NEXTRXC
-#define ZSWR0_SEND_ABORT ZSM_SEND_ABORT
-#define ZSWR0_RESET_STATUS ZSM_RESET_STINT
-#define ZSWR0_RESET_TXINT ZSM_RESET_TXINT
-
-/*
- * Bits in Write Register 1 (`Transmit/Receive Interrupt and Data
- * Transfer Mode Definition'). Note that bits 3 and 4 are taken together
- * as a single unit, and bits 5 and 6 are useful only if bit 7 is set.
- */
-#define ZSWR1_REQ_WAIT 0x80 /* WAIT*-REQ* pin gives WAIT* */
-#define ZSWR1_REQ_REQ 0xc0 /* WAIT*-REQ* pin gives REQ* */
-#define ZSWR1_REQ_TX 0x00 /* WAIT*-REQ* pin follows xmit buf */
-#define ZSWR1_REQ_RX 0x20 /* WAIT*-REQ* pin follows recv buf */
-
-#define ZSWR1_RIE_NONE 0x00 /* disable rxint entirely */
-#define ZSWR1_RIE_FIRST 0x08 /* rxint on first char & on S.C. */
-#define ZSWR1_RIE 0x10 /* rxint per char & on S.C. */
-#define ZSWR1_RIE_SPECIAL_ONLY 0x18 /* rxint on S.C. only */
-
-#define ZSWR1_PE_SC 0x04 /* parity error is special condition */
-#define ZSWR1_TIE 0x02 /* transmit interrupt enable */
-#define ZSWR1_SIE 0x01 /* external/status interrupt enable */
-
-#define ZSWR1_IMASK 0x1F /* mask of all itr. enable bits. */
-
-/* HSIS compat */
-#define ZSWR1_REQ_ENABLE (ZSWR1_REQ_WAIT | ZSWR1_REQ_TX)
-
-/*
- * Bits in Write Register 3 (`Receive Parameters and Control').
- * Bits 7 and 6 are taken as a unit. Note that the receive bits
- * per character ordering is insane.
- *
- * Here `hardware flow control' means CTS enables the transmitter
- * and DCD enables the receiver. The latter is neither interesting
- * nor useful, and gets in our way, making it almost unusable.
- */
-#define ZSWR3_RX_5 0x00 /* receive 5 bits per char */
-#define ZSWR3_RX_7 0x40 /* receive 7 bits per char */
-#define ZSWR3_RX_6 0x80 /* receive 6 bits per char */
-#define ZSWR3_RX_8 0xc0 /* receive 8 bits per char */
-#define ZSWR3_RXSIZE 0xc0 /* receive char size mask */
-
-#define ZSWR3_HFC 0x20 /* hardware flow control */
-#define ZSWR3_HUNT 0x10 /* enter hunt mode */
-#define ZSWR3_RXCRC_ENABLE 0x08 /* enable recv crc calculation */
-#define ZSWR3_ADDR_SEARCH_MODE 0x04 /* address search mode (SDLC only) */
-#define ZSWR3_SDLC_SHORT_ADDR 0x02 /* short address mode (SDLC only) */
-#define ZSWR3_SYNC_LOAD_INH 0x02 /* sync character load inhibit */
-#define ZSWR3_RX_ENABLE 0x01 /* receiver enable */
-
-/*
- * Bits in Write Register 4 (`Transmit/Receive Miscellaneous Parameters
- * and Modes'). Bits 7&6, 5&4, and 3&2 are taken as units.
- */
-#define ZSWR4_CLK_X1 0x00 /* clock divisor = 1 */
-#define ZSWR4_CLK_X16 0x40 /* clock divisor = 16 */
-#define ZSWR4_CLK_X32 0x80 /* clock divisor = 32 */
-#define ZSWR4_CLK_X64 0xc0 /* clock divisor = 64 */
-#define ZSWR4_CLK_MASK 0xc0 /* clock divisor mask */
-
-#define ZSWR4_MONOSYNC 0x00 /* 8 bit sync char (sync only) */
-#define ZSWR4_BISYNC 0x10 /* 16 bit sync char (sync only) */
-#define ZSWR4_SDLC 0x20 /* SDLC mode */
-#define ZSWR4_EXTSYNC 0x30 /* external sync mode */
-#define ZSWR4_SYNC_MASK 0x30 /* sync mode bit mask */
-
-#define ZSWR4_SYNCMODE 0x00 /* no stop bit (sync mode only) */
-#define ZSWR4_ONESB 0x04 /* 1 stop bit */
-#define ZSWR4_1P5SB 0x08 /* 1.5 stop bits (clk cannot be 1x) */
-#define ZSWR4_TWOSB 0x0c /* 2 stop bits */
-#define ZSWR4_SBMASK 0x0c /* mask of all stop bits */
-
-#define ZSWR4_EVENP 0x02 /* check for even parity */
-#define ZSWR4_PARENB 0x01 /* enable parity checking */
-#define ZSWR4_PARMASK 0x03 /* mask of all parity bits */
-
-/*
- * Bits in Write Register 5 (`Transmit Parameter and Controls').
- * Bits 6 and 5 are taken as a unit; the ordering is, as with RX
- * bits per char, not sensible.
- */
-#define ZSWR5_DTR 0x80 /* assert (set to -12V) DTR */
-
-#define ZSWR5_TX_5 0x00 /* transmit 5 or fewer bits */
-#define ZSWR5_TX_7 0x20 /* transmit 7 bits */
-#define ZSWR5_TX_6 0x40 /* transmit 6 bits */
-#define ZSWR5_TX_8 0x60 /* transmit 8 bits */
-#define ZSWR5_TXSIZE 0x60 /* transmit char size mask */
-
-#define ZSWR5_BREAK 0x10 /* send break (continuous 0s) */
-#define ZSWR5_TX_ENABLE 0x08 /* enable transmitter */
-#define ZSWR5_CRC16 0x04 /* use CRC16 (off => use SDLC) */
-#define ZSWR5_RTS 0x02 /* assert RTS */
-#define ZSWR5_TXCRC_ENABLE 0x01 /* enable xmit crc calculation */
-
-#ifdef not_done_here
-/*
- * Bits in Write Register 7 when the chip is in SDLC mode.
- */
-#define ZSWR7_SDLCFLAG 0x7e /* this value makes SDLC mode work */
-#endif
-
-/*
- * Bits in Write Register 7' (ZSWR_ENHANCED above). This register is
- * only available on the 85230. Dispite the fact it contains flags
- * and not a single value, the register was named as it is read
- * via RR14. Weird.
- */
- /* 0x80 unused */
-#define ZSWR7P_EXTEND_READ 0x40 /* modify read map; make most regs readable */
-#define ZSWR7P_TX_FIFO 0x20 /* change level for Tx FIFO empty int */
-#define ZSWR7P_DTR_TIME 0x10 /* modifies deact. speed of /DTR//REQ */
-#define ZSWR7P_RX_FIFO 0x08 /* Rx FIFO int on 1/2 full? */
-#define ZSWR7P_RTS_DEACT 0x04 /* automatically deassert RTS */
-#define ZSWR7P_AUTO_EOM_RESET 0x02 /* automatically reset EMO/Tx Underrun */
-#define ZSWR7P_AUTO_TX_FLAG 0x01 /* Auto send SDLC flag at transmit start */
-
-/*
- * Bits in Write Register 9 (`Master Interrupt Control'). Bits 7 & 6
- * are taken as a unit and indicate the type of reset; 00 means no reset
- * (and is not defined here).
- */
-#define ZSWR9_HARD_RESET 0xc0 /* force hardware reset */
-#define ZSWR9_A_RESET 0x80 /* reset channel A (0) */
-#define ZSWR9_B_RESET 0x40 /* reset channel B (1) */
-#define ZSWR9_SOFT_INTAC 0x20 /* Not in NMOS version */
-
-#define ZSWR9_STATUS_HIGH 0x10 /* status in high bits of intr vec */
-#define ZSWR9_MASTER_IE 0x08 /* master interrupt enable */
-#define ZSWR9_DLC 0x04 /* disable lower chain */
-#define ZSWR9_NO_VECTOR 0x02 /* no vector */
-#define ZSWR9_VECTOR_INCL_STAT 0x01 /* vector includes status */
-
-/*
- * Bits in Write Register 10 (`Miscellaneous Transmitter/Receiver Control
- * Bits'). Bits 6 & 5 are taken as a unit, and some of the bits are
- * meaningful only in certain modes. Bleah.
- */
-#define ZSWR10_PRESET_ONES 0x80 /* preset CRC to all 1 (else all 0) */
-
-#define ZSWR10_NRZ 0x00 /* NRZ encoding */
-#define ZSWR10_NRZI 0x20 /* NRZI encoding */
-#define ZSWR10_FM1 0x40 /* FM1 encoding */
-#define ZSWR10_FM0 0x60 /* FM0 encoding */
-
-#define ZSWR10_GA_ON_POLL 0x10 /* go active on poll (loop mode) */
-#define ZSWR10_MARK_IDLE 0x08 /* all 1s (vs flag) when idle (SDLC) */
-#define ZSWR10_ABORT_ON_UNDERRUN 0x4 /* abort on xmit underrun (SDLC) */
-#define ZSWR10_LOOP_MODE 0x02 /* loop mode (SDLC) */
-#define ZSWR10_6_BIT_SYNC 0x01 /* 6 bits per sync char (sync modes) */
-
-/*
- * Bits in Write Register 11 (`Clock Mode Control'). Bits 6&5, 4&3, and
- * 1&0 are taken as units. Various bits depend on other bits in complex
- * ways; see the Zilog manual.
- */
-#define ZSWR11_XTAL 0x80 /* have xtal between RTxC* and SYNC* */
- /* (else have TTL oscil. on RTxC*) */
-#define ZSWR11_RXCLK_RTXC 0x00 /* recv clock taken from RTxC* pin */
-#define ZSWR11_RXCLK_TRXC 0x20 /* recv clock taken from TRxC* pin */
-#define ZSWR11_RXCLK_BAUD 0x40 /* recv clock taken from BRG */
-#define ZSWR11_RXCLK_DPLL 0x60 /* recv clock taken from DPLL */
-
-#define ZSWR11_TXCLK_RTXC 0x00 /* xmit clock taken from RTxC* pin */
-#define ZSWR11_TXCLK_TRXC 0x08 /* xmit clock taken from TRxC* pin */
-#define ZSWR11_TXCLK_BAUD 0x10 /* xmit clock taken from BRG */
-#define ZSWR11_TXCLK_DPLL 0x18 /* xmit clock taken from DPLL */
-
-#define ZSWR11_TRXC_OUT_ENA 0x04 /* TRxC* pin will be an output */
- /* (unless it is being used above) */
-#define ZSWR11_TRXC_XTAL 0x00 /* TRxC output from xtal oscillator */
-#define ZSWR11_TRXC_XMIT 0x01 /* TRxC output from xmit clock */
-#define ZSWR11_TRXC_BAUD 0x02 /* TRxC output from BRG */
-#define ZSWR11_TRXC_DPLL 0x03 /* TRxC output from DPLL */
-
-/*
- * Formula for Write Registers 12 and 13 (`Lower Byte of Baud Rate
- * Generator Time Constant' and `Upper Byte of ...'). Inputs:
- *
- * f BRG input clock frequency (in Hz) AFTER division
- * by 1, 16, 32, or 64 (per clock divisor in WR4)
- * bps desired rate in bits per second (9600, etc)
- *
- * We want
- *
- * f
- * ----- + 0.5 - 2
- * 2 bps
- *
- * rounded down to an integer. This can be computed entirely
- * in integer arithmetic as:
- *
- * f + bps
- * ------- - 2
- * 2 bps
- */
-#define BPS_TO_TCONST(f, bps) ((((f) + (bps)) / (2 * (bps))) - 2)
-
-/* inverse of above: given a BRG Time Constant, return Bits Per Second */
-#define TCONST_TO_BPS(f, tc) ((f) / 2 / ((tc) + 2))
-
-/*
- * Bits in Write Register 14 (`Miscellaneous Control Bits').
- * Bits 7 through 5 are taken as a unit and make up a `DPLL command'.
- */
-#define ZSWR14_DPLL_NOOP 0x00 /* leave DPLL alone */
-#define ZSWR14_DPLL_SEARCH 0x20 /* enter search mode */
-#define ZSWR14_DPLL_RESET_CM 0x40 /* reset `clock missing' in RR10 */
-#define ZSWR14_DPLL_DISABLE 0x60 /* disable DPLL (continuous search) */
-#define ZSWR14_DPLL_SRC_BAUD 0x80 /* set DPLL src = BRG */
-#define ZSWR14_DPLL_SRC_RTXC 0xa0 /* set DPLL src = RTxC* or xtal osc */
-#define ZSWR14_DPLL_FM 0xc0 /* operate in FM mode */
-#define ZSWR14_DPLL_NRZI 0xe0 /* operate in NRZI mode */
-
-#define ZSWR14_LOCAL_LOOPBACK 0x10 /* set local loopback mode */
-#define ZSWR14_AUTO_ECHO 0x08 /* set auto echo mode */
-#define ZSWR14_DTR_REQ 0x04 /* DTR* / REQ* pin gives REQ* */
-#define ZSWR14_BAUD_FROM_PCLK 0x02 /* BRG clock taken from PCLK */
- /* (else from RTxC* pin or xtal osc) */
-#define ZSWR14_BAUD_ENA 0x01 /* enable BRG countdown */
-
-/*
- * Bits in Write Register 15 (`External/Status Interrupt Control').
- * Most of these cause status interrupts whenever the corresponding
- * bit or pin changes state (i.e., any rising or falling edge).
- *
- * NOTE: ZSWR15_SDLC_FIFO & ZSWR15_ENABLE_ENHANCED should not be
- * set on an NMOS 8530. Also, ZSWR15_ENABLE_ENHANCED is only
- * available on the 85230.
- */
-#define ZSWR15_BREAK_IE 0x80 /* enable break/abort status int */
-#define ZSWR15_TXUEOM_IE 0x40 /* enable TX underrun/EOM status int */
-#define ZSWR15_CTS_IE 0x20 /* enable CTS* pin status int */
-#define ZSWR15_SYNCHUNT_IE 0x10 /* enable SYNC* pin/hunt status int */
-#define ZSWR15_DCD_IE 0x08 /* enable DCD* pin status int */
-#define ZSWR15_SDLC_FIFO 0x04 /* enable SDLC FIFO enhancements */
-#define ZSWR15_ZERO_COUNT_IE 0x02 /* enable BRG-counter = 0 status int */
-#define ZSWR15_ENABLE_ENHANCED 0x01 /* enable writing WR7' at reg 7 */
-
-/*
- * Bits in Read Register 0 (`Transmit/Receive Buffer Status and External
- * Status').
- */
-#define ZSRR0_BREAK 0x80 /* break/abort detected */
-#define ZSRR0_TXUNDER 0x40 /* transmit underrun/EOM (sync) */
-#define ZSRR0_CTS 0x20 /* clear to send */
-#define ZSRR0_SYNC_HUNT 0x10 /* sync/hunt (sync mode) */
-#define ZSRR0_DCD 0x08 /* data carrier detect */
-#define ZSRR0_TX_READY 0x04 /* transmit buffer empty */
-#define ZSRR0_ZERO_COUNT 0x02 /* zero count in baud clock */
-#define ZSRR0_RX_READY 0x01 /* received character ready */
-
-/*
- * Bits in Read Register 1 (the Zilog book does not name this one).
- */
-#define ZSRR1_EOF 0x80 /* end of frame (SDLC mode) */
-#define ZSRR1_FE 0x40 /* CRC/framing error */
-#define ZSRR1_DO 0x20 /* data (receiver) overrun */
-#define ZSRR1_PE 0x10 /* parity error */
-#define ZSRR1_RC0 0x08 /* residue code 0 (SDLC mode) */
-#define ZSRR1_RC1 0x04 /* residue code 1 (SDLC mode) */
-#define ZSRR1_RC2 0x02 /* residue code 2 (SDLC mode) */
-#define ZSRR1_ALL_SENT 0x01 /* all chars out of xmitter (async) */
-
-/*
- * Read Register 2 in B channel contains status bits if VECTOR_INCL_STAT
- * is set.
- */
-
-/*
- * Bits in Read Register 3 (`Interrupt Pending'). Only channel A
- * has an RR3.
- */
- /* 0x80 unused, returned as 0 */
- /* 0x40 unused, returned as 0 */
-#define ZSRR3_IP_A_RX 0x20 /* channel A recv int pending */
-#define ZSRR3_IP_A_TX 0x10 /* channel A xmit int pending */
-#define ZSRR3_IP_A_STAT 0x08 /* channel A status int pending */
-#define ZSRR3_IP_B_RX 0x04 /* channel B recv int pending */
-#define ZSRR3_IP_B_TX 0x02 /* channel B xmit int pending */
-#define ZSRR3_IP_B_STAT 0x01 /* channel B status int pending */
-
-/*
- * Bits in Read Register 10 (`contains some miscellaneous status bits').
- */
-#define ZSRR10_1_CLOCK_MISSING 0x80 /* 1 clock edge missing (FM mode) */
-#define ZSRR10_2_CLOCKS_MISSING 0x40 /* 2 clock edges missing (FM mode) */
- /* 0x20 unused */
-#define ZSRR10_LOOP_SENDING 0x10 /* xmitter controls loop (SDLC loop) */
- /* 0x08 unused */
- /* 0x04 unused */
-#define ZSRR10_ON_LOOP 0x02 /* SCC is on loop (SDLC/X.21 modes) */
-
-/*
- * Bits in Read Register 15. This register is one of the few that
- * simply reads back the corresponding Write Register.
- */
-#define ZSRR15_BREAK_IE 0x80 /* break/abort status int enable */
-#define ZSRR15_TXUEOM_IE 0x40 /* TX underrun/EOM status int enable */
-#define ZSRR15_CTS_IE 0x20 /* CTS* pin status int enable */
-#define ZSRR15_SYNCHUNT_IE 0x10 /* SYNC* pin/hunt status int enable */
-#define ZSRR15_DCD_IE 0x08 /* DCD* pin status int enable */
- /* 0x04 unused, returned as zero */
-#define ZSRR15_ZERO_COUNT_IE 0x02 /* BRG-counter = 0 status int enable */
- /* 0x01 unused, returned as zero */
diff --git a/sys/arch/sparc64/dev/z8530sc.c b/sys/arch/sparc64/dev/z8530sc.c
deleted file mode 100644
index bfc1dcc34f3..00000000000
--- a/sys/arch/sparc64/dev/z8530sc.c
+++ /dev/null
@@ -1,353 +0,0 @@
-/* $OpenBSD: z8530sc.c,v 1.3 2003/06/02 23:27:55 millert Exp $ */
-/* $NetBSD: z8530sc.c,v 1.15 2001/07/07 15:53:22 thorpej Exp $ */
-
-/*
- * Copyright (c) 1994 Gordon W. Ross
- * Copyright (c) 1992, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * This software was developed by the Computer Systems Engineering group
- * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
- * contributed to Berkeley.
- *
- * All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Lawrence Berkeley Laboratory.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)zs.c 8.1 (Berkeley) 7/19/93
- */
-
-/*
- * Zilog Z8530 Dual UART driver (common part)
- *
- * This file contains the machine-independent parts of the
- * driver common to tty and keyboard/mouse sub-drivers.
- */
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/proc.h>
-#include <sys/device.h>
-#include <sys/conf.h>
-#include <sys/file.h>
-#include <sys/ioctl.h>
-#include <sys/tty.h>
-#include <sys/time.h>
-#include <sys/kernel.h>
-#include <sys/syslog.h>
-
-#include <sparc64/dev/z8530reg.h>
-#include <machine/z8530var.h>
-
-void
-zs_break(cs, set)
- struct zs_chanstate *cs;
- int set;
-{
-
- if (set) {
- cs->cs_preg[5] |= ZSWR5_BREAK;
- cs->cs_creg[5] |= ZSWR5_BREAK;
- } else {
- cs->cs_preg[5] &= ~ZSWR5_BREAK;
- cs->cs_creg[5] &= ~ZSWR5_BREAK;
- }
- zs_write_reg(cs, 5, cs->cs_creg[5]);
-}
-
-
-/*
- * drain on-chip fifo
- */
-void
-zs_iflush(cs)
- struct zs_chanstate *cs;
-{
- u_char c, rr0, rr1;
- int i;
-
- /*
- * Count how many times we loop. Some systems, such as some
- * Apple PowerBooks, claim to have SCC's which they really don't.
- */
- for (i = 0; i < 32; i++) {
- /* Is there input available? */
- rr0 = zs_read_csr(cs);
- if ((rr0 & ZSRR0_RX_READY) == 0)
- break;
-
- /*
- * First read the status, because reading the data
- * destroys the status of this char.
- */
- rr1 = zs_read_reg(cs, 1);
- c = zs_read_data(cs);
-
- if (rr1 & (ZSRR1_FE | ZSRR1_DO | ZSRR1_PE)) {
- /* Clear the receive error. */
- zs_write_csr(cs, ZSWR0_RESET_ERRORS);
- }
- }
-}
-
-
-/*
- * Write the given register set to the given zs channel in the proper order.
- * The channel must not be transmitting at the time. The receiver will
- * be disabled for the time it takes to write all the registers.
- * Call this with interrupts disabled.
- */
-void
-zs_loadchannelregs(cs)
- struct zs_chanstate *cs;
-{
- u_char *reg;
-
- zs_write_csr(cs, ZSM_RESET_ERR); /* XXX: reset error condition */
-
-#if 1
- /*
- * XXX: Is this really a good idea?
- * XXX: Should go elsewhere! -gwr
- */
- zs_iflush(cs); /* XXX */
-#endif
-
- if (memcmp((caddr_t)cs->cs_preg, (caddr_t)cs->cs_creg, 16) == 0)
- return; /* only change if values are different */
-
- /* Copy "pending" regs to "current" */
- memcpy((caddr_t)cs->cs_creg, (caddr_t)cs->cs_preg, 16);
- reg = cs->cs_creg; /* current regs */
-
- /* disable interrupts */
- zs_write_reg(cs, 1, reg[1] & ~ZSWR1_IMASK);
-
- /* baud clock divisor, stop bits, parity */
- zs_write_reg(cs, 4, reg[4]);
-
- /* misc. TX/RX control bits */
- zs_write_reg(cs, 10, reg[10]);
-
- /* char size, enable (RX/TX) */
- zs_write_reg(cs, 3, reg[3] & ~ZSWR3_RX_ENABLE);
- zs_write_reg(cs, 5, reg[5] & ~ZSWR5_TX_ENABLE);
-
- /* synchronous mode stuff */
- zs_write_reg(cs, 6, reg[6]);
- zs_write_reg(cs, 7, reg[7]);
-
-#if 0
- /*
- * Registers 2 and 9 are special because they are
- * actually common to both channels, but must be
- * programmed through channel A. The "zsc" attach
- * function takes care of setting these registers
- * and they should not be touched thereafter.
- */
- /* interrupt vector */
- zs_write_reg(cs, 2, reg[2]);
- /* master interrupt control */
- zs_write_reg(cs, 9, reg[9]);
-#endif
-
- /* Shut down the BRG */
- zs_write_reg(cs, 14, reg[14] & ~ZSWR14_BAUD_ENA);
-
-#ifdef ZS_MD_SETCLK
- /* Let the MD code setup any external clock. */
- ZS_MD_SETCLK(cs);
-#endif /* ZS_MD_SETCLK */
-
- /* clock mode control */
- zs_write_reg(cs, 11, reg[11]);
-
- /* baud rate (lo/hi) */
- zs_write_reg(cs, 12, reg[12]);
- zs_write_reg(cs, 13, reg[13]);
-
- /* Misc. control bits */
- zs_write_reg(cs, 14, reg[14]);
-
- /* which lines cause status interrupts */
- zs_write_reg(cs, 15, reg[15]);
-
- /*
- * Zilog docs recommend resetting external status twice at this
- * point. Mainly as the status bits are latched, and the first
- * interrupt clear might unlatch them to new values, generating
- * a second interrupt request.
- */
- zs_write_csr(cs, ZSM_RESET_STINT);
- zs_write_csr(cs, ZSM_RESET_STINT);
-
- /* char size, enable (RX/TX)*/
- zs_write_reg(cs, 3, reg[3]);
- zs_write_reg(cs, 5, reg[5]);
-
- /* interrupt enables: RX, TX, STATUS */
- zs_write_reg(cs, 1, reg[1]);
-}
-
-
-/*
- * ZS hardware interrupt. Scan all ZS channels. NB: we know here that
- * channels are kept in (A,B) pairs.
- *
- * Do just a little, then get out; set a software interrupt if more
- * work is needed.
- *
- * We deliberately ignore the vectoring Zilog gives us, and match up
- * only the number of `reset interrupt under service' operations, not
- * the order.
- */
-int
-zsc_intr_hard(arg)
- void *arg;
-{
- struct zsc_softc *zsc = arg;
- struct zs_chanstate *cs;
- u_char rr3;
-
- /* First look at channel A. */
- cs = zsc->zsc_cs[0];
- /* Note: only channel A has an RR3 */
- rr3 = zs_read_reg(cs, 3);
-
- /*
- * Clear interrupt first to avoid a race condition.
- * If a new interrupt condition happens while we are
- * servicing this one, we will get another interrupt
- * shortly. We can NOT just sit here in a loop, or
- * we will cause horrible latency for other devices
- * on this interrupt level (i.e. sun3x floppy disk).
- */
- if (rr3 & (ZSRR3_IP_A_RX | ZSRR3_IP_A_TX | ZSRR3_IP_A_STAT)) {
- zs_write_csr(cs, ZSWR0_CLR_INTR);
- if (rr3 & ZSRR3_IP_A_RX)
- (*cs->cs_ops->zsop_rxint)(cs);
- if (rr3 & ZSRR3_IP_A_STAT)
- (*cs->cs_ops->zsop_stint)(cs, 0);
- if (rr3 & ZSRR3_IP_A_TX)
- (*cs->cs_ops->zsop_txint)(cs);
- }
-
- /* Now look at channel B. */
- cs = zsc->zsc_cs[1];
- if (rr3 & (ZSRR3_IP_B_RX | ZSRR3_IP_B_TX | ZSRR3_IP_B_STAT)) {
- zs_write_csr(cs, ZSWR0_CLR_INTR);
- if (rr3 & ZSRR3_IP_B_RX)
- (*cs->cs_ops->zsop_rxint)(cs);
- if (rr3 & ZSRR3_IP_B_STAT)
- (*cs->cs_ops->zsop_stint)(cs, 0);
- if (rr3 & ZSRR3_IP_B_TX)
- (*cs->cs_ops->zsop_txint)(cs);
- }
-
- /* Note: caller will check cs_x->cs_softreq and DTRT. */
- return (rr3);
-}
-
-
-/*
- * ZS software interrupt. Scan all channels for deferred interrupts.
- */
-int
-zsc_intr_soft(arg)
- void *arg;
-{
- struct zsc_softc *zsc = arg;
- struct zs_chanstate *cs;
- int rval, chan;
-
- rval = 0;
- for (chan = 0; chan < 2; chan++) {
- cs = zsc->zsc_cs[chan];
-
- /*
- * The softint flag can be safely cleared once
- * we have decided to call the softint routine.
- * (No need to do splzs() first.)
- */
- if (cs->cs_softreq) {
- cs->cs_softreq = 0;
- (*cs->cs_ops->zsop_softint)(cs);
- rval++;
- }
- }
- return (rval);
-}
-
-/*
- * Provide a null zs "ops" vector.
- */
-
-static void zsnull_rxint(struct zs_chanstate *);
-static void zsnull_stint(struct zs_chanstate *, int);
-static void zsnull_txint(struct zs_chanstate *);
-static void zsnull_softint(struct zs_chanstate *);
-
-static void
-zsnull_rxint(cs)
- struct zs_chanstate *cs;
-{
- /* Ask for softint() call. */
- cs->cs_softreq = 1;
-}
-
-static void
-zsnull_stint(cs, force)
- struct zs_chanstate *cs;
- int force;
-{
- /* Ask for softint() call. */
- cs->cs_softreq = 1;
-}
-
-static void
-zsnull_txint(cs)
- struct zs_chanstate *cs;
-{
- /* Ask for softint() call. */
- cs->cs_softreq = 1;
-}
-
-static void
-zsnull_softint(cs)
- struct zs_chanstate *cs;
-{
- zs_write_reg(cs, 1, 0);
- zs_write_reg(cs, 15, 0);
-}
-
-struct zsops zsops_null = {
- zsnull_rxint, /* receive char available */
- zsnull_stint, /* external/status */
- zsnull_txint, /* xmit buffer empty */
- zsnull_softint, /* process software interrupt */
-};
diff --git a/sys/arch/sparc64/dev/z8530sc.h b/sys/arch/sparc64/dev/z8530sc.h
deleted file mode 100644
index ef370ce420a..00000000000
--- a/sys/arch/sparc64/dev/z8530sc.h
+++ /dev/null
@@ -1,154 +0,0 @@
-/* $OpenBSD: z8530sc.h,v 1.5 2010/03/03 20:13:34 miod Exp $ */
-/* $NetBSD: z8530sc.h,v 1.15 2001/05/11 01:40:48 thorpej Exp $ */
-
-/*
- * Copyright (c) 1994 Gordon W. Ross
- * Copyright (c) 1992, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * This software was developed by the Computer Systems Engineering group
- * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
- * contributed to Berkeley.
- *
- * All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Lawrence Berkeley Laboratory.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)zsvar.h 8.1 (Berkeley) 6/11/93
- */
-
-
-/*
- * Function vector - per channel
- */
-struct zs_chanstate;
-struct zsops {
- void (*zsop_rxint)(struct zs_chanstate *);
- /* receive char available */
- void (*zsop_stint)(struct zs_chanstate *, int);
- /* external/status */
- void (*zsop_txint)(struct zs_chanstate *);
- /* xmit buffer empty */
- void (*zsop_softint)(struct zs_chanstate *);
- /* process software interrupt */
-};
-
-extern struct zsops zsops_null;
-
-
-/*
- * Software state, per zs channel.
- */
-struct zs_chanstate {
-
- /* Pointers to the device registers. */
- volatile u_char *cs_reg_csr; /* ctrl, status, and reg. number. */
- volatile u_char *cs_reg_data; /* data or numbered register */
-
- int cs_channel; /* sub-unit number */
- void *cs_private; /* sub-driver data pointer */
- struct zsops *cs_ops;
-
- int cs_brg_clk; /* BAUD Rate Generator clock
- * (usually PCLK / 16) */
- int cs_defspeed; /* default baud rate */
- int cs_defcflag; /* default cflag */
-
- /*
- * We must keep a copy of the write registers as they are
- * mostly write-only and we sometimes need to set and clear
- * individual bits (e.g., in WR3). Not all of these are
- * needed but 16 bytes is cheap and this makes the addressing
- * simpler. Unfortunately, we can only write to some registers
- * when the chip is not actually transmitting, so whenever
- * we are expecting a `transmit done' interrupt the preg array
- * is allowed to `get ahead' of the current values. In a
- * few places we must change the current value of a register,
- * rather than (or in addition to) the pending value; for these
- * cs_creg[] contains the current value.
- */
- u_char cs_creg[16]; /* current values */
- u_char cs_preg[16]; /* pending values */
- int cs_heldchange; /* change pending (creg != preg) */
-
- u_char cs_rr0; /* last rr0 processed */
- u_char cs_rr0_delta; /* rr0 changes at status intr. */
- u_char cs_rr0_mask; /* rr0 bits that stop output */
- u_char cs_rr0_dcd; /* which bit to read as DCD */
- u_char cs_rr0_cts; /* which bit to read as CTS */
- u_char cs_rr0_pps; /* which bit to use for PPS */
- /* the above is set only while CRTSCTS is enabled. */
-
- u_char cs_wr5_dtr; /* which bit to write as DTR */
- u_char cs_wr5_rts; /* which bit to write as RTS */
- /* the above is set only while CRTSCTS is enabled. */
-
- char cs_softreq; /* need soft interrupt call */
- char cs_cua; /* CUA mode flag */
-
- /* power management hooks */
- int (*enable)(struct zs_chanstate *);
- void (*disable)(struct zs_chanstate *);
- int enabled;
-
- /* MD code might define a larger variant of this. */
-};
-
-struct consdev;
-struct zsc_attach_args {
- char *type; /* type name 'serial', 'keyboard', 'mouse' */
- int channel; /* two serial channels per zsc */
- int hwflags; /* see definitions below */
- /* `consdev' is only valid if ZS_HWFLAG_USE_CONSDEV is set */
- struct consdev *consdev;
-};
-/* In case of split console devices, use these: */
-#define ZS_HWFLAG_CONSOLE_INPUT 1
-#define ZS_HWFLAG_CONSOLE_OUTPUT 2
-#define ZS_HWFLAG_CONSOLE \
- (ZS_HWFLAG_CONSOLE_INPUT | ZS_HWFLAG_CONSOLE_OUTPUT)
-#define ZS_HWFLAG_NO_DCD 4 /* Ignore the DCD bit */
-#define ZS_HWFLAG_NO_CTS 8 /* Ignore the CTS bit */
-#define ZS_HWFLAG_RAW 16 /* advise raw mode */
-#define ZS_HWFLAG_USE_CONSDEV 32 /* Use console ops from `consdev' */
-#define ZS_HWFLAG_NORESET 64 /* Don't reset at attach time */
-
-int zsc_intr_soft(void *);
-int zsc_intr_hard(void *);
-
-void zs_abort(struct zs_chanstate *);
-void zs_break(struct zs_chanstate *, int);
-void zs_iflush(struct zs_chanstate *);
-void zs_loadchannelregs(struct zs_chanstate *);
-int zs_set_speed(struct zs_chanstate *, int);
-int zs_set_modes(struct zs_chanstate *, int);
-
-extern int zs_major;
-
-int zs_check_kgdb(struct zs_chanstate *, int);
-
diff --git a/sys/arch/sparc64/dev/z8530tty.c b/sys/arch/sparc64/dev/z8530tty.c
deleted file mode 100644
index d20f7c3137d..00000000000
--- a/sys/arch/sparc64/dev/z8530tty.c
+++ /dev/null
@@ -1,1668 +0,0 @@
-/* $OpenBSD: z8530tty.c,v 1.22 2010/07/02 17:27:01 nicm Exp $ */
-/* $NetBSD: z8530tty.c,v 1.77 2001/05/30 15:24:24 lukem Exp $ */
-
-/*-
- * Copyright (c) 1993, 1994, 1995, 1996, 1997, 1998, 1999
- * Charles M. Hannum. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Charles M. Hannum.
- * 4. The name of the author may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * Copyright (c) 1994 Gordon W. Ross
- * Copyright (c) 1992, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * This software was developed by the Computer Systems Engineering group
- * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
- * contributed to Berkeley.
- *
- * All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Lawrence Berkeley Laboratory.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)zs.c 8.1 (Berkeley) 7/19/93
- */
-
-/*
- * Zilog Z8530 Dual UART driver (tty interface)
- *
- * This is the "slave" driver that will be attached to
- * the "zsc" driver for plain "tty" async. serial lines.
- *
- * Credits, history:
- *
- * The original version of this code was the sparc/dev/zs.c driver
- * as distributed with the Berkeley 4.4 Lite release. Since then,
- * Gordon Ross reorganized the code into the current parent/child
- * driver scheme, separating the Sun keyboard and mouse support
- * into independent child drivers.
- *
- * RTS/CTS flow-control support was a collaboration of:
- * Gordon Ross <gwr@netbsd.org>,
- * Bill Studenmund <wrstuden@loki.stanford.edu>
- * Ian Dall <Ian.Dall@dsto.defence.gov.au>
- *
- * The driver was massively overhauled in November 1997 by Charles Hannum,
- * fixing *many* bugs, and substantially improving performance.
- */
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/proc.h>
-#include <sys/device.h>
-#include <sys/conf.h>
-#include <sys/file.h>
-#include <sys/ioctl.h>
-#include <sys/malloc.h>
-#include <sys/tty.h>
-#include <sys/time.h>
-#include <sys/kernel.h>
-#include <sys/syslog.h>
-
-#include <sparc64/dev/z8530reg.h>
-#include <machine/z8530var.h>
-
-#include <dev/cons.h>
-
-/*
- * How many input characters we can buffer.
- * The port-specific var.h may override this.
- * Note: must be a power of two!
- */
-#ifndef ZSTTY_RING_SIZE
-#define ZSTTY_RING_SIZE 2048
-#endif
-
-struct cfdriver zstty_cd = {
- NULL, "zstty", DV_TTY
-};
-
-/*
- * Make this an option variable one can patch.
- * But be warned: this must be a power of 2!
- */
-u_int zstty_rbuf_size = ZSTTY_RING_SIZE;
-
-/* Stop input when 3/4 of the ring is full; restart when only 1/4 is full. */
-u_int zstty_rbuf_hiwat = (ZSTTY_RING_SIZE * 1) / 4;
-u_int zstty_rbuf_lowat = (ZSTTY_RING_SIZE * 3) / 4;
-
-struct zstty_softc {
- struct device zst_dev; /* required first: base device */
- struct tty *zst_tty;
- struct zs_chanstate *zst_cs;
-
- struct timeout zst_diag_ch;
-
- u_int zst_overflows,
- zst_floods,
- zst_errors;
-
- int zst_hwflags, /* see z8530var.h */
- zst_swflags; /* TIOCFLAG_SOFTCAR, ... <ttycom.h> */
-
- u_int zst_r_hiwat,
- zst_r_lowat;
- u_char *volatile zst_rbget,
- *volatile zst_rbput;
- volatile u_int zst_rbavail;
- u_char *zst_rbuf,
- *zst_ebuf;
-
- /*
- * The transmit byte count and address are used for pseudo-DMA
- * output in the hardware interrupt code. PDMA can be suspended
- * to get pending changes done; heldtbc is used for this. It can
- * also be stopped for ^S; this sets TS_TTSTOP in tp->t_state.
- */
- u_char *zst_tba; /* transmit buffer address */
- u_int zst_tbc, /* transmit byte count */
- zst_heldtbc; /* held tbc while xmission stopped */
-
- /* Flags to communicate with zstty_softint() */
- volatile u_char zst_rx_flags, /* receiver blocked */
-#define RX_TTY_BLOCKED 0x01
-#define RX_TTY_OVERFLOWED 0x02
-#define RX_IBUF_BLOCKED 0x04
-#define RX_IBUF_OVERFLOWED 0x08
-#define RX_ANY_BLOCK 0x0f
- zst_tx_busy, /* working on an output chunk */
- zst_tx_done, /* done with one output chunk */
- zst_tx_stopped, /* H/W level stop (lost CTS) */
- zst_st_check, /* got a status interrupt */
- zst_rx_ready;
-
- /* PPS signal on DCD, with or without inkernel clock disciplining */
- u_char zst_ppsmask; /* pps signal mask */
- u_char zst_ppsassert; /* pps leading edge */
- u_char zst_ppsclear; /* pps trailing edge */
-};
-
-/* Definition of the driver for autoconfig. */
-static int zstty_match(struct device *, void *, void *);
-static void zstty_attach(struct device *, struct device *, void *);
-
-struct cfattach zstty_ca = {
- sizeof(struct zstty_softc), zstty_match, zstty_attach
-};
-
-extern struct cfdriver zstty_cd;
-
-struct zsops zsops_tty;
-
-/* Routines called from other code. */
-cdev_decl(zs); /* open, close, read, write, ioctl, stop, ... */
-
-static void zs_shutdown(struct zstty_softc *);
-static void zsstart(struct tty *);
-static int zsparam(struct tty *, struct termios *);
-static void zs_modem(struct zstty_softc *, int);
-static void tiocm_to_zs(struct zstty_softc *, u_long, int);
-static int zs_to_tiocm(struct zstty_softc *);
-static int zshwiflow(struct tty *, int);
-static void zs_hwiflow(struct zstty_softc *);
-static void zs_maskintr(struct zstty_softc *);
-
-struct zstty_softc *zs_device_lookup(struct cfdriver *, int);
-
-/* Low-level routines. */
-static void zstty_rxint(struct zs_chanstate *);
-static void zstty_stint(struct zs_chanstate *, int);
-static void zstty_txint(struct zs_chanstate *);
-static void zstty_softint(struct zs_chanstate *);
-static void zstty_diag(void *);
-
-#define ZSUNIT(x) (minor(x) & 0x7f)
-#define ZSDIALOUT(x) (minor(x) & 0x80)
-
-struct zstty_softc *
-zs_device_lookup(cf, unit)
- struct cfdriver *cf;
- int unit;
-{
- return (struct zstty_softc *)device_lookup(cf, unit);
-}
-
-/*
- * zstty_match: how is this zs channel configured?
- */
-int
-zstty_match(parent, vcf, aux)
- struct device *parent;
- void *vcf;
- void *aux;
-{
- struct cfdata *cf = vcf;
- struct zsc_attach_args *args = aux;
-
- /* Exact match is better than wildcard. */
- if (cf->cf_loc[ZSCCF_CHANNEL] == args->channel)
- return 2;
-
- /* This driver accepts wildcard. */
- if (cf->cf_loc[ZSCCF_CHANNEL] == ZSCCF_CHANNEL_DEFAULT)
- return 1;
-
- return 0;
-}
-
-void
-zstty_attach(parent, self, aux)
- struct device *parent, *self;
- void *aux;
-
-{
- struct zsc_softc *zsc = (void *) parent;
- struct zstty_softc *zst = (void *) self;
- struct cfdata *cf = self->dv_cfdata;
- struct zsc_attach_args *args = aux;
- struct zs_chanstate *cs;
- struct tty *tp;
- int channel, s, tty_unit;
- dev_t dev;
- char *i, *o;
-
- timeout_set(&zst->zst_diag_ch, zstty_diag, zst);
-
- tty_unit = zst->zst_dev.dv_unit;
- channel = args->channel;
- cs = zsc->zsc_cs[channel];
- cs->cs_private = zst;
- cs->cs_ops = &zsops_tty;
-
- zst->zst_cs = cs;
- zst->zst_swflags = cf->cf_flags; /* softcar, etc. */
- zst->zst_hwflags = args->hwflags;
- dev = makedev(zs_major, tty_unit);
-
- if (zst->zst_swflags)
- printf(" flags 0x%x", zst->zst_swflags);
-
- /*
- * Check whether we serve as a console device.
- * XXX - split console input/output channels aren't
- * supported yet on /dev/console
- */
- i = o = NULL;
- if ((zst->zst_hwflags & ZS_HWFLAG_CONSOLE_INPUT) != 0) {
- i = " input";
- if ((args->hwflags & ZS_HWFLAG_USE_CONSDEV) != 0) {
- args->consdev->cn_dev = dev;
- cn_tab->cn_pollc = args->consdev->cn_pollc;
- cn_tab->cn_getc = args->consdev->cn_getc;
- }
- cn_tab->cn_dev = dev;
- /* Set console magic to BREAK */
- }
- if ((zst->zst_hwflags & ZS_HWFLAG_CONSOLE_OUTPUT) != 0) {
- i = " output";
- if ((args->hwflags & ZS_HWFLAG_USE_CONSDEV) != 0) {
- cn_tab->cn_putc = args->consdev->cn_putc;
- }
- cn_tab->cn_dev = dev;
- }
- if (i != NULL || o != NULL)
- printf(": console%s", i ? (o ? "" : i) : o);
-
-#ifdef KGDB
- if (zs_check_kgdb(cs, dev)) {
- /*
- * Allow kgdb to "take over" this port. Returns true
- * if this serial port is in-use by kgdb.
- */
- printf(" (kgdb)\n");
- /*
- * This is the kgdb port (exclusive use)
- * so skip the normal attach code.
- */
- return;
- }
-#endif
-
- if (strcmp(args->type, "keyboard") == 0 ||
- strcmp(args->type, "mouse") == 0)
- printf(": %s", args->type);
-
- printf("\n");
-
- tp = ttymalloc(0);
- tp->t_dev = dev;
- tp->t_oproc = zsstart;
- tp->t_param = zsparam;
- tp->t_hwiflow = zshwiflow;
-
- zst->zst_tty = tp;
- zst->zst_rbuf = malloc(zstty_rbuf_size << 1, M_DEVBUF, M_WAITOK);
- zst->zst_ebuf = zst->zst_rbuf + (zstty_rbuf_size << 1);
- /* Disable the high water mark. */
- zst->zst_r_hiwat = 0;
- zst->zst_r_lowat = 0;
- zst->zst_rbget = zst->zst_rbput = zst->zst_rbuf;
- zst->zst_rbavail = zstty_rbuf_size;
-
- /* if there are no enable/disable functions, assume the device
- is always enabled */
- if (!cs->enable)
- cs->enabled = 1;
-
- /*
- * Hardware init
- */
- if (ISSET(zst->zst_hwflags, ZS_HWFLAG_CONSOLE)) {
- /* Call zsparam similar to open. */
- struct termios t;
-
- /* Wait a while for previous console output to complete */
- DELAY(10000);
-
- /* Setup the "new" parameters in t. */
- t.c_ispeed = 0;
- t.c_ospeed = cs->cs_defspeed;
- t.c_cflag = cs->cs_defcflag;
-
- s = splzs();
-
- /*
- * Turn on receiver and status interrupts.
- * We defer the actual write of the register to zsparam(),
- * but we must make sure status interrupts are turned on by
- * the time zsparam() reads the initial rr0 state.
- */
- SET(cs->cs_preg[1], ZSWR1_RIE | ZSWR1_SIE);
-
- splx(s);
-
- /* Make sure zsparam will see changes. */
- tp->t_ospeed = 0;
- (void) zsparam(tp, &t);
-
- s = splzs();
-
- /* Make sure DTR is on now. */
- zs_modem(zst, 1);
-
- splx(s);
- } else if (!ISSET(zst->zst_hwflags, ZS_HWFLAG_NORESET)) {
- /* Not the console; may need reset. */
- int reset;
-
- reset = (channel == 0) ? ZSWR9_A_RESET : ZSWR9_B_RESET;
-
- s = splzs();
-
- zs_write_reg(cs, 9, reset);
-
- /* Will raise DTR in open. */
- zs_modem(zst, 0);
-
- splx(s);
- }
-}
-
-
-/*
- * Return pointer to our tty.
- */
-struct tty *
-zstty(dev)
- dev_t dev;
-{
- struct zstty_softc *zst = zs_device_lookup(&zstty_cd, ZSUNIT(dev));
-
- return (zst->zst_tty);
-}
-
-
-void
-zs_shutdown(zst)
- struct zstty_softc *zst;
-{
- struct zs_chanstate *cs = zst->zst_cs;
- struct tty *tp = zst->zst_tty;
- int s;
-
- s = splzs();
-
- /* If we were asserting flow control, then deassert it. */
- SET(zst->zst_rx_flags, RX_IBUF_BLOCKED);
- zs_hwiflow(zst);
-
- /* Clear any break condition set with TIOCSBRK. */
- zs_break(cs, 0);
-
- /* Turn off PPS capture on last close. */
- zst->zst_ppsmask = 0;
-
- /*
- * Hang up if necessary. Wait a bit, so the other side has time to
- * notice even if we immediately open the port again.
- */
- if (ISSET(tp->t_cflag, HUPCL) || ISSET(tp->t_state, TS_WOPEN)) {
- zs_modem(zst, 0);
- /* hold low for 1 second */
- (void) tsleep(cs, TTIPRI, ttclos, hz);
- }
-
- /* Turn off interrupts if not the console. */
- if (!ISSET(zst->zst_hwflags, ZS_HWFLAG_CONSOLE)) {
- CLR(cs->cs_preg[1], ZSWR1_RIE | ZSWR1_SIE);
- cs->cs_creg[1] = cs->cs_preg[1];
- zs_write_reg(cs, 1, cs->cs_creg[1]);
- }
-
- /* Call the power management hook. */
- if (cs->disable) {
-#ifdef DIAGNOSTIC
- if (!cs->enabled)
- panic("zs_shutdown: not enabled?");
-#endif
- (*cs->disable)(zst->zst_cs);
- }
-
- splx(s);
-}
-
-/*
- * Open a zs serial (tty) port.
- */
-int
-zsopen(dev, flags, mode, p)
- dev_t dev;
- int flags;
- int mode;
- struct proc *p;
-{
- struct zstty_softc *zst;
- struct zs_chanstate *cs;
- struct tty *tp;
- int s, s2;
- int error;
-
- zst = zs_device_lookup(&zstty_cd, ZSUNIT(dev));
- if (zst == NULL)
- return (ENXIO);
-
- tp = zst->zst_tty;
- cs = zst->zst_cs;
-
- /* If KGDB took the line, then tp==NULL */
- if (tp == NULL)
- return (EBUSY);
-
- if (ISSET(tp->t_state, TS_ISOPEN) &&
- ISSET(tp->t_state, TS_XCLUDE) &&
- suser(p, 0) != 0)
- return (EBUSY);
-
- s = spltty();
-
- /*
- * Do the following iff this is a first open.
- */
- if (!ISSET(tp->t_state, TS_ISOPEN)) {
- struct termios t;
-
- tp->t_dev = dev;
-
- /* Call the power management hook. */
- if (cs->enable) {
- if ((*cs->enable)(cs)) {
- splx(s);
- printf("%s: device enable failed\n",
- zst->zst_dev.dv_xname);
- return (EIO);
- }
- }
-
- /*
- * Initialize the termios status to the defaults. Add in the
- * sticky bits from TIOCSFLAGS.
- */
- t.c_ispeed = 0;
- t.c_ospeed = cs->cs_defspeed;
- t.c_cflag = cs->cs_defcflag;
- if (ISSET(zst->zst_swflags, TIOCFLAG_CLOCAL))
- SET(t.c_cflag, CLOCAL);
- if (ISSET(zst->zst_swflags, TIOCFLAG_CRTSCTS))
- SET(t.c_cflag, CRTSCTS);
- if (ISSET(zst->zst_swflags, TIOCFLAG_MDMBUF))
- SET(t.c_cflag, MDMBUF);
-
- s2 = splzs();
-
- /*
- * Turn on receiver and status interrupts.
- * We defer the actual write of the register to zsparam(),
- * but we must make sure status interrupts are turned on by
- * the time zsparam() reads the initial rr0 state.
- */
- SET(cs->cs_preg[1], ZSWR1_RIE | ZSWR1_SIE);
-
- /* Clear PPS capture state on first open. */
- zst->zst_ppsmask = 0;
-
- splx(s2);
-
- /* Make sure zsparam will see changes. */
- tp->t_ospeed = 0;
- (void) zsparam(tp, &t);
-
- /*
- * Note: zsparam has done: cflag, ispeed, ospeed
- * so we just need to do: iflag, oflag, lflag, cc
- * For "raw" mode, just leave all zeros.
- */
- if (!ISSET(zst->zst_hwflags, ZS_HWFLAG_RAW)) {
- tp->t_iflag = TTYDEF_IFLAG;
- tp->t_oflag = TTYDEF_OFLAG;
- tp->t_lflag = TTYDEF_LFLAG;
- } else {
- tp->t_iflag = 0;
- tp->t_oflag = 0;
- tp->t_lflag = 0;
- }
- ttychars(tp);
- ttsetwater(tp);
-
- if (ZSDIALOUT(dev))
- SET(tp->t_state, TS_CARR_ON);
- else
- CLR(tp->t_state, TS_CARR_ON);
-
- s2 = splzs();
-
- /* Clear the input ring, and unblock. */
- zst->zst_rbget = zst->zst_rbput = zst->zst_rbuf;
- zst->zst_rbavail = zstty_rbuf_size;
- zs_iflush(cs);
- CLR(zst->zst_rx_flags, RX_ANY_BLOCK);
- zs_hwiflow(zst);
-
- splx(s2);
- }
-
- if (ZSDIALOUT(dev)) {
- if (ISSET(tp->t_state, TS_ISOPEN)) {
- /* someone already is dialed in... */
- splx(s);
- return EBUSY;
- }
- cs->cs_cua = 1;
- }
-
- error = 0;
- /* wait for carrier if necessary */
- if (ISSET(flags, O_NONBLOCK)) {
- if (!ZSDIALOUT(dev) && cs->cs_cua) {
- /* Opening TTY non-blocking... but the CUA is busy */
- error = EBUSY;
- }
- } else
- while (cs->cs_cua ||
- (!ISSET(tp->t_cflag, CLOCAL) && !ISSET(tp->t_state, TS_CARR_ON))) {
- int rr0;
-
- error = 0;
- SET(tp->t_state, TS_WOPEN);
-
- if (!ZSDIALOUT(dev) && !cs->cs_cua) {
- /*
- * Turn on DTR. We must always do this on non-CUA
- * devices, even if carrier is not present, because
- * otherwise we'd have to use TIOCSDTR immediately
- * after setting CLOCAL, which applications do not
- * expect. We always assert DTR while the device is
- * open unless explicitly requested to deassert it.
- */
- s2 = splzs();
- zs_modem(zst, 1);
- rr0 = zs_read_csr(cs);
- splx(s2);
-
- /* loop, turning on the device, until carrier present */
- if (ISSET(rr0, ZSRR0_DCD) ||
- ISSET(zst->zst_swflags, TIOCFLAG_SOFTCAR))
- SET(tp->t_state, TS_CARR_ON);
- }
-
- if ((ISSET(tp->t_cflag, CLOCAL) ||
- ISSET(tp->t_state, TS_CARR_ON)) && !cs->cs_cua)
- break;
-
- error = ttysleep(tp, (caddr_t)&tp->t_rawq, TTIPRI | PCATCH,
- ttopen, 0);
-
- if (!ZSDIALOUT(dev) && cs->cs_cua && error == EINTR) {
- error = 0;
- continue;
- }
-
- if (error) {
- if (!ISSET(tp->t_state, TS_ISOPEN)) {
- s2 = splzs();
- zs_modem(zst, 0);
- splx(s2);
- CLR(tp->t_state, TS_WOPEN);
- ttwakeup(tp);
- }
- if (ZSDIALOUT(dev))
- cs->cs_cua = 0;
- CLR(tp->t_state, TS_WOPEN);
- break;
- }
- if (!ZSDIALOUT(dev) && cs->cs_cua)
- continue;
- }
-
- splx(s);
-
- if (error == 0)
- error = ((*linesw[tp->t_line].l_open)(dev, tp, p));
- if (error)
- goto bad;
-
- return (0);
-
-bad:
- if (!ISSET(tp->t_state, TS_ISOPEN)) {
- /*
- * We failed to open the device, and nobody else had it opened.
- * Clean up the state as appropriate.
- */
- zs_shutdown(zst);
- }
-
- return (error);
-}
-
-/*
- * Close a zs serial port.
- */
-int
-zsclose(dev, flags, mode, p)
- dev_t dev;
- int flags;
- int mode;
- struct proc *p;
-{
- struct zstty_softc *zst = zs_device_lookup(&zstty_cd, ZSUNIT(dev));
- struct zs_chanstate *cs = zst->zst_cs;
- struct tty *tp = zst->zst_tty;
- int s;
-
- /* XXX This is for cons.c. */
- if (!ISSET(tp->t_state, TS_ISOPEN))
- return 0;
-
- (*linesw[tp->t_line].l_close)(tp, flags, p);
-
- s = spltty();
- cs->cs_cua = 0;
- ttyclose(tp);
- splx(s);
-
- if (!ISSET(tp->t_state, TS_ISOPEN)) {
- /*
- * Although we got a last close, the device may still be in
- * use; e.g. if this was the dialout node, and there are still
- * processes waiting for carrier on the non-dialout node.
- */
- zs_shutdown(zst);
- }
-
- return (0);
-}
-
-/*
- * Read/write zs serial port.
- */
-int
-zsread(dev, uio, flags)
- dev_t dev;
- struct uio *uio;
- int flags;
-{
- struct zstty_softc *zst = zs_device_lookup(&zstty_cd, ZSUNIT(dev));
- struct tty *tp = zst->zst_tty;
-
- return (*linesw[tp->t_line].l_read)(tp, uio, flags);
-}
-
-int
-zswrite(dev, uio, flags)
- dev_t dev;
- struct uio *uio;
- int flags;
-{
- struct zstty_softc *zst = zs_device_lookup(&zstty_cd, ZSUNIT(dev));
- struct tty *tp = zst->zst_tty;
-
- return ((*linesw[tp->t_line].l_write)(tp, uio, flags));
-}
-
-int
-zsioctl(dev, cmd, data, flag, p)
- dev_t dev;
- u_long cmd;
- caddr_t data;
- int flag;
- struct proc *p;
-{
- struct zstty_softc *zst = zs_device_lookup(&zstty_cd, ZSUNIT(dev));
- struct zs_chanstate *cs = zst->zst_cs;
- struct tty *tp = zst->zst_tty;
- int error;
- int s;
-
- error = ((*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag, p));
- if (error >= 0)
- return (error);
-
- error = ttioctl(tp, cmd, data, flag, p);
- if (error >= 0)
- return (error);
-
-#ifdef ZS_MD_IOCTL
- error = ZS_MD_IOCTL;
- if (error >= 0)
- return (error);
-#endif /* ZS_MD_IOCTL */
-
- error = 0;
-
- s = splzs();
-
- switch (cmd) {
- case TIOCSBRK:
- zs_break(cs, 1);
- break;
-
- case TIOCCBRK:
- zs_break(cs, 0);
- break;
-
- case TIOCGFLAGS:
- *(int *)data = zst->zst_swflags;
- break;
-
- case TIOCSFLAGS:
- error = suser(p, 0);
- if (error)
- break;
- zst->zst_swflags = *(int *)data;
- break;
-
- case TIOCSDTR:
- zs_modem(zst, 1);
- break;
-
- case TIOCCDTR:
- zs_modem(zst, 0);
- break;
-
- case TIOCMSET:
- case TIOCMBIS:
- case TIOCMBIC:
- tiocm_to_zs(zst, cmd, *(int *)data);
- break;
-
- case TIOCMGET:
- *(int *)data = zs_to_tiocm(zst);
- break;
-
- default:
- error = ENOTTY;
- break;
- }
-
- splx(s);
-
- return (error);
-}
-
-/*
- * Start or restart transmission.
- */
-static void
-zsstart(tp)
- struct tty *tp;
-{
- struct zstty_softc *zst = zs_device_lookup(&zstty_cd, ZSUNIT(tp->t_dev));
- struct zs_chanstate *cs = zst->zst_cs;
- int s;
-
- s = spltty();
- if (ISSET(tp->t_state, TS_BUSY | TS_TIMEOUT | TS_TTSTOP))
- goto out;
- if (zst->zst_tx_stopped)
- goto out;
-
- ttwakeupwr(tp);
- if (tp->t_outq.c_cc == 0)
- goto out;
-
- /* Grab the first contiguous region of buffer space. */
- {
- u_char *tba;
- int tbc;
-
- tba = tp->t_outq.c_cf;
- tbc = ndqb(&tp->t_outq, 0);
-
- (void) splzs();
-
- zst->zst_tba = tba;
- zst->zst_tbc = tbc;
- }
-
- SET(tp->t_state, TS_BUSY);
- zst->zst_tx_busy = 1;
-
- /* Enable transmit completion interrupts if necessary. */
- if (!ISSET(cs->cs_preg[1], ZSWR1_TIE)) {
- SET(cs->cs_preg[1], ZSWR1_TIE);
- cs->cs_creg[1] = cs->cs_preg[1];
- zs_write_reg(cs, 1, cs->cs_creg[1]);
- }
-
- /* Output the first character of the contiguous buffer. */
- {
- zs_write_data(cs, *zst->zst_tba);
- zst->zst_tbc--;
- zst->zst_tba++;
- }
-out:
- splx(s);
- return;
-}
-
-/*
- * Stop output, e.g., for ^S or output flush.
- */
-int
-zsstop(tp, flag)
- struct tty *tp;
- int flag;
-{
- struct zstty_softc *zst = zs_device_lookup(&zstty_cd, ZSUNIT(tp->t_dev));
- int s;
-
- s = splzs();
- if (ISSET(tp->t_state, TS_BUSY)) {
- /* Stop transmitting at the next chunk. */
- zst->zst_tbc = 0;
- zst->zst_heldtbc = 0;
- if (!ISSET(tp->t_state, TS_TTSTOP))
- SET(tp->t_state, TS_FLUSH);
- }
- splx(s);
- return (0);
-}
-
-/*
- * Set ZS tty parameters from termios.
- * XXX - Should just copy the whole termios after
- * making sure all the changes could be done.
- */
-static int
-zsparam(tp, t)
- struct tty *tp;
- struct termios *t;
-{
- struct zstty_softc *zst = zs_device_lookup(&zstty_cd, ZSUNIT(tp->t_dev));
- struct zs_chanstate *cs = zst->zst_cs;
- int ospeed, cflag;
- u_char tmp3, tmp4, tmp5;
- int s, error;
-
- ospeed = t->c_ospeed;
- cflag = t->c_cflag;
-
- /* Check requested parameters. */
- if (ospeed < 0)
- return (EINVAL);
- if (t->c_ispeed && t->c_ispeed != ospeed)
- return (EINVAL);
-
- /*
- * For the console, always force CLOCAL and !HUPCL, so that the port
- * is always active.
- */
- if (ISSET(zst->zst_swflags, TIOCFLAG_SOFTCAR) ||
- ISSET(zst->zst_hwflags, ZS_HWFLAG_CONSOLE)) {
- SET(cflag, CLOCAL);
- CLR(cflag, HUPCL);
- }
-
- /*
- * Only whack the UART when params change.
- * Some callers need to clear tp->t_ospeed
- * to make sure initialization gets done.
- */
- if (tp->t_ospeed == ospeed &&
- tp->t_cflag == cflag)
- return (0);
-
- /*
- * Call MD functions to deal with changed
- * clock modes or H/W flow control modes.
- * The BRG divisor is set now. (reg 12,13)
- */
- error = zs_set_speed(cs, ospeed);
- if (error)
- return (error);
- error = zs_set_modes(cs, cflag);
- if (error)
- return (error);
-
- /*
- * Block interrupts so that state will not
- * be altered until we are done setting it up.
- *
- * Initial values in cs_preg are set before
- * our attach routine is called. The master
- * interrupt enable is handled by zsc.c
- *
- */
- s = splzs();
-
- /*
- * Recalculate which status ints to enable.
- */
- zs_maskintr(zst);
-
- /* Recompute character size bits. */
- tmp3 = cs->cs_preg[3];
- tmp5 = cs->cs_preg[5];
- CLR(tmp3, ZSWR3_RXSIZE);
- CLR(tmp5, ZSWR5_TXSIZE);
- switch (ISSET(cflag, CSIZE)) {
- case CS5:
- SET(tmp3, ZSWR3_RX_5);
- SET(tmp5, ZSWR5_TX_5);
- break;
- case CS6:
- SET(tmp3, ZSWR3_RX_6);
- SET(tmp5, ZSWR5_TX_6);
- break;
- case CS7:
- SET(tmp3, ZSWR3_RX_7);
- SET(tmp5, ZSWR5_TX_7);
- break;
- case CS8:
- SET(tmp3, ZSWR3_RX_8);
- SET(tmp5, ZSWR5_TX_8);
- break;
- }
- cs->cs_preg[3] = tmp3;
- cs->cs_preg[5] = tmp5;
-
- /*
- * Recompute the stop bits and parity bits. Note that
- * zs_set_speed() may have set clock selection bits etc.
- * in wr4, so those must preserved.
- */
- tmp4 = cs->cs_preg[4];
- CLR(tmp4, ZSWR4_SBMASK | ZSWR4_PARMASK);
- if (ISSET(cflag, CSTOPB))
- SET(tmp4, ZSWR4_TWOSB);
- else
- SET(tmp4, ZSWR4_ONESB);
- if (!ISSET(cflag, PARODD))
- SET(tmp4, ZSWR4_EVENP);
- if (ISSET(cflag, PARENB))
- SET(tmp4, ZSWR4_PARENB);
- cs->cs_preg[4] = tmp4;
-
- /* And copy to tty. */
- tp->t_ispeed = 0;
- tp->t_ospeed = ospeed;
- tp->t_cflag = cflag;
-
- /*
- * If nothing is being transmitted, set up new current values,
- * else mark them as pending.
- */
- if (!cs->cs_heldchange) {
- if (zst->zst_tx_busy) {
- zst->zst_heldtbc = zst->zst_tbc;
- zst->zst_tbc = 0;
- cs->cs_heldchange = 1;
- } else
- zs_loadchannelregs(cs);
- }
-
- /*
- * If hardware flow control is disabled, turn off the buffer water
- * marks and unblock any soft flow control state. Otherwise, enable
- * the water marks.
- */
- if (!ISSET(cflag, CHWFLOW)) {
- zst->zst_r_hiwat = 0;
- zst->zst_r_lowat = 0;
- if (ISSET(zst->zst_rx_flags, RX_TTY_OVERFLOWED)) {
- CLR(zst->zst_rx_flags, RX_TTY_OVERFLOWED);
- zst->zst_rx_ready = 1;
- cs->cs_softreq = 1;
- }
- if (ISSET(zst->zst_rx_flags, RX_TTY_BLOCKED|RX_IBUF_BLOCKED)) {
- CLR(zst->zst_rx_flags, RX_TTY_BLOCKED|RX_IBUF_BLOCKED);
- zs_hwiflow(zst);
- }
- } else {
- zst->zst_r_hiwat = zstty_rbuf_hiwat;
- zst->zst_r_lowat = zstty_rbuf_lowat;
- }
-
- /*
- * Force a recheck of the hardware carrier and flow control status,
- * since we may have changed which bits we're looking at.
- */
- zstty_stint(cs, 1);
-
- splx(s);
-
- /*
- * If hardware flow control is disabled, unblock any hard flow control
- * state.
- */
- if (!ISSET(cflag, CHWFLOW)) {
- if (zst->zst_tx_stopped) {
- zst->zst_tx_stopped = 0;
- zsstart(tp);
- }
- }
-
- zstty_softint(cs);
-
- return (0);
-}
-
-/*
- * Compute interrupt enable bits and set in the pending bits. Called both
- * in zsparam() and when PPS (pulse per second timing) state changes.
- * Must be called at splzs().
- */
-static void
-zs_maskintr(zst)
- struct zstty_softc *zst;
-{
- struct zs_chanstate *cs = zst->zst_cs;
- int tmp15;
-
- cs->cs_rr0_mask = cs->cs_rr0_cts | cs->cs_rr0_dcd;
- if (zst->zst_ppsmask != 0)
- cs->cs_rr0_mask |= cs->cs_rr0_pps;
- tmp15 = cs->cs_preg[15];
- if (ISSET(cs->cs_rr0_mask, ZSRR0_DCD))
- SET(tmp15, ZSWR15_DCD_IE);
- else
- CLR(tmp15, ZSWR15_DCD_IE);
- if (ISSET(cs->cs_rr0_mask, ZSRR0_CTS))
- SET(tmp15, ZSWR15_CTS_IE);
- else
- CLR(tmp15, ZSWR15_CTS_IE);
- cs->cs_preg[15] = tmp15;
-}
-
-
-/*
- * Raise or lower modem control (DTR/RTS) signals. If a character is
- * in transmission, the change is deferred.
- */
-static void
-zs_modem(zst, onoff)
- struct zstty_softc *zst;
- int onoff;
-{
- struct zs_chanstate *cs = zst->zst_cs;
-
- if (cs->cs_wr5_dtr == 0)
- return;
-
- if (onoff)
- SET(cs->cs_preg[5], cs->cs_wr5_dtr);
- else
- CLR(cs->cs_preg[5], cs->cs_wr5_dtr);
-
- if (!cs->cs_heldchange) {
- if (zst->zst_tx_busy) {
- zst->zst_heldtbc = zst->zst_tbc;
- zst->zst_tbc = 0;
- cs->cs_heldchange = 1;
- } else
- zs_loadchannelregs(cs);
- }
-}
-
-static void
-tiocm_to_zs(zst, how, ttybits)
- struct zstty_softc *zst;
- u_long how;
- int ttybits;
-{
- struct zs_chanstate *cs = zst->zst_cs;
- u_char zsbits;
-
- zsbits = 0;
- if (ISSET(ttybits, TIOCM_DTR))
- SET(zsbits, ZSWR5_DTR);
- if (ISSET(ttybits, TIOCM_RTS))
- SET(zsbits, ZSWR5_RTS);
-
- switch (how) {
- case TIOCMBIC:
- CLR(cs->cs_preg[5], zsbits);
- break;
-
- case TIOCMBIS:
- SET(cs->cs_preg[5], zsbits);
- break;
-
- case TIOCMSET:
- CLR(cs->cs_preg[5], ZSWR5_RTS | ZSWR5_DTR);
- SET(cs->cs_preg[5], zsbits);
- break;
- }
-
- if (!cs->cs_heldchange) {
- if (zst->zst_tx_busy) {
- zst->zst_heldtbc = zst->zst_tbc;
- zst->zst_tbc = 0;
- cs->cs_heldchange = 1;
- } else
- zs_loadchannelregs(cs);
- }
-}
-
-static int
-zs_to_tiocm(zst)
- struct zstty_softc *zst;
-{
- struct zs_chanstate *cs = zst->zst_cs;
- u_char zsbits;
- int ttybits = 0;
-
- zsbits = cs->cs_preg[5];
- if (ISSET(zsbits, ZSWR5_DTR))
- SET(ttybits, TIOCM_DTR);
- if (ISSET(zsbits, ZSWR5_RTS))
- SET(ttybits, TIOCM_RTS);
-
- zsbits = cs->cs_rr0;
- if (ISSET(zsbits, ZSRR0_DCD))
- SET(ttybits, TIOCM_CD);
- if (ISSET(zsbits, ZSRR0_CTS))
- SET(ttybits, TIOCM_CTS);
-
- return (ttybits);
-}
-
-/*
- * Try to block or unblock input using hardware flow-control.
- * This is called by kern/tty.c if MDMBUF|CRTSCTS is set, and
- * if this function returns non-zero, the TS_TBLOCK flag will
- * be set or cleared according to the "block" arg passed.
- */
-int
-zshwiflow(tp, block)
- struct tty *tp;
- int block;
-{
- struct zstty_softc *zst = zs_device_lookup(&zstty_cd, ZSUNIT(tp->t_dev));
- struct zs_chanstate *cs = zst->zst_cs;
- int s;
-
- if (cs->cs_wr5_rts == 0)
- return (0);
-
- s = splzs();
- if (block) {
- if (!ISSET(zst->zst_rx_flags, RX_TTY_BLOCKED)) {
- SET(zst->zst_rx_flags, RX_TTY_BLOCKED);
- zs_hwiflow(zst);
- }
- } else {
- if (ISSET(zst->zst_rx_flags, RX_TTY_OVERFLOWED)) {
- CLR(zst->zst_rx_flags, RX_TTY_OVERFLOWED);
- zst->zst_rx_ready = 1;
- cs->cs_softreq = 1;
- }
- if (ISSET(zst->zst_rx_flags, RX_TTY_BLOCKED)) {
- CLR(zst->zst_rx_flags, RX_TTY_BLOCKED);
- zs_hwiflow(zst);
- }
- }
- splx(s);
- return (1);
-}
-
-/*
- * Internal version of zshwiflow
- * called at splzs
- */
-static void
-zs_hwiflow(zst)
- struct zstty_softc *zst;
-{
- struct zs_chanstate *cs = zst->zst_cs;
-
- if (cs->cs_wr5_rts == 0)
- return;
-
- if (ISSET(zst->zst_rx_flags, RX_ANY_BLOCK)) {
- CLR(cs->cs_preg[5], cs->cs_wr5_rts);
- CLR(cs->cs_creg[5], cs->cs_wr5_rts);
- } else {
- SET(cs->cs_preg[5], cs->cs_wr5_rts);
- SET(cs->cs_creg[5], cs->cs_wr5_rts);
- }
- zs_write_reg(cs, 5, cs->cs_creg[5]);
-}
-
-
-/****************************************************************
- * Interface to the lower layer (zscc)
- ****************************************************************/
-
-#define integrate static inline
-integrate void zstty_rxsoft(struct zstty_softc *, struct tty *);
-integrate void zstty_txsoft(struct zstty_softc *, struct tty *);
-integrate void zstty_stsoft(struct zstty_softc *, struct tty *);
-/*
- * receiver ready interrupt.
- * called at splzs
- */
-static void
-zstty_rxint(cs)
- struct zs_chanstate *cs;
-{
- struct zstty_softc *zst = cs->cs_private;
- u_char *put, *end;
- u_int cc;
- u_char rr0, rr1, c;
-
- end = zst->zst_ebuf;
- put = zst->zst_rbput;
- cc = zst->zst_rbavail;
-
- while (cc > 0) {
- /*
- * First read the status, because reading the received char
- * destroys the status of this char.
- */
- rr1 = zs_read_reg(cs, 1);
- c = zs_read_data(cs);
-
- if (ISSET(rr1, ZSRR1_FE | ZSRR1_DO | ZSRR1_PE)) {
- /* Clear the receive error. */
- zs_write_csr(cs, ZSWR0_RESET_ERRORS);
- }
-
- put[0] = c;
- put[1] = rr1;
- put += 2;
- if (put >= end)
- put = zst->zst_rbuf;
- cc--;
-
- rr0 = zs_read_csr(cs);
- if (!ISSET(rr0, ZSRR0_RX_READY))
- break;
- }
-
- /*
- * Current string of incoming characters ended because
- * no more data was available or we ran out of space.
- * Schedule a receive event if any data was received.
- * If we're out of space, turn off receive interrupts.
- */
- zst->zst_rbput = put;
- zst->zst_rbavail = cc;
- if (!ISSET(zst->zst_rx_flags, RX_TTY_OVERFLOWED)) {
- zst->zst_rx_ready = 1;
- cs->cs_softreq = 1;
- }
-
- /*
- * See if we are in danger of overflowing a buffer. If
- * so, use hardware flow control to ease the pressure.
- */
- if (!ISSET(zst->zst_rx_flags, RX_IBUF_BLOCKED) &&
- cc < zst->zst_r_hiwat) {
- SET(zst->zst_rx_flags, RX_IBUF_BLOCKED);
- zs_hwiflow(zst);
- }
-
- /*
- * If we're out of space, disable receive interrupts
- * until the queue has drained a bit.
- */
- if (!cc) {
- SET(zst->zst_rx_flags, RX_IBUF_OVERFLOWED);
- CLR(cs->cs_preg[1], ZSWR1_RIE);
- cs->cs_creg[1] = cs->cs_preg[1];
- zs_write_reg(cs, 1, cs->cs_creg[1]);
- }
-}
-
-/*
- * transmitter ready interrupt. (splzs)
- */
-static void
-zstty_txint(cs)
- struct zs_chanstate *cs;
-{
- struct zstty_softc *zst = cs->cs_private;
-
- /*
- * If we've delayed a parameter change, do it now, and restart
- * output.
- */
- if (cs->cs_heldchange) {
- zs_loadchannelregs(cs);
- cs->cs_heldchange = 0;
- zst->zst_tbc = zst->zst_heldtbc;
- zst->zst_heldtbc = 0;
- }
-
- /* Output the next character in the buffer, if any. */
- if (zst->zst_tbc > 0) {
- zs_write_data(cs, *zst->zst_tba);
- zst->zst_tbc--;
- zst->zst_tba++;
- } else {
- /* Disable transmit completion interrupts if necessary. */
- if (ISSET(cs->cs_preg[1], ZSWR1_TIE)) {
- CLR(cs->cs_preg[1], ZSWR1_TIE);
- cs->cs_creg[1] = cs->cs_preg[1];
- zs_write_reg(cs, 1, cs->cs_creg[1]);
- }
- if (zst->zst_tx_busy) {
- zst->zst_tx_busy = 0;
- zst->zst_tx_done = 1;
- cs->cs_softreq = 1;
- }
- }
-}
-
-#ifdef DDB
-#include <ddb/db_var.h>
-#define DB_CONSOLE db_console
-#else
-#define DB_CONSOLE 1
-#endif
-
-/*
- * status change interrupt. (splzs)
- */
-static void
-zstty_stint(cs, force)
- struct zs_chanstate *cs;
- int force;
-{
- struct zstty_softc *zst = cs->cs_private;
- struct tty *tp = zst->zst_tty;
- u_char rr0, delta;
-
- rr0 = zs_read_csr(cs);
- zs_write_csr(cs, ZSWR0_RESET_STATUS);
-
- /*
- * Check here for console break, so that we can abort
- * even when interrupts are locking up the machine.
- */
- if ((zst->zst_hwflags & ZS_HWFLAG_CONSOLE_INPUT) &&
- ISSET(rr0, ZSRR0_BREAK) && DB_CONSOLE)
- zs_abort(cs);
-
- if (!force)
- delta = rr0 ^ cs->cs_rr0;
- else
- delta = cs->cs_rr0_mask;
-
- ttytstamp(tp, cs->cs_rr0 & ZSRR0_CTS, rr0 & ZSRR0_CTS,
- cs->cs_rr0 & ZSRR0_DCD, rr0 & ZSRR0_DCD);
-
- cs->cs_rr0 = rr0;
-
- if (ISSET(delta, cs->cs_rr0_mask)) {
- SET(cs->cs_rr0_delta, delta);
-
- /*
- * Stop output immediately if we lose the output
- * flow control signal or carrier detect.
- */
- if (ISSET(~rr0, cs->cs_rr0_mask)) {
- zst->zst_tbc = 0;
- zst->zst_heldtbc = 0;
- }
-
- zst->zst_st_check = 1;
- cs->cs_softreq = 1;
- }
-}
-
-void
-zstty_diag(arg)
- void *arg;
-{
- struct zstty_softc *zst = arg;
- int overflows, floods;
- int s;
-
- s = splzs();
- overflows = zst->zst_overflows;
- zst->zst_overflows = 0;
- floods = zst->zst_floods;
- zst->zst_floods = 0;
- zst->zst_errors = 0;
- splx(s);
-
- log(LOG_WARNING, "%s: %d silo overflow%s, %d ibuf flood%s\n",
- zst->zst_dev.dv_xname,
- overflows, overflows == 1 ? "" : "s",
- floods, floods == 1 ? "" : "s");
-}
-
-integrate void
-zstty_rxsoft(zst, tp)
- struct zstty_softc *zst;
- struct tty *tp;
-{
- struct zs_chanstate *cs = zst->zst_cs;
- int (*rint)(int c, struct tty *tp) = linesw[tp->t_line].l_rint;
- u_char *get, *end;
- u_int cc, scc;
- u_char rr1;
- int code;
- int s;
-
- end = zst->zst_ebuf;
- get = zst->zst_rbget;
- scc = cc = zstty_rbuf_size - zst->zst_rbavail;
-
- if (cc == zstty_rbuf_size) {
- zst->zst_floods++;
- if (zst->zst_errors++ == 0)
- timeout_add_sec(&zst->zst_diag_ch, 60);
- }
-
- /* If not yet open, drop the entire buffer content here */
- if (!ISSET(tp->t_state, TS_ISOPEN)) {
- get += cc << 1;
- if (get >= end)
- get -= zstty_rbuf_size << 1;
- cc = 0;
- }
- while (cc) {
- code = get[0];
- rr1 = get[1];
- if (ISSET(rr1, ZSRR1_DO | ZSRR1_FE | ZSRR1_PE)) {
- if (ISSET(rr1, ZSRR1_DO)) {
- zst->zst_overflows++;
- if (zst->zst_errors++ == 0)
- timeout_add_sec(&zst->zst_diag_ch, 60);
- }
- if (ISSET(rr1, ZSRR1_FE))
- SET(code, TTY_FE);
- if (ISSET(rr1, ZSRR1_PE))
- SET(code, TTY_PE);
- }
- if ((*rint)(code, tp) == -1) {
- /*
- * The line discipline's buffer is out of space.
- */
- if (!ISSET(zst->zst_rx_flags, RX_TTY_BLOCKED)) {
- /*
- * We're either not using flow control, or the
- * line discipline didn't tell us to block for
- * some reason. Either way, we have no way to
- * know when there's more space available, so
- * just drop the rest of the data.
- */
- get += cc << 1;
- if (get >= end)
- get -= zstty_rbuf_size << 1;
- cc = 0;
- } else {
- /*
- * Don't schedule any more receive processing
- * until the line discipline tells us there's
- * space available (through comhwiflow()).
- * Leave the rest of the data in the input
- * buffer.
- */
- SET(zst->zst_rx_flags, RX_TTY_OVERFLOWED);
- }
- break;
- }
- get += 2;
- if (get >= end)
- get = zst->zst_rbuf;
- cc--;
- }
-
- if (cc != scc) {
- zst->zst_rbget = get;
- s = splzs();
- cc = zst->zst_rbavail += scc - cc;
- /* Buffers should be ok again, release possible block. */
- if (cc >= zst->zst_r_lowat) {
- if (ISSET(zst->zst_rx_flags, RX_IBUF_OVERFLOWED)) {
- CLR(zst->zst_rx_flags, RX_IBUF_OVERFLOWED);
- SET(cs->cs_preg[1], ZSWR1_RIE);
- cs->cs_creg[1] = cs->cs_preg[1];
- zs_write_reg(cs, 1, cs->cs_creg[1]);
- }
- if (ISSET(zst->zst_rx_flags, RX_IBUF_BLOCKED)) {
- CLR(zst->zst_rx_flags, RX_IBUF_BLOCKED);
- zs_hwiflow(zst);
- }
- }
- splx(s);
- }
-}
-
-integrate void
-zstty_txsoft(zst, tp)
- struct zstty_softc *zst;
- struct tty *tp;
-{
-
- CLR(tp->t_state, TS_BUSY);
- if (ISSET(tp->t_state, TS_FLUSH))
- CLR(tp->t_state, TS_FLUSH);
- else
- ndflush(&tp->t_outq, (int)(zst->zst_tba - tp->t_outq.c_cf));
- (*linesw[tp->t_line].l_start)(tp);
-}
-
-integrate void
-zstty_stsoft(zst, tp)
- struct zstty_softc *zst;
- struct tty *tp;
-{
- struct zs_chanstate *cs = zst->zst_cs;
- u_char rr0, delta;
- int s;
-
- s = splzs();
- rr0 = cs->cs_rr0;
- delta = cs->cs_rr0_delta;
- cs->cs_rr0_delta = 0;
- splx(s);
-
- if (ISSET(delta, cs->cs_rr0_dcd)) {
- /*
- * Inform the tty layer that carrier detect changed.
- */
- (void) (*linesw[tp->t_line].l_modem)(tp, ISSET(rr0, ZSRR0_DCD));
- }
-
- if (ISSET(delta, cs->cs_rr0_cts)) {
- /* Block or unblock output according to flow control. */
- if (ISSET(rr0, cs->cs_rr0_cts)) {
- zst->zst_tx_stopped = 0;
- (*linesw[tp->t_line].l_start)(tp);
- } else {
- zst->zst_tx_stopped = 1;
- }
- }
-}
-
-/*
- * Software interrupt. Called at zssoft
- *
- * The main job to be done here is to empty the input ring
- * by passing its contents up to the tty layer. The ring is
- * always emptied during this operation, therefore the ring
- * must not be larger than the space after "high water" in
- * the tty layer, or the tty layer might drop our input.
- *
- * Note: an "input blockage" condition is assumed to exist if
- * EITHER the TS_TBLOCK flag or zst_rx_blocked flag is set.
- */
-static void
-zstty_softint(cs)
- struct zs_chanstate *cs;
-{
- struct zstty_softc *zst = cs->cs_private;
- struct tty *tp = zst->zst_tty;
- int s;
-
- s = spltty();
-
- if (zst->zst_rx_ready) {
- zst->zst_rx_ready = 0;
- zstty_rxsoft(zst, tp);
- }
-
- if (zst->zst_st_check) {
- zst->zst_st_check = 0;
- zstty_stsoft(zst, tp);
- }
-
- if (zst->zst_tx_done) {
- zst->zst_tx_done = 0;
- zstty_txsoft(zst, tp);
- }
-
- splx(s);
-}
-
-struct zsops zsops_tty = {
- zstty_rxint, /* receive char available */
- zstty_stint, /* external/status */
- zstty_txint, /* xmit buffer empty */
- zstty_softint, /* process software interrupt */
-};
diff --git a/sys/arch/sparc64/dev/zs.c b/sys/arch/sparc64/dev/zs.c
index 078e5ed0cc2..287e80d42b2 100644
--- a/sys/arch/sparc64/dev/zs.c
+++ b/sys/arch/sparc64/dev/zs.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: zs.c,v 1.23 2009/09/10 21:30:00 kettenis Exp $ */
+/* $OpenBSD: zs.c,v 1.24 2013/04/21 14:44:16 sebastia Exp $ */
/* $NetBSD: zs.c,v 1.29 2001/05/30 15:24:24 lukem Exp $ */
/*-
@@ -58,7 +58,7 @@
#include <machine/z8530var.h>
#include <dev/cons.h>
-#include <sparc64/dev/z8530reg.h>
+#include <dev/ic/z8530reg.h>
#include <sparc64/dev/fhcvar.h>
#include <ddb/db_output.h>
diff --git a/sys/arch/sparc64/include/z8530var.h b/sys/arch/sparc64/include/z8530var.h
index 76fe029b04a..23ec9c047a0 100644
--- a/sys/arch/sparc64/include/z8530var.h
+++ b/sys/arch/sparc64/include/z8530var.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: z8530var.h,v 1.7 2005/12/28 22:39:52 miod Exp $ */
+/* $OpenBSD: z8530var.h,v 1.8 2013/04/21 14:44:16 sebastia Exp $ */
/* $NetBSD: z8530var.h,v 1.4 2000/11/08 23:41:42 eeh Exp $ */
/*
@@ -42,7 +42,7 @@
*/
#include <machine/bus.h>
-#include <sparc64/dev/z8530sc.h>
+#include <dev/ic/z8530sc.h>
struct zsc_softc {
struct device zsc_dev; /* base device */
diff --git a/sys/dev/ic/z8530sc.c b/sys/dev/ic/z8530sc.c
index f631e607b15..17d55067579 100644
--- a/sys/dev/ic/z8530sc.c
+++ b/sys/dev/ic/z8530sc.c
@@ -1,8 +1,7 @@
-/* $OpenBSD: z8530sc.c,v 1.6 2003/06/02 23:28:02 millert Exp $ */
-/* $NetBSD: z8530sc.c,v 1.4 1996/05/17 19:30:34 gwr Exp $ */
+/* $OpenBSD: z8530sc.c,v 1.7 2013/04/21 14:44:16 sebastia Exp $ */
+/* $NetBSD: z8530sc.c,v 1.30 2009/05/22 03:51:30 mrg Exp $ */
/*
- * Copyright (c) 1994 Gordon W. Ross
* Copyright (c) 1992, 1993
* The Regents of the University of California. All rights reserved.
*
@@ -43,6 +42,49 @@
*/
/*
+ * Copyright (c) 1994 Gordon W. Ross
+ *
+ * This software was developed by the Computer Systems Engineering group
+ * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
+ * contributed to Berkeley.
+ *
+ * All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Lawrence Berkeley Laboratory.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)zs.c 8.1 (Berkeley) 7/19/93
+ */
+
+/*
* Zilog Z8530 Dual UART driver (common part)
*
* This file contains the machine-independent parts of the
@@ -64,17 +106,10 @@
#include <dev/ic/z8530reg.h>
#include <machine/z8530var.h>
-static void zsnull_intr(struct zs_chanstate *);
-static void zsnull_softint(struct zs_chanstate *);
-
void
-zs_break(cs, set)
- struct zs_chanstate *cs;
- int set;
+zs_break(struct zs_chanstate *cs, int set)
{
- int s;
- s = splzs();
if (set) {
cs->cs_preg[5] |= ZSWR5_BREAK;
cs->cs_creg[5] |= ZSWR5_BREAK;
@@ -83,34 +118,23 @@ zs_break(cs, set)
cs->cs_creg[5] &= ~ZSWR5_BREAK;
}
zs_write_reg(cs, 5, cs->cs_creg[5]);
- splx(s);
}
/*
- * Compute the current baud rate given a ZSCC channel.
- */
-int
-zs_getspeed(cs)
- struct zs_chanstate *cs;
-{
- int tconst;
-
- tconst = zs_read_reg(cs, 12);
- tconst |= zs_read_reg(cs, 13) << 8;
- return (TCONST_TO_BPS(cs->cs_brg_clk, tconst));
-}
-
-/*
* drain on-chip fifo
*/
void
-zs_iflush(cs)
- struct zs_chanstate *cs;
+zs_iflush(struct zs_chanstate *cs)
{
- u_char c, rr0, rr1;
+ uint8_t c, rr0, rr1;
+ int i;
- for (;;) {
+ /*
+ * Count how many times we loop. Some systems, such as some
+ * Apple PowerBooks, claim to have SCC's which they really don't.
+ */
+ for (i = 0; i < 32; i++) {
/* Is there input available? */
rr0 = zs_read_csr(cs);
if ((rr0 & ZSRR0_RX_READY) == 0)
@@ -129,7 +153,7 @@ zs_iflush(cs)
}
}
}
-
+
/*
* Write the given register set to the given zs channel in the proper order.
@@ -138,16 +162,11 @@ zs_iflush(cs)
* Call this with interrupts disabled.
*/
void
-zs_loadchannelregs(cs)
- struct zs_chanstate *cs;
+zs_loadchannelregs(struct zs_chanstate *cs)
{
- u_char *reg;
-
- /* Copy "pending" regs to "current" */
- bcopy((caddr_t)cs->cs_preg, (caddr_t)cs->cs_creg, 16);
- reg = cs->cs_creg; /* current regs */
+ uint8_t *reg, v;
- zs_write_csr(cs, ZSM_RESET_ERR); /* XXX: reset error condition */
+ zs_write_csr(cs, ZSM_RESET_ERR); /* XXX: reset error condition */
#if 1
/*
@@ -157,6 +176,22 @@ zs_loadchannelregs(cs)
zs_iflush(cs); /* XXX */
#endif
+ if (cs->cs_ctl_chan != NULL)
+ v = ((cs->cs_ctl_chan->cs_creg[5] & (ZSWR5_RTS | ZSWR5_DTR)) !=
+ (cs->cs_ctl_chan->cs_preg[5] & (ZSWR5_RTS | ZSWR5_DTR)));
+ else
+ v = 0;
+
+ if (memcmp((void *)cs->cs_preg, (void *)cs->cs_creg, 16) == 0 && !v)
+ return; /* only change if values are different */
+
+ /* Copy "pending" regs to "current" */
+ memcpy((void *)cs->cs_creg, (void *)cs->cs_preg, 16);
+ reg = cs->cs_creg; /* current regs */
+
+ /* disable interrupts */
+ zs_write_reg(cs, 1, reg[1] & ~ZSWR1_IMASK);
+
/* baud clock divisor, stop bits, parity */
zs_write_reg(cs, 4, reg[4]);
@@ -167,8 +202,11 @@ zs_loadchannelregs(cs)
zs_write_reg(cs, 3, reg[3] & ~ZSWR3_RX_ENABLE);
zs_write_reg(cs, 5, reg[5] & ~ZSWR5_TX_ENABLE);
- /* interrupt enables: TX, TX, STATUS */
- zs_write_reg(cs, 1, reg[1]);
+ /* synchronous mode stuff */
+ zs_write_reg(cs, 6, reg[6]);
+ if (reg[15] & ZSWR15_ENABLE_ENHANCED)
+ zs_write_reg(cs, 15, 0);
+ zs_write_reg(cs, 7, reg[7]);
#if 0
/*
@@ -184,6 +222,14 @@ zs_loadchannelregs(cs)
zs_write_reg(cs, 9, reg[9]);
#endif
+ /* Shut down the BRG */
+ zs_write_reg(cs, 14, reg[14] & ~ZSWR14_BAUD_ENA);
+
+#ifdef ZS_MD_SETCLK
+ /* Let the MD code setup any external clock. */
+ ZS_MD_SETCLK(cs);
+#endif /* ZS_MD_SETCLK */
+
/* clock mode control */
zs_write_reg(cs, 11, reg[11]);
@@ -197,11 +243,33 @@ zs_loadchannelregs(cs)
/* which lines cause status interrupts */
zs_write_reg(cs, 15, reg[15]);
+ /*
+ * Zilog docs recommend resetting external status twice at this
+ * point. Mainly as the status bits are latched, and the first
+ * interrupt clear might unlatch them to new values, generating
+ * a second interrupt request.
+ */
+ zs_write_csr(cs, ZSM_RESET_STINT);
+ zs_write_csr(cs, ZSM_RESET_STINT);
+
/* char size, enable (RX/TX)*/
zs_write_reg(cs, 3, reg[3]);
zs_write_reg(cs, 5, reg[5]);
-}
+ /* Write the status bits on the alternate channel also. */
+ if (cs->cs_ctl_chan != NULL) {
+ v = cs->cs_ctl_chan->cs_preg[5];
+ cs->cs_ctl_chan->cs_creg[5] = v;
+ zs_write_reg(cs->cs_ctl_chan, 5, v);
+ }
+
+ /* Register 7' if applicable */
+ if (reg[15] & ZSWR15_ENABLE_ENHANCED)
+ zs_write_reg(cs, 7, reg[16]);
+
+ /* interrupt enables: RX, TX, STATUS */
+ zs_write_reg(cs, 1, reg[1]);
+}
/*
* ZS hardware interrupt. Scan all ZS channels. NB: we know here that
@@ -215,56 +283,58 @@ zs_loadchannelregs(cs)
* the order.
*/
int
-zsc_intr_hard(arg)
- void *arg;
+zsc_intr_hard(void *arg)
{
- register struct zsc_softc *zsc = arg;
- register struct zs_chanstate *cs_a;
- register struct zs_chanstate *cs_b;
- register int rval;
- register u_char rr3;
-
- cs_a = &zsc->zsc_cs[0];
- cs_b = &zsc->zsc_cs[1];
- rval = 0;
+ struct zsc_softc *zsc = arg;
+ struct zs_chanstate *cs0, *cs1;
+ int handled;
+ uint8_t rr3;
- /* Note: only channel A has an RR3 */
- rr3 = zs_read_reg(cs_a, 3);
-
- /* Handle receive interrupts first. */
- if (rr3 & ZSRR3_IP_A_RX)
- (*cs_a->cs_ops->zsop_rxint)(cs_a);
- if (rr3 & ZSRR3_IP_B_RX)
- (*cs_b->cs_ops->zsop_rxint)(cs_b);
-
- /* Handle status interrupts (i.e. flow control). */
- if (rr3 & ZSRR3_IP_A_STAT)
- (*cs_a->cs_ops->zsop_stint)(cs_a);
- if (rr3 & ZSRR3_IP_B_STAT)
- (*cs_b->cs_ops->zsop_stint)(cs_b);
-
- /* Handle transmit done interrupts. */
- if (rr3 & ZSRR3_IP_A_TX)
- (*cs_a->cs_ops->zsop_txint)(cs_a);
- if (rr3 & ZSRR3_IP_B_TX)
- (*cs_b->cs_ops->zsop_txint)(cs_b);
-
- /* Clear interrupt. */
- if (rr3 & (ZSRR3_IP_A_RX | ZSRR3_IP_A_TX | ZSRR3_IP_A_STAT)) {
- zs_write_csr(cs_a, ZSWR0_CLR_INTR);
- rval |= 1;
- }
- if (rr3 & (ZSRR3_IP_B_RX | ZSRR3_IP_B_TX | ZSRR3_IP_B_STAT)) {
- zs_write_csr(cs_b, ZSWR0_CLR_INTR);
- rval |= 2;
- }
+ handled = 0;
+
+ /* First look at channel A. */
+ cs0 = zsc->zsc_cs[0];
+ cs1 = zsc->zsc_cs[1];
+
+ /*
+ * We have to clear interrupt first to avoid a race condition,
+ * but it will be done in each MD handler.
+ */
+ for (;;) {
+ /* Note: only channel A has an RR3 */
+ rr3 = zs_read_reg(cs0, 3);
- if ((cs_a->cs_softreq) || (cs_b->cs_softreq)) {
- /* This is a machine-dependent function (or macro). */
- zsc_req_softint(zsc);
+ if ((rr3 & (ZSRR3_IP_A_RX | ZSRR3_IP_A_TX | ZSRR3_IP_A_STAT |
+ ZSRR3_IP_B_RX | ZSRR3_IP_B_TX | ZSRR3_IP_B_STAT)) == 0) {
+ break;
+ }
+ handled = 1;
+
+ /* First look at channel A. */
+ if (rr3 & (ZSRR3_IP_A_RX | ZSRR3_IP_A_TX | ZSRR3_IP_A_STAT))
+ zs_write_csr(cs0, ZSWR0_CLR_INTR);
+
+ if (rr3 & ZSRR3_IP_A_RX)
+ (*cs0->cs_ops->zsop_rxint)(cs0);
+ if (rr3 & ZSRR3_IP_A_STAT)
+ (*cs0->cs_ops->zsop_stint)(cs0, 0);
+ if (rr3 & ZSRR3_IP_A_TX)
+ (*cs0->cs_ops->zsop_txint)(cs0);
+
+ /* Now look at channel B. */
+ if (rr3 & (ZSRR3_IP_B_RX | ZSRR3_IP_B_TX | ZSRR3_IP_B_STAT))
+ zs_write_csr(cs1, ZSWR0_CLR_INTR);
+
+ if (rr3 & ZSRR3_IP_B_RX)
+ (*cs1->cs_ops->zsop_rxint)(cs1);
+ if (rr3 & ZSRR3_IP_B_STAT)
+ (*cs1->cs_ops->zsop_stint)(cs1, 0);
+ if (rr3 & ZSRR3_IP_B_TX)
+ (*cs1->cs_ops->zsop_txint)(cs1);
}
- return (rval);
+ /* Note: caller will check cs_x->cs_softreq and DTRT. */
+ return handled;
}
@@ -272,16 +342,15 @@ zsc_intr_hard(arg)
* ZS software interrupt. Scan all channels for deferred interrupts.
*/
int
-zsc_intr_soft(arg)
- void *arg;
+zsc_intr_soft(void *arg)
{
- register struct zsc_softc *zsc = arg;
- register struct zs_chanstate *cs;
- register int rval, unit;
+ struct zsc_softc *zsc = arg;
+ struct zs_chanstate *cs;
+ int rval, chan;
rval = 0;
- for (unit = 0; unit < 2; unit++) {
- cs = &zsc->zsc_cs[unit];
+ for (chan = 0; chan < 2; chan++) {
+ cs = zsc->zsc_cs[chan];
/*
* The softint flag can be safely cleared once
@@ -291,30 +360,56 @@ zsc_intr_soft(arg)
if (cs->cs_softreq) {
cs->cs_softreq = 0;
(*cs->cs_ops->zsop_softint)(cs);
- rval = 1;
+ rval++;
}
}
return (rval);
}
+/*
+ * Provide a null zs "ops" vector.
+ */
+
+static void zsnull_rxint (struct zs_chanstate *);
+static void zsnull_stint (struct zs_chanstate *, int);
+static void zsnull_txint (struct zs_chanstate *);
+static void zsnull_softint(struct zs_chanstate *);
static void
-zsnull_intr(cs)
- struct zs_chanstate *cs;
+zsnull_rxint(struct zs_chanstate *cs)
{
- zs_write_reg(cs, 1, 0);
- zs_write_reg(cs, 15, 0);
+
+ /* Ask for softint() call. */
+ cs->cs_softreq = 1;
}
static void
-zsnull_softint(cs)
- struct zs_chanstate *cs;
+zsnull_stint(struct zs_chanstate *cs, int force)
+{
+
+ /* Ask for softint() call. */
+ cs->cs_softreq = 1;
+}
+
+static void
+zsnull_txint(struct zs_chanstate *cs)
+{
+
+ /* Ask for softint() call. */
+ cs->cs_softreq = 1;
+}
+
+static void
+zsnull_softint(struct zs_chanstate *cs)
{
+
+ zs_write_reg(cs, 1, 0);
+ zs_write_reg(cs, 15, 0);
}
struct zsops zsops_null = {
- zsnull_intr, /* receive char available */
- zsnull_intr, /* external/status */
- zsnull_intr, /* xmit buffer empty */
+ zsnull_rxint, /* receive char available */
+ zsnull_stint, /* external/status */
+ zsnull_txint, /* xmit buffer empty */
zsnull_softint, /* process software interrupt */
};
diff --git a/sys/dev/ic/z8530sc.h b/sys/dev/ic/z8530sc.h
index 178cdcba4a3..9ce5fa6dbee 100644
--- a/sys/dev/ic/z8530sc.h
+++ b/sys/dev/ic/z8530sc.h
@@ -1,5 +1,5 @@
-/* $OpenBSD: z8530sc.h,v 1.10 2003/06/02 23:28:02 millert Exp $ */
-/* $NetBSD: z8530sc.h,v 1.4 1996/10/16 20:34:54 gwr Exp $ */
+/* $OpenBSD: z8530sc.h,v 1.11 2013/04/21 14:44:16 sebastia Exp $ */
+/* $NetBSD: z8530sc.h,v 1.15 2001/05/11 01:40:48 thorpej Exp $ */
/*
* Copyright (c) 1994 Gordon W. Ross
@@ -44,13 +44,31 @@
/*
+ * Function vector - per channel
+ */
+struct zs_chanstate;
+struct zsops {
+ void (*zsop_rxint)(struct zs_chanstate *);
+ /* receive char available */
+ void (*zsop_stint)(struct zs_chanstate *, int);
+ /* external/status */
+ void (*zsop_txint)(struct zs_chanstate *);
+ /* xmit buffer empty */
+ void (*zsop_softint)(struct zs_chanstate *);
+ /* process software interrupt */
+};
+
+extern struct zsops zsops_null;
+
+
+/*
* Software state, per zs channel.
*/
struct zs_chanstate {
/* Pointers to the device registers. */
- volatile u_char *cs_reg_csr; /* ctrl, status, and reg. number. */
- volatile u_char *cs_reg_data; /* data or numbered register */
+ volatile uint8_t *cs_reg_csr; /* ctrl, status, and reg. number. */
+ volatile uint8_t *cs_reg_data; /* data or numbered register */
int cs_channel; /* sub-unit number */
void *cs_private; /* sub-driver data pointer */
@@ -58,7 +76,8 @@ struct zs_chanstate {
int cs_brg_clk; /* BAUD Rate Generator clock
* (usually PCLK / 16) */
- int cs_defspeed; /* default baud rate (from PROM) */
+ int cs_defspeed; /* default baud rate */
+ int cs_defcflag; /* default cflag */
/*
* We must keep a copy of the write registers as they are
@@ -73,44 +92,69 @@ struct zs_chanstate {
* rather than (or in addition to) the pending value; for these
* cs_creg[] contains the current value.
*/
- u_char cs_creg[16]; /* current values */
- u_char cs_preg[16]; /* pending values */
+ uint8_t cs_creg[17]; /* current values */
+ uint8_t cs_preg[17]; /* pending values */
+ int cs_heldchange; /* change pending (creg != preg) */
- u_char cs_heldchange; /* change pending (creg != preg) */
- u_char cs_rr0; /* last rr0 processed */
- u_char cs_rr0_delta; /* rr0 changes at status intr. */
+ uint8_t cs_rr0; /* last rr0 processed */
+ uint8_t cs_rr0_delta; /* rr0 changes at status intr. */
+ uint8_t cs_rr0_mask; /* rr0 bits that stop output */
+ uint8_t cs_rr0_dcd; /* which bit to read as DCD */
+ uint8_t cs_rr0_cts; /* which bit to read as CTS */
+ uint8_t cs_rr0_pps; /* which bit to use for PPS */
+ /* the above is set only while CRTSCTS is enabled. */
- char cs_softreq; /* need soft interrupt call */
-};
+ uint8_t cs_wr5_dtr; /* which bit to write as DTR */
+ uint8_t cs_wr5_rts; /* which bit to write as RTS */
+ /* the above is set only while CRTSCTS is enabled. */
-/*
- * Function vector - per channel
- */
-struct zsops {
- /* receive char available */
- void (*zsop_rxint)(register struct zs_chanstate *);
+ volatile uint8_t cs_softreq; /* need soft interrupt call */
+ char cs_cua; /* CUA mode flag */
- /* external/status */
- void (*zsop_stint)(register struct zs_chanstate *);
+ /*
+ * For strange systems that have oddly wired serial ports, we
+ * provide a pointer to the channel state of the port that has
+ * our status lines on it.
+ */
+ struct zs_chanstate *cs_ctl_chan;
- /* xmit buffer empty */
- void (*zsop_txint)(register struct zs_chanstate *);
+ /* power management hooks */
+ int (*enable)(struct zs_chanstate *);
+ void (*disable)(struct zs_chanstate *);
+ int enabled;
- /* process software interrupt */
- void (*zsop_softint)(struct zs_chanstate *);
+ /* MD code might define a larger variant of this. */
};
-extern struct zsops zsops_null;
-
+struct consdev;
struct zsc_attach_args {
- int channel; /* two serial channels per zsc */
- int hwflags;
+ char *type; /* type name 'serial', 'keyboard', 'mouse' */
+ int channel; /* two serial channels per zsc */
+ int hwflags; /* see definitions below */
+ /* `consdev' is only valid if ZS_HWFLAG_USE_CONSDEV is set */
+ struct consdev *consdev;
};
-#define ZS_HWFLAG_CONSOLE 1
-
-int zsc_intr_hard(void *);
-int zsc_intr_soft(void *);
-void zs_break(struct zs_chanstate *, int);
-int zs_getspeed(struct zs_chanstate *);
-void zs_iflush(struct zs_chanstate *);
-void zs_loadchannelregs(struct zs_chanstate *);
+/* In case of split console devices, use these: */
+#define ZS_HWFLAG_CONSOLE_INPUT 1
+#define ZS_HWFLAG_CONSOLE_OUTPUT 2
+#define ZS_HWFLAG_CONSOLE \
+ (ZS_HWFLAG_CONSOLE_INPUT | ZS_HWFLAG_CONSOLE_OUTPUT)
+#define ZS_HWFLAG_NO_DCD 4 /* Ignore the DCD bit */
+#define ZS_HWFLAG_NO_CTS 8 /* Ignore the CTS bit */
+#define ZS_HWFLAG_RAW 16 /* advise raw mode */
+#define ZS_HWFLAG_USE_CONSDEV 32 /* Use console ops from `consdev' */
+#define ZS_HWFLAG_NORESET 64 /* Don't reset at attach time */
+
+int zsc_intr_soft(void *);
+int zsc_intr_hard(void *);
+
+void zs_abort(struct zs_chanstate *);
+void zs_break(struct zs_chanstate *, int);
+void zs_iflush(struct zs_chanstate *);
+void zs_loadchannelregs(struct zs_chanstate *);
+int zs_set_speed(struct zs_chanstate *, int);
+int zs_set_modes(struct zs_chanstate *, int);
+
+extern int zs_major;
+
+int zs_check_kgdb(struct zs_chanstate *, int);
diff --git a/sys/dev/ic/z8530tty.c b/sys/dev/ic/z8530tty.c
index e22122b010d..c31c146b998 100644
--- a/sys/dev/ic/z8530tty.c
+++ b/sys/dev/ic/z8530tty.c
@@ -1,5 +1,35 @@
-/* $OpenBSD: z8530tty.c,v 1.23 2010/07/02 17:27:01 nicm Exp $ */
-/* $NetBSD: z8530tty.c,v 1.13 1996/10/16 20:42:14 gwr Exp $ */
+/* $OpenBSD: z8530tty.c,v 1.24 2013/04/21 14:44:16 sebastia Exp $ */
+/* $NetBSD: z8530tty.c,v 1.77 2001/05/30 15:24:24 lukem Exp $ */
+
+/*-
+ * Copyright (c) 1993, 1994, 1995, 1996, 1997, 1998, 1999
+ * Charles M. Hannum. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Charles M. Hannum.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
/*
* Copyright (c) 1994 Gordon W. Ross
@@ -57,9 +87,12 @@
* into independent child drivers.
*
* RTS/CTS flow-control support was a collaboration of:
- * Gordon Ross <gwr@netbsd.org>,
+ * Gordon Ross <gwr@NetBSD.org>,
* Bill Studenmund <wrstuden@loki.stanford.edu>
* Ian Dall <Ian.Dall@dsto.defence.gov.au>
+ *
+ * The driver was massively overhauled in November 1997 by Charles Hannum,
+ * fixing *many* bugs, and substantially improving performance.
*/
#include <sys/param.h>
@@ -78,9 +111,7 @@
#include <dev/ic/z8530reg.h>
#include <machine/z8530var.h>
-#ifdef KGDB
-extern int zs_check_kgdb();
-#endif
+#include <dev/cons.h>
/*
* Allow the MD var.h to override the default CFLAG so that
@@ -99,39 +130,41 @@ extern int zs_check_kgdb();
#define ZSTTY_RING_SIZE 2048
#endif
+struct cfdriver zstty_cd = {
+ NULL, "zstty", DV_TTY
+};
+
/*
* Make this an option variable one can patch.
* But be warned: this must be a power of 2!
*/
-int zstty_rbuf_size = ZSTTY_RING_SIZE;
+u_int zstty_rbuf_size = ZSTTY_RING_SIZE;
-/* This should usually be 3/4 of ZSTTY_RING_SIZE */
-int zstty_rbuf_hiwat = (ZSTTY_RING_SIZE - (ZSTTY_RING_SIZE >> 2));
+/* Stop input when 3/4 of the ring is full; restart when only 1/4 is full. */
+u_int zstty_rbuf_hiwat = (ZSTTY_RING_SIZE * 1) / 4;
+u_int zstty_rbuf_lowat = (ZSTTY_RING_SIZE * 3) / 4;
struct zstty_softc {
struct device zst_dev; /* required first: base device */
struct tty *zst_tty;
struct zs_chanstate *zst_cs;
- int zst_hwflags; /* see z8530var.h */
- int zst_swflags; /* TIOCFLAG_SOFTCAR, ... <ttycom.h> */
+ struct timeout zst_diag_ch;
- /*
- * Printing an overrun error message often takes long enough to
- * cause another overrun, so we only print one per second.
- */
- long zst_rotime; /* time of last ring overrun */
- long zst_fotime; /* time of last fifo overrun */
+ u_int zst_overflows,
+ zst_floods,
+ zst_errors;
- /*
- * The receive ring buffer.
- */
- int zst_rbget; /* ring buffer `get' index */
- volatile int zst_rbput; /* ring buffer `put' index */
- int zst_ringmask;
- int zst_rbhiwat;
+ int zst_hwflags, /* see z8530var.h */
+ zst_swflags; /* TIOCFLAG_SOFTCAR, ... <ttycom.h> */
- u_short *zst_rbuf; /* rr1, data pairs */
+ u_int zst_r_hiwat,
+ zst_r_lowat;
+ uint8_t *volatile zst_rbget,
+ *volatile zst_rbput;
+ volatile u_int zst_rbavail;
+ uint8_t *zst_rbuf,
+ *zst_ebuf;
/*
* The transmit byte count and address are used for pseudo-DMA
@@ -139,57 +172,76 @@ struct zstty_softc {
* to get pending changes done; heldtbc is used for this. It can
* also be stopped for ^S; this sets TS_TTSTOP in tp->t_state.
*/
- int zst_tbc; /* transmit byte count */
- caddr_t zst_tba; /* transmit buffer address */
- int zst_heldtbc; /* held tbc while xmission stopped */
+ uint8_t *zst_tba; /* transmit buffer address */
+ u_int zst_tbc, /* transmit byte count */
+ zst_heldtbc; /* held tbc while xmission stopped */
/* Flags to communicate with zstty_softint() */
- volatile char zst_rx_blocked; /* input block at ring */
- volatile char zst_rx_overrun; /* ring overrun */
- volatile char zst_tx_busy; /* working on an output chunk */
- volatile char zst_tx_done; /* done with one output chunk */
- volatile char zst_tx_stopped; /* H/W level stop (lost CTS) */
- volatile char zst_st_check; /* got a status interrupt */
- char pad[2];
+ volatile uint8_t zst_rx_flags, /* receiver blocked */
+#define RX_TTY_BLOCKED 0x01
+#define RX_TTY_OVERFLOWED 0x02
+#define RX_IBUF_BLOCKED 0x04
+#define RX_IBUF_OVERFLOWED 0x08
+#define RX_ANY_BLOCK 0x0f
+ zst_tx_busy, /* working on an output chunk */
+ zst_tx_done, /* done with one output chunk */
+ zst_tx_stopped, /* H/W level stop (lost CTS) */
+ zst_st_check, /* got a status interrupt */
+ zst_rx_ready;
+
+ /* PPS signal on DCD, with or without inkernel clock disciplining */
+ uint8_t zst_ppsmask; /* pps signal mask */
+ uint8_t zst_ppsassert; /* pps leading edge */
+ uint8_t zst_ppsclear; /* pps trailing edge */
};
-
/* Definition of the driver for autoconfig. */
-static int zstty_match(struct device *, void *, void *);
-static void zstty_attach(struct device *, struct device *, void *);
+int zstty_match(struct device *, void *, void *);
+void zstty_attach(struct device *, struct device *, void *);
-struct cfattach zstty_ca = {
+const struct cfattach zstty_ca = {
sizeof(struct zstty_softc), zstty_match, zstty_attach
};
-struct cfdriver zstty_cd = {
- NULL, "zstty", DV_TTY
-};
+cdev_decl(zs);
struct zsops zsops_tty;
-/* Routines called from other code. */
-cdev_decl(zs); /* open, close, read, write, ioctl, stop, ... */
-
-static void zsstart(struct tty *);
-static int zsparam(struct tty *, struct termios *);
-static void zs_modem(struct zstty_softc *zst, int onoff);
-static int zshwiflow(struct tty *, int);
-static void zs_hwiflow(struct zstty_softc *, int);
-static void zstty_rxint(register struct zs_chanstate *);
-static void zstty_txint(register struct zs_chanstate *);
-static void zstty_stint(register struct zs_chanstate *);
-static void zstty_softint(struct zs_chanstate *);
-static void zsoverrun(struct zstty_softc *, long *, char *);
+void zs_shutdown(struct zstty_softc *);
+void zsstart(struct tty *);
+int zsparam(struct tty *, struct termios *);
+void zs_modem(struct zstty_softc *, int);
+void tiocm_to_zs(struct zstty_softc *, u_long, int);
+int zs_to_tiocm(struct zstty_softc *);
+int zshwiflow(struct tty *, int);
+void zs_hwiflow(struct zstty_softc *);
+void zs_maskintr(struct zstty_softc *);
+
+struct zstty_softc *zs_device_lookup(struct cfdriver *, int);
+
+/* Low-level routines. */
+void zstty_rxint(struct zs_chanstate *);
+void zstty_stint(struct zs_chanstate *, int);
+void zstty_txint(struct zs_chanstate *);
+void zstty_softint(struct zs_chanstate *);
+void zstty_diag(void *);
+
+#define ZSUNIT(x) (minor(x) & 0x7f)
+#define ZSDIALOUT(x) (minor(x) & 0x80)
+
+struct zstty_softc *
+zs_device_lookup(struct cfdriver *cf, int unit)
+{
+ return (struct zstty_softc *)device_lookup(cf, unit);
+}
+
/*
* zstty_match: how is this zs channel configured?
*/
-int
-zstty_match(parent, match, aux)
- struct device *parent;
- void *match, *aux;
+int
+zstty_match(struct device *parent, void *vcf, void *aux)
{
- struct cfdata *cf = match;
+ struct cfdata *cf = vcf;
struct zsc_attach_args *args = aux;
/* Exact match is better than wildcard. */
@@ -203,55 +255,84 @@ zstty_match(parent, match, aux)
return 0;
}
-void
-zstty_attach(parent, self, aux)
- struct device *parent, *self;
- void *aux;
-
+void
+zstty_attach(struct device *parent, struct device *self, void *aux)
{
- struct zsc_softc *zsc = (void *) parent;
- struct zstty_softc *zst = (void *) self;
+ struct zsc_softc *zsc = (struct zsc_softc *)parent;
+ struct zstty_softc *zst = (struct zstty_softc *)self;
+ struct cfdata *cf = self->dv_cfdata;
struct zsc_attach_args *args = aux;
struct zs_chanstate *cs;
- struct cfdata *cf;
struct tty *tp;
- int channel, tty_unit;
+ int channel, s, tty_unit;
dev_t dev;
+ const char *i, *o;
+ int dtr_on;
+ int resetbit;
+
+ timeout_set(&zst->zst_diag_ch, zstty_diag, zst);
- cf = zst->zst_dev.dv_cfdata;
tty_unit = zst->zst_dev.dv_unit;
channel = args->channel;
- cs = &zsc->zsc_cs[channel];
+ cs = zsc->zsc_cs[channel];
cs->cs_private = zst;
cs->cs_ops = &zsops_tty;
zst->zst_cs = cs;
zst->zst_swflags = cf->cf_flags; /* softcar, etc. */
zst->zst_hwflags = args->hwflags;
- dev = makedev(ZSTTY_MAJOR, tty_unit);
+ dev = makedev(zs_major, tty_unit);
if (zst->zst_swflags)
printf(" flags 0x%x", zst->zst_swflags);
- if (zst->zst_hwflags & ZS_HWFLAG_CONSOLE)
- printf(": console");
- else {
+ /*
+ * Check whether we serve as a console device.
+ * XXX - split console input/output channels aren't
+ * supported yet on /dev/console
+ */
+ i = o = NULL;
+ if ((zst->zst_hwflags & ZS_HWFLAG_CONSOLE_INPUT) != 0) {
+ i = " input";
+ if ((args->hwflags & ZS_HWFLAG_USE_CONSDEV) != 0) {
+ args->consdev->cn_dev = dev;
+ cn_tab->cn_pollc = args->consdev->cn_pollc;
+ cn_tab->cn_getc = args->consdev->cn_getc;
+ }
+ cn_tab->cn_dev = dev;
+ }
+ if ((zst->zst_hwflags & ZS_HWFLAG_CONSOLE_OUTPUT) != 0) {
+ o = " output";
+ if ((args->hwflags & ZS_HWFLAG_USE_CONSDEV) != 0) {
+ cn_tab->cn_putc = args->consdev->cn_putc;
+ }
+ cn_tab->cn_dev = dev;
+ }
+ if (i != NULL || o != NULL) {
+ printf(": console%s", i ? (o ? "" : i) : o);
+ }
+
#ifdef KGDB
+ if (zs_check_kgdb(cs, dev)) {
/*
- * Allow kgdb to "take over" this port. If this port is
- * NOT the kgdb port, zs_check_kgdb() will return zero.
- * If it IS the kgdb port, it will print "kgdb,...\n"
- * and then return non-zero.
+ * Allow kgdb to "take over" this port. Returns true
+ * if this serial port is in-use by kgdb.
*/
- if (zs_check_kgdb(cs, dev)) {
- /*
- * This is the kgdb port (exclusive use)
- * so skip the normal attach code.
- */
- return;
- }
-#endif
+ printf(": kgdb\n");
+ /*
+ * This is the kgdb port (exclusive use)
+ * so skip the normal attach code.
+ */
+ return;
}
+#endif
+
+#if defined(__sparc__) || defined(__sparc64__)
+ if (strcmp(args->type, "keyboard") == 0 ||
+ strcmp(args->type, "mouse") == 0)
+ printf(": %s", args->type);
+#endif
+
printf("\n");
tp = ttymalloc(0);
@@ -261,40 +342,64 @@ zstty_attach(parent, self, aux)
tp->t_hwiflow = zshwiflow;
zst->zst_tty = tp;
- zst->zst_rbhiwat = zstty_rbuf_size; /* impossible value */
- zst->zst_ringmask = zstty_rbuf_size - 1;
- zst->zst_rbuf = malloc(zstty_rbuf_size * sizeof(zst->zst_rbuf[0]),
- M_DEVBUF, M_WAITOK);
+ zst->zst_rbuf = malloc(zstty_rbuf_size << 1, M_DEVBUF, M_WAITOK);
+ zst->zst_ebuf = zst->zst_rbuf + (zstty_rbuf_size << 1);
+ /* Disable the high water mark. */
+ zst->zst_r_hiwat = 0;
+ zst->zst_r_lowat = 0;
+ zst->zst_rbget = zst->zst_rbput = zst->zst_rbuf;
+ zst->zst_rbavail = zstty_rbuf_size;
+
+ /* if there are no enable/disable functions, assume the device
+ is always enabled */
+ if (!cs->enable)
+ cs->enabled = 1;
/*
* Hardware init
*/
- if (zst->zst_hwflags & ZS_HWFLAG_CONSOLE) {
- /* This unit is the console. */
- zst->zst_swflags |= TIOCFLAG_SOFTCAR;
- /* Call _param so interrupts get enabled. */
- cs->cs_defspeed = zs_getspeed(cs);
- tp->t_ispeed = cs->cs_defspeed;
- tp->t_ospeed = cs->cs_defspeed;
- tp->t_cflag = ZSTTY_DEF_CFLAG;
- (void) zsparam(tp, &tp->t_termios);
- } else {
- /* Not the console; may need reset. */
- int reset, s;
- reset = (channel == 0) ?
- ZSWR9_A_RESET : ZSWR9_B_RESET;
+ dtr_on = 0;
+ resetbit = 0;
+ if (ISSET(zst->zst_hwflags, ZS_HWFLAG_CONSOLE)) {
+ /* Call zsparam similar to open. */
+ struct termios t;
+
+ /* Wait a while for previous console output to complete */
+ DELAY(10000);
+
+ /* Setup the "new" parameters in t. */
+ t.c_ispeed = 0;
+ t.c_ospeed = cs->cs_defspeed;
+ t.c_cflag = cs->cs_defcflag;
+
s = splzs();
- zs_write_reg(cs, 9, reset);
+
+ /*
+ * Turn on receiver and status interrupts.
+ * We defer the actual write of the register to zsparam(),
+ * but we must make sure status interrupts are turned on by
+ * the time zsparam() reads the initial rr0 state.
+ */
+ SET(cs->cs_preg[1], ZSWR1_RIE | ZSWR1_TIE | ZSWR1_SIE);
+
splx(s);
+
+ /* Make sure zsparam will see changes. */
+ tp->t_ospeed = 0;
+ (void)zsparam(tp, &t);
+
+ /* Make sure DTR is on now. */
+ dtr_on = 1;
+ } else if (!ISSET(zst->zst_hwflags, ZS_HWFLAG_NORESET)) {
+ /* Not the console; may need reset. */
+ resetbit = (channel == 0) ? ZSWR9_A_RESET : ZSWR9_B_RESET;
}
- /*
- * Initialize state of modem control lines (DTR).
- * If softcar is set, turn on DTR now and leave it.
- * otherwise, turn off DTR now, and raise in open.
- * (Keeps modem from answering too early.)
- */
- zs_modem(zst, (zst->zst_swflags & TIOCFLAG_SOFTCAR) ? 1 : 0);
+ s = splzs();
+ if (resetbit)
+ zs_write_reg(cs, 9, resetbit);
+ zs_modem(zst, dtr_on);
+ splx(s);
}
@@ -302,42 +407,81 @@ zstty_attach(parent, self, aux)
* Return pointer to our tty.
*/
struct tty *
-zstty(dev)
- dev_t dev;
+zstty(dev_t dev)
{
- struct zstty_softc *zst;
- int unit = minor(dev);
+ struct zstty_softc *zst = zs_device_lookup(&zstty_cd, ZSUNIT(dev));
-#ifdef DIAGNOSTIC
- if (unit >= zstty_cd.cd_ndevs)
- panic("zstty");
-#endif
- zst = zstty_cd.cd_devs[unit];
return (zst->zst_tty);
}
+void
+zs_shutdown(struct zstty_softc *zst)
+{
+ struct zs_chanstate *cs = zst->zst_cs;
+ struct tty *tp = zst->zst_tty;
+ int s;
+
+ s = splzs();
+
+ /* If we were asserting flow control, then deassert it. */
+ SET(zst->zst_rx_flags, RX_IBUF_BLOCKED);
+ zs_hwiflow(zst);
+
+ /* Clear any break condition set with TIOCSBRK. */
+ zs_break(cs, 0);
+
+ /* Turn off PPS capture on last close. */
+ zst->zst_ppsmask = 0;
+
+ /*
+ * Hang up if necessary. Wait a bit, so the other side has time to
+ * notice even if we immediately open the port again.
+ */
+ if (ISSET(tp->t_cflag, HUPCL) || ISSET(tp->t_state, TS_WOPEN)) {
+ zs_modem(zst, 0);
+ /* hold low for 1 second */
+ (void)tsleep(cs, TTIPRI, ttclos, hz);
+ }
+
+ /* Turn off interrupts if not the console. */
+ if (!ISSET(zst->zst_hwflags, ZS_HWFLAG_CONSOLE)) {
+ CLR(cs->cs_preg[1], ZSWR1_RIE | ZSWR1_TIE | ZSWR1_SIE);
+ cs->cs_creg[1] = cs->cs_preg[1];
+ zs_write_reg(cs, 1, cs->cs_creg[1]);
+ }
+
+ /* Call the power management hook. */
+ if (cs->disable) {
+#ifdef DIAGNOSTIC
+ if (!cs->enabled)
+ panic("%s: not enabled?", __func__);
+#endif
+ (*cs->disable)(zst->zst_cs);
+ }
+
+ splx(s);
+}
+
/*
* Open a zs serial (tty) port.
*/
int
-zsopen(dev, flags, mode, p)
- dev_t dev;
- int flags;
- int mode;
- struct proc *p;
+zsopen(dev_t dev, int flags, int mode, struct proc *p)
{
- register struct tty *tp;
- register struct zs_chanstate *cs;
struct zstty_softc *zst;
- int error, s, unit;
+ struct zs_chanstate *cs;
+ struct tty *tp;
+ int s;
+#if IPL_ZS != IPL_TTY
+ int s2;
+#endif
+ int error;
- unit = minor(dev);
- if (unit >= zstty_cd.cd_ndevs)
- return (ENXIO);
- zst = zstty_cd.cd_devs[unit];
+ zst = zs_device_lookup(&zstty_cd, ZSUNIT(dev));
if (zst == NULL)
return (ENXIO);
+
tp = zst->zst_tty;
cs = zst->zst_cs;
@@ -345,78 +489,204 @@ zsopen(dev, flags, mode, p)
if (tp == NULL)
return (EBUSY);
- /* It's simpler to do this up here. */
- if (((tp->t_state & (TS_ISOPEN | TS_XCLUDE))
- == (TS_ISOPEN | TS_XCLUDE))
- && (suser(p, 0) != 0) )
- {
+ if (ISSET(tp->t_state, TS_ISOPEN) &&
+ ISSET(tp->t_state, TS_XCLUDE) &&
+ suser(p, 0) != 0)
return (EBUSY);
- }
s = spltty();
- if ((tp->t_state & TS_ISOPEN) == 0) {
- /* First open. */
+ /*
+ * Do the following iff this is a first open.
+ */
+ if (!ISSET(tp->t_state, TS_ISOPEN)) {
+ struct termios t;
+
+ tp->t_dev = dev;
+
+ /* Call the power management hook. */
+ if (cs->enable) {
+ if ((*cs->enable)(cs)) {
+ splx(s);
+ printf("%s: device enable failed\n",
+ zst->zst_dev.dv_xname);
+ return (EIO);
+ }
+ }
+
+ /*
+ * Initialize the termios status to the defaults. Add in the
+ * sticky bits from TIOCSFLAGS.
+ */
+ t.c_ispeed = 0;
+ t.c_ospeed = cs->cs_defspeed;
+ t.c_cflag = cs->cs_defcflag;
+ if (ISSET(zst->zst_swflags, TIOCFLAG_CLOCAL))
+ SET(t.c_cflag, CLOCAL);
+ if (ISSET(zst->zst_swflags, TIOCFLAG_CRTSCTS))
+ SET(t.c_cflag, CRTSCTS);
+ if (ISSET(zst->zst_swflags, TIOCFLAG_MDMBUF))
+ SET(t.c_cflag, MDMBUF);
+
+#if IPL_ZS != IPL_TTY
+ s2 = splzs();
+#endif
+
+ /*
+ * Turn on receiver and status interrupts.
+ * We defer the actual write of the register to zsparam(),
+ * but we must make sure status interrupts are turned on by
+ * the time zsparam() reads the initial rr0 state.
+ */
+ SET(cs->cs_preg[1], ZSWR1_RIE | ZSWR1_TIE | ZSWR1_SIE);
+
+ /* Clear PPS capture state on first open. */
+ zst->zst_ppsmask = 0;
+
+#if IPL_ZS != IPL_TTY
+ splx(s2);
+#endif
+
+ /* Make sure zsparam will see changes. */
+ tp->t_ospeed = 0;
+ (void)zsparam(tp, &t);
+
+ /*
+ * Note: zsparam has done: cflag, ispeed, ospeed
+ * so we just need to do: iflag, oflag, lflag, cc
+ * For "raw" mode, just leave all zeros.
+ */
+ if (!ISSET(zst->zst_hwflags, ZS_HWFLAG_RAW)) {
+ tp->t_iflag = TTYDEF_IFLAG;
+ tp->t_oflag = TTYDEF_OFLAG;
+ tp->t_lflag = TTYDEF_LFLAG;
+ } else {
+ tp->t_iflag = 0;
+ tp->t_oflag = 0;
+ tp->t_lflag = 0;
+ }
ttychars(tp);
- tp->t_iflag = TTYDEF_IFLAG;
- tp->t_oflag = TTYDEF_OFLAG;
- tp->t_cflag = ZSTTY_DEF_CFLAG;
- if (zst->zst_swflags & TIOCFLAG_CLOCAL)
- tp->t_cflag |= CLOCAL;
- if (zst->zst_swflags & TIOCFLAG_CRTSCTS)
- tp->t_cflag |= CRTSCTS;
- if (zst->zst_swflags & TIOCFLAG_MDMBUF)
- tp->t_cflag |= MDMBUF;
- tp->t_lflag = TTYDEF_LFLAG;
- tp->t_ispeed = tp->t_ospeed = cs->cs_defspeed;
- (void) zsparam(tp, &tp->t_termios);
ttsetwater(tp);
- /* Flush any pending input. */
- zst->zst_rbget = zst->zst_rbput;
- zs_iflush(cs); /* XXX */
- /* Turn on DTR */
- zs_modem(zst, 1);
- if (zst->zst_swflags & TIOCFLAG_SOFTCAR) {
- tp->t_state |= TS_CARR_ON;
+
+ if (ZSDIALOUT(dev))
+ SET(tp->t_state, TS_CARR_ON);
+ else
+ CLR(tp->t_state, TS_CARR_ON);
+
+#if IPL_ZS != IPL_TTY
+ s2 = splzs();
+#endif
+
+ /* Clear the input ring, and unblock. */
+ zst->zst_rbget = zst->zst_rbput = zst->zst_rbuf;
+ zst->zst_rbavail = zstty_rbuf_size;
+ zs_iflush(cs);
+ CLR(zst->zst_rx_flags, RX_ANY_BLOCK);
+ zs_hwiflow(zst);
+
+#if IPL_ZS != IPL_TTY
+ splx(s2);
+#endif
+ }
+
+ if (ZSDIALOUT(dev)) {
+ if (ISSET(tp->t_state, TS_ISOPEN)) {
+ /* someone already is dialed in... */
+ splx(s);
+ return EBUSY;
}
+ cs->cs_cua = 1;
}
+
error = 0;
+ /* wait for carrier if necessary */
+ if (ISSET(flags, O_NONBLOCK)) {
+ if (!ZSDIALOUT(dev) && cs->cs_cua) {
+ /* Opening TTY non-blocking... but the CUA is busy */
+ error = EBUSY;
+ }
+ } else
+ while (cs->cs_cua ||
+ (!ISSET(tp->t_cflag, CLOCAL) && !ISSET(tp->t_state, TS_CARR_ON))) {
+ int rr0;
- /* Wait for carrier. */
- for (;;) {
+ error = 0;
+ SET(tp->t_state, TS_WOPEN);
- /* Might never get status intr if carrier already on. */
- cs->cs_rr0 = zs_read_csr(cs);
- if (cs->cs_rr0 & ZSRR0_DCD) {
- tp->t_state |= TS_CARR_ON;
- break;
+ if (!ZSDIALOUT(dev) && !cs->cs_cua) {
+ /*
+ * Turn on DTR. We must always do this on non-CUA
+ * devices, even if carrier is not present, because
+ * otherwise we'd have to use TIOCSDTR immediately
+ * after setting CLOCAL, which applications do not
+ * expect. We always assert DTR while the device is
+ * open unless explicitly requested to deassert it.
+ */
+#if IPL_ZS != IPL_TTY
+ s2 = splzs();
+#endif
+ zs_modem(zst, 1);
+ rr0 = zs_read_csr(cs);
+#if IPL_ZS != IPL_TTY
+ splx(s2);
+#endif
+
+ /* loop, turning on the device, until carrier present */
+ if (ISSET(rr0, ZSRR0_DCD) ||
+ ISSET(zst->zst_swflags, TIOCFLAG_SOFTCAR))
+ SET(tp->t_state, TS_CARR_ON);
}
- if ((tp->t_state & TS_CARR_ON) ||
- (tp->t_cflag & CLOCAL) ||
- (flags & O_NONBLOCK) )
- {
+ if ((ISSET(tp->t_cflag, CLOCAL) ||
+ ISSET(tp->t_state, TS_CARR_ON)) && !cs->cs_cua)
break;
+
+ error = ttysleep(tp, (caddr_t)&tp->t_rawq, TTIPRI | PCATCH,
+ ttopen, 0);
+
+ if (!ZSDIALOUT(dev) && cs->cs_cua && error == EINTR) {
+ error = 0;
+ continue;
}
- tp->t_state |= TS_WOPEN;
- error = ttysleep(tp, (caddr_t)&tp->t_rawq,
- TTIPRI | PCATCH, ttopen, 0);
if (error) {
- if ((tp->t_state & TS_ISOPEN) == 0) {
- /* Never get here with softcar */
+ if (!ISSET(tp->t_state, TS_ISOPEN)) {
+#if IPL_ZS != IPL_TTY
+ s2 = splzs();
+#endif
zs_modem(zst, 0);
- tp->t_state &= ~TS_WOPEN;
+#if IPL_ZS != IPL_TTY
+ splx(s2);
+#endif
+ CLR(tp->t_state, TS_WOPEN);
ttwakeup(tp);
}
+ if (ZSDIALOUT(dev))
+ cs->cs_cua = 0;
+ CLR(tp->t_state, TS_WOPEN);
break;
}
+ if (!ZSDIALOUT(dev) && cs->cs_cua)
+ continue;
}
splx(s);
if (error == 0)
- error = linesw[tp->t_line].l_open(dev, tp, p);
+ error = ((*linesw[tp->t_line].l_open)(dev, tp, p));
+ if (error)
+ goto bad;
+
+ return (0);
+
+bad:
+ if (!ISSET(tp->t_state, TS_ISOPEN)) {
+ /*
+ * We failed to open the device, and nobody else had it opened.
+ * Clean up the state as appropriate.
+ */
+ zs_shutdown(zst);
+ }
return (error);
}
@@ -425,40 +695,33 @@ zsopen(dev, flags, mode, p)
* Close a zs serial port.
*/
int
-zsclose(dev, flags, mode, p)
- dev_t dev;
- int flags;
- int mode;
- struct proc *p;
+zsclose(dev_t dev, int flags, int mode, struct proc *p)
{
- struct zstty_softc *zst;
- register struct zs_chanstate *cs;
- register struct tty *tp;
- int hup;
-
- zst = zstty_cd.cd_devs[minor(dev)];
- cs = zst->zst_cs;
- tp = zst->zst_tty;
+ struct zstty_softc *zst = zs_device_lookup(&zstty_cd, ZSUNIT(dev));
+ struct zs_chanstate *cs = zst->zst_cs;
+ struct tty *tp = zst->zst_tty;
+ int s;
/* XXX This is for cons.c. */
- if ((tp->t_state & TS_ISOPEN) == 0)
+ if (!ISSET(tp->t_state, TS_ISOPEN))
return 0;
(*linesw[tp->t_line].l_close)(tp, flags, p);
- hup = tp->t_cflag & HUPCL;
- if (zst->zst_swflags & TIOCFLAG_SOFTCAR)
- hup = 0;
- if (hup) {
- zs_modem(zst, 0);
- /* hold low for 1 second */
- (void) tsleep((caddr_t)cs, TTIPRI, ttclos, hz);
- }
- if (cs->cs_creg[5] & ZSWR5_BREAK) {
- zs_break(cs, 0);
- }
- /* XXX - turn off interrupts? */
+ s = spltty();
+ cs->cs_cua = 0;
ttyclose(tp);
+ splx(s);
+
+ if (!ISSET(tp->t_state, TS_ISOPEN)) {
+ /*
+ * Although we got a last close, the device may still be in
+ * use; e.g. if this was the dialout node, and there are still
+ * processes waiting for carrier on the non-dialout node.
+ */
+ zs_shutdown(zst);
+ }
+
return (0);
}
@@ -466,62 +729,51 @@ zsclose(dev, flags, mode, p)
* Read/write zs serial port.
*/
int
-zsread(dev, uio, flags)
- dev_t dev;
- struct uio *uio;
- int flags;
+zsread(dev_t dev, struct uio *uio, int flags)
{
- register struct zstty_softc *zst;
- register struct tty *tp;
+ struct zstty_softc *zst = zs_device_lookup(&zstty_cd, ZSUNIT(dev));
+ struct tty *tp = zst->zst_tty;
- zst = zstty_cd.cd_devs[minor(dev)];
- tp = zst->zst_tty;
- return (linesw[tp->t_line].l_read(tp, uio, flags));
+ return (*linesw[tp->t_line].l_read)(tp, uio, flags);
}
int
-zswrite(dev, uio, flags)
- dev_t dev;
- struct uio *uio;
- int flags;
+zswrite(dev_t dev, struct uio *uio, int flags)
{
- register struct zstty_softc *zst;
- register struct tty *tp;
+ struct zstty_softc *zst = zs_device_lookup(&zstty_cd, ZSUNIT(dev));
+ struct tty *tp = zst->zst_tty;
- zst = zstty_cd.cd_devs[minor(dev)];
- tp = zst->zst_tty;
- return (linesw[tp->t_line].l_write(tp, uio, flags));
+ return (*linesw[tp->t_line].l_write)(tp, uio, flags);
}
-#define TIOCFLAG_ALL (TIOCFLAG_SOFTCAR | TIOCFLAG_CLOCAL | \
- TIOCFLAG_CRTSCTS | TIOCFLAG_MDMBUF )
-
int
-zsioctl(dev, cmd, data, flag, p)
- dev_t dev;
- u_long cmd;
- caddr_t data;
- int flag;
- struct proc *p;
+zsioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
{
- register struct zstty_softc *zst;
- register struct zs_chanstate *cs;
- register struct tty *tp;
- register int error, tmp;
-
- zst = zstty_cd.cd_devs[minor(dev)];
- cs = zst->zst_cs;
- tp = zst->zst_tty;
+ struct zstty_softc *zst = zs_device_lookup(&zstty_cd, ZSUNIT(dev));
+ struct zs_chanstate *cs = zst->zst_cs;
+ struct tty *tp = zst->zst_tty;
+ int error;
+ int s;
error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag, p);
if (error >= 0)
return (error);
+
error = ttioctl(tp, cmd, data, flag, p);
if (error >= 0)
return (error);
- switch (cmd) {
+#ifdef ZS_MD_IOCTL
+ error = ZS_MD_IOCTL;
+ if (error >= 0)
+ return (error);
+#endif /* ZS_MD_IOCTL */
+
+ error = 0;
+
+ s = splzs();
+ switch (cmd) {
case TIOCSBRK:
zs_break(cs, 1);
break;
@@ -536,17 +788,9 @@ zsioctl(dev, cmd, data, flag, p)
case TIOCSFLAGS:
error = suser(p, 0);
- if (error != 0)
- return (EPERM);
- tmp = *(int *)data;
- /* Check for random bits... */
- if (tmp & ~TIOCFLAG_ALL)
- return(EINVAL);
- /* Silently enforce softcar on the console. */
- if (zst->zst_hwflags & ZS_HWFLAG_CONSOLE)
- tmp |= TIOCFLAG_SOFTCAR;
- /* These flags take effect during open. */
- zst->zst_swflags = tmp;
+ if (error)
+ break;
+ zst->zst_swflags = *(int *)data;
break;
case TIOCSDTR:
@@ -560,72 +804,68 @@ zsioctl(dev, cmd, data, flag, p)
case TIOCMSET:
case TIOCMBIS:
case TIOCMBIC:
+ tiocm_to_zs(zst, cmd, *(int *)data);
+ break;
+
case TIOCMGET:
+ *(int *)data = zs_to_tiocm(zst);
+ break;
+
default:
- return (ENOTTY);
+ error = ENOTTY;
+ break;
}
- return (0);
+
+ splx(s);
+
+ return (error);
}
/*
* Start or restart transmission.
*/
-static void
-zsstart(tp)
- register struct tty *tp;
+void
+zsstart(struct tty *tp)
{
- register struct zstty_softc *zst;
- register struct zs_chanstate *cs;
- register int s, nch;
-
- zst = zstty_cd.cd_devs[minor(tp->t_dev)];
- cs = zst->zst_cs;
+ struct zstty_softc *zst = zs_device_lookup(&zstty_cd, ZSUNIT(tp->t_dev));
+ struct zs_chanstate *cs = zst->zst_cs;
+ u_char *tba;
+ int tbc, rr0;
+ int s;
s = spltty();
+ if (ISSET(tp->t_state, TS_BUSY | TS_TIMEOUT | TS_TTSTOP))
+ goto out;
+ if (zst->zst_tx_stopped)
+ goto out;
- /*
- * If currently active or delaying, no need to do anything.
- */
- if (tp->t_state & (TS_TIMEOUT | TS_BUSY | TS_TTSTOP))
+ ttwakeupwr(tp);
+ if (tp->t_outq.c_cc == 0)
goto out;
- /*
- * If under CRTSCTS hfc and halted, do nothing
- */
- if (tp->t_cflag & CRTSCTS)
- if (zst->zst_tx_stopped)
- goto out;
+ /* Grab the first contiguous region of buffer space. */
+ tba = tp->t_outq.c_cf;
+ tbc = ndqb(&tp->t_outq, 0);
- /*
- * If there are sleepers, and output has drained below low
- * water mark, awaken.
- */
- ttwakeupwr(tp);
+#if IPL_ZS != IPL_TTY
+ (void)splzs();
+#endif
- nch = ndqb(&tp->t_outq, 0); /* XXX */
- (void) splzs();
+ zst->zst_tba = tba;
+ zst->zst_tbc = tbc;
+ SET(tp->t_state, TS_BUSY);
+ zst->zst_tx_busy = 1;
- if (nch) {
- register char *p = tp->t_outq.c_cf;
+ do {
+ rr0 = zs_read_csr(cs);
+ if ((rr0 & ZSRR0_TX_READY) == 0)
+ break;
+
+ zs_write_data(cs, *zst->zst_tba);
+ zst->zst_tbc--;
+ zst->zst_tba++;
+ } while (zst->zst_tbc > 0);
- /* mark busy, enable tx done interrupts, & send first byte */
- tp->t_state |= TS_BUSY;
- zst->zst_tx_busy = 1;
- cs->cs_preg[1] |= ZSWR1_TIE;
- cs->cs_creg[1] = cs->cs_preg[1];
- zs_write_reg(cs, 1, cs->cs_creg[1]);
- zs_write_data(cs, *p);
- zst->zst_tba = p + 1;
- zst->zst_tbc = nch - 1;
- } else {
- /*
- * Nothing to send, turn off transmit done interrupts.
- * This is useful if something is doing polled output.
- */
- cs->cs_preg[1] &= ~ZSWR1_TIE;
- cs->cs_creg[1] = cs->cs_preg[1];
- zs_write_reg(cs, 1, cs->cs_creg[1]);
- }
out:
splx(s);
}
@@ -634,263 +874,388 @@ out:
* Stop output, e.g., for ^S or output flush.
*/
int
-zsstop(tp, flag)
- struct tty *tp;
- int flag;
+zsstop(struct tty *tp, int flag)
{
- register struct zstty_softc *zst;
- register struct zs_chanstate *cs;
- register int s;
-
- zst = zstty_cd.cd_devs[minor(tp->t_dev)];
- cs = zst->zst_cs;
+ struct zstty_softc *zst = zs_device_lookup(&zstty_cd, ZSUNIT(tp->t_dev));
+ int s;
s = splzs();
- if (tp->t_state & TS_BUSY) {
- /*
- * Device is transmitting; must stop it.
- * Also clear _heldtbc to prevent any
- * flow-control event from resuming.
- */
+ if (ISSET(tp->t_state, TS_BUSY)) {
+ /* Stop transmitting at the next chunk. */
zst->zst_tbc = 0;
zst->zst_heldtbc = 0;
- if ((tp->t_state & TS_TTSTOP) == 0)
- tp->t_state |= TS_FLUSH;
+ if (!ISSET(tp->t_state, TS_TTSTOP))
+ SET(tp->t_state, TS_FLUSH);
}
splx(s);
- return (0);
+ return 0;
}
/*
* Set ZS tty parameters from termios.
* XXX - Should just copy the whole termios after
* making sure all the changes could be done.
- * XXX - Only whack the UART when params change...
*/
-static int
-zsparam(tp, t)
- register struct tty *tp;
- register struct termios *t;
+int
+zsparam(struct tty *tp, struct termios *t)
{
- register struct zstty_softc *zst;
- register struct zs_chanstate *cs;
- register int s, bps, cflag, tconst;
- u_char tmp3, tmp4, tmp5;
-
- zst = zstty_cd.cd_devs[minor(tp->t_dev)];
- cs = zst->zst_cs;
+ struct zstty_softc *zst = zs_device_lookup(&zstty_cd, ZSUNIT(tp->t_dev));
+ struct zs_chanstate *cs = zst->zst_cs;
+ int ospeed;
+ tcflag_t cflag;
+ uint8_t tmp3, tmp4, tmp5;
+ int s, error;
+
+ ospeed = t->c_ospeed;
+ cflag = t->c_cflag;
- /* XXX: Need to use an MD function for this. */
- bps = t->c_ospeed;
- if (bps < 0 || (t->c_ispeed && t->c_ispeed != bps))
+ /* Check requested parameters. */
+ if (ospeed < 0)
return (EINVAL);
- if (bps == 0) {
- /* stty 0 => drop DTR and RTS */
- zs_modem(zst, 0);
- return (0);
- }
- tconst = BPS_TO_TCONST(cs->cs_brg_clk, bps);
- if (tconst < 0)
+ if (t->c_ispeed && t->c_ispeed != ospeed)
return (EINVAL);
- /* Convert back to make sure we can do it. */
- bps = TCONST_TO_BPS(cs->cs_brg_clk, tconst);
- if (bps != t->c_ospeed)
- return (EINVAL);
- tp->t_ispeed = tp->t_ospeed = bps;
+ /*
+ * For the console, always force CLOCAL and !HUPCL, so that the port
+ * is always active.
+ */
+ if (ISSET(zst->zst_swflags, TIOCFLAG_SOFTCAR) ||
+ ISSET(zst->zst_hwflags, ZS_HWFLAG_CONSOLE)) {
+ SET(cflag, CLOCAL);
+ CLR(cflag, HUPCL);
+ }
- cflag = t->c_cflag;
- tp->t_cflag = cflag;
+ /*
+ * Only whack the UART when params change.
+ * Some callers need to clear tp->t_ospeed
+ * to make sure initialization gets done.
+ */
+ if (tp->t_ospeed == ospeed &&
+ tp->t_cflag == cflag)
+ return (0);
/*
- * Block interrupts so that state will not
- * be altered until we are done setting it up.
+ * Call MD functions to deal with changed
+ * clock modes or H/W flow control modes.
+ * The BRG divisor is set now. (reg 12,13)
*/
- s = splzs();
+ error = zs_set_speed(cs, ospeed);
+ if (error)
+ return (error);
+ error = zs_set_modes(cs, cflag);
+ if (error)
+ return (error);
/*
+ * Block interrupts so that state will not
+ * be altered until we are done setting it up.
+ *
* Initial values in cs_preg are set before
* our attach routine is called. The master
* interrupt enable is handled by zsc.c
+ *
*/
+ s = splzs();
- cs->cs_preg[12] = tconst;
- cs->cs_preg[13] = tconst >> 8;
-
- switch (cflag & CSIZE) {
+ /*
+ * Recalculate which status ints to enable.
+ */
+ zs_maskintr(zst);
+
+ /* Recompute character size bits. */
+ tmp3 = cs->cs_preg[3];
+ tmp5 = cs->cs_preg[5];
+ CLR(tmp3, ZSWR3_RXSIZE);
+ CLR(tmp5, ZSWR5_TXSIZE);
+ switch (ISSET(cflag, CSIZE)) {
case CS5:
- tmp3 = ZSWR3_RX_5;
- tmp5 = ZSWR5_TX_5;
+ SET(tmp3, ZSWR3_RX_5);
+ SET(tmp5, ZSWR5_TX_5);
break;
case CS6:
- tmp3 = ZSWR3_RX_6;
- tmp5 = ZSWR5_TX_6;
+ SET(tmp3, ZSWR3_RX_6);
+ SET(tmp5, ZSWR5_TX_6);
break;
case CS7:
- tmp3 = ZSWR3_RX_7;
- tmp5 = ZSWR5_TX_7;
+ SET(tmp3, ZSWR3_RX_7);
+ SET(tmp5, ZSWR5_TX_7);
break;
case CS8:
- default:
- tmp3 = ZSWR3_RX_8;
- tmp5 = ZSWR5_TX_8;
+ SET(tmp3, ZSWR3_RX_8);
+ SET(tmp5, ZSWR5_TX_8);
break;
}
-
- cs->cs_preg[3] = tmp3 | ZSWR3_RX_ENABLE;
- cs->cs_preg[5] = tmp5 | ZSWR5_TX_ENABLE | ZSWR5_DTR | ZSWR5_RTS;
-
- tmp4 = ZSWR4_CLK_X16 | (cflag & CSTOPB ? ZSWR4_TWOSB : ZSWR4_ONESB);
- if ((cflag & PARODD) == 0)
- tmp4 |= ZSWR4_EVENP;
- if (cflag & PARENB)
- tmp4 |= ZSWR4_PARENB;
- cs->cs_preg[4] = tmp4;
+ cs->cs_preg[3] = tmp3;
+ cs->cs_preg[5] = tmp5;
/*
- * Output hardware flow control on the chip is horrendous:
- * if carrier detect drops, the receiver is disabled.
- * Therefore, NEVER set the HFC bit, and instead use
- * the status interrupts to detect CTS changes.
+ * Recompute the stop bits and parity bits. Note that
+ * zs_set_speed() may have set clock selection bits etc.
+ * in wr4, so those must preserved.
*/
- if (cflag & CRTSCTS) {
- zst->zst_rbhiwat = zstty_rbuf_hiwat;
- cs->cs_preg[15] |= ZSWR15_CTS_IE;
- } else {
- zst->zst_rbhiwat = zstty_rbuf_size; /* impossible value */
- cs->cs_preg[15] &= ~ZSWR15_CTS_IE;
- }
+ tmp4 = cs->cs_preg[4];
+ CLR(tmp4, ZSWR4_SBMASK | ZSWR4_PARMASK);
+ if (ISSET(cflag, CSTOPB))
+ SET(tmp4, ZSWR4_TWOSB);
+ else
+ SET(tmp4, ZSWR4_ONESB);
+ if (!ISSET(cflag, PARODD))
+ SET(tmp4, ZSWR4_EVENP);
+ if (ISSET(cflag, PARENB))
+ SET(tmp4, ZSWR4_PARENB);
+ cs->cs_preg[4] = tmp4;
+
+ /* And copy to tty. */
+ tp->t_ispeed = 0;
+ tp->t_ospeed = ospeed;
+ tp->t_cflag = cflag;
/*
* If nothing is being transmitted, set up new current values,
* else mark them as pending.
*/
- if (cs->cs_heldchange == 0) {
+ if (!cs->cs_heldchange) {
if (zst->zst_tx_busy) {
zst->zst_heldtbc = zst->zst_tbc;
zst->zst_tbc = 0;
- cs->cs_heldchange = 0xFF; /* XXX */
- } else {
+ cs->cs_heldchange = 1;
+ } else
zs_loadchannelregs(cs);
+ }
+
+ /*
+ * If hardware flow control is disabled, turn off the buffer water
+ * marks and unblock any soft flow control state. Otherwise, enable
+ * the water marks.
+ */
+ if (!ISSET(cflag, CHWFLOW)) {
+ zst->zst_r_hiwat = 0;
+ zst->zst_r_lowat = 0;
+ if (ISSET(zst->zst_rx_flags, RX_TTY_OVERFLOWED)) {
+ CLR(zst->zst_rx_flags, RX_TTY_OVERFLOWED);
+ zst->zst_rx_ready = 1;
+ cs->cs_softreq = 1;
}
+ if (ISSET(zst->zst_rx_flags, RX_TTY_BLOCKED|RX_IBUF_BLOCKED)) {
+ CLR(zst->zst_rx_flags, RX_TTY_BLOCKED|RX_IBUF_BLOCKED);
+ zs_hwiflow(zst);
+ }
+ } else {
+ zst->zst_r_hiwat = zstty_rbuf_hiwat;
+ zst->zst_r_lowat = zstty_rbuf_lowat;
}
+
+ /*
+ * Force a recheck of the hardware carrier and flow control status,
+ * since we may have changed which bits we're looking at.
+ */
+ zstty_stint(cs, 1);
+
splx(s);
+
+ /*
+ * If hardware flow control is disabled, unblock any hard flow control
+ * state.
+ */
+ if (!ISSET(cflag, CHWFLOW)) {
+ if (zst->zst_tx_stopped) {
+ zst->zst_tx_stopped = 0;
+ zsstart(tp);
+ }
+ }
+
+ zstty_softint(cs);
+
return (0);
}
/*
+ * Compute interrupt enable bits and set in the pending bits. Called both
+ * in zsparam() and when PPS (pulse per second timing) state changes.
+ * Must be called at splzs().
+ */
+void
+zs_maskintr(struct zstty_softc *zst)
+{
+ struct zs_chanstate *cs = zst->zst_cs;
+ uint8_t tmp15;
+
+ cs->cs_rr0_mask = cs->cs_rr0_cts | cs->cs_rr0_dcd;
+ if (zst->zst_ppsmask != 0)
+ cs->cs_rr0_mask |= cs->cs_rr0_pps;
+ tmp15 = cs->cs_preg[15];
+ if (ISSET(cs->cs_rr0_mask, ZSRR0_DCD))
+ SET(tmp15, ZSWR15_DCD_IE);
+ else
+ CLR(tmp15, ZSWR15_DCD_IE);
+ if (ISSET(cs->cs_rr0_mask, ZSRR0_CTS))
+ SET(tmp15, ZSWR15_CTS_IE);
+ else
+ CLR(tmp15, ZSWR15_CTS_IE);
+ cs->cs_preg[15] = tmp15;
+}
+
+
+/*
* Raise or lower modem control (DTR/RTS) signals. If a character is
* in transmission, the change is deferred.
+ * Called at splzs().
*/
-static void
-zs_modem(zst, onoff)
- struct zstty_softc *zst;
- int onoff;
+void
+zs_modem(struct zstty_softc *zst, int onoff)
{
- struct zs_chanstate *cs;
- struct tty *tp;
- int s, bis, and;
+ struct zs_chanstate *cs = zst->zst_cs, *ccs;
- cs = zst->zst_cs;
- tp = zst->zst_tty;
+ if (cs->cs_wr5_dtr == 0)
+ return;
- if (onoff) {
- bis = ZSWR5_DTR | ZSWR5_RTS;
- and = ~0;
- } else {
- bis = 0;
- and = ~(ZSWR5_DTR | ZSWR5_RTS);
+ ccs = (cs->cs_ctl_chan != NULL ? cs->cs_ctl_chan : cs);
+
+ if (onoff)
+ SET(ccs->cs_preg[5], cs->cs_wr5_dtr);
+ else
+ CLR(ccs->cs_preg[5], cs->cs_wr5_dtr);
+
+ if (!cs->cs_heldchange) {
+ if (zst->zst_tx_busy) {
+ zst->zst_heldtbc = zst->zst_tbc;
+ zst->zst_tbc = 0;
+ cs->cs_heldchange = 1;
+ } else
+ zs_loadchannelregs(cs);
}
- s = splzs();
- cs->cs_preg[5] = (cs->cs_preg[5] | bis) & and;
- if (cs->cs_heldchange == 0) {
+}
+
+/*
+ * Set modem bits.
+ * Called at splzs().
+ */
+void
+tiocm_to_zs(struct zstty_softc *zst, u_long how, int ttybits)
+{
+ struct zs_chanstate *cs = zst->zst_cs, *ccs;
+ uint8_t zsbits;
+
+ ccs = (cs->cs_ctl_chan != NULL ? cs->cs_ctl_chan : cs);
+
+ zsbits = 0;
+ if (ISSET(ttybits, TIOCM_DTR))
+ SET(zsbits, ZSWR5_DTR);
+ if (ISSET(ttybits, TIOCM_RTS))
+ SET(zsbits, ZSWR5_RTS);
+
+ switch (how) {
+ case TIOCMBIC:
+ CLR(ccs->cs_preg[5], zsbits);
+ break;
+
+ case TIOCMBIS:
+ SET(ccs->cs_preg[5], zsbits);
+ break;
+
+ case TIOCMSET:
+ CLR(ccs->cs_preg[5], ZSWR5_RTS | ZSWR5_DTR);
+ SET(ccs->cs_preg[5], zsbits);
+ break;
+ }
+
+ if (!cs->cs_heldchange) {
if (zst->zst_tx_busy) {
zst->zst_heldtbc = zst->zst_tbc;
zst->zst_tbc = 0;
- cs->cs_heldchange = (1<<5);
- } else {
- cs->cs_creg[5] = cs->cs_preg[5];
- zs_write_reg(cs, 5, cs->cs_creg[5]);
- }
+ cs->cs_heldchange = 1;
+ } else
+ zs_loadchannelregs(cs);
}
- splx(s);
+}
+
+/*
+ * Get modem bits.
+ * Called at splzs().
+ */
+int
+zs_to_tiocm(struct zstty_softc *zst)
+{
+ struct zs_chanstate *cs = zst->zst_cs, *ccs;
+ uint8_t zsbits;
+ int ttybits = 0;
+
+ ccs = (cs->cs_ctl_chan != NULL ? cs->cs_ctl_chan : cs);
+
+ zsbits = ccs->cs_preg[5];
+ if (ISSET(zsbits, ZSWR5_DTR))
+ SET(ttybits, TIOCM_DTR);
+ if (ISSET(zsbits, ZSWR5_RTS))
+ SET(ttybits, TIOCM_RTS);
+
+ zsbits = cs->cs_rr0;
+ if (ISSET(zsbits, ZSRR0_DCD))
+ SET(ttybits, TIOCM_CD);
+ if (ISSET(zsbits, ZSRR0_CTS))
+ SET(ttybits, TIOCM_CTS);
+
+ return (ttybits);
}
/*
* Try to block or unblock input using hardware flow-control.
* This is called by kern/tty.c if MDMBUF|CRTSCTS is set, and
* if this function returns non-zero, the TS_TBLOCK flag will
- * be set or cleared according to the "stop" arg passed.
+ * be set or cleared according to the "block" arg passed.
*/
int
-zshwiflow(tp, stop)
- struct tty *tp;
- int stop;
+zshwiflow(struct tty *tp, int block)
{
- register struct zstty_softc *zst;
+ struct zstty_softc *zst = zs_device_lookup(&zstty_cd, ZSUNIT(tp->t_dev));
+ struct zs_chanstate *cs = zst->zst_cs;
int s;
- zst = zstty_cd.cd_devs[minor(tp->t_dev)];
+ if (cs->cs_wr5_rts == 0)
+ return (0);
s = splzs();
- if (stop) {
- /*
- * The tty layer is asking us to block input.
- * If we already did it, just return TRUE.
- */
- if (zst->zst_rx_blocked)
- goto out;
- zst->zst_rx_blocked = 1;
+ if (block) {
+ if (!ISSET(zst->zst_rx_flags, RX_TTY_BLOCKED)) {
+ SET(zst->zst_rx_flags, RX_TTY_BLOCKED);
+ zs_hwiflow(zst);
+ }
} else {
- /*
- * The tty layer is asking us to resume input.
- * The input ring is always empty by now.
- */
- zst->zst_rx_blocked = 0;
+ if (ISSET(zst->zst_rx_flags, RX_TTY_OVERFLOWED)) {
+ CLR(zst->zst_rx_flags, RX_TTY_OVERFLOWED);
+ zst->zst_rx_ready = 1;
+ cs->cs_softreq = 1;
+ }
+ if (ISSET(zst->zst_rx_flags, RX_TTY_BLOCKED)) {
+ CLR(zst->zst_rx_flags, RX_TTY_BLOCKED);
+ zs_hwiflow(zst);
+ }
}
- zs_hwiflow(zst, stop);
- out:
splx(s);
- return 1;
+ return (1);
}
/*
* Internal version of zshwiflow
- * called at splzs
+ * Called at splzs()
*/
-static void
-zs_hwiflow(zst, stop)
- register struct zstty_softc *zst;
- int stop;
+void
+zs_hwiflow(struct zstty_softc *zst)
{
- register struct zs_chanstate *cs;
- register struct tty *tp;
- register int bis, and;
+ struct zs_chanstate *cs = zst->zst_cs, *ccs;
- cs = zst->zst_cs;
- tp = zst->zst_tty;
+ if (cs->cs_wr5_rts == 0)
+ return;
- if (stop) {
- /* Block input (Lower RTS) */
- bis = 0;
- and = ~ZSWR5_RTS;
- } else {
- /* Unblock input (Raise RTS) */
- bis = ZSWR5_RTS;
- and = ~0;
- }
+ ccs = (cs->cs_ctl_chan != NULL ? cs->cs_ctl_chan : cs);
- cs->cs_preg[5] = (cs->cs_preg[5] | bis) & and;
- if (cs->cs_heldchange == 0) {
- if (zst->zst_tx_busy) {
- zst->zst_heldtbc = zst->zst_tbc;
- zst->zst_tbc = 0;
- cs->cs_heldchange = (1<<5);
- } else {
- cs->cs_creg[5] = cs->cs_preg[5];
- zs_write_reg(cs, 5, cs->cs_creg[5]);
- }
+ if (ISSET(zst->zst_rx_flags, RX_ANY_BLOCK)) {
+ CLR(ccs->cs_preg[5], cs->cs_wr5_rts);
+ CLR(ccs->cs_creg[5], cs->cs_wr5_rts);
+ } else {
+ SET(ccs->cs_preg[5], cs->cs_wr5_rts);
+ SET(ccs->cs_creg[5], cs->cs_wr5_rts);
}
+ zs_write_reg(ccs, 5, ccs->cs_creg[5]);
}
@@ -898,140 +1263,146 @@ zs_hwiflow(zst, stop)
* Interface to the lower layer (zscc)
****************************************************************/
+void zstty_rxsoft(struct zstty_softc *, struct tty *);
+void zstty_txsoft(struct zstty_softc *, struct tty *);
+void zstty_stsoft(struct zstty_softc *, struct tty *);
+void zstty_diag(void *);
/*
- * receiver ready interrupt.
- * called at splzs
+ * Receiver Ready interrupt.
+ * Called at splzs().
*/
-static void
-zstty_rxint(cs)
- register struct zs_chanstate *cs;
+void
+zstty_rxint(struct zs_chanstate *cs)
{
- register struct zstty_softc *zst;
- register int cc, put, put_next, ringmask;
- register u_char c, rr0, rr1;
- register u_short ch_rr1;
+ struct zstty_softc *zst = cs->cs_private;
+ uint8_t *put, *end;
+ u_int cc;
+ uint8_t rr0, rr1, c;
- zst = cs->cs_private;
+ end = zst->zst_ebuf;
put = zst->zst_rbput;
- ringmask = zst->zst_ringmask;
-
-nextchar:
-
- /*
- * First read the status, because reading the received char
- * destroys the status of this char.
- */
- rr1 = zs_read_reg(cs, 1);
- c = zs_read_data(cs);
- ch_rr1 = (c << 8) | rr1;
+ cc = zst->zst_rbavail;
- if (ch_rr1 & (ZSRR1_FE | ZSRR1_DO | ZSRR1_PE)) {
- /* Clear the receive error. */
- zs_write_csr(cs, ZSWR0_RESET_ERRORS);
- }
+ while (cc > 0) {
+ /*
+ * First read the status, because reading the received char
+ * destroys the status of this char.
+ */
+ rr1 = zs_read_reg(cs, 1);
+ c = zs_read_data(cs);
- /* XXX: Check for the stop character? */
+ if (ISSET(rr1, ZSRR1_FE | ZSRR1_DO | ZSRR1_PE)) {
+ /* Clear the receive error. */
+ zs_write_csr(cs, ZSWR0_RESET_ERRORS);
+ }
- zst->zst_rbuf[put] = ch_rr1;
- put_next = (put + 1) & ringmask;
+ put[0] = c;
+ put[1] = rr1;
+ put += 2;
+ if (put >= end)
+ put = zst->zst_rbuf;
+ cc--;
- /* Would overrun if increment makes (put==get). */
- if (put_next == zst->zst_rbget) {
- zst->zst_rx_overrun = 1;
- } else {
- /* OK, really increment. */
- put = put_next;
+ rr0 = zs_read_csr(cs);
+ if (!ISSET(rr0, ZSRR0_RX_READY))
+ break;
}
- /* Keep reading until the FIFO is empty. */
- rr0 = zs_read_csr(cs);
- if (rr0 & ZSRR0_RX_READY)
- goto nextchar;
-
- /* Done reading. */
+ /*
+ * Current string of incoming characters ended because
+ * no more data was available or we ran out of space.
+ * Schedule a receive event if any data was received.
+ * If we're out of space, turn off receive interrupts.
+ */
zst->zst_rbput = put;
+ zst->zst_rbavail = cc;
+ if (!ISSET(zst->zst_rx_flags, RX_TTY_OVERFLOWED)) {
+ zst->zst_rx_ready = 1;
+ cs->cs_softreq = 1;
+ }
/*
- * If ring is getting too full, try to block input.
+ * See if we are in danger of overflowing a buffer. If
+ * so, use hardware flow control to ease the pressure.
*/
- cc = put - zst->zst_rbget;
- if (cc < 0)
- cc += zstty_rbuf_size;
- if ((cc > zst->zst_rbhiwat) && (zst->zst_rx_blocked == 0)) {
- zst->zst_rx_blocked = 1;
- zs_hwiflow(zst, 1);
+ if (!ISSET(zst->zst_rx_flags, RX_IBUF_BLOCKED) &&
+ cc < zst->zst_r_hiwat) {
+ SET(zst->zst_rx_flags, RX_IBUF_BLOCKED);
+ zs_hwiflow(zst);
}
- /* Ask for softint() call. */
- cs->cs_softreq = 1;
+ /*
+ * If we're out of space, disable receive interrupts
+ * until the queue has drained a bit.
+ */
+ if (!cc) {
+ SET(zst->zst_rx_flags, RX_IBUF_OVERFLOWED);
+ CLR(cs->cs_preg[1], ZSWR1_RIE);
+ cs->cs_creg[1] = cs->cs_preg[1];
+ zs_write_reg(cs, 1, cs->cs_creg[1]);
+ }
}
/*
- * transmitter ready interrupt. (splzs)
+ * Transmitter Ready interrupt.
+ * Called at splzs().
*/
-static void
-zstty_txint(cs)
- register struct zs_chanstate *cs;
+void
+zstty_txint(struct zs_chanstate *cs)
{
- register struct zstty_softc *zst;
- register int count;
+ struct zstty_softc *zst = cs->cs_private;
+ int rr0;
- zst = cs->cs_private;
+ zs_write_csr(cs, ZSWR0_RESET_TXINT);
/*
- * If we suspended output for a "held" change,
- * then handle that now and resume.
- * Do flow-control changes ASAP.
- * When the only change is for flow control,
- * avoid hitting other registers, because that
- * often makes the stupid zs drop input...
+ * If we've delayed a parameter change, do it now, and restart
+ * output.
*/
if (cs->cs_heldchange) {
- if (cs->cs_heldchange == (1<<5)) {
- /* Avoid whacking the chip... */
- cs->cs_creg[5] = cs->cs_preg[5];
- zs_write_reg(cs, 5, cs->cs_creg[5]);
- } else
- zs_loadchannelregs(cs);
+ zs_loadchannelregs(cs);
cs->cs_heldchange = 0;
- count = zst->zst_heldtbc;
- } else
- count = zst->zst_tbc;
+ zst->zst_tbc = zst->zst_heldtbc;
+ zst->zst_heldtbc = 0;
+ }
+
+ while (zst->zst_tbc > 0) {
+ rr0 = zs_read_csr(cs);
+ if ((rr0 & ZSRR0_TX_READY) == 0)
+ break;
- /*
- * If our transmit buffer still has data,
- * just send the next character.
- */
- if (count > 0) {
- /* Send the next char. */
- zst->zst_tbc = --count;
zs_write_data(cs, *zst->zst_tba);
+ zst->zst_tbc--;
zst->zst_tba++;
- return;
}
- zs_write_csr(cs, ZSWR0_RESET_TXINT);
-
- /* Ask the softint routine for more output. */
- zst->zst_tx_busy = 0;
- zst->zst_tx_done = 1;
- cs->cs_softreq = 1;
+ if (zst->zst_tbc == 0) {
+ if (zst->zst_tx_busy) {
+ zst->zst_tx_busy = 0;
+ zst->zst_tx_done = 1;
+ cs->cs_softreq = 1;
+ }
+ }
}
+#ifdef DDB
+#include <ddb/db_var.h>
+#define DB_CONSOLE db_console
+#else
+#define DB_CONSOLE 0
+#endif
+
/*
- * status change interrupt. (splzs)
+ * Status Change interrupt.
+ * Called at splzs().
*/
-static void
-zstty_stint(cs)
- register struct zs_chanstate *cs;
+void
+zstty_stint(struct zs_chanstate *cs, int force)
{
- register struct zstty_softc *zst;
- register struct tty *tp;
- register u_char rr0;
-
- zst = cs->cs_private;
- tp = zst->zst_tty;
+ struct zstty_softc *zst = cs->cs_private;
+ struct tty *tp = zst->zst_tty;
+ uint8_t rr0, delta;
rr0 = zs_read_csr(cs);
zs_write_csr(cs, ZSWR0_RESET_STATUS);
@@ -1040,59 +1411,199 @@ zstty_stint(cs)
* Check here for console break, so that we can abort
* even when interrupts are locking up the machine.
*/
- if ((rr0 & ZSRR0_BREAK) &&
- (zst->zst_hwflags & ZS_HWFLAG_CONSOLE))
- {
- zs_abort();
- return;
- }
+ if ((zst->zst_hwflags & ZS_HWFLAG_CONSOLE_INPUT) &&
+ ISSET(rr0, ZSRR0_BREAK) && DB_CONSOLE)
+ zs_abort(cs);
- /*
- * Need to handle CTS output flow control here.
- * Output remains stopped as long as either the
- * zst_tx_stopped or TS_TTSTOP flag is set.
- * Never restart here; the softint routine will
- * do that after things are ready to move.
- */
- if (((rr0 & ZSRR0_CTS) == 0) && (tp->t_cflag & CRTSCTS)) {
- zst->zst_tbc = 0;
- zst->zst_heldtbc = 0;
- zst->zst_tx_stopped = 1;
- }
-
- /*
- * We have to accumulate status line changes here.
- * Otherwise, if we get multiple status interrupts
- * before the softint runs, we could fail to notice
- * some status line changes in the softint routine.
- * Fix from Bill Studenmund, October 1996.
- */
- cs->cs_rr0_delta |= (cs->cs_rr0 ^ rr0);
+ if (!force)
+ delta = rr0 ^ cs->cs_rr0;
+ else
+ delta = cs->cs_rr0_mask;
ttytstamp(tp, cs->cs_rr0 & ZSRR0_CTS, rr0 & ZSRR0_CTS,
cs->cs_rr0 & ZSRR0_DCD, rr0 & ZSRR0_DCD);
cs->cs_rr0 = rr0;
- zst->zst_st_check = 1;
- /* Ask for softint() call. */
- cs->cs_softreq = 1;
+ if (ISSET(delta, cs->cs_rr0_mask)) {
+ SET(cs->cs_rr0_delta, delta);
+
+ /*
+ * Stop output immediately if we lose the output
+ * flow control signal or carrier detect.
+ */
+ if (ISSET(~rr0, cs->cs_rr0_mask)) {
+ zst->zst_tbc = 0;
+ zst->zst_heldtbc = 0;
+ }
+
+ zst->zst_st_check = 1;
+ cs->cs_softreq = 1;
+ }
}
-/*
- * Print out a ring or fifo overrun error message.
- */
-static void
-zsoverrun(zst, ptime, what)
- struct zstty_softc *zst;
- long *ptime;
- char *what;
+void
+zstty_diag(void *arg)
{
+ struct zstty_softc *zst = arg;
+ int overflows, floods;
+ int s;
- if (*ptime != time_second) {
- *ptime = time_second;
- log(LOG_WARNING, "%s: %s overrun\n",
- zst->zst_dev.dv_xname, what);
+ s = splzs();
+ overflows = zst->zst_overflows;
+ zst->zst_overflows = 0;
+ floods = zst->zst_floods;
+ zst->zst_floods = 0;
+ zst->zst_errors = 0;
+ splx(s);
+
+ log(LOG_WARNING, "%s: %d silo overflow%s, %d ibuf flood%s\n",
+ zst->zst_dev.dv_xname,
+ overflows, overflows == 1 ? "" : "s",
+ floods, floods == 1 ? "" : "s");
+}
+
+void
+zstty_rxsoft(struct zstty_softc *zst, struct tty *tp)
+{
+ struct zs_chanstate *cs = zst->zst_cs;
+ int (*rint)(int, struct tty *) = linesw[tp->t_line].l_rint;
+ uint8_t *get, *end;
+ u_int cc, scc;
+ uint8_t rr1;
+ int code;
+ int s;
+
+ end = zst->zst_ebuf;
+ get = zst->zst_rbget;
+ scc = cc = zstty_rbuf_size - zst->zst_rbavail;
+
+ if (cc == zstty_rbuf_size) {
+ zst->zst_floods++;
+ if (zst->zst_errors++ == 0)
+ timeout_add_sec(&zst->zst_diag_ch, 60);
+ }
+
+ /* If not yet open, drop the entire buffer content here */
+ if (!ISSET(tp->t_state, TS_ISOPEN)) {
+ get += cc << 1;
+ if (get >= end)
+ get -= zstty_rbuf_size << 1;
+ cc = 0;
+ }
+ while (cc) {
+ code = get[0];
+ rr1 = get[1];
+ if (ISSET(rr1, ZSRR1_DO | ZSRR1_FE | ZSRR1_PE)) {
+ if (ISSET(rr1, ZSRR1_DO)) {
+ zst->zst_overflows++;
+ if (zst->zst_errors++ == 0)
+ timeout_add_sec(&zst->zst_diag_ch, 60);
+ }
+ if (ISSET(rr1, ZSRR1_FE))
+ SET(code, TTY_FE);
+ if (ISSET(rr1, ZSRR1_PE))
+ SET(code, TTY_PE);
+ }
+ if ((*rint)(code, tp) == -1) {
+ /*
+ * The line discipline's buffer is out of space.
+ */
+ if (!ISSET(zst->zst_rx_flags, RX_TTY_BLOCKED)) {
+ /*
+ * We're either not using flow control, or the
+ * line discipline didn't tell us to block for
+ * some reason. Either way, we have no way to
+ * know when there's more space available, so
+ * just drop the rest of the data.
+ */
+ get += cc << 1;
+ if (get >= end)
+ get -= zstty_rbuf_size << 1;
+ cc = 0;
+ } else {
+ /*
+ * Don't schedule any more receive processing
+ * until the line discipline tells us there's
+ * space available (through comhwiflow()).
+ * Leave the rest of the data in the input
+ * buffer.
+ */
+ SET(zst->zst_rx_flags, RX_TTY_OVERFLOWED);
+ }
+ break;
+ }
+ get += 2;
+ if (get >= end)
+ get = zst->zst_rbuf;
+ cc--;
+ }
+
+ if (cc != scc) {
+ zst->zst_rbget = get;
+ s = splzs();
+ cc = zst->zst_rbavail += scc - cc;
+ /* Buffers should be ok again, release possible block. */
+ if (cc >= zst->zst_r_lowat) {
+ if (ISSET(zst->zst_rx_flags, RX_IBUF_OVERFLOWED)) {
+ CLR(zst->zst_rx_flags, RX_IBUF_OVERFLOWED);
+ SET(cs->cs_preg[1], ZSWR1_RIE);
+ cs->cs_creg[1] = cs->cs_preg[1];
+ zs_write_reg(cs, 1, cs->cs_creg[1]);
+ }
+ if (ISSET(zst->zst_rx_flags, RX_IBUF_BLOCKED)) {
+ CLR(zst->zst_rx_flags, RX_IBUF_BLOCKED);
+ zs_hwiflow(zst);
+ }
+ }
+ splx(s);
+ }
+}
+
+void
+zstty_txsoft(struct zstty_softc *zst, struct tty *tp)
+{
+ int s;
+
+ CLR(tp->t_state, TS_BUSY);
+ if (ISSET(tp->t_state, TS_FLUSH))
+ CLR(tp->t_state, TS_FLUSH);
+ else {
+ s = splzs();
+ ndflush(&tp->t_outq, (int)(zst->zst_tba - tp->t_outq.c_cf));
+ splx(s);
+ }
+ (*linesw[tp->t_line].l_start)(tp);
+}
+
+void
+zstty_stsoft(struct zstty_softc *zst, struct tty *tp)
+{
+ struct zs_chanstate *cs = zst->zst_cs;
+ uint8_t rr0, delta;
+ int s;
+
+ s = splzs();
+ rr0 = cs->cs_rr0;
+ delta = cs->cs_rr0_delta;
+ cs->cs_rr0_delta = 0;
+ splx(s);
+
+ if (ISSET(delta, cs->cs_rr0_dcd)) {
+ /*
+ * Inform the tty layer that carrier detect changed.
+ */
+ (void)(*linesw[tp->t_line].l_modem)(tp, ISSET(rr0, ZSRR0_DCD));
+ }
+
+ if (ISSET(delta, cs->cs_rr0_cts)) {
+ /* Block or unblock output according to flow control. */
+ if (ISSET(rr0, cs->cs_rr0_cts)) {
+ zst->zst_tx_stopped = 0;
+ (*linesw[tp->t_line].l_start)(tp);
+ } else {
+ zst->zst_tx_stopped = 1;
+ }
}
}
@@ -1108,115 +1619,28 @@ zsoverrun(zst, ptime, what)
* Note: an "input blockage" condition is assumed to exist if
* EITHER the TS_TBLOCK flag or zst_rx_blocked flag is set.
*/
-static void
-zstty_softint(cs)
- struct zs_chanstate *cs;
+void
+zstty_softint(struct zs_chanstate *cs)
{
- register struct zstty_softc *zst;
- register struct linesw *line;
- register struct tty *tp;
- register int get, c, s;
- int ringmask, overrun;
- register u_short ring_data;
- register u_char rr0, delta;
-
- zst = cs->cs_private;
- tp = zst->zst_tty;
- line = &linesw[tp->t_line];
- ringmask = zst->zst_ringmask;
- overrun = 0;
+ struct zstty_softc *zst = cs->cs_private;
+ struct tty *tp = zst->zst_tty;
+ int s;
- /*
- * Raise to tty priority while servicing the ring.
- */
s = spltty();
- if (zst->zst_rx_overrun) {
- zst->zst_rx_overrun = 0;
- zsoverrun(zst, &zst->zst_rotime, "ring");
+ if (zst->zst_rx_ready) {
+ zst->zst_rx_ready = 0;
+ zstty_rxsoft(zst, tp);
}
- /*
- * Copy data from the receive ring into the tty layer.
- */
- get = zst->zst_rbget;
- while (get != zst->zst_rbput) {
- ring_data = zst->zst_rbuf[get];
- get = (get + 1) & ringmask;
-
- if (ring_data & ZSRR1_DO)
- overrun++;
- /* low byte of ring_data is rr1 */
- c = (ring_data >> 8) & 0xff;
- if (ring_data & ZSRR1_FE)
- c |= TTY_FE;
- if (ring_data & ZSRR1_PE)
- c |= TTY_PE;
-
- line->l_rint(c, tp);
- }
- zst->zst_rbget = get;
-
- /*
- * If the overrun flag is set now, it was set while
- * copying char/status pairs from the ring, which
- * means this was a hardware (fifo) overrun.
- */
- if (overrun) {
- zsoverrun(zst, &zst->zst_fotime, "fifo");
- }
-
- /*
- * We have emptied the input ring. Maybe unblock input.
- * Note: an "input blockage" condition is assumed to exist
- * when EITHER zst_rx_blocked or the TS_TBLOCK flag is set,
- * so unblock here ONLY if TS_TBLOCK has not been set.
- */
- if (zst->zst_rx_blocked && ((tp->t_state & TS_TBLOCK) == 0)) {
- (void) splzs();
- zst->zst_rx_blocked = 0;
- zs_hwiflow(zst, 0); /* unblock input */
- (void) spltty();
- }
-
- /*
- * Do any deferred work for status interrupts.
- * The rr0 was saved in the h/w interrupt to
- * avoid another splzs in here.
- */
if (zst->zst_st_check) {
zst->zst_st_check = 0;
-
- rr0 = cs->cs_rr0;
- delta = cs->cs_rr0_delta;
- cs->cs_rr0_delta = 0;
- if (delta & ZSRR0_DCD) {
- c = ((rr0 & ZSRR0_DCD) != 0);
- if (line->l_modem(tp, c) == 0)
- zs_modem(zst, c);
- }
- if ((delta & ZSRR0_CTS) && (tp->t_cflag & CRTSCTS)) {
- /*
- * Only do restart here. Stop is handled
- * at the h/w interrupt level.
- */
- if (rr0 & ZSRR0_CTS) {
- zst->zst_tx_stopped = 0;
- tp->t_state &= ~TS_TTSTOP;
- (*line->l_start)(tp);
- }
- }
+ zstty_stsoft(zst, tp);
}
if (zst->zst_tx_done) {
zst->zst_tx_done = 0;
- tp->t_state &= ~TS_BUSY;
- if (tp->t_state & TS_FLUSH)
- tp->t_state &= ~TS_FLUSH;
- else
- ndflush(&tp->t_outq, zst->zst_tba -
- (caddr_t) tp->t_outq.c_cf);
- line->l_start(tp);
+ zstty_txsoft(zst, tp);
}
splx(s);
@@ -1228,4 +1652,3 @@ struct zsops zsops_tty = {
zstty_txint, /* xmit buffer empty */
zstty_softint, /* process software interrupt */
};
-
diff --git a/sys/dev/sun/z8530ms.c b/sys/dev/sun/z8530ms.c
index c3e23c9d92d..a47844d62a8 100644
--- a/sys/dev/sun/z8530ms.c
+++ b/sys/dev/sun/z8530ms.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: z8530ms.c,v 1.1 2009/05/20 18:22:33 miod Exp $ */
+/* $OpenBSD: z8530ms.c,v 1.2 2013/04/21 14:44:16 sebastia Exp $ */
/* $NetBSD: ms.c,v 1.12 1997/07/17 01:17:47 jtk Exp $ */
/*
@@ -85,11 +85,7 @@
#include <sys/proc.h>
#include <sys/syslog.h>
-#ifndef __sparc64__ /* until zs driver is unified... */
-#include <sparc/dev/z8530reg.h>
-#else
-#include <sparc64/dev/z8530reg.h>
-#endif
+#include <dev/ic/z8530reg.h>
#include <machine/z8530var.h>
#include <dev/wscons/wsmousevar.h>
@@ -206,11 +202,7 @@ zsms_attach(struct device *parent, struct device *self, void *aux)
int s;
channel = args->channel;
-#ifndef __sparc64__ /* until driver is unified... */
- cs = &zsc->zsc_cs[channel];
-#else
cs = zsc->zsc_cs[channel];
-#endif
cs->cs_private = sc;
cs->cs_ops = &zsops_ms;
sc->sc_cs = cs;