Home | History | Annotate | Line # | Download | only in vsa
dz_vsbus.c revision 1.15
      1 /*	$NetBSD: dz_vsbus.c,v 1.15 2001/01/28 19:26:34 ragge Exp $ */
      2 /*
      3  * Copyright (c) 1998 Ludd, University of Lule}, Sweden.
      4  * All rights reserved.
      5  *
      6  * Redistribution and use in source and binary forms, with or without
      7  * modification, are permitted provided that the following conditions
      8  * are met:
      9  * 1. Redistributions of source code must retain the above copyright
     10  *    notice, this list of conditions and the following disclaimer.
     11  * 2. Redistributions in binary form must reproduce the above copyright
     12  *    notice, this list of conditions and the following disclaimer in the
     13  *    documentation and/or other materials provided with the distribution.
     14  * 3. All advertising materials mentioning features or use of this software
     15  *    must display the following acknowledgement:
     16  *      This product includes software developed at Ludd, University of
     17  *      Lule}, Sweden and its contributors.
     18  * 4. The name of the author may not be used to endorse or promote products
     19  *    derived from this software without specific prior written permission
     20  *
     21  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
     22  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     23  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     24  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
     25  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     26  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     27  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     28  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     29  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     30  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     31  */
     32 
     33 
     34 
     35 #include <sys/param.h>
     36 #include <sys/proc.h>
     37 #include <sys/systm.h>
     38 #include <sys/ioctl.h>
     39 #include <sys/tty.h>
     40 #include <sys/file.h>
     41 #include <sys/conf.h>
     42 #include <sys/device.h>
     43 #include <sys/reboot.h>
     44 
     45 #include <dev/cons.h>
     46 
     47 #include <machine/mtpr.h>
     48 #include <machine/sid.h>
     49 #include <machine/uvax.h>
     50 #include <machine/vsbus.h>
     51 #include <machine/cpu.h>
     52 #include <machine/scb.h>
     53 
     54 #include <arch/vax/vax/gencons.h>
     55 
     56 #include <dev/qbus/dzreg.h>
     57 #include <dev/qbus/dzvar.h>
     58 
     59 #include "ioconf.h"
     60 #include "dzkbd.h"
     61 #include "dzms.h"
     62 
     63 #if NDZKBD > 0 || NDZMS > 0
     64 #include <dev/dec/dzkbdvar.h>
     65 
     66 #if 0
     67 static	struct dz_linestate dz_conslinestate = { NULL, -1, NULL, NULL, NULL };
     68 #endif
     69 #endif
     70 
     71 static  int     dz_vsbus_match(struct device *, struct cfdata *, void *);
     72 static  void    dz_vsbus_attach(struct device *, struct device *, void *);
     73 
     74 static	vaddr_t dz_regs; /* Used for console */
     75 
     76 struct  cfattach dz_vsbus_ca = {
     77 	sizeof(struct dz_softc), dz_vsbus_match, dz_vsbus_attach
     78 };
     79 
     80 #define REG(name)     short name; short X##name##X;
     81 static volatile struct ss_dz {/* base address of DZ-controller: 0x200A0000 */
     82 	REG(csr);	/* 00 Csr: control/status register */
     83 	REG(rbuf);	/* 04 Rbuf/Lpr: receive buffer/line param reg. */
     84 	REG(tcr);	/* 08 Tcr: transmit console register */
     85 	REG(tdr);	/* 0C Msr/Tdr: modem status reg/transmit data reg */
     86 	REG(lpr0);	/* 10 Lpr0: */
     87 	REG(lpr1);	/* 14 Lpr0: */
     88 	REG(lpr2);	/* 18 Lpr0: */
     89 	REG(lpr3);	/* 1C Lpr0: */
     90 } *dz;
     91 #undef REG
     92 
     93 cons_decl(dz);
     94 cdev_decl(dz);
     95 
     96 #if NDZKBD > 0 || NDZMS > 0
     97 static int
     98 dz_print(void *aux, const char *name)
     99 {
    100 #if 0
    101 #if NDZKBD > 0 || NDZMS > 0
    102 	struct dz_attach_args *dz_args = aux;
    103 	if (name == NULL) {
    104 		printf (" line %d", dz_args->line);
    105 		if (dz_args->hwflags & DZ_HWFLAG_CONSOLE)
    106 			printf (" (console)");
    107 	}
    108 	return (QUIET);
    109 #else
    110 	if (name)
    111 		printf ("lkc at %s", name);
    112 	return (UNCONF);
    113 #endif
    114 #endif
    115 	return (UNCONF);
    116 }
    117 #endif
    118 
    119 static int
    120 dz_vsbus_match(struct device *parent, struct cfdata *cf, void *aux)
    121 {
    122 	struct vsbus_attach_args *va = aux;
    123 	struct ss_dz *dzP;
    124 	short i;
    125 
    126 	dzP = (struct ss_dz *)va->va_addr;
    127 	i = dzP->tcr;
    128 	dzP->csr = DZ_CSR_MSE|DZ_CSR_TXIE;
    129 	dzP->tcr = 0;
    130 	DELAY(1000);
    131 	dzP->tcr = 1;
    132 	DELAY(100000);
    133 	dzP->tcr = i;
    134 
    135 	/* If the device doesn't exist, no interrupt has been generated */
    136 	return 1;
    137 }
    138 
    139 static void
    140 dz_vsbus_attach(struct device *parent, struct device *self, void *aux)
    141 {
    142 	struct dz_softc *sc = (void *)self;
    143 	struct vsbus_attach_args *va = aux;
    144 #if NDZKBD > 0 || NDZMS > 0
    145 	struct dzkm_attach_args daa;
    146 #endif
    147 
    148 	/*
    149 	 * XXX - This is evil and ugly, but...
    150 	 * due to the nature of how bus_space_* works on VAX, this will
    151 	 * be perfectly good until everything is converted.
    152 	 */
    153 	sc->sc_ioh = dz_regs;
    154 	sc->sc_dr.dr_csr = 0;
    155 	sc->sc_dr.dr_rbuf = 4;
    156 	sc->sc_dr.dr_dtr = 9;
    157 	sc->sc_dr.dr_break = 13;
    158 	sc->sc_dr.dr_tbuf = 12;
    159 	sc->sc_dr.dr_tcr = 8;
    160 	sc->sc_dr.dr_dcd = 13;
    161 	sc->sc_dr.dr_ring = 13;
    162 
    163 	sc->sc_type = DZ_DZV;
    164 
    165 	sc->sc_dsr = 0x0f; /* XXX check if VS has modem ctrl bits */
    166 
    167 	scb_vecalloc(va->va_cvec, dzxint, sc, SCB_ISTACK, &sc->sc_tintrcnt);
    168 	scb_vecalloc(va->va_cvec - 4, dzrint, sc, SCB_ISTACK, &sc->sc_rintrcnt);
    169 
    170 	printf("\n%s: 4 lines", self->dv_xname);
    171 
    172 	dzattach(sc, NULL);
    173 
    174 #if NDZKBD > 0
    175 	/* Don't change speed if this is the console */
    176 	if (cn_tab->cn_dev != makedev(getmajor(dzopen), 0))
    177 		dz->rbuf = DZ_LPR_RX_ENABLE | (DZ_LPR_B4800 << 8)
    178 		    | DZ_LPR_8_BIT_CHAR;
    179 	daa.daa_line = 0;
    180 	daa.daa_flags = (cn_tab->cn_pri == CN_INTERNAL ? DZKBD_CONSOLE : 0);
    181 	config_found(self, &daa, dz_print);
    182 #endif
    183 #if NDZMS > 0
    184 	dz->rbuf = DZ_LPR_RX_ENABLE | (DZ_LPR_B4800 << 8) | DZ_LPR_7_BIT_CHAR \
    185 	    | DZ_LPR_PARENB | DZ_LPR_OPAR | 1 /* line */;
    186 	daa.daa_line = 1;
    187 	daa.daa_flags = 0;
    188 	config_found(self, &daa, dz_print);
    189 #endif
    190 	dzrint(sc);
    191 	dzxint(sc);
    192 }
    193 
    194 int
    195 dzcngetc(dev_t dev)
    196 {
    197 	int c = 0;
    198 	int mino = minor(dev);
    199 	u_short rbuf;
    200 
    201 	do {
    202 		while ((dz->csr & 0x80) == 0)
    203 			; /* Wait for char */
    204 		rbuf = dz->rbuf;
    205 		if (((rbuf >> 8) & 3) != mino)
    206 			continue;
    207 		c = rbuf & 0x7f;
    208 	} while (c == 17 || c == 19);		/* ignore XON/XOFF */
    209 
    210 	if (c == 13)
    211 		c = 10;
    212 
    213 	return (c);
    214 }
    215 
    216 void
    217 dzcnprobe(struct consdev *cndev)
    218 {
    219 	extern	vaddr_t iospace;
    220 	int diagcons;
    221 	paddr_t ioaddr = 0x200A0000;
    222 
    223 	switch (vax_boardtype) {
    224 	case VAX_BTYP_410:
    225 	case VAX_BTYP_420:
    226 	case VAX_BTYP_43:
    227 		diagcons = (vax_confdata & 0x20 ? 3 : 0);
    228 		break;
    229 
    230 	case VAX_BTYP_46:
    231 	case VAX_BTYP_48:
    232 		diagcons = (vax_confdata & 0x100 ? 3 : 0);
    233 		break;
    234 
    235 	case VAX_BTYP_49:
    236 		ioaddr = 0x25000000;
    237 		diagcons = 3;
    238 		break;
    239 
    240 	default:
    241 		cndev->cn_pri = CN_DEAD;
    242 		return;
    243 	}
    244 	if (diagcons)
    245 		cndev->cn_pri = CN_REMOTE;
    246 	else
    247 		cndev->cn_pri = CN_NORMAL;
    248 	cndev->cn_dev = makedev(getmajor(dzopen), diagcons);
    249 	(vaddr_t)dz = dz_regs = iospace;
    250 	ioaccess(iospace, ioaddr, 1);
    251 }
    252 
    253 void
    254 dzcninit(struct consdev *cndev)
    255 {
    256 	dz = (void*)dz_regs;
    257 
    258 	dz->csr = 0;    /* Disable scanning until initting is done */
    259 	dz->tcr = (1 << minor(cndev->cn_dev));    /* Turn on xmitter */
    260 	dz->csr = 0x20; /* Turn scanning back on */
    261 }
    262 
    263 
    264 void
    265 dzcnputc(dev_t dev, int	ch)
    266 {
    267 	int timeout = 1<<15;            /* don't hang the machine! */
    268 	int mino = minor(dev);
    269 	u_short tcr;
    270 
    271 	if (mfpr(PR_MAPEN) == 0)
    272 		return;
    273 
    274 	tcr = dz->tcr;	/* remember which lines to scan */
    275 	dz->tcr = (1 << mino);
    276 
    277 	while ((dz->csr & 0x8000) == 0) /* Wait until ready */
    278 		if (--timeout < 0)
    279 			break;
    280 	dz->tdr = ch;                    /* Put the  character */
    281 	timeout = 1<<15;
    282 	while ((dz->csr & 0x8000) == 0) /* Wait until ready */
    283 		if (--timeout < 0)
    284 			break;
    285 
    286 	dz->tcr = tcr;
    287 }
    288 
    289 void
    290 dzcnpollc(dev_t dev, int pollflag)
    291 {
    292 	static	u_char mask;
    293 
    294 	if (pollflag)
    295 		mask = vsbus_setmask(0);
    296 	else
    297 		vsbus_setmask(mask);
    298 }
    299 
    300 #if NDZKBD > 0 || NDZMS > 0
    301 int
    302 dzgetc(struct dz_linestate *ls)
    303 {
    304 	int line = ls->dz_line;
    305 	u_short rbuf;
    306 
    307 	for (;;) {
    308 		for(; (dz->csr & DZ_CSR_RX_DONE) == 0;);
    309 		rbuf = dz->rbuf;
    310 		if (((rbuf >> 8) & 3) == line)
    311 			return (rbuf & 0xff);
    312 	}
    313 }
    314 
    315 void
    316 dzputc(struct dz_linestate *ls, int ch)
    317 {
    318 	int line = 0; /* = ls->dz_line; */
    319 	u_short tcr;
    320 	int s;
    321 
    322 	/* if the dz has already been attached, the MI
    323 	   driver will do the transmitting: */
    324 	if (ls && ls->dz_sc) {
    325 		s = spltty();
    326 		putc(ch, &ls->dz_sc->sc_dz[line].dz_tty->t_outq);
    327 		tcr = dz->tcr;
    328 		if (!(tcr & (1 << line)))
    329 			dz->tcr = tcr | (1 << line);
    330 		dzxint(ls->dz_sc);
    331 		splx(s);
    332 		return;
    333 	}
    334 
    335 	/* use dzcnputc to do the transmitting: */
    336 	dzcnputc(makedev(getmajor(dzopen), line), ch);
    337 }
    338 #endif /* NDZKBD > 0 || NDZMS > 0 */
    339