xref: /plan9/sys/src/9/port/devkbin.c (revision 58da3067adcdccaaa043d0bfde28ba83b7ced07d)
1 /*
2  *  keyboard scan code input from outside the kernel.
3  *  to avoid duplication of keyboard map processing for usb.
4  */
5 
6 #include	"u.h"
7 #include	"../port/lib.h"
8 #include	"mem.h"
9 #include	"dat.h"
10 #include	"fns.h"
11 #include	"../port/error.h"
12 
13 extern	void kbdputsc(int, int);
14 
15 enum {
16 	Qdir,
17 	Qkbd,
18 };
19 
20 Dirtab kbintab[] = {
21 	".",	{Qdir, 0, QTDIR},	0,	0555,
22 	"kbin",	{Qkbd, 0},		0,	0200,
23 };
24 
25 Lock	kbinlck;
26 int	kbinbusy;
27 
28 static Chan *
29 kbinattach(char *spec)
30 {
31 	return devattach(L'Ι', spec);
32 }
33 
34 static Walkqid*
35 kbinwalk(Chan *c, Chan *nc, char **name, int nname)
36 {
37 	return devwalk(c, nc, name, nname, kbintab, nelem(kbintab), devgen);
38 }
39 
40 static int
41 kbinstat(Chan *c, uchar *dp, int n)
42 {
43 	return devstat(c, dp, n, kbintab, nelem(kbintab), devgen);
44 }
45 
46 static Chan*
47 kbinopen(Chan *c, int omode)
48 {
49 	if(!iseve())
50 		error(Eperm);
51 	if(c->qid.path == Qkbd){
52 		lock(&kbinlck);
53 		if(kbinbusy){
54 			unlock(&kbinlck);
55 			error(Einuse);
56 		}
57 		kbinbusy++;
58 		unlock(&kbinlck);
59 	}
60 	return devopen(c, omode, kbintab, nelem(kbintab), devgen);
61 }
62 
63 static void
64 kbinclose(Chan *c)
65 {
66 	if(c->aux){
67 		free(c->aux);
68 		c->aux = nil;
69 	}
70 	if(c->qid.path == Qkbd)
71 		kbinbusy = 0;
72 }
73 
74 static long
75 kbinread(Chan *c, void *a, long n, vlong )
76 {
77 	if(c->qid.type == QTDIR)
78 		return devdirread(c, a, n, kbintab, nelem(kbintab), devgen);
79 	return 0;
80 }
81 
82 static long
83 kbinwrite(Chan *c, void *a, long n, vlong)
84 {
85 	int i;
86 	uchar *p = a;
87 
88 	if(c->qid.type == QTDIR)
89 		error(Eisdir);
90 	switch((int)c->qid.path){
91 	case Qkbd:
92 		for(i = 0; i < n; i++)
93 			kbdputsc(*p++, 1);	/* external source */
94 		break;
95 	default:
96 		error(Egreg);
97 	}
98 	return n;
99 }
100 
101 Dev kbindevtab = {
102 	L'Ι',
103 	"kbin",
104 
105 	devreset,
106 	devinit,
107 	devshutdown,
108 	kbinattach,
109 	kbinwalk,
110 	kbinstat,
111 	kbinopen,
112 	devcreate,
113 	kbinclose,
114 	kbinread,
115 	devbread,
116 	kbinwrite,
117 	devbwrite,
118 	devremove,
119 	devwstat,
120 };
121