diff options
author | cinap_lenrek <cinap_lenrek@felloff.net> | 2022-10-08 10:38:14 +0000 |
---|---|---|
committer | cinap_lenrek <cinap_lenrek@felloff.net> | 2022-10-08 10:38:14 +0000 |
commit | 166e8b3cf8d2e087258eb47fdba7e890d6a8432a (patch) | |
tree | da16c7d2198956abacd36cb99a6137136503a11e /sys/src/cmd/nusb | |
parent | 2a29b497f215f91d05b6718a0e852e8a9b6ce6da (diff) | |
parent | c6ae349e9d67ef24ce429f699c5232a9acdcb1ea (diff) |
merge
Diffstat (limited to 'sys/src/cmd/nusb')
-rw-r--r-- | sys/src/cmd/nusb/disk/disk.c | 4 | ||||
-rw-r--r-- | sys/src/cmd/nusb/kb/hid.h | 1 | ||||
-rw-r--r-- | sys/src/cmd/nusb/kb/kb.c | 211 |
3 files changed, 169 insertions, 47 deletions
diff --git a/sys/src/cmd/nusb/disk/disk.c b/sys/src/cmd/nusb/disk/disk.c index 196894cfe..2fb8fc324 100644 --- a/sys/src/cmd/nusb/disk/disk.c +++ b/sys/src/cmd/nusb/disk/disk.c @@ -155,10 +155,10 @@ ctlstring(Umsc *lun) part = &lun->part[0]; fmtstrinit(&fmt); - fmtprint(&fmt, "dev %s\n", dev->dir); - fmtprint(&fmt, "lun %zd\n", lun - &ums->lun[0]); if(lun->flags & Finqok) fmtprint(&fmt, "inquiry %s\n", lun->inq); + fmtprint(&fmt, "dev %s\n", dev->dir); + fmtprint(&fmt, "lun %zd\n", lun - &ums->lun[0]); if(lun->blocks > 0) fmtprint(&fmt, "geometry %llud %ld\n", lun->blocks, lun->lbsize); for (p = &part[Qdata+1]; p < &part[Qmax]; p++) diff --git a/sys/src/cmd/nusb/kb/hid.h b/sys/src/cmd/nusb/kb/hid.h index 10e614f4b..5c51250aa 100644 --- a/sys/src/cmd/nusb/kb/hid.h +++ b/sys/src/cmd/nusb/kb/hid.h @@ -4,6 +4,7 @@ enum { Stack = 32 * 1024, + Nkey = 64, /* HID class subclass protocol ids */ PtrCSP = 0x020103, /* mouse.boot.hid */ diff --git a/sys/src/cmd/nusb/kb/kb.c b/sys/src/cmd/nusb/kb/kb.c index e748c9268..5a7b8ee5e 100644 --- a/sys/src/cmd/nusb/kb/kb.c +++ b/sys/src/cmd/nusb/kb/kb.c @@ -13,21 +13,21 @@ #include <u.h> #include <libc.h> +#include <ctype.h> +#include <fcall.h> #include <thread.h> +#include <9p.h> #include "usb.h" #include "hid.h" enum { - Awakemsg=0xdeaddead, + Awakemsg = 0xdeaddead, Diemsg = 0xbeefbeef, + Rawon = 0x0defaced, }; -enum -{ - Kbdelay = 500, - Kbrepeat = 100, -}; +char user[] = "kb"; typedef struct Hiddev Hiddev; struct Hiddev @@ -78,7 +78,7 @@ struct Hidreport Hidslot s[16]; int nk; - uchar k[64]; + ushort k[Nkey]; int o; uchar *e; @@ -92,6 +92,7 @@ enum { /* Scan codes (see kbd.c) */ SCesc1 = 0xe0, /* first of a 2-character sequence */ SCesc2 = 0xe1, + Consumer = 0x100, /* the key is on consumer page */ Keyup = 0x80, /* flag bit */ Keymask = 0x7f, /* regular scan code bits */ }; @@ -101,12 +102,12 @@ enum { */ #define isext(sc) ((sc) >= 0x80) +static char sctab[2*256] = +{ /* * key code to scan code; for the page table used by * the logitech bluetooth keyboard. */ -static char sctab[256] = -{ [0x00] 0x0, 0x0, 0x0, 0x0, 0x1e, 0x30, 0x2e, 0x20, [0x08] 0x12, 0x21, 0x22, 0x23, 0x17, 0x24, 0x25, 0x26, [0x10] 0x32, 0x31, 0x18, 0x19, 0x10, 0x13, 0x1f, 0x14, @@ -124,7 +125,7 @@ static char sctab[256] = [0x70] 0xf8, 0xf9, 0xfa, 0xfb, 0x0, 0x0, 0x0, 0x0, [0x78] 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xf1, [0x80] 0xf3, 0xf2, 0x0, 0x0, 0x0, 0xfc, 0x0, 0x0, -[0x88] 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +[0x88] 0x70, 0x0, 0x79, 0x7b, 0x0, 0x0, 0x0, 0x0, [0x90] 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, [0x98] 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, [0xa0] 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, @@ -135,10 +136,43 @@ static char sctab[256] = [0xc8] 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, [0xd0] 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, [0xd8] 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -[0xe0] 0x1d, 0x2a, 0x38, 0xdb, 0xe1, 0x36, 0xb8, 0xfe, +[0xe0] 0x1d, 0x2a, 0x38, 0xdb, 0x9d, 0x36, 0xb8, 0xfe, [0xe8] 0x0, 0x0, 0x0, 0x0, 0x0, 0xf3, 0xf2, 0xf1, [0xf0] 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, [0xf8] 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +/* consumer page to scan code */ +[0x100] 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +[0x108] 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +[0x110] 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +[0x118] 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +[0x120] 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +[0x128] 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +[0x130] 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +[0x138] 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +[0x140] 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +[0x148] 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +[0x150] 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +[0x158] 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +[0x160] 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +[0x168] 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x9a, +[0x170] 0x91, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +[0x178] 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +[0x180] 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +[0x188] 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +[0x190] 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +[0x198] 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +[0x1a0] 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +[0x1a8] 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +[0x1b0] 0x0, 0x0, 0x0, 0x0, 0x0, 0x99, 0x90, 0x0, +[0x1b8] 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +[0x1c0] 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +[0x1c8] 0x0, 0x0, 0x0, 0x0, 0x0, 0xa2, 0x0, 0x0, +[0x1d0] 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +[0x1d8] 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +[0x1e0] 0x0, 0x0, 0xa0, 0x0, 0x0, 0x0, 0x0, 0x0, +[0x1e8] 0x0, 0xb0, 0xae, 0x0, 0x0, 0x0, 0x0, 0x0, +[0x1f0] 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +[0x1f8] 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, }; static uchar kbdbootrep[] = { @@ -165,6 +199,9 @@ static uchar ptrbootrep[] = { }; static int debug = 0; +static int kbdelay = 500; +static int kbrepeat = 100; +static int havekbd; static int signext(int v, int bits) @@ -377,12 +414,6 @@ setproto(Hiddev *f, Iface *iface) return usbcmd(f->dev, Rh2d|Rclass|Riface, Setproto, proto, iface->id, nil, 0); } -static int -setleds(Hiddev* f, int, uchar leds) -{ - return usbcmd(f->dev, Rh2d|Rclass|Riface, Setreport, Reportout, 0, &leds, 1); -} - static void hdfree(Hiddev *f) { @@ -498,9 +529,9 @@ repeatproc(void* arg) continue; } sc = l & 0xff; - t = Kbdelay; + t = kbdelay; if(alt(a) == 1){ - t = Kbrepeat; + t = kbrepeat; while(alt(a) == 1) putscan(f, sc, 0); } @@ -528,7 +559,7 @@ hidparse(int t, int f, int g[], int l[], int, void *a) { Hidreport *p = a; Hidslot *s = &p->s[p->ns]; - int v, m; + int v, m, cp; switch(t){ case Input: @@ -571,11 +602,11 @@ hidparse(int t, int f, int g[], int l[], int, void *a) if(debug > 1) fprint(2, "hidparse: t=%x f=%x usage=%x v=%x\n", t, f, l[Usage], v); - if((l[Usage]>>16) == 0x07){ /* keycode */ + if((cp = ((l[Usage]>>16) == 0x0c)) || (l[Usage]>>16) == 0x07){ /* consumer/keycode */ if((f & (Fvar|Farray)) == Fvar) if(v != 0) v = l[Usage] & 0xFF; if(p->nk < nelem(p->k) && v != 0) - p->k[p->nk++] = v; + p->k[p->nk++] = v | cp*Consumer; return; } @@ -677,12 +708,23 @@ sethipri(void) close(fd); } +static ushort * +keykey(ushort *a, ushort k, int n) +{ + while(n > 0){ + if(*a++ == k) + return a-1; + n--; + } + return nil; +} + static void readerproc(void* a) { char err[ERRMAX], mbuf[80]; - uchar lastk[64], uk, dk; - int i, c, nerrs, bpress, lastb, nlastk; + ushort lastk[Nkey], uks[Nkey], dks[Nkey], nuks, ndks; + int i, c, nerrs, bpress, lastb, nlastk, stopped; int abs, x, y, z, b; Hidreport p; Hidslot lasts[nelem(p.s)], *s, *l; @@ -730,7 +772,7 @@ readerproc(void* a) if(debug){ fprint(2, "kbd: "); for(i = 0; i < p.nk; i++) - fprint(2, "%#2.2ux ", p.k[i]); + fprint(2, "%#4.4ux ", p.k[i]); fprint(2, "\n"); } @@ -745,25 +787,36 @@ readerproc(void* a) proccreate(repeatproc, f, Stack); } - dk = uk = 0; - for(i=0; i<nlastk; i++){ - if(memchr(p.k, lastk[i], p.nk) == nil){ - uk = sctab[lastk[i]]; - putscan(f, uk, Keyup); - } + /* collect key presses/releases */ + for(i=nuks=0; i<nlastk; i++){ + if(keykey(p.k, lastk[i], p.nk) == nil) + uks[nuks++] = sctab[lastk[i]]; } - for(i=0; i<p.nk; i++){ - if(memchr(lastk, p.k[i], nlastk) == nil){ - dk = sctab[p.k[i]]; - putscan(f, dk, 0); + for(i=ndks=0; i<p.nk; i++){ + if(keykey(lastk, p.k[i], nlastk) == nil) + dks[ndks++] = sctab[p.k[i]]; + } + + /* + * stop the repeats first to avoid race condition when + * the key is released but the repeat happens right after + */ + for(stopped = i = 0; i < nuks; i++){ + if(ndks == 0 || keykey(dks, uks[i], ndks) != nil){ + stoprepeat(f); + stopped = 1; + break; } } - if(uk != 0 && (dk == 0 || dk == uk)) - stoprepeat(f); - else if(dk != 0) - startrepeat(f, dk); + for(i = 0; i < nuks; i++) + putscan(f, uks[i], Keyup); + for(i = 0; i < ndks; i++) + putscan(f, dks[i], 0); + + if(stopped == 0 && ndks > 0) + startrepeat(f, dks[ndks-1]); - memmove(lastk, p.k, nlastk = p.nk); + memmove(lastk, p.k, (nlastk = p.nk)*sizeof(lastk[0])); p.nk = 0; } @@ -871,7 +924,7 @@ quirks(Hiddev *f) } } -static void +static int hdsetup(Dev *d, Ep *ep) { Hiddev *f; @@ -896,12 +949,71 @@ hdsetup(Dev *d, Ep *ep) } quirks(f); procrfork(readerproc, f, Stack, RFNOTEG); - return; + return 0; Err: hdfree(f); + return -1; +} + +static void +fsread(Req *r) +{ + char msg[48], *s, *e; + + s = msg; + e = msg+sizeof(msg); + *s = 0; + if(havekbd) + e = seprint(s, e, "repeat %d\ndelay %d\n", kbrepeat, kbdelay); + USED(e); + readstr(r, msg); + respond(r, nil); } static void +fswrite(Req *r) +{ + char msg[256], *f[4]; + void *data; + int nf, sz; + Dev *dev; + + dev = r->fid->file->aux; + data = r->ifcall.data; + sz = r->ifcall.count; + if(r->fid->aux == (void*)Rawon){ + if(sz == 6 && memcmp(data, "rawoff", 6) == 0) + r->fid->aux = nil; + else if(usbcmd(dev, Rh2d|Rclass|Riface, Setreport, Reportout, 0, data, sz) < 0){ + responderror(r); + return; + } + }else{ + snprint(msg, sizeof(msg), "%.*s", utfnlen(data, sz), data); + nf = tokenize(msg, f, nelem(f)); + if(nf == 1 && strcmp(f[0], "rawon") == 0) + r->fid->aux = (void*)Rawon; + else if(nf == 2 && strcmp(f[0], "repeat") == 0) + kbrepeat = atoi(f[1]); + else if(nf == 2 && strcmp(f[0], "delay") == 0) + kbdelay = atoi(f[1]); + else if(nf == 2 && strcmp(f[0], "debug") == 0) + debug = atoi(f[1]); + else{ + respond(r, "invalid ctl message"); + return; + } + } + r->ofcall.count = sz; + respond(r, nil); +} + +static Srv fs = { + .read = fsread, + .write = fswrite, +}; + +static void usage(void) { fprint(2, "usage: %s [-d] devid\n", argv0); @@ -911,10 +1023,11 @@ usage(void) void threadmain(int argc, char* argv[]) { - int i; + int i, n; Dev *d; Ep *ep; Usbdev *ud; + char buf[32]; ARGBEGIN{ case 'd': @@ -929,20 +1042,28 @@ threadmain(int argc, char* argv[]) if(d == nil) sysfatal("getdev: %r"); ud = d->usb; - for(i = 0; i < nelem(ud->ep); i++){ + for(i = n = 0; i < nelem(ud->ep); i++){ if((ep = ud->ep[i]) == nil) continue; if(ep->type != Eintr || ep->dir != Ein) continue; switch(ep->iface->csp){ case KbdCSP: + havekbd = 1; case PtrCSP: case PtrNonBootCSP: case HidCSP: - hdsetup(d, ep); + n += hdsetup(d, ep) == 0; break; } } closedev(d); + if(n > 0){ + fs.tree = alloctree(user, "usb", DMDIR|0555, nil); + snprint(buf, sizeof buf, "hidU%sctl", d->hname); + createfile(fs.tree->root, buf, user, 0666, d); + snprint(buf, sizeof buf, "%s.hid", d->hname); + threadpostsharesrv(&fs, nil, "usb", buf); + } threadexits(nil); } |