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