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*/
kbopen(dev,flag)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*/
kbclose(dev,flag)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*/
kbread(dev,uio)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*/
kbwrite(dev,uio)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*/
kbioctl(dev,cmd,data,flag)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*/
kbselect(dev,flag)186 kbselect(dev, flag)
187 dev_t dev;
188 int flag;
189 {
190
191 }
192
kbchange(argp)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
kb_open()237 kb_open()
238 {
239
240 if (tty00_is_console)
241 kbm_open(SCC_KEYBOARD);
242 return (0);
243 }
244
kb_close()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
kb_ctrl(func,arg)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
kb_open()321 kb_open()
322 {
323
324 return (0);
325 }
326
kb_close()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
kb_ctrl(func,arg)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