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