ref: a8ad9632ff7447b8ca448cc23dfbc60f0e36d8ec
parent: 87b61fddf25d5a3278509e636ab7328ac582d9a0
parent: c33588da6fc879d6c355cd1df29b4c1a8f75f854
author: cinap_lenrek <cinap_lenrek@felloff.net>
date: Mon May 22 16:15:37 EDT 2023
merge...
--- a/sys/man/1/kbmap
+++ b/sys/man/1/kbmap
@@ -1,11 +1,22 @@
.TH KBMAP 1
.SH NAME
-kbmap \- show a list of available keyboard maps and switch between them.
+kbmap, kbremap \- show a list of available keyboard maps and switch between them.
.SH SYNOPSIS
.B kbmap
[
.IR file ...
]
+.PP
+.B kbremap
+[
+.B -m
+.I mod
+]
+[
+.B -k
+.I scancode
+]
+map1 map2 ...
.SH DESCRIPTION
.I Kbmap
shows a single column consisting of the names of keyboard maps for different
@@ -18,16 +29,49 @@
keyboard mapping defined in the corresponding file to become current
for the system; typing 'q' quits.
.PP
+.I Kbremap
+reads keyboard events from standard input, filters out a shortcut
+to change the keyboard map, and writes the result to standard
+output. The shortcut cycles through the keyboard maps provided
+as arguments. By default this shortcut is mapped to
+.LR Ctrl
++
+.LR Space .
+The
+.B -m
+and
+.B -k
+flags change the default mod and key used respectfully.
+.I Mod
+is given as a numeric shift layer as understood by
+.IR kbdfs (8).
+.PP
.I Kbmap
-requires that the file
+and
+.I kbremap
+require that the file
.B /dev/kbmap
served by
.IR kbdfs (8)
exists and is writable.
-..SH FILES
-.TF /lib/kbmap/*
+.SH EXAMPLES
+Use
+.I kbremap
+with
+.B /dev/kbdtap
+provided by
+.IR rio (4):
+.IP
+.EX
+kbremap us de uk </dev/kbdtap >/dev/kbdtap
+.EE
+.PP
+.SH FILES
+.B /sys/lib/kbmap/*
.SH SOURCE
.B /sys/src/cmd/kbmap.c
+.br
+.B /sys/src/cmd/kbremap.c
.SH "SEE ALSO"
.IR kbdfs (8)
.SH BUGS
--- a/sys/src/cmd/aux/acpi.c
+++ b/sys/src/cmd/aux/acpi.c
@@ -9,6 +9,7 @@
typedef struct Bat Bat;
typedef struct Tbl Tbl;
typedef struct Therm Therm;
+typedef struct FACP FACP;
struct Batstat {
int rate;
@@ -45,6 +46,31 @@
void *tmp;
};
+struct FACP {
+ int ok;
+
+ uvlong pm1a;
+ int pm1aspace;
+ int pm1awid;
+
+ uvlong pm1b;
+ int pm1bspace;
+ int pm1bwid;
+
+ uvlong gpe0;
+ ulong gpe0len;
+ int gpe0space;
+ int gpe0wid;
+
+ uvlong gpe1;
+ ulong gpe1len;
+ int gpe1space;
+ int gpe1wid;
+
+ ulong slpa;
+ ulong slpb;
+};
+
enum {
Tblsz = 4+4+1+1+6+8+4+4+4,
@@ -56,12 +82,11 @@
SLP_TM = 0x1c00,
};
-static ulong PM1a_CNT_BLK, PM1b_CNT_BLK, SLP_TYPa, SLP_TYPb;
-static ulong GPE0_BLK, GPE1_BLK, GPE0_BLK_LEN, GPE1_BLK_LEN;
-static int ec, mem, iofd[5], nbats, ntherms, facp;
+static int ec, mem, iofd[5], nbats, ntherms;
static char *uid = "pm", *units[] = {"mW", "mA"};
static Therm therms[16];
static Bat bats[4];
+static FACP facp;
static int
enumec(void *dot, void *)
@@ -240,16 +265,32 @@
close(ctl);
}
+static ulong
+get32(uchar *p)
+{
+ return p[3]<<24 | p[2]<<16 | p[1]<<8 | p[0];
+}
+
+static uvlong
+get64(uchar *p)
+{
+ return ((uvlong)p[7]<<56) | ((uvlong)p[6]<<48)
+ | ((uvlong)p[5]<<40) | ((uvlong)p[4]<<32)
+ | ((uvlong)p[3]<<24) | ((uvlong)p[2]<<16)
+ | ((uvlong)p[1]<<8) | ((uvlong)p[0]);
+}
+
static void
-outw(long addr, ushort val)
+amlwrite(Amlio *io, int addr, int wid, uvlong v)
{
- uchar buf[2];
+ uchar b[8];
- if(addr == 0)
- return;
- buf[0] = val;
- buf[1] = val >> 8;
- pwrite(iofd[2], buf, 2, addr);
+ b[0] = v; b[1] = v >> 8;
+ b[2] = v >> 16; b[3] = v >> 24;
+ b[4] = v >> 32; b[5] = v >> 40;
+ b[6] = v >> 48; b[7] = v >> 56;
+
+ (*io->write)(io, b, 1<<(wid-1), addr);
}
static void
@@ -256,8 +297,10 @@
poweroff(void)
{
int n;
+ void *tts, *pts;
+ Amlio ioa, iob;
- if(facp == 0){
+ if(facp.ok == 0){
werrstr("no FACP");
return;
}
@@ -264,18 +307,43 @@
wirecpu0();
+ /* The ACPI spec requires we call _TTS and _PTS to prepare
+ * the system to go to _S5 state. If they fail, too bad,
+ * try to go to _S5 state anyway. */
+ pts = amlval(amlwalk(amlroot, "_PTS"));
+ tts = amlval(amlwalk(amlroot, "_TTS"));
+ if(pts)
+ amleval(pts, "i", 5, nil);
+ if(tts)
+ amleval(tts, "i", 5, nil);
+
/* disable GPEs */
- for(n = 0; GPE0_BLK > 0 && n < GPE0_BLK_LEN/2; n += 2){
- outw(GPE0_BLK + GPE0_BLK_LEN/2 + n, 0); /* EN */
- outw(GPE0_BLK + n, 0xffff); /* STS */
+ ioa.space = facp.gpe0space;
+ iob.space = facp.gpe1space;
+ ioa.off = facp.gpe0;
+ iob.off = facp.gpe1;
+ amlmapio(&ioa);
+ amlmapio(&iob);
+
+ for(n = 0; facp.gpe0 > 0 && n < facp.gpe0len/2; n += facp.gpe0wid){
+ amlwrite(&ioa, facp.gpe0len/2 + n, facp.gpe0wid, 0);
+ amlwrite(&ioa, n, facp.gpe0wid, ~0);
}
- for(n = 0; GPE1_BLK > 0 && n < GPE1_BLK_LEN/2; n += 2){
- outw(GPE1_BLK + GPE1_BLK_LEN/2 + n, 0); /* EN */
- outw(GPE1_BLK + n, 0xffff); /* STS */
+
+ for(n = 0; facp.gpe1 > 0 && n < facp.gpe1len/2; n += facp.gpe1wid){
+ amlwrite(&iob, facp.gpe1len/2 + n, facp.gpe1wid, 0);
+ amlwrite(&iob, n, facp.gpe1wid, ~0);
}
- outw(PM1a_CNT_BLK, ((SLP_TYPa << 10) & SLP_TM) | SLP_EN);
- outw(PM1b_CNT_BLK, ((SLP_TYPb << 10) & SLP_TM) | SLP_EN);
+ ioa.space = facp.pm1aspace;
+ iob.space = facp.pm1bspace;
+ ioa.off = facp.pm1a;
+ iob.off = facp.pm1b;
+ amlmapio(&ioa);
+ amlmapio(&iob);
+
+ amlwrite(&ioa, 0, facp.pm1awid, ((facp.slpa << 10) & SLP_TM) | SLP_EN);
+ amlwrite(&iob, 0, facp.pm1bwid, ((facp.slpb << 10) & SLP_TM) | SLP_EN);
sleep(100);
/*
@@ -287,9 +355,10 @@
* PM1a_CNT_BLK seems to have no effect but 0x7 seems
* to work fine. So trying the following as a last effort.
*/
- SLP_TYPa |= SLP_TYPb;
- outw(PM1a_CNT_BLK, ((SLP_TYPa << 10) & SLP_TM) | SLP_EN);
- outw(PM1b_CNT_BLK, ((SLP_TYPa << 10) & SLP_TM) | SLP_EN);
+
+ facp.slpa |= facp.slpb;
+ amlwrite(&ioa, 0, facp.pm1awid, ((facp.slpa << 10) & SLP_TM) | SLP_EN);
+ amlwrite(&iob, 0, facp.pm1bwid, ((facp.slpa << 10) & SLP_TM) | SLP_EN);
sleep(100);
werrstr("acpi failed");
@@ -360,12 +429,8 @@
.write = fswrite,
};
-static ulong
-get32(uchar *p)
-{
- return p[3]<<24 | p[2]<<16 | p[1]<<8 | p[0];
-}
+
void
threadmain(int argc, char **argv)
{
@@ -431,19 +496,58 @@
}else if(memcmp("SSDT", t->sig, 4) == 0){
amlload(t->data, l);
}else if(memcmp("FACP", t->sig, 4) == 0){
- facp = 1;
- PM1a_CNT_BLK = get32(((uchar*)t) + 64);
- PM1b_CNT_BLK = get32(((uchar*)t) + 68);
- GPE0_BLK = get32(((uchar*)t) + 80);
- GPE1_BLK = get32(((uchar*)t) + 84);
- GPE0_BLK_LEN = *(((uchar*)t) + 92);
- GPE1_BLK_LEN = *(((uchar*)t) + 93);
+ facp.ok = 1;
+ if(t->rev >= 2) {
+ /* try the ACPI 2.0 method */
+ facp.pm1aspace = *(((uchar*)t) + 172);
+ facp.pm1awid = *(((uchar*)t) + 175);
+ facp.pm1a = get64(((uchar*)t) + 176);
+
+ facp.pm1bspace = *(((uchar*)t) + 184);
+ facp.pm1bwid = *(((uchar*)t) + 187);
+ facp.pm1b = get64(((uchar*)t) + 188);
+
+ facp.gpe0space = *(((uchar*)t) + 220);
+ facp.gpe0wid = *(((uchar*)t) + 223);
+ facp.gpe0 = get64(((uchar*)t) + 224);
+
+ facp.gpe1space = *(((uchar*)t) + 232);
+ facp.gpe1wid = *(((uchar*)t) + 235);
+ facp.gpe1 = get64(((uchar*)t) + 236);
+ }
+
+ /* fall back to the ACPI 1.0 io port method */
+ if(!facp.pm1a) {
+ facp.pm1aspace = IoSpace;
+ facp.pm1awid = 2;
+ facp.pm1a = get32(((uchar*)t) + 64);
+ }
+
+ if(!facp.pm1b) {
+ facp.pm1bspace = IoSpace;
+ facp.pm1bwid = 2;
+ facp.pm1b = get32(((uchar*)t) + 68);
+ }
+
+ if(!facp.gpe0) {
+ facp.gpe0space = IoSpace;
+ facp.gpe0wid = 2;
+ facp.gpe0 = get32(((uchar*)t) + 80);
+ facp.gpe0len = *(((uchar*)t) + 92);
+ }
+
+ if(!facp.gpe1) {
+ facp.gpe1space = IoSpace;
+ facp.gpe1wid = 2;
+ facp.gpe1 = get32(((uchar*)t) + 84);
+ facp.gpe1len = *(((uchar*)t) + 93);
+ }
}
}
if(amleval(amlwalk(amlroot, "_S5"), "", &r) >= 0 && amltag(r) == 'p' && amllen(r) >= 2){
rr = amlval(r);
- SLP_TYPa = amlint(rr[0]);
- SLP_TYPb = amlint(rr[1]);
+ facp.slpa = amlint(rr[0]);
+ facp.slpb = amlint(rr[1]);
}
close(fd);
--- a/sys/src/cmd/ip/ppp/ipaux.c
+++ b/sys/src/cmd/ip/ppp/ipaux.c
@@ -8,10 +8,18 @@
ptclcsum(Block *bp, int offset, int len)
{
uchar *addr;
- int blen;
+ ulong losum, hisum;
+ ushort csum;
+ int odd, blen, x;
- if(bp == nil || bp->rptr + offset >= bp->wptr)
+ /* Correct to front of data area */
+ while(bp != nil && offset && offset >= BLEN(bp)) {
+ offset -= BLEN(bp);
+ bp = bp->next;
+ }
+ if(bp == nil)
return 0;
+
addr = bp->rptr + offset;
blen = BLEN(bp) - offset;
if(blen < len)
--- a/sys/src/cmd/ip/tftpd.c
+++ b/sys/src/cmd/ip/tftpd.c
@@ -204,7 +204,7 @@
exits(0);
remoteaddr(ldir, raddr, sizeof(raddr));
pid = getpid();
- syslog(0, flog, "tftp %d connection from %s dir %s",
+ syslog(0, flog, "tftpd %d connection from %s dir %s",
pid, raddr, ldir);
doserve(dfd);
exits("done");
@@ -227,7 +227,7 @@
n = strtol(val, nil, 10);
if (n < op->min || n > op->max) {
nak(fd, Errbadopt, "option value out of range");
- syslog(dbg, flog, "tftp bad option value from "
+ syslog(dbg, flog, "tftpd bad option value from "
"client: %s %s", name, val);
sysfatal("bad option value from client: %s %s",
name, val);
--- /dev/null
+++ b/sys/src/cmd/kbremap.c
@@ -1,0 +1,80 @@
+#include <u.h>
+#include <libc.h>
+
+char *mod = "4";
+char *key = "57";
+enum{ Kswitch = 0xF000|0x0701 };
+
+static void
+writemap(char *file)
+{
+ int i, fd, ofd;
+ char buf[8192];
+
+ if((fd = open(file, OREAD)) < 0)
+ sysfatal("cannot open %s: %r", file);
+
+ if((ofd = open("/dev/kbmap", OWRITE)) < 0)
+ sysfatal("cannot open /dev/kbmap: %r");
+
+ while((i = read(fd, buf, sizeof buf)) > 0)
+ if(write(ofd, buf, i) != i)
+ sysfatal("writing /dev/kbmap: %r");
+
+ fprint(ofd, "%s\t%s\t0x%X\n", mod, key, Kswitch);
+ close(fd);
+ close(ofd);
+}
+
+void
+usage(void)
+{
+ fprint(2, "usage: %s [ -m mod ] [ -k scancode ] map1 map2 ...\n", argv0);
+ exits("usage");
+}
+
+void
+main(int argc, char **argv)
+{
+ char *p, buf[8192];
+ Rune r;
+ long n;
+ int index;
+
+ index = 0;
+ ARGBEGIN{
+ case 'm':
+ mod = EARGF(usage());
+ break;
+ case 'k':
+ key = EARGF(usage());
+ break;
+ default:
+ usage();
+ }ARGEND;
+ if(argc < 2)
+ usage();
+
+ chdir("/sys/lib/kbmap");
+ writemap("ascii");
+ writemap(argv[0]);
+ for(;;){
+ n = read(0, buf, sizeof buf - 1);
+ if(n <= 0)
+ break;
+ buf[n] = '\0';
+ for(p = buf; p < buf+n; p += strlen(p) + 1){
+ chartorune(&r, p+1);
+ if(*p != 'c' || r != Kswitch){
+ write(1, p, strlen(p));
+ continue;
+ }
+ index++;
+ if(argv[index] == nil)
+ index = 0;
+ writemap("ascii");
+ writemap(argv[index]);
+ }
+ }
+ exits(nil);
+}
--- a/sys/src/cmd/nusb/ether/ether.c
+++ b/sys/src/cmd/nusb/ether/ether.c
@@ -642,15 +642,18 @@
ctlif = datif = nil;
for(j = 0; j < nelem(c->iface); j++){
for(iface = c->iface[j]; iface != nil; iface = iface->next){
- if(iface->id == ctlid)
+ if(ctlif == nil && iface->id == ctlid)
ctlif = iface;
- if(iface->id == datid)
+ if(datif == nil && iface->id == datid)
datif = iface;
}
if(datif != nil && ctlif != nil){
- if(Subclass(ctlif->csp) == Scether)
+ if(Subclass(ctlif->csp) == Scether) {
+ if(setconf(d, c) < 0)
+ break;
if(ifaceinit(d, datif, ein, eout) != -1)
return 0;
+ }
break;
}
}
@@ -659,6 +662,8 @@
/* try any other one that seems to be ok */
for(i = 0; i < nelem(ud->conf); i++){
if((c = ud->conf[i]) != nil){
+ if(setconf(d, c) < 0)
+ break;
for(j = 0; j < nelem(c->iface); j++){
for(datif = c->iface[j]; datif != nil; datif = datif->next){
if(ifaceinit(d, datif, ein, eout) != -1)
--- a/sys/src/cmd/nusb/lib/dev.c
+++ b/sys/src/cmd/nusb/lib/dev.c
@@ -483,6 +483,16 @@
}
int
+setconf(Dev *d, Conf *c)
+{
+ if(usbcmd(d, Rh2d|Rstd|Rdev, Rsetconf, c->cval, 0, nil, 0) > 0) {
+ werrstr("setconf: %s: %r", d->dir);
+ return -1;
+ }
+ return 0;
+}
+
+int
setalt(Dev *d, Iface *ifc)
{
if(usbcmd(d, Rh2d|Rstd|Riface, Rsetiface, ifc->alt, ifc->id, nil, 0) < 0){
--- a/sys/src/cmd/nusb/lib/usb.h
+++ b/sys/src/cmd/nusb/lib/usb.h
@@ -353,6 +353,7 @@
int unstall(Dev *dev, Dev *ep, int dir);
int usbcmd(Dev *d, int type, int req, int value, int index, uchar *data, int count);
Dev* getdev(char *devid);
+int setconf(Dev *d, Conf *c);
int setalt(Dev *d, Iface *ifc);
extern int usbdebug; /* more messages for bigger values */
--- a/sys/src/cmd/riow.c
+++ b/sys/src/cmd/riow.c
@@ -444,7 +444,7 @@
main(int argc, char **argv)
{
char b[128];
- int i, j, n;
+ int i, j, n, r;
for(n = 0; sticky[n] != nil; n++)
;
@@ -468,18 +468,19 @@
ws[i].vd = vd;
fprint(3, "%d\n", vd);
- for(i = 0;;){
- if((n = read(0, b+i, sizeof(b)-i)) <= 0)
+ for(n = 0;;){
+ if((r = read(0, b+n, sizeof(b)-n-1)) <= 0)
break;
- n += i;
- for(j = 0; j < n; j++){
+ n += r;
+ b[n] = 0;
+ for(i = j = 0; j <= n; j++){
if(b[j] == 0){
process(b+i);
i = j+1;
}
}
- memmove(b, b+i, j-i);
- i -= j;
+ n = j-i;
+ memmove(b, b+i, n);
}
exits(nil);
--- a/sys/src/libaml/aml.c
+++ b/sys/src/libaml/aml.c
@@ -150,7 +150,7 @@
Oindex, Omatch, Omutex, Oevent,
Ocfld, Ocfld0, Ocfld1, Ocfld2, Ocfld4, Ocfld8,
Oif, Oelse, Owhile, Obreak, Oret, Ocall,
- Ostore, Oderef, Ootype, Osize, Oref, Ocref, Ocat,
+ Ostore, Oderef, Ootype, Osize, Oref, Ocref, Ocat, Ocatr, Omid,
Oacq, Osignal, Orel, Ostall, Osleep, Oload, Ounload,
Otodec, Otohex, Otoint, Otostr,
};
@@ -1711,6 +1711,66 @@
}
static void*
+evalcatres(void)
+{
+ void *r, *a, *b;
+ int n, m;
+ uchar c[2];
+
+ a = FP->arg[0];
+ b = FP->arg[1];
+ if(a == nil)
+ a = copy('b', a);
+ if(b == nil)
+ b = copy('b', b);
+ if(TAG(a) != 'b' || TAG(b) != 'b')
+ return nil;
+
+ n = SIZE(a);
+ m = SIZE(b);
+ r = mk('b', n + m + 2);
+ memmove(r, a, n);
+ memmove((uchar*)r + n, b, m);
+
+ c[0] = 0x78;
+ c[1] = 0;
+ memmove((uchar*)r + n + m, c, 2);
+
+ store(r, FP->arg[2]);
+ return r;
+}
+
+static void*
+evalmid(void)
+{
+ void *r, *a;
+ int n, m;
+
+ a = FP->arg[1];
+ n = ival(FP->arg[1]);
+ m = ival(FP->arg[2]);
+ if(a == nil)
+ a = copy('b', a);
+
+ switch(TAG(a)) {
+ default:
+ return nil; /* botch */
+ case 's':
+ case 'b':
+ if(n > SIZE(a))
+ n = SIZE(a);
+ if((n + m) > SIZE(a))
+ m = SIZE(a) - n;
+
+ r = mk(TAG(a), m); memmove(r, (uchar*)a + n, m);
+ break;
+ }
+
+ store(r, FP->arg[3]);
+ return r;
+}
+
+static void*
evalindex(void)
{
Field *f;
@@ -2150,6 +2210,8 @@
[Ocref] "CondRefOf", "@@", evalcondref,
[Oderef] "DerefOf", "@", evalderef,
[Ocat] "Concatenate", "**@", evalcat,
+ [Ocatr] "ConcatenateRes", "***", evalcatres,
+ [Omid] "Mid", "*ii@", evalmid,
[Oacq] "Acquire", "@2", evalnop,
[Osignal] "Signal", "@", evalnop,
@@ -2182,10 +2244,10 @@
/* 68 */ Oenv, Oenv, Oenv, Oenv, Oenv, Oenv, Oenv, Obad,
/* 70 */ Ostore, Oref, Oadd, Ocat, Osub, Oinc, Odec, Omul,
/* 78 */ Odiv, Oshl, Oshr, Oand, Onand, Oor, Onor, Oxor,
-/* 80 */ Onot, Olbit, Orbit, Oderef, Obad, Omod, Obad, Osize,
+/* 80 */ Onot, Olbit, Orbit, Oderef, Ocatr, Omod, Obad, Osize,
/* 88 */ Oindex, Omatch, Ocfld4, Ocfld2, Ocfld1, Ocfld0, Ootype, Ocfld8,
/* 90 */ Oland, Olor, Olnot, Oleq, Olgt, Ollt, Obad, Otodec,
-/* 98 */ Otohex, Otoint, Obad, Obad, Otostr, Obad, Obad, Obad,
+/* 98 */ Otohex, Otoint, Obad, Obad, Otostr, Obad, Omid, Obad,
/* A0 */ Oif, Oelse, Owhile, Onop, Oret, Obreak, Obad, Obad,
/* A8 */ Obad, Obad, Obad, Obad, Obad, Obad, Obad, Obad,
/* B0 */ Obad, Obad, Obad, Obad, Obad, Obad, Obad, Obad,