xref: /csrg-svn/sys/news3400/iop/kb.c (revision 57183)
153887Smckusick /*
253887Smckusick  * Copyright (c) 1992 The Regents of the University of California.
353887Smckusick  * All rights reserved.
453887Smckusick  *
553887Smckusick  * This code is derived from software contributed to Berkeley by
653887Smckusick  * Sony Corp. and Kazumasa Utashiro of Software Research Associates, Inc.
753887Smckusick  *
853887Smckusick  * %sccs.include.redist.c%
953887Smckusick  *
1053887Smckusick  * from: $Hdr: kb.c,v 4.300 91/06/09 06:42:44 root Rel41 $ SONY
1153887Smckusick  *
12*57183Sutashiro  *	@(#)kb.c	7.2 (Berkeley) 12/17/92
1353887Smckusick  */
1453887Smckusick 
1553887Smckusick #include "kb.h"
1653887Smckusick 
1753887Smckusick #if NKB > 0
18*57183Sutashiro #include <machine/fix_machine_type.h>
1953887Smckusick 
20*57183Sutashiro #include <sys/param.h>
21*57183Sutashiro #include <sys/proc.h>
22*57183Sutashiro #include <sys/user.h>
23*57183Sutashiro #include <sys/ioctl.h>
24*57183Sutashiro #include <sys/buf.h>
25*57183Sutashiro #include <sys/systm.h>
26*57183Sutashiro #include <sys/map.h>
27*57183Sutashiro #include <sys/uio.h>
28*57183Sutashiro #include <sys/kernel.h>
2953887Smckusick 
30*57183Sutashiro #include <news3400/iop/keyboard.h>
31*57183Sutashiro #include <news3400/iop/kbreg.h>
3253887Smckusick 
3353887Smckusick #ifdef CPU_SINGLE
34*57183Sutashiro #include <sys/tty.h>
35*57183Sutashiro #include <sys/clist.h>
36*57183Sutashiro #include <news3400/sio/scc.h>
37*57183Sutashiro #include <news3400/hbdev/hbvar.h>
3853887Smckusick #define	iop_device	hb_device
3953887Smckusick #define	ii_alive	hi_alive
4053887Smckusick #else
4153887Smckusick #include "../iop/iopvar.h"
4253887Smckusick #endif
4353887Smckusick 
4453887Smckusick int kbprobe(), kbattach();
4553887Smckusick extern Key_table key_table[];
4653887Smckusick extern Key_table default_table[];
4753887Smckusick extern int country;
4853887Smckusick 
4953887Smckusick #ifdef CPU_SINGLE
5053887Smckusick struct hb_device *kbinfo[NKB];
5153887Smckusick struct hb_driver kbdriver =
5253887Smckusick 	{ kbprobe, 0, kbattach, 0, 0, "kb", kbinfo, "mc", 0, 0 };
5353887Smckusick extern	Key_table *key_table_addr;
5453887Smckusick #endif
5553887Smckusick 
5653887Smckusick #ifdef CPU_DOUBLE
5753887Smckusick struct iop_device *kbinfo[NKB];
5853887Smckusick struct iop_driver kbdriver =
5953887Smckusick 	{ kbprobe, 0, kbattach, 0, "kb", kbinfo };
6053887Smckusick #endif
6153887Smckusick 
6253887Smckusick char	kb_busy;
6353887Smckusick 
6453887Smckusick /*ARGSUSED*/
6553887Smckusick kbprobe(ii)
6653887Smckusick 	struct iop_device *ii;
6753887Smckusick {
6853887Smckusick 
6953887Smckusick 	return (kb_probe(ii));
7053887Smckusick }
7153887Smckusick 
7253887Smckusick /*ARGSUSED*/
7353887Smckusick kbattach(ii)
7453887Smckusick 	struct iop_device *ii;
7553887Smckusick {
7653887Smckusick 
7753887Smckusick 	kb_attach(ii);
7853887Smckusick }
7953887Smckusick 
8053887Smckusick /*ARGSUSED*/
8153887Smckusick kbopen(dev, flag)
8253887Smckusick 	dev_t dev;
8353887Smckusick 	int flag;
8453887Smckusick {
8553887Smckusick 	register int unit;
8653887Smckusick 	register struct iop_device *ii;
8753887Smckusick 
8853887Smckusick 	if ((unit = minor(dev)) >= NKB || (ii = kbinfo[unit]) == 0 ||
8953887Smckusick 	    ii->ii_alive == 0)
9053887Smckusick 		return (ENXIO);
9153887Smckusick 	if (kb_busy)
9253887Smckusick 		return (EBUSY);
9353887Smckusick 	kb_busy = 1;
9453887Smckusick 	return (kb_open());
9553887Smckusick }
9653887Smckusick 
9753887Smckusick /*ARGSUSED*/
9853887Smckusick kbclose(dev, flag)
9953887Smckusick 	dev_t dev;
10053887Smckusick 	int flag;
10153887Smckusick {
10253887Smckusick 	kb_close();
10353887Smckusick 	kb_busy = 0;
10453887Smckusick }
10553887Smckusick 
10653887Smckusick #ifdef KBDEBUG
10753887Smckusick /*ARGSUSED*/
10853887Smckusick kbread(dev, uio)
10953887Smckusick 	dev_t dev;
11053887Smckusick 	struct uio *uio;
11153887Smckusick {
11253887Smckusick 	int error = 0;
11353887Smckusick 
11453887Smckusick 	while (uio->uio_resid > 0)
11553887Smckusick 		if (error = kb_read(uio))
11653887Smckusick 			break;
11753887Smckusick 	return (error);
11853887Smckusick }
11953887Smckusick #endif /* KBDEBUG */
12053887Smckusick 
12153887Smckusick /*ARGSUSED*/
12253887Smckusick kbwrite(dev, uio)
12353887Smckusick 	dev_t dev;
12453887Smckusick 	struct uio *uio;
12553887Smckusick {
12653887Smckusick 	int error = 0;
12753887Smckusick 
12853887Smckusick 	while (uio->uio_resid > 0)
12953887Smckusick 		if (error = kb_write(uio))
13053887Smckusick 			break;
13153887Smckusick 
13253887Smckusick 	return (error);
13353887Smckusick }
13453887Smckusick 
13553887Smckusick /*ARGSUSED*/
13653887Smckusick kbioctl(dev, cmd, data, flag)
13753887Smckusick 	dev_t dev;
13853887Smckusick 	caddr_t data;
13953887Smckusick {
14053887Smckusick 	int error = 0;
14153887Smckusick 
14253887Smckusick 	switch (cmd) {
14353887Smckusick 
14453887Smckusick 	case KBIOCBELL:
14553887Smckusick 		error = kb_ctrl(KIOCBELL, (int *)data);
14653887Smckusick 		break;
14753887Smckusick 
14853887Smckusick 	case KBIOCREPT:
14953887Smckusick 		error = kb_ctrl(KIOCREPT, 0);
15053887Smckusick 		break;
15153887Smckusick 
15253887Smckusick 	case KBIOCNRPT:
15353887Smckusick 		error = kb_ctrl(KIOCNRPT, 0);
15453887Smckusick 		break;
15553887Smckusick 
15653887Smckusick 	case KBIOCSETLOCK:
15753887Smckusick 		error = kb_ctrl(KIOCSETLOCK, (int *)data);
15853887Smckusick 		break;
15953887Smckusick 
16053887Smckusick 	case KBIOCSETTBL:
16153887Smckusick 		error = kbchange((Key_tab_info *)data);
16253887Smckusick 		break;
16353887Smckusick 
16453887Smckusick 	case KBIOCGETCNUM:
16553887Smckusick 		error = kb_ctrl(KIOCGETCNUM, (int *)data);
16653887Smckusick 		break;
16753887Smckusick 
16853887Smckusick 	case KBIOCSETCNUM:
16953887Smckusick 		error = kb_ctrl(KIOCSETCNUM, (int *)data);
17053887Smckusick 		break;
17153887Smckusick 
17253887Smckusick 	case KBIOCGETSTAT:
17353887Smckusick 		error = kb_ctrl(KIOCGETSTAT, (int *)data);
17453887Smckusick 		break;
17553887Smckusick 
17653887Smckusick 	case KBIOCSETSTAT:
17753887Smckusick 		error = kb_ctrl(KIOCSETSTAT, (int *)data);
17853887Smckusick 		break;
17953887Smckusick 
18053887Smckusick 	default:
18153887Smckusick 		return (EIO);
18253887Smckusick 	}
18353887Smckusick 	return (error);
18453887Smckusick }
18553887Smckusick 
18653887Smckusick /*ARGSUSED*/
18753887Smckusick kbselect(dev, flag)
18853887Smckusick 	dev_t dev;
18953887Smckusick 	int flag;
19053887Smckusick {
19153887Smckusick 
19253887Smckusick }
19353887Smckusick 
19453887Smckusick kbchange(argp)
19553887Smckusick 	Key_tab_info *argp;
19653887Smckusick {
19753887Smckusick 	int keynumber;
19853887Smckusick 
19953887Smckusick 	keynumber = ((Key_tab_info *)argp)->key_number;
20053887Smckusick 	if (keynumber < 0 || keynumber > N_KEY)
20153887Smckusick 		return (EINVAL);
20253887Smckusick 
20353887Smckusick 	key_table[keynumber] = argp->key_num_table;
20453887Smckusick 	return (kb_ctrl(KIOCCHTBL, (Key_table *)key_table));
20553887Smckusick }
20653887Smckusick 
20753887Smckusick /*
20853887Smckusick  * Machine dependent functions
20953887Smckusick  *
21053887Smckusick  *	kb_probe()
21153887Smckusick  *	kb_attach()
21253887Smckusick  *	kb_open()
21353887Smckusick  *	kb_close()
21453887Smckusick  *	kb_write()
21553887Smckusick  *	kb_ctrl()
21653887Smckusick  */
21753887Smckusick 
21853887Smckusick #ifdef CPU_SINGLE
21953887Smckusick extern int tty00_is_console;
22053887Smckusick extern Key_table *key_table_addr;
22153887Smckusick #define KBPRI	(PZERO+1)
22253887Smckusick 
22353887Smckusick kb_probe(hi)
22453887Smckusick 	struct hb_device *hi;
22553887Smckusick {
22653887Smckusick 
22753887Smckusick 	return (1);
22853887Smckusick }
22953887Smckusick 
23053887Smckusick kb_attach(hi)
23153887Smckusick 	struct hb_device *hi;
23253887Smckusick {
23353887Smckusick 
23453887Smckusick 	kbd_init();
23553887Smckusick 	kbd_ioctl(0, KIOCSETCNUM, &country);
23653887Smckusick }
23753887Smckusick 
23853887Smckusick kb_open()
23953887Smckusick {
24053887Smckusick 
24153887Smckusick #ifndef news700
24253887Smckusick 	if (tty00_is_console)
24353887Smckusick 		kbm_open(SCC_KEYBOARD);
24453887Smckusick #endif
24553887Smckusick 	return (0);
24653887Smckusick }
24753887Smckusick 
24853887Smckusick kb_close()
24953887Smckusick {
25053887Smckusick 
25153887Smckusick #ifndef news700
25253887Smckusick 	if (tty00_is_console)
25353887Smckusick 		kbm_close(SCC_KEYBOARD);
25453887Smckusick #endif
25553887Smckusick 	return (0);
25653887Smckusick }
25753887Smckusick 
25853887Smckusick #ifdef KB_DEBUG
25953887Smckusick kb_read(uio)
26053887Smckusick 	struct uio *uio;
26153887Smckusick {
26253887Smckusick 	int n;
26353887Smckusick 	char buf[32];
26453887Smckusick 
26553887Smckusick 	return (uiomove((caddr_t)buf, n, UIO_READ, uio));
26653887Smckusick 	n = kbd_read_raw(SCC_KEYBOARD, buf, min(uio->uio_resid, sizeof (buf)));
26753887Smckusick 	if (n == 0)
26853887Smckusick 		return (0);
26953887Smckusick 	return (uiomove((caddr_t)buf, n, UIO_READ, uio));
27053887Smckusick }
27153887Smckusick #endif /* KB_DEBUG */
27253887Smckusick 
27353887Smckusick kb_write(uio)
27453887Smckusick 	struct uio *uio;
27553887Smckusick {
27653887Smckusick 	int n, error;
27753887Smckusick 	char buf[32];
27853887Smckusick 
27953887Smckusick 	n = min(sizeof(buf), uio->uio_resid);
28053887Smckusick 	if (error = uiomove((caddr_t)buf, n, UIO_WRITE, uio))
28153887Smckusick 		return (error);
28253887Smckusick 	kbd_write(SCC_KEYBOARD, buf, n);
28353887Smckusick 	return (0);
28453887Smckusick }
28553887Smckusick 
28653887Smckusick kb_ctrl(func, arg)
28753887Smckusick 	int func;
28853887Smckusick 	int *arg;
28953887Smckusick {
29053887Smckusick 
29153887Smckusick 	return (kbd_ioctl(0, func, arg));
29253887Smckusick }
29353887Smckusick #endif /* CPU_SINGLE */
29453887Smckusick 
29553887Smckusick #ifdef IPC_MRX
29653887Smckusick #include "../ipc/newsipc.h"
29753887Smckusick #include "../mrx/h/kbms.h"
29853887Smckusick 
29953887Smckusick #ifdef news1800
30053887Smckusick #define ipc_phys(x)	(caddr_t)((int)(x) & ~0x80000000)
30153887Smckusick #endif
30253887Smckusick #ifdef news3800
30353887Smckusick #define ipc_phys(x)	(caddr_t)(K0_TT0(x))
30453887Smckusick #endif
30553887Smckusick 
30653887Smckusick int	port_kboutput, port_kboutput_iop, port_kbctrl, port_kbctrl_iop;
30753887Smckusick 
30853887Smckusick kb_probe(ii)
30953887Smckusick 	struct iop_device *ii;
31053887Smckusick {
31153887Smckusick 
31253887Smckusick 	port_kboutput_iop = object_query("kbd_output");
31353887Smckusick 	port_kbctrl_iop = object_query("kbd_io");
31453887Smckusick 	if (port_kboutput_iop <= 0 || port_kbctrl_iop <= 0)
31553887Smckusick 		return (0);
31653887Smckusick 	port_kboutput = port_create("@kboutput", NULL, 0);
31753887Smckusick 	port_kbctrl = port_create("@kbctrl", NULL, 0);
31853887Smckusick 	return (1);
31953887Smckusick }
32053887Smckusick 
32153887Smckusick kb_attach(ii)
32253887Smckusick 	struct iop_device *ii;
32353887Smckusick {
32453887Smckusick 
32553887Smckusick 	(void) kb_ctrl(KIOCCHTBL, (Key_table *)key_table);
32653887Smckusick 	(void) kb_ctrl(KIOCSETCNUM, &country);
32753887Smckusick }
32853887Smckusick 
32953887Smckusick kb_open()
33053887Smckusick {
33153887Smckusick 
33253887Smckusick 	return (0);
33353887Smckusick }
33453887Smckusick 
33553887Smckusick kb_close()
33653887Smckusick {
33753887Smckusick 
33853887Smckusick 	return (0);
33953887Smckusick }
34053887Smckusick 
34153887Smckusick #ifdef KB_DEBUG
34253887Smckusick kb_read(uio)
34353887Smckusick 	struct uio *uio;
34453887Smckusick {
34553887Smckusick 	char *addr;
34653887Smckusick 	int len;
34753887Smckusick 	int error;
34853887Smckusick 
34953887Smckusick 	len = uio->uio_resid;
35053887Smckusick 	msg_send(port_kbinput_iop, port_kbinput, &len, sizeof(len), 0);
35153887Smckusick 	msg_recv(port_kbinput, NULL, &addr, &len, 0);
35253887Smckusick 	error = uiomove(addr, len, UIO_READ, uio);
35353887Smckusick 	msg_free(port_kbinput);
35453887Smckusick 	return (error);
35553887Smckusick }
35653887Smckusick #endif /* KB_DEBUG */
35753887Smckusick 
35853887Smckusick kb_write(uio)
35953887Smckusick 	struct uio *uio;
36053887Smckusick {
36153887Smckusick 	int len;
36253887Smckusick 	int error;
36353887Smckusick 	char buf[MAX_CIO];
36453887Smckusick 
36553887Smckusick 	len = min(MAX_CIO, uio->uio_resid);
36653887Smckusick 	if (error = uiomove(buf, len, UIO_WRITE, uio))
36753887Smckusick 		return (error);
36853887Smckusick 	msg_send(port_kboutput_iop, port_kboutput, buf, len, 0);
36953887Smckusick 	msg_recv(port_kboutput, NULL, NULL, NULL, 0);
37053887Smckusick 	msg_free(port_kboutput);
37153887Smckusick 	return (0);
37253887Smckusick }
37353887Smckusick 
37453887Smckusick kb_ctrl(func, arg)
37553887Smckusick 	int func;
37653887Smckusick 	int *arg;
37753887Smckusick {
37853887Smckusick 	struct kb_ctrl_req req;
37953887Smckusick 	int *reply, result;
38053887Smckusick 	static int tmp;
38153887Smckusick 
38253887Smckusick 	if (func == KIOCCHTBL || func == KIOCOYATBL)
38353887Smckusick 		req.kb_arg = (int)ipc_phys(arg);
38453887Smckusick 	else if (arg == NULL)
38553887Smckusick 		req.kb_arg = (int)&tmp;
38653887Smckusick 	else
38753887Smckusick 		req.kb_arg = *arg;
38853887Smckusick 	req.kb_func = func;
38953887Smckusick 	msg_send(port_kbctrl_iop, port_kbctrl, &req, sizeof(req), 0);
39053887Smckusick 	msg_recv(port_kbctrl, NULL, &reply, NULL, 0);
39153887Smckusick 	result = *reply;
39253887Smckusick 	msg_free(port_kbctrl);
39353887Smckusick 	switch (func) {
39453887Smckusick 
39553887Smckusick 	case KIOCGETCNUM:
39653887Smckusick 	case KIOCGETSTAT:
39753887Smckusick 		if (arg)
39853887Smckusick 			*(int *)arg = result;
39953887Smckusick 	}
40053887Smckusick 	return (0);
40153887Smckusick }
40253887Smckusick #endif /* IPC_MRX */
40353887Smckusick #endif /* NKB > 0 */
404