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