1 /* $NetBSD: gencons.c,v 1.49 2008/03/11 05:34:03 matt Exp $ */
4 * Copyright (c) 1994 Gordon W. Ross
5 * Copyright (c) 1994 Ludd, University of Lule}, Sweden.
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. All advertising materials mentioning features or use of this software
17 * must display the following acknowledgement:
18 * This product includes software developed at Ludd, University of Lule}.
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
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.
33 * kd.c,v 1.2 1994/05/05 04:46:51 gwr Exp $
36 /* All bugs are subject to removal without further notice */
38 #include <sys/cdefs.h>
39 __KERNEL_RCSID(0, "$NetBSD: gencons.c,v 1.49 2008/03/11 05:34:03 matt Exp $");
42 #include "opt_cputype.h"
43 #include "opt_multiprocessor.h"
45 #include <sys/param.h>
47 #include <sys/systm.h>
48 #include <sys/ioctl.h>
52 #include <sys/device.h>
53 #include <sys/reboot.h>
54 #include <sys/kernel.h>
55 #include <sys/kauth.h>
59 #include <machine/mtpr.h>
60 #include <machine/sid.h>
61 #include <machine/cpu.h>
62 #include <machine/scb.h>
63 #include <vax/vax/gencons.h>
65 static struct gc_softc
{
68 struct tty
*gencn_tty
;
71 static int maxttys
= 1;
73 static int pr_txcs
[4] = {PR_TXCS
, PR_TXCS1
, PR_TXCS2
, PR_TXCS3
};
74 static int pr_rxcs
[4] = {PR_RXCS
, PR_RXCS1
, PR_RXCS2
, PR_RXCS3
};
75 static int pr_txdb
[4] = {PR_TXDB
, PR_TXDB1
, PR_TXDB2
, PR_TXDB3
};
76 static int pr_rxdb
[4] = {PR_RXDB
, PR_RXDB1
, PR_RXDB2
, PR_RXDB3
};
80 static int gencnparam(struct tty
*, struct termios
*);
81 static void gencnstart(struct tty
*);
83 dev_type_open(gencnopen
);
84 dev_type_close(gencnclose
);
85 dev_type_read(gencnread
);
86 dev_type_write(gencnwrite
);
87 dev_type_ioctl(gencnioctl
);
88 dev_type_tty(gencntty
);
89 dev_type_poll(gencnpoll
);
91 const struct cdevsw gen_cdevsw
= {
92 gencnopen
, gencnclose
, gencnread
, gencnwrite
, gencnioctl
,
93 nostop
, gencntty
, gencnpoll
, nommap
, ttykqfilter
, D_TTY
97 gencnopen(dev_t dev
, int flag
, int mode
, struct lwp
*l
)
106 if (gc_softc
[unit
].gencn_tty
== NULL
)
107 gc_softc
[unit
].gencn_tty
= ttymalloc();
109 gc_softc
[unit
].alive
= 1;
110 gc_softc
[unit
].unit
= unit
;
111 tp
= gc_softc
[unit
].gencn_tty
;
113 tp
->t_oproc
= gencnstart
;
114 tp
->t_param
= gencnparam
;
117 if (kauth_authorize_device_tty(l
->l_cred
, KAUTH_DEVICE_TTY_OPEN
, tp
))
120 if ((tp
->t_state
& TS_ISOPEN
) == 0) {
122 tp
->t_iflag
= TTYDEF_IFLAG
;
123 tp
->t_oflag
= TTYDEF_OFLAG
;
124 tp
->t_cflag
= TTYDEF_CFLAG
;
125 tp
->t_lflag
= TTYDEF_LFLAG
;
126 tp
->t_ispeed
= tp
->t_ospeed
= TTYDEF_SPEED
;
127 gencnparam(tp
, &tp
->t_termios
);
130 tp
->t_state
|= TS_CARR_ON
;
132 return ((*tp
->t_linesw
->l_open
)(dev
, tp
));
136 gencnclose(dev_t dev
, int flag
, int mode
, struct lwp
*l
)
138 struct tty
*tp
= gc_softc
[minor(dev
)].gencn_tty
;
140 (*tp
->t_linesw
->l_close
)(tp
, flag
);
142 gc_softc
[minor(dev
)].alive
= 0;
149 return gc_softc
[minor(dev
)].gencn_tty
;
153 gencnread(dev_t dev
, struct uio
*uio
, int flag
)
155 struct tty
*tp
= gc_softc
[minor(dev
)].gencn_tty
;
157 return ((*tp
->t_linesw
->l_read
)(tp
, uio
, flag
));
161 gencnwrite(dev_t dev
, struct uio
*uio
, int flag
)
163 struct tty
*tp
= gc_softc
[minor(dev
)].gencn_tty
;
165 return ((*tp
->t_linesw
->l_write
)(tp
, uio
, flag
));
169 gencnpoll(dev_t dev
, int events
, struct lwp
*l
)
171 struct tty
*tp
= gc_softc
[minor(dev
)].gencn_tty
;
173 return ((*tp
->t_linesw
->l_poll
)(tp
, events
, l
));
177 gencnioctl(dev_t dev
, u_long cmd
, void *data
, int flag
, struct lwp
*l
)
179 struct tty
*tp
= gc_softc
[minor(dev
)].gencn_tty
;
182 error
= (*tp
->t_linesw
->l_ioctl
)(tp
, cmd
, data
, flag
, l
);
183 if (error
!= EPASSTHROUGH
)
185 return ttioctl(tp
, cmd
, data
, flag
, l
);
189 gencnstart(struct tty
*tp
)
194 #if defined(MULTIPROCESSOR)
195 if ((curcpu()->ci_flags
& CI_MASTERCPU
) == 0)
196 return cpu_send_ipi(IPI_DEST_MASTER
, IPI_START_CNTX
);
200 if (tp
->t_state
& (TS_BUSY
|TS_TTSTOP
|TS_TIMEOUT
))
205 tp
->t_state
|= TS_BUSY
;
207 mtpr(ch
, pr_txdb
[minor(tp
->t_dev
)]);
216 struct gc_softc
*sc
= arg
;
217 struct tty
*tp
= sc
->gencn_tty
;
222 i
= mfpr(pr_rxdb
[sc
->unit
]) & 0377; /* Mask status flags etc... */
223 KERNEL_LOCK(1, NULL
);
226 if (tp
->t_dev
== cn_tab
->cn_dev
) {
229 if (j
== 1) { /* Escape received, just return */
230 KERNEL_UNLOCK_ONE(NULL
);
234 if (j
== 2) /* Second char wasn't 'D' */
235 (*tp
->t_linesw
->l_rint
)(27, tp
);
239 (*tp
->t_linesw
->l_rint
)(i
, tp
);
240 KERNEL_UNLOCK_ONE(NULL
);
246 struct gc_softc
*sc
= arg
;
247 struct tty
*tp
= sc
->gencn_tty
;
251 KERNEL_LOCK(1, NULL
);
252 tp
->t_state
&= ~TS_BUSY
;
255 KERNEL_UNLOCK_ONE(NULL
);
259 gencnparam(struct tty
*tp
, struct termios
*t
)
261 /* XXX - These are ignored... */
262 tp
->t_ispeed
= t
->c_ispeed
;
263 tp
->t_ospeed
= t
->c_ospeed
;
264 tp
->t_cflag
= t
->c_cflag
;
269 gencnprobe(struct consdev
*cndev
)
271 if ((vax_cputype
< VAX_TYP_UV2
) || /* All older has MTPR console */
272 (vax_boardtype
== VAX_BTYP_9RR
) ||
273 (vax_boardtype
== VAX_BTYP_630
) ||
274 (vax_boardtype
== VAX_BTYP_660
) ||
275 (vax_boardtype
== VAX_BTYP_670
) ||
276 (vax_boardtype
== VAX_BTYP_680
) ||
277 (vax_boardtype
== VAX_BTYP_681
) ||
278 (vax_boardtype
== VAX_BTYP_650
)) {
279 cndev
->cn_dev
= makedev(cdevsw_lookup_major(&gen_cdevsw
), 0);
280 cndev
->cn_pri
= CN_NORMAL
;
282 cndev
->cn_pri
= CN_DEAD
;
286 gencninit(struct consdev
*cndev
)
289 /* Allocate interrupt vectors */
290 scb_vecalloc(SCB_G0R
, gencnrint
, &gc_softc
[0], SCB_ISTACK
, NULL
);
291 scb_vecalloc(SCB_G0T
, gencntint
, &gc_softc
[0], SCB_ISTACK
, NULL
);
292 mtpr(GC_RIE
, pr_rxcs
[0]); /* Turn on interrupts */
293 mtpr(GC_TIE
, pr_txcs
[0]);
295 if (vax_cputype
== VAX_TYP_8SS
) {
297 scb_vecalloc(SCB_G1R
, gencnrint
, &gc_softc
[1], SCB_ISTACK
, NULL
);
298 scb_vecalloc(SCB_G1T
, gencntint
, &gc_softc
[1], SCB_ISTACK
, NULL
);
300 scb_vecalloc(SCB_G2R
, gencnrint
, &gc_softc
[2], SCB_ISTACK
, NULL
);
301 scb_vecalloc(SCB_G2T
, gencntint
, &gc_softc
[2], SCB_ISTACK
, NULL
);
303 scb_vecalloc(SCB_G3R
, gencnrint
, &gc_softc
[3], SCB_ISTACK
, NULL
);
304 scb_vecalloc(SCB_G3T
, gencntint
, &gc_softc
[3], SCB_ISTACK
, NULL
);
309 mtpr(0, PR_TBIA
); /* ??? */
314 gencnputc(dev_t dev
, int ch
)
316 #if VAX8800 || VAXANY
318 * On KA88 we may get C-S/C-Q from the console.
319 * XXX - this will cause a loop at spltty() in kernel and will
320 * interfere with other console communication. Fortunately
321 * kernel printf's are uncommon.
323 if (vax_cputype
== VAX_TYP_8NN
) {
326 while (mfpr(PR_RXCS
) & GC_DON
) {
327 if ((mfpr(PR_RXDB
) & 0x7f) == 19) {
329 while ((mfpr(PR_RXCS
) & GC_DON
) == 0)
331 if ((mfpr(PR_RXDB
) & 0x7f) == 17)
340 while ((mfpr(PR_TXCS
) & GC_RDY
) == 0) /* Wait until xmit ready */
342 mtpr(ch
, PR_TXDB
); /* xmit character */
344 gencnputc(dev
, 13); /* CR/LF */
353 while ((mfpr(PR_RXCS
) & GC_DON
) == 0) /* Receive chr */
355 i
= mfpr(PR_RXDB
) & 0x7f;
362 gencnpollc(dev_t dev
, int pollflag
)
368 mtpr(GC_RIE
, PR_RXCS
);
369 mtpr(GC_TIE
, PR_TXCS
);
373 #if defined(MULTIPROCESSOR)
377 gencnstart(gc_softc
[0].gencn_tty
);