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