Home | History | Annotate | Line # | Download | only in apbus
zs_ap.c revision 1.26
      1  1.26   tsutsui /*	$NetBSD: zs_ap.c,v 1.26 2010/06/26 03:44:49 tsutsui Exp $	*/
      2   1.1    tsubai 
      3   1.1    tsubai /*-
      4   1.1    tsubai  * Copyright (c) 1996 The NetBSD Foundation, Inc.
      5   1.1    tsubai  * All rights reserved.
      6   1.1    tsubai  *
      7   1.1    tsubai  * This code is derived from software contributed to The NetBSD Foundation
      8   1.1    tsubai  * by Gordon W. Ross.
      9   1.1    tsubai  *
     10   1.1    tsubai  * Redistribution and use in source and binary forms, with or without
     11   1.1    tsubai  * modification, are permitted provided that the following conditions
     12   1.1    tsubai  * are met:
     13   1.1    tsubai  * 1. Redistributions of source code must retain the above copyright
     14   1.1    tsubai  *    notice, this list of conditions and the following disclaimer.
     15   1.1    tsubai  * 2. Redistributions in binary form must reproduce the above copyright
     16   1.1    tsubai  *    notice, this list of conditions and the following disclaimer in the
     17   1.1    tsubai  *    documentation and/or other materials provided with the distribution.
     18   1.1    tsubai  *
     19   1.1    tsubai  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
     20   1.1    tsubai  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     21   1.1    tsubai  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     22   1.1    tsubai  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
     23   1.1    tsubai  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     24   1.1    tsubai  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     25   1.1    tsubai  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     26   1.1    tsubai  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     27   1.1    tsubai  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     28   1.1    tsubai  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     29   1.1    tsubai  * POSSIBILITY OF SUCH DAMAGE.
     30   1.1    tsubai  */
     31   1.1    tsubai 
     32   1.1    tsubai /*
     33   1.1    tsubai  * Zilog Z8530 Dual UART driver (machine-dependent part)
     34   1.1    tsubai  *
     35   1.1    tsubai  * Runs two serial lines per chip using slave drivers.
     36   1.1    tsubai  * Plain tty/async lines use the zs_async slave.
     37   1.1    tsubai  * Sun keyboard/mouse uses the zs_kbd/zs_ms slaves.
     38   1.1    tsubai  */
     39  1.16     lukem 
     40  1.16     lukem #include <sys/cdefs.h>
     41  1.26   tsutsui __KERNEL_RCSID(0, "$NetBSD: zs_ap.c,v 1.26 2010/06/26 03:44:49 tsutsui Exp $");
     42   1.1    tsubai 
     43   1.1    tsubai #include <sys/param.h>
     44   1.1    tsubai #include <sys/systm.h>
     45   1.1    tsubai #include <sys/device.h>
     46   1.1    tsubai #include <sys/tty.h>
     47   1.6   gehenna #include <sys/conf.h>
     48  1.23        ad #include <sys/cpu.h>
     49  1.23        ad #include <sys/intr.h>
     50   1.1    tsubai 
     51   1.1    tsubai #include <machine/adrsmap.h>
     52   1.1    tsubai #include <machine/z8530var.h>
     53   1.1    tsubai 
     54   1.1    tsubai #include <dev/cons.h>
     55   1.1    tsubai #include <dev/ic/z8530reg.h>
     56   1.1    tsubai 
     57   1.1    tsubai #include <newsmips/apbus/apbusvar.h>
     58   1.1    tsubai 
     59   1.1    tsubai #include "zsc.h"	/* NZSC */
     60   1.1    tsubai #define NZS NZSC
     61   1.1    tsubai 
     62   1.1    tsubai /* Make life easier for the initialized arrays here. */
     63   1.1    tsubai #if NZS < 2
     64   1.1    tsubai #undef  NZS
     65   1.1    tsubai #define NZS 2
     66   1.1    tsubai #endif
     67   1.1    tsubai 
     68   1.2    tsubai #define PORTB_XPORT	0x00000000
     69   1.2    tsubai #define PORTB_RPORT	0x00010000
     70   1.2    tsubai #define PORTA_XPORT	0x00020000
     71   1.2    tsubai #define PORTA_RPORT	0x00030000
     72   1.2    tsubai #define   DMA_MODE_REG		3
     73   1.2    tsubai #define     DMA_ENABLE		0x01	/* DMA enable */
     74   1.2    tsubai #define     DMA_DIR_DM		0x00	/* device to memory */
     75   1.2    tsubai #define     DMA_DIR_MD		0x02	/* memory to device */
     76   1.2    tsubai #define     DMA_EXTRDY		0x08	/* DMA external ready */
     77   1.2    tsubai #define PORTB_OFFSET	0x00040000
     78   1.2    tsubai #define PORTA_OFFSET	0x00050000
     79   1.2    tsubai #define   PORT_CTL		2
     80   1.2    tsubai #define     PORTCTL_RI		0x01
     81  1.12   tsutsui #define     PORTCTL_DSR		0x02
     82   1.2    tsubai #define     PORTCTL_DTR		0x04
     83   1.2    tsubai #define   PORT_SEL		3
     84   1.2    tsubai #define     PORTSEL_LOCALTALK	0x01
     85   1.2    tsubai #define     PORTSEL_RS232C	0x02
     86   1.2    tsubai #define ESCC_REG	0x00060000
     87   1.2    tsubai #define   ESCCREG_INTSTAT	0
     88   1.2    tsubai #define     INTSTAT_SCC		0x01
     89   1.2    tsubai #define   ESCCREG_INTMASK	1
     90   1.2    tsubai #define     INTMASK_SCC		0x01
     91   1.1    tsubai 
     92   1.1    tsubai extern int zs_def_cflag;
     93  1.17   tsutsui extern void (*zs_delay)(void);
     94   1.1    tsubai 
     95   1.1    tsubai /*
     96   1.1    tsubai  * The news5000 provides a 9.8304 MHz clock to the ZS chips.
     97   1.1    tsubai  */
     98   1.1    tsubai #define PCLK	(9600 * 1024)	/* PCLK pin input clock rate */
     99   1.1    tsubai 
    100   1.1    tsubai #define ZS_DELAY()	DELAY(2)
    101   1.1    tsubai 
    102   1.1    tsubai /* The layout of this is hardware-dependent (padding, order). */
    103   1.1    tsubai struct zschan {
    104  1.24   tsutsui 	volatile uint8_t pad1[3];
    105  1.24   tsutsui 	volatile uint8_t zc_csr;	/* ctrl,status, and indirect access */
    106  1.24   tsutsui 	volatile uint8_t pad2[3];
    107  1.24   tsutsui 	volatile uint8_t zc_data;	/* data */
    108   1.1    tsubai };
    109   1.1    tsubai 
    110  1.20  christos static void *zsaddr[NZS];
    111   1.1    tsubai 
    112   1.1    tsubai /* Flags from cninit() */
    113   1.1    tsubai static int zs_hwflags[NZS][2];
    114   1.1    tsubai 
    115   1.1    tsubai /* Default speed for all channels */
    116   1.1    tsubai static int zs_defspeed = 9600;
    117   1.1    tsubai 
    118  1.24   tsutsui static uint8_t zs_init_reg[16] = {
    119   1.1    tsubai 	0,	/* 0: CMD (reset, etc.) */
    120   1.1    tsubai 	0,	/* 1: No interrupts yet. */
    121   1.1    tsubai 	0,	/* IVECT */
    122   1.1    tsubai 	ZSWR3_RX_8 | ZSWR3_RX_ENABLE,
    123   1.1    tsubai 	ZSWR4_CLK_X16 | ZSWR4_ONESB | ZSWR4_EVENP,
    124   1.1    tsubai 	ZSWR5_TX_8 | ZSWR5_TX_ENABLE,
    125   1.1    tsubai 	0,	/* 6: TXSYNC/SYNCLO */
    126   1.1    tsubai 	0,	/* 7: RXSYNC/SYNCHI */
    127   1.1    tsubai 	0,	/* 8: alias for data port */
    128   1.1    tsubai 	ZSWR9_MASTER_IE,
    129   1.1    tsubai 	0,	/*10: Misc. TX/RX control bits */
    130   1.1    tsubai 	ZSWR11_TXCLK_BAUD | ZSWR11_RXCLK_BAUD,
    131   1.1    tsubai 	((PCLK/32)/9600)-2,	/*12: BAUDLO (default=9600) */
    132   1.1    tsubai 	0,			/*13: BAUDHI (default=9600) */
    133   1.1    tsubai 	ZSWR14_BAUD_ENA | ZSWR14_BAUD_FROM_PCLK,
    134   1.1    tsubai 	ZSWR15_BREAK_IE,
    135   1.1    tsubai };
    136   1.1    tsubai 
    137  1.17   tsutsui static struct zschan * zs_get_chan_addr(int, int);
    138  1.17   tsutsui static void zs_ap_delay(void);
    139  1.17   tsutsui static int zshard_ap(void *);
    140  1.17   tsutsui static int zs_getc(void *);
    141  1.17   tsutsui static void zs_putc(void *, int);
    142   1.1    tsubai 
    143   1.1    tsubai struct zschan *
    144  1.17   tsutsui zs_get_chan_addr(int zs_unit, int channel)
    145   1.1    tsubai {
    146  1.20  christos 	void *addr;
    147   1.1    tsubai 	struct zschan *zc;
    148   1.1    tsubai 
    149   1.1    tsubai 	if (zs_unit >= NZS)
    150   1.1    tsubai 		return NULL;
    151   1.1    tsubai 	addr = zsaddr[zs_unit];
    152   1.1    tsubai 	if (addr == NULL)
    153   1.1    tsubai 		return NULL;
    154   1.1    tsubai 	if (channel == 0) {
    155  1.24   tsutsui 		zc = (void *)((uint8_t *)addr + PORTA_OFFSET);
    156   1.1    tsubai 	} else {
    157  1.24   tsutsui 		zc = (void *)((uint8_t *)addr + PORTB_OFFSET);
    158   1.1    tsubai 	}
    159  1.17   tsutsui 	return zc;
    160   1.1    tsubai }
    161   1.1    tsubai 
    162   1.1    tsubai void
    163  1.17   tsutsui zs_ap_delay(void)
    164   1.1    tsubai {
    165  1.13   tsutsui 
    166   1.1    tsubai 	ZS_DELAY();
    167   1.1    tsubai }
    168   1.1    tsubai 
    169   1.1    tsubai /****************************************************************
    170   1.1    tsubai  * Autoconfig
    171   1.1    tsubai  ****************************************************************/
    172   1.1    tsubai 
    173   1.1    tsubai /* Definition of the driver for autoconfig. */
    174  1.24   tsutsui int zs_ap_match(device_t, cfdata_t, void *);
    175  1.24   tsutsui void zs_ap_attach(device_t, device_t, void *);
    176   1.1    tsubai 
    177  1.24   tsutsui CFATTACH_DECL_NEW(zsc_ap, sizeof(struct zsc_softc),
    178   1.8   thorpej     zs_ap_match, zs_ap_attach, NULL, NULL);
    179   1.1    tsubai 
    180   1.1    tsubai /*
    181   1.1    tsubai  * Is the zs chip present?
    182   1.1    tsubai  */
    183   1.1    tsubai int
    184  1.24   tsutsui zs_ap_match(device_t parent, cfdata_t cf, void *aux)
    185   1.1    tsubai {
    186   1.1    tsubai 	struct apbus_attach_args *apa = aux;
    187   1.1    tsubai 
    188   1.1    tsubai 	if (strcmp("esccf", apa->apa_name) != 0)
    189   1.1    tsubai 		return 0;
    190   1.1    tsubai 
    191   1.1    tsubai 	return 1;
    192   1.1    tsubai }
    193   1.1    tsubai 
    194   1.1    tsubai /*
    195   1.1    tsubai  * Attach a found zs.
    196   1.1    tsubai  *
    197   1.1    tsubai  * Match slave number to zs unit number, so that misconfiguration will
    198   1.1    tsubai  * not set up the keyboard as ttya, etc.
    199   1.1    tsubai  */
    200   1.1    tsubai void
    201  1.24   tsutsui zs_ap_attach(device_t parent, device_t self, void *aux)
    202   1.1    tsubai {
    203  1.24   tsutsui 	struct zsc_softc *zsc = device_private(self);
    204   1.1    tsubai 	struct apbus_attach_args *apa = aux;
    205   1.1    tsubai 	struct zsc_attach_args zsc_args;
    206   1.1    tsubai 	volatile struct zschan *zc;
    207   1.1    tsubai 	struct zs_chanstate *cs;
    208   1.1    tsubai 	int s, zs_unit, channel;
    209   1.2    tsubai 	volatile u_int *txBfifo = (void *)(apa->apa_hwbase + PORTB_XPORT);
    210   1.2    tsubai 	volatile u_int *rxBfifo = (void *)(apa->apa_hwbase + PORTB_RPORT);
    211   1.2    tsubai 	volatile u_int *txAfifo = (void *)(apa->apa_hwbase + PORTA_XPORT);
    212   1.2    tsubai 	volatile u_int *rxAfifo = (void *)(apa->apa_hwbase + PORTA_RPORT);
    213   1.2    tsubai 	volatile u_int *portBctl = (void *)(apa->apa_hwbase + PORTB_OFFSET);
    214   1.2    tsubai 	volatile u_int *portActl = (void *)(apa->apa_hwbase + PORTA_OFFSET);
    215   1.2    tsubai 	volatile u_int *esccregs = (void *)(apa->apa_hwbase + ESCC_REG);
    216   1.1    tsubai 
    217  1.24   tsutsui 	zsc->zsc_dev = self;
    218  1.24   tsutsui 	zs_unit = device_unit(self);
    219  1.20  christos 	zsaddr[zs_unit] = (void *)apa->apa_hwbase;
    220   1.1    tsubai 
    221  1.24   tsutsui 	aprint_normal(" slot%d addr 0x%lx\n", apa->apa_slotno, apa->apa_hwbase);
    222   1.1    tsubai 
    223   1.2    tsubai 	txAfifo[DMA_MODE_REG] = rxAfifo[DMA_MODE_REG] = DMA_EXTRDY;
    224   1.2    tsubai 	txBfifo[DMA_MODE_REG] = rxBfifo[DMA_MODE_REG] = DMA_EXTRDY;
    225   1.1    tsubai 
    226   1.1    tsubai 	/* assert DTR */			/* XXX */
    227   1.2    tsubai 	portBctl[PORT_CTL] = portActl[PORT_CTL] = PORTCTL_DTR;
    228   1.1    tsubai 
    229   1.1    tsubai 	/* select RS-232C (ch1 only) */
    230   1.2    tsubai 	portActl[PORT_SEL] = PORTSEL_RS232C;
    231   1.1    tsubai 
    232   1.1    tsubai 	/* enable SCC interrupts */
    233   1.2    tsubai 	esccregs[ESCCREG_INTMASK] = INTMASK_SCC;
    234   1.1    tsubai 
    235   1.1    tsubai 	zs_delay = zs_ap_delay;
    236   1.1    tsubai 
    237   1.1    tsubai 	/*
    238   1.1    tsubai 	 * Initialize software state for each channel.
    239   1.1    tsubai 	 */
    240   1.1    tsubai 	for (channel = 0; channel < 2; channel++) {
    241   1.1    tsubai 		zsc_args.channel = channel;
    242   1.1    tsubai 		zsc_args.hwflags = zs_hwflags[zs_unit][channel];
    243   1.1    tsubai 		cs = &zsc->zsc_cs_store[channel];
    244   1.1    tsubai 		zsc->zsc_cs[channel] = cs;
    245   1.1    tsubai 
    246  1.22        ad 		zs_lock_init(cs);
    247   1.1    tsubai 		cs->cs_channel = channel;
    248   1.1    tsubai 		cs->cs_private = NULL;
    249   1.1    tsubai 		cs->cs_ops = &zsops_null;
    250   1.1    tsubai 		cs->cs_brg_clk = PCLK / 16;
    251   1.1    tsubai 
    252   1.1    tsubai 		zc = zs_get_chan_addr(zs_unit, channel);
    253   1.1    tsubai 		cs->cs_reg_csr  = &zc->zc_csr;
    254   1.1    tsubai 		cs->cs_reg_data = &zc->zc_data;
    255   1.1    tsubai 
    256  1.17   tsutsui 		memcpy(cs->cs_creg, zs_init_reg, 16);
    257  1.17   tsutsui 		memcpy(cs->cs_preg, zs_init_reg, 16);
    258   1.1    tsubai 
    259   1.1    tsubai 		/* XXX: Get these from the EEPROM instead? */
    260   1.1    tsubai 		/* XXX: See the mvme167 code.  Better. */
    261   1.1    tsubai 		if (zsc_args.hwflags & ZS_HWFLAG_CONSOLE)
    262   1.1    tsubai 			cs->cs_defspeed = zs_get_speed(cs);
    263   1.1    tsubai 		else
    264   1.1    tsubai 			cs->cs_defspeed = zs_defspeed;
    265   1.1    tsubai 		cs->cs_defcflag = zs_def_cflag;
    266   1.1    tsubai 
    267   1.1    tsubai 		/* Make these correspond to cs_defcflag (-crtscts) */
    268   1.1    tsubai 		cs->cs_rr0_dcd = ZSRR0_DCD;
    269   1.1    tsubai 		cs->cs_rr0_cts = 0;
    270   1.1    tsubai 		cs->cs_wr5_dtr = ZSWR5_DTR | ZSWR5_RTS;
    271   1.1    tsubai 		cs->cs_wr5_rts = 0;
    272   1.1    tsubai 
    273   1.1    tsubai 		/*
    274   1.1    tsubai 		 * Clear the master interrupt enable.
    275   1.1    tsubai 		 * The INTENA is common to both channels,
    276   1.1    tsubai 		 * so just do it on the A channel.
    277   1.1    tsubai 		 */
    278   1.1    tsubai 		if (channel == 0) {
    279   1.1    tsubai 			zs_write_reg(cs, 9, 0);
    280   1.1    tsubai 		}
    281   1.1    tsubai 
    282   1.1    tsubai 		/*
    283   1.1    tsubai 		 * Look for a child driver for this channel.
    284   1.1    tsubai 		 * The child attach will setup the hardware.
    285   1.1    tsubai 		 */
    286   1.1    tsubai 		if (!config_found(self, (void *)&zsc_args, zs_print)) {
    287   1.1    tsubai 			/* No sub-driver.  Just reset it. */
    288  1.24   tsutsui 			uint8_t reset = (channel == 0) ?
    289  1.24   tsutsui 			    ZSWR9_A_RESET : ZSWR9_B_RESET;
    290   1.1    tsubai 			s = splhigh();
    291   1.1    tsubai 			zs_write_reg(cs, 9, reset);
    292   1.1    tsubai 			splx(s);
    293   1.1    tsubai 		}
    294   1.1    tsubai 	}
    295   1.1    tsubai 
    296   1.1    tsubai 	/*
    297  1.26   tsutsui 	 * Now safe to install interrupt handlers.
    298   1.1    tsubai 	 */
    299  1.26   tsutsui 	zsc->zsc_si = softint_establish(SOFTINT_SERIAL, zssoft, zsc);
    300  1.26   tsutsui 	apbus_intr_establish(1, /* interrupt level ( 0 or 1 ) */
    301  1.26   tsutsui 	    NEWS5000_INT1_SCC, 0, /* priority */
    302  1.26   tsutsui 	    zshard_ap, zsc, apa->apa_name, apa->apa_ctlnum);
    303   1.1    tsubai 	/* XXX; evcnt_attach() ? */
    304   1.1    tsubai 
    305   1.1    tsubai #if 0
    306   1.1    tsubai {
    307   1.1    tsubai 	u_int x;
    308   1.1    tsubai 
    309   1.1    tsubai 	/* determine SCC/ESCC type */
    310   1.1    tsubai 	x = zs_read_reg(cs, 15);
    311   1.1    tsubai 	zs_write_reg(cs, 15, x | ZSWR15_ENABLE_ENHANCED);
    312   1.1    tsubai 
    313   1.1    tsubai 	if (zs_read_reg(cs, 15) & ZSWR15_ENABLE_ENHANCED) { /* ESCC Z85230 */
    314   1.1    tsubai 		zs_write_reg(cs, 7, ZSWR7P_EXTEND_READ | ZSWR7P_TX_FIFO);
    315   1.1    tsubai 	}
    316   1.1    tsubai }
    317   1.1    tsubai #endif
    318   1.1    tsubai 
    319   1.1    tsubai 	/*
    320   1.1    tsubai 	 * Set the master interrupt enable and interrupt vector.
    321   1.1    tsubai 	 * (common to both channels, do it on A)
    322   1.1    tsubai 	 */
    323   1.1    tsubai 	cs = zsc->zsc_cs[0];
    324   1.1    tsubai 	s = splhigh();
    325   1.1    tsubai 	/* interrupt vector */
    326   1.1    tsubai 	zs_write_reg(cs, 2, zs_init_reg[2]);
    327   1.1    tsubai 	/* master interrupt control (enable) */
    328   1.1    tsubai 	zs_write_reg(cs, 9, zs_init_reg[9]);
    329   1.1    tsubai 	splx(s);
    330   1.1    tsubai }
    331   1.1    tsubai 
    332   1.5      onoe static int
    333  1.17   tsutsui zshard_ap(void *arg)
    334   1.1    tsubai {
    335  1.13   tsutsui 
    336   1.3    tsubai 	zshard(arg);
    337   1.5      onoe 	return 1;
    338   1.1    tsubai }
    339   1.1    tsubai 
    340   1.1    tsubai /*
    341   1.1    tsubai  * Polled input char.
    342   1.1    tsubai  */
    343   1.1    tsubai int
    344  1.17   tsutsui zs_getc(void *arg)
    345   1.1    tsubai {
    346  1.13   tsutsui 	volatile struct zschan *zc = arg;
    347  1.24   tsutsui 	int s, c;
    348  1.24   tsutsui 	uint8_t rr0;
    349   1.1    tsubai 
    350   1.1    tsubai 	s = splhigh();
    351   1.1    tsubai 	/* Wait for a character to arrive. */
    352   1.1    tsubai 	do {
    353   1.1    tsubai 		rr0 = zc->zc_csr;
    354   1.1    tsubai 		ZS_DELAY();
    355   1.1    tsubai 	} while ((rr0 & ZSRR0_RX_READY) == 0);
    356   1.1    tsubai 
    357   1.1    tsubai 	c = zc->zc_data;
    358   1.1    tsubai 	ZS_DELAY();
    359   1.1    tsubai 	splx(s);
    360   1.1    tsubai 
    361   1.1    tsubai 	/*
    362   1.1    tsubai 	 * This is used by the kd driver to read scan codes,
    363   1.1    tsubai 	 * so don't translate '\r' ==> '\n' here...
    364   1.1    tsubai 	 */
    365  1.17   tsutsui 	return c;
    366   1.1    tsubai }
    367   1.1    tsubai 
    368   1.1    tsubai /*
    369   1.1    tsubai  * Polled output char.
    370   1.1    tsubai  */
    371   1.1    tsubai void
    372  1.17   tsutsui zs_putc(void *arg, int c)
    373   1.1    tsubai {
    374  1.13   tsutsui 	volatile struct zschan *zc = arg;
    375  1.24   tsutsui 	int s;
    376  1.24   tsutsui 	uint8_t rr0;
    377   1.1    tsubai 
    378   1.1    tsubai 	s = splhigh();
    379   1.1    tsubai 	/* Wait for transmitter to become ready. */
    380   1.1    tsubai 	do {
    381   1.1    tsubai 		rr0 = zc->zc_csr;
    382   1.1    tsubai 		ZS_DELAY();
    383   1.1    tsubai 	} while ((rr0 & ZSRR0_TX_READY) == 0);
    384   1.1    tsubai 
    385   1.1    tsubai 	zc->zc_data = c;
    386   1.1    tsubai 	ZS_DELAY();
    387   1.1    tsubai 	splx(s);
    388   1.1    tsubai }
    389   1.1    tsubai 
    390   1.1    tsubai /*****************************************************************/
    391   1.1    tsubai 
    392  1.17   tsutsui static void zscnprobe(struct consdev *);
    393  1.17   tsutsui static void zscninit(struct consdev *);
    394  1.17   tsutsui static int  zscngetc(dev_t);
    395  1.17   tsutsui static void zscnputc(dev_t, int);
    396   1.1    tsubai 
    397   1.1    tsubai struct consdev consdev_zs_ap = {
    398   1.1    tsubai 	zscnprobe,
    399   1.1    tsubai 	zscninit,
    400   1.1    tsubai 	zscngetc,
    401   1.1    tsubai 	zscnputc,
    402  1.13   tsutsui 	nullcnpollc,
    403  1.13   tsutsui 	NULL,
    404  1.13   tsutsui 	NULL,
    405   1.4   thorpej 	NULL,
    406  1.13   tsutsui 	NODEV,
    407  1.13   tsutsui 	CN_DEAD
    408   1.1    tsubai };
    409   1.1    tsubai 
    410  1.13   tsutsui static void
    411  1.17   tsutsui zscnprobe(struct consdev *cn)
    412   1.1    tsubai {
    413   1.1    tsubai }
    414   1.1    tsubai 
    415  1.13   tsutsui static void
    416  1.17   tsutsui zscninit(struct consdev *cn)
    417   1.1    tsubai {
    418   1.6   gehenna 	extern const struct cdevsw zstty_cdevsw;
    419   1.6   gehenna 
    420   1.6   gehenna 	cn->cn_dev = makedev(cdevsw_lookup_major(&zstty_cdevsw), 0);
    421   1.1    tsubai 	cn->cn_pri = CN_REMOTE;
    422   1.1    tsubai 	zs_hwflags[0][0] = ZS_HWFLAG_CONSOLE;
    423   1.1    tsubai }
    424   1.1    tsubai 
    425  1.13   tsutsui static int
    426  1.17   tsutsui zscngetc(dev_t dev)
    427   1.1    tsubai {
    428  1.13   tsutsui 
    429   1.1    tsubai 	return zs_getc((void *)NEWS5000_SCCPORT0A);
    430   1.1    tsubai }
    431   1.1    tsubai 
    432  1.13   tsutsui static void
    433  1.17   tsutsui zscnputc(dev_t dev, int c)
    434   1.1    tsubai {
    435  1.13   tsutsui 
    436   1.1    tsubai 	zs_putc((void *)NEWS5000_SCCPORT0A, c);
    437   1.1    tsubai }
    438