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