Browse Source

usb keyboard: add kbin device

We can now use the keyboard on the NUC.

Change-Id: Icdb4a77b7297d915baf25474f074f82b4e592f67
Signed-off-by: Ronald G. Minnich <rminnich@gmail.com>
Ronald G. Minnich 8 years ago
parent
commit
c22688af2f
5 changed files with 133 additions and 0 deletions
  1. 6 0
      sys/src/9/386/i8042.c
  2. 1 0
      sys/src/9/amd64/amd64cpu.json
  3. 5 0
      sys/src/9/boot/boot.c
  4. 120 0
      sys/src/9/port/devkbin.c
  5. 1 0
      sys/src/9/port/port.json

+ 6 - 0
sys/src/9/386/i8042.c

@@ -193,6 +193,12 @@ i8042intr(Ureg* u, void* v)
 	}
 }
 
+void
+kbdputsc(int data, int _)
+{
+	qiwrite(keybq, &data, 1);
+}
+
 static int
 outbyte(int port, int c)
 {

+ 1 - 0
sys/src/9/amd64/amd64cpu.json

@@ -26,6 +26,7 @@
 					"env",
 					"ether",
 					"ip",
+					"kbin",
 					"kprof",
 					"mnt",
 					"mouse",

+ 5 - 0
sys/src/9/boot/boot.c

@@ -290,6 +290,11 @@ usbinit(void)
 		return;
 	}
 
+	if (bind("#I", "/dev", MAFTER) < 0) {
+		print("usbinit: can't bind #I to /dev: %r\n");
+		return;
+	}
+
 	if (bind("#u", "/dev", MAFTER) < 0) {
 		print("usbinit: can't bind #u to /dev: %r\n");
 		return;

+ 120 - 0
sys/src/9/port/devkbin.c

@@ -0,0 +1,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, uint8_t *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 int32_t
+kbinread(Chan *c, void *a, int32_t n, int64_t _)
+{
+	if(c->qid.type == QTDIR)
+		return devdirread(c, a, n, kbintab, nelem(kbintab), devgen);
+	return 0;
+}
+
+static int32_t
+kbinwrite(Chan *c, void *a, int32_t n, int64_t _)
+{
+	int i;
+	uint8_t *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,
+};

+ 1 - 0
sys/src/9/port/port.json

@@ -25,6 +25,7 @@
 			"../port/devenv.c",
 			"../port/devkexec.c",
 			"../port/devkprof.c",
+			"../port/devkbin.c",
 			"../port/devmnt.c",
 			"../port/devmouse.c",
 			"../port/devpci.c",