xref: /original-bsd/sys/news3400/iop/kb.c (revision 29faa970)
1 /*
2  * Copyright (c) 1992, 1993
3  *	The Regents of the University of California.  All rights reserved.
4  *
5  * This code is derived from software contributed to Berkeley by
6  * Sony Corp. and Kazumasa Utashiro of Software Research Associates, Inc.
7  *
8  * %sccs.include.redist.c%
9  *
10  * from: $Hdr: kb.c,v 4.300 91/06/09 06:42:44 root Rel41 $ SONY
11  *
12  *	@(#)kb.c	8.1 (Berkeley) 06/11/93
13  */
14 
15 #include "kb.h"
16 
17 #if NKB > 0
18 
19 #include <sys/param.h>
20 #include <sys/proc.h>
21 #include <sys/user.h>
22 #include <sys/ioctl.h>
23 #include <sys/buf.h>
24 #include <sys/systm.h>
25 #include <sys/map.h>
26 #include <sys/uio.h>
27 #include <sys/kernel.h>
28 
29 #include <news3400/iop/keyboard.h>
30 #include <news3400/iop/kbreg.h>
31 
32 #ifdef CPU_SINGLE
33 #include <sys/tty.h>
34 #include <sys/clist.h>
35 #include <news3400/sio/scc.h>
36 #include <news3400/hbdev/hbvar.h>
37 #define	iop_device	hb_device
38 #define	ii_alive	hi_alive
39 #else
40 #include "../iop/iopvar.h"
41 #endif
42 
43 int kbprobe(), kbattach();
44 extern Key_table key_table[];
45 extern Key_table default_table[];
46 extern int country;
47 
48 #ifdef CPU_SINGLE
49 struct hb_device *kbinfo[NKB];
50 struct hb_driver kbdriver =
51 	{ kbprobe, 0, kbattach, 0, 0, "kb", kbinfo, "mc", 0, 0 };
52 extern	Key_table *key_table_addr;
53 #endif
54 
55 #ifdef CPU_DOUBLE
56 struct iop_device *kbinfo[NKB];
57 struct iop_driver kbdriver =
58 	{ kbprobe, 0, kbattach, 0, "kb", kbinfo };
59 #endif
60 
61 char	kb_busy;
62 
63 /*ARGSUSED*/
64 kbprobe(ii)
65 	struct iop_device *ii;
66 {
67 
68 	return (kb_probe(ii));
69 }
70 
71 /*ARGSUSED*/
72 kbattach(ii)
73 	struct iop_device *ii;
74 {
75 
76 	kb_attach(ii);
77 }
78 
79 /*ARGSUSED*/
80 kbopen(dev, flag)
81 	dev_t dev;
82 	int flag;
83 {
84 	register int unit;
85 	register struct iop_device *ii;
86 
87 	if ((unit = minor(dev)) >= NKB || (ii = kbinfo[unit]) == 0 ||
88 	    ii->ii_alive == 0)
89 		return (ENXIO);
90 	if (kb_busy)
91 		return (EBUSY);
92 	kb_busy = 1;
93 	return (kb_open());
94 }
95 
96 /*ARGSUSED*/
97 kbclose(dev, flag)
98 	dev_t dev;
99 	int flag;
100 {
101 	kb_close();
102 	kb_busy = 0;
103 }
104 
105 #ifdef KBDEBUG
106 /*ARGSUSED*/
107 kbread(dev, uio)
108 	dev_t dev;
109 	struct uio *uio;
110 {
111 	int error = 0;
112 
113 	while (uio->uio_resid > 0)
114 		if (error = kb_read(uio))
115 			break;
116 	return (error);
117 }
118 #endif /* KBDEBUG */
119 
120 /*ARGSUSED*/
121 kbwrite(dev, uio)
122 	dev_t dev;
123 	struct uio *uio;
124 {
125 	int error = 0;
126 
127 	while (uio->uio_resid > 0)
128 		if (error = kb_write(uio))
129 			break;
130 
131 	return (error);
132 }
133 
134 /*ARGSUSED*/
135 kbioctl(dev, cmd, data, flag)
136 	dev_t dev;
137 	caddr_t data;
138 {
139 	int error = 0;
140 
141 	switch (cmd) {
142 
143 	case KBIOCBELL:
144 		error = kb_ctrl(KIOCBELL, (int *)data);
145 		break;
146 
147 	case KBIOCREPT:
148 		error = kb_ctrl(KIOCREPT, 0);
149 		break;
150 
151 	case KBIOCNRPT:
152 		error = kb_ctrl(KIOCNRPT, 0);
153 		break;
154 
155 	case KBIOCSETLOCK:
156 		error = kb_ctrl(KIOCSETLOCK, (int *)data);
157 		break;
158 
159 	case KBIOCSETTBL:
160 		error = kbchange((Key_tab_info *)data);
161 		break;
162 
163 	case KBIOCGETCNUM:
164 		error = kb_ctrl(KIOCGETCNUM, (int *)data);
165 		break;
166 
167 	case KBIOCSETCNUM:
168 		error = kb_ctrl(KIOCSETCNUM, (int *)data);
169 		break;
170 
171 	case KBIOCGETSTAT:
172 		error = kb_ctrl(KIOCGETSTAT, (int *)data);
173 		break;
174 
175 	case KBIOCSETSTAT:
176 		error = kb_ctrl(KIOCSETSTAT, (int *)data);
177 		break;
178 
179 	default:
180 		return (EIO);
181 	}
182 	return (error);
183 }
184 
185 /*ARGSUSED*/
186 kbselect(dev, flag)
187 	dev_t dev;
188 	int flag;
189 {
190 
191 }
192 
193 kbchange(argp)
194 	Key_tab_info *argp;
195 {
196 	int keynumber;
197 
198 	keynumber = ((Key_tab_info *)argp)->key_number;
199 	if (keynumber < 0 || keynumber > N_KEY)
200 		return (EINVAL);
201 
202 	key_table[keynumber] = argp->key_num_table;
203 	return (kb_ctrl(KIOCCHTBL, (Key_table *)key_table));
204 }
205 
206 /*
207  * Machine dependent functions
208  *
209  *	kb_probe()
210  *	kb_attach()
211  *	kb_open()
212  *	kb_close()
213  *	kb_write()
214  *	kb_ctrl()
215  */
216 
217 #ifdef CPU_SINGLE
218 extern int tty00_is_console;
219 extern Key_table *key_table_addr;
220 #define KBPRI	(PZERO+1)
221 
222 kb_probe(hi)
223 	struct hb_device *hi;
224 {
225 
226 	return (1);
227 }
228 
229 kb_attach(hi)
230 	struct hb_device *hi;
231 {
232 
233 	kbd_init();
234 	kbd_ioctl(0, KIOCSETCNUM, &country);
235 }
236 
237 kb_open()
238 {
239 
240 	if (tty00_is_console)
241 		kbm_open(SCC_KEYBOARD);
242 	return (0);
243 }
244 
245 kb_close()
246 {
247 
248 	if (tty00_is_console)
249 		kbm_close(SCC_KEYBOARD);
250 	return (0);
251 }
252 
253 #ifdef KB_DEBUG
254 kb_read(uio)
255 	struct uio *uio;
256 {
257 	int n;
258 	char buf[32];
259 
260 	return (uiomove((caddr_t)buf, n, UIO_READ, uio));
261 	n = kbd_read_raw(SCC_KEYBOARD, buf, min(uio->uio_resid, sizeof (buf)));
262 	if (n == 0)
263 		return (0);
264 	return (uiomove((caddr_t)buf, n, UIO_READ, uio));
265 }
266 #endif /* KB_DEBUG */
267 
268 kb_write(uio)
269 	struct uio *uio;
270 {
271 	int n, error;
272 	char buf[32];
273 
274 	n = min(sizeof(buf), uio->uio_resid);
275 	if (error = uiomove((caddr_t)buf, n, UIO_WRITE, uio))
276 		return (error);
277 	kbd_write(SCC_KEYBOARD, buf, n);
278 	return (0);
279 }
280 
281 kb_ctrl(func, arg)
282 	int func;
283 	int *arg;
284 {
285 
286 	return (kbd_ioctl(0, func, arg));
287 }
288 #endif /* CPU_SINGLE */
289 
290 #ifdef IPC_MRX
291 #include "../ipc/newsipc.h"
292 #include "../mrx/h/kbms.h"
293 
294 #ifdef news3800
295 #define ipc_phys(x)	(caddr_t)(K0_TT0(x))
296 #endif
297 
298 int	port_kboutput, port_kboutput_iop, port_kbctrl, port_kbctrl_iop;
299 
300 kb_probe(ii)
301 	struct iop_device *ii;
302 {
303 
304 	port_kboutput_iop = object_query("kbd_output");
305 	port_kbctrl_iop = object_query("kbd_io");
306 	if (port_kboutput_iop <= 0 || port_kbctrl_iop <= 0)
307 		return (0);
308 	port_kboutput = port_create("@kboutput", NULL, 0);
309 	port_kbctrl = port_create("@kbctrl", NULL, 0);
310 	return (1);
311 }
312 
313 kb_attach(ii)
314 	struct iop_device *ii;
315 {
316 
317 	(void) kb_ctrl(KIOCCHTBL, (Key_table *)key_table);
318 	(void) kb_ctrl(KIOCSETCNUM, &country);
319 }
320 
321 kb_open()
322 {
323 
324 	return (0);
325 }
326 
327 kb_close()
328 {
329 
330 	return (0);
331 }
332 
333 #ifdef KB_DEBUG
334 kb_read(uio)
335 	struct uio *uio;
336 {
337 	char *addr;
338 	int len;
339 	int error;
340 
341 	len = uio->uio_resid;
342 	msg_send(port_kbinput_iop, port_kbinput, &len, sizeof(len), 0);
343 	msg_recv(port_kbinput, NULL, &addr, &len, 0);
344 	error = uiomove(addr, len, UIO_READ, uio);
345 	msg_free(port_kbinput);
346 	return (error);
347 }
348 #endif /* KB_DEBUG */
349 
350 kb_write(uio)
351 	struct uio *uio;
352 {
353 	int len;
354 	int error;
355 	char buf[MAX_CIO];
356 
357 	len = min(MAX_CIO, uio->uio_resid);
358 	if (error = uiomove(buf, len, UIO_WRITE, uio))
359 		return (error);
360 	msg_send(port_kboutput_iop, port_kboutput, buf, len, 0);
361 	msg_recv(port_kboutput, NULL, NULL, NULL, 0);
362 	msg_free(port_kboutput);
363 	return (0);
364 }
365 
366 kb_ctrl(func, arg)
367 	int func;
368 	int *arg;
369 {
370 	struct kb_ctrl_req req;
371 	int *reply, result;
372 	static int tmp;
373 
374 	if (func == KIOCCHTBL || func == KIOCOYATBL)
375 		req.kb_arg = (int)ipc_phys(arg);
376 	else if (arg == NULL)
377 		req.kb_arg = (int)&tmp;
378 	else
379 		req.kb_arg = *arg;
380 	req.kb_func = func;
381 	msg_send(port_kbctrl_iop, port_kbctrl, &req, sizeof(req), 0);
382 	msg_recv(port_kbctrl, NULL, &reply, NULL, 0);
383 	result = *reply;
384 	msg_free(port_kbctrl);
385 	switch (func) {
386 
387 	case KIOCGETCNUM:
388 	case KIOCGETSTAT:
389 		if (arg)
390 			*(int *)arg = result;
391 	}
392 	return (0);
393 }
394 #endif /* IPC_MRX */
395 #endif /* NKB > 0 */
396