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