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