1 /* 2 * USB Human Interaction Device: keyboard and mouse. 3 * 4 * If there's no usb keyboard, it tries to setup the mouse, if any. 5 * It should be started at boot time. 6 * 7 * Mouse events are converted to the format of mouse(3)'s 8 * mousein file. 9 * Keyboard keycodes are translated to scan codes and sent to kbin(3). 10 * 11 */ 12 13 #include <u.h> 14 #include <libc.h> 15 #include <thread.h> 16 #include "usb.h" 17 #include "hid.h" 18 19 /* 20 * Map for the logitech bluetooth mouse with 8 buttons and wheels. 21 * { ptr ->mouse} 22 * { 0x01, 0x01 }, // left 23 * { 0x04, 0x02 }, // middle 24 * { 0x02, 0x04 }, // right 25 * { 0x40, 0x08 }, // up 26 * { 0x80, 0x10 }, // down 27 * { 0x10, 0x08 }, // side up 28 * { 0x08, 0x10 }, // side down 29 * { 0x20, 0x02 }, // page 30 * besides wheel and regular up/down report the 4th byte as 1/-1 31 */ 32 33 /* 34 * key code to scan code; for the page table used by 35 * the logitech bluetooth keyboard. 36 */ 37 char sctab[256] = 38 { 39 [0x00] 0x0, 0x0, 0x0, 0x0, 0x1e, 0x30, 0x2e, 0x20, 40 [0x08] 0x12, 0x21, 0x22, 0x23, 0x17, 0x24, 0x25, 0x26, 41 [0x10] 0x32, 0x31, 0x18, 0x19, 0x10, 0x13, 0x1f, 0x14, 42 [0x18] 0x16, 0x2f, 0x11, 0x2d, 0x15, 0x2c, 0x2, 0x3, 43 [0x20] 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa, 0xb, 44 [0x28] 0x1c, 0x1, 0xe, 0xf, 0x39, 0xc, 0xd, 0x1a, 45 [0x30] 0x1b, 0x2b, 0x2b, 0x27, 0x28, 0x29, 0x33, 0x34, 46 [0x38] 0x35, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 0x40, 47 [0x40] 0x41, 0x42, 0x43, 0x44, 0x57, 0x58, 0x63, 0x46, 48 [0x48] 0x77, 0x52, 0x47, 0x49, 0x53, 0x4f, 0x51, 0x4d, 49 [0x50] 0x4b, 0x50, 0x48, 0x45, 0x35, 0x37, 0x4a, 0x4e, 50 [0x58] 0x1c, 0x4f, 0x50, 0x51, 0x4b, 0x4c, 0x4d, 0x47, 51 [0x60] 0x48, 0x49, 0x52, 0x53, 0x56, 0x7f, 0x74, 0x75, 52 [0x68] 0x55, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, 53 [0x70] 0x78, 0x79, 0x7a, 0x7b, 0x0, 0x0, 0x0, 0x0, 54 [0x78] 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x71, 55 [0x80] 0x73, 0x72, 0x0, 0x0, 0x0, 0x7c, 0x0, 0x0, 56 [0x88] 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 57 [0x90] 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 58 [0x98] 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 59 [0xa0] 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 60 [0xa8] 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 61 [0xb0] 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 62 [0xb8] 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 63 [0xc0] 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 64 [0xc8] 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 65 [0xd0] 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 66 [0xd8] 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 67 [0xe0] 0x1d, 0x2a, 0x38, 0x7d, 0x61, 0x36, 0x64, 0x7e, 68 [0xe8] 0x0, 0x0, 0x0, 0x0, 0x0, 0x73, 0x72, 0x71, 69 [0xf0] 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 70 [0xf8] 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 71 }; 72 73 typedef struct Dev Dev; 74 struct Dev { 75 char* name; /* debug */ 76 void (*proc)(void*); /* handler process */ 77 int csp; /* the csp we want */ 78 int enabled; /* can we start it? */ 79 int ctlrno; /* controller number, for probing*/ 80 int id; /* device id, for probing*/ 81 int ep; /* endpoint used to get events */ 82 int msz; /* message size */ 83 int fd; /* to the endpoint data file */ 84 Device* dev; /* usb device*/ 85 }; 86 87 88 Dev kf, pf; /* kbd and pointer drivers*/ 89 Channel *repeatc; /* channel to request key repeating*/ 90 91 void (*dprinter[])(Device *, int, ulong, void *b, int n) = { 92 [STRING] pstring, 93 [DEVICE] pdevice, 94 [HID] phid, 95 }; 96 97 int accel; 98 int hdebug; 99 int dryrun; 100 int verbose; 101 102 int mainstacksize = 32*1024; 103 104 int 105 robusthandler(void*, char *s) 106 { 107 if(hdebug) 108 fprint(2, "inthandler: %s\n", s); 109 return (s && (strstr(s, "interrupted")|| strstr(s, "hangup"))); 110 } 111 112 long 113 robustread(int fd, void *buf, long sz) 114 { 115 long r; 116 char err[ERRMAX]; 117 118 do { 119 r = read(fd , buf, sz); 120 if(r < 0) 121 rerrstr(err, sizeof err); 122 } while(r < 0 && robusthandler(nil, err)); 123 return r; 124 } 125 126 static int 127 scale(int x) 128 { 129 int sign = 1; 130 131 if(x < 0){ 132 sign = -1; 133 x = -x; 134 } 135 switch(x){ 136 case 0: 137 case 1: 138 case 2: 139 case 3: 140 break; 141 case 4: 142 x = 6 + (accel>>2); 143 break; 144 case 5: 145 x = 9 + (accel>>1); 146 break; 147 default: 148 x *= MaxAcc; 149 break; 150 } 151 return sign*x; 152 } 153 154 void 155 ptrwork(void* a) 156 { 157 int x, y, b, c, mfd, ptrfd; 158 char buf[32]; 159 Dev* f = a; 160 static char maptab[] = {0x0, 0x1, 0x4, 0x5, 0x2, 0x3, 0x6, 0x7}; 161 162 ptrfd = f->fd; 163 if(ptrfd < 0) 164 return; 165 mfd = -1; 166 if(f->msz < 3 || f->msz > sizeof buf) 167 sysfatal("bug: ptrwork: bad mouse maxpkt"); 168 if(!dryrun){ 169 mfd = open("#m/mousein", OWRITE); 170 if(mfd < 0) 171 sysfatal("%s: mousein: %r", f->name); 172 } 173 for(;;){ 174 memset(buf, 0, sizeof buf); 175 c = robustread(ptrfd, buf, f->msz); 176 if(c == 0) 177 fprint(2, "%s: %s: eof\n", argv0, f->name); 178 if(c < 0) 179 fprint(2, "%s: %s: read: %r\n", argv0, f->name); 180 if(c <= 0){ 181 if(!dryrun) 182 close(mfd); 183 close(f->fd); 184 threadexits("read"); 185 } 186 if(c < 3) 187 continue; 188 if(accel) { 189 x = scale(buf[1]); 190 y = scale(buf[2]); 191 } else { 192 x = buf[1]; 193 y = buf[2]; 194 } 195 b = maptab[buf[0] & 0x7]; 196 if(c > 3 && buf[3] == 1) /* up */ 197 b |= 0x08; 198 if(c > 3 && buf[3] == -1) /* down */ 199 b |= 0x10; 200 if(hdebug) 201 fprint(2, "%s: %s: m%11d %11d %11d\n", 202 argv0, f->name, x, y, b); 203 if(!dryrun) 204 if(fprint(mfd, "m%11d %11d %11d", x, y, b) < 0){ 205 fprint(2, "%s: #m/mousein: write: %r", argv0); 206 close(mfd); 207 close(f->fd); 208 threadexits("write"); 209 } 210 } 211 } 212 213 static void 214 stoprepeat(void) 215 { 216 sendul(repeatc, Awakemsg); 217 } 218 219 static void 220 startrepeat(uchar esc1, uchar sc) 221 { 222 ulong c; 223 224 if(esc1) 225 c = SCesc1 << 8 | (sc & 0xff); 226 else 227 c = sc; 228 sendul(repeatc, c); 229 } 230 231 static int kbinfd = -1; 232 233 static void 234 putscan(uchar esc, uchar sc) 235 { 236 static uchar s[2] = {SCesc1, 0}; 237 238 if(sc == 0x41){ 239 hdebug = 1; 240 return; 241 } 242 if(sc == 0x42){ 243 hdebug = 0; 244 return; 245 } 246 if(kbinfd < 0 && !dryrun) 247 kbinfd = open("#Ι/kbin", OWRITE); 248 if(kbinfd < 0 && !dryrun) 249 sysfatal("/dev/kbin: %r"); 250 if(hdebug) 251 fprint(2, "sc: %x %x\n", (esc? SCesc1: 0), sc); 252 if(!dryrun){ 253 s[1] = sc; 254 if(esc && sc != 0) 255 write(kbinfd, s, 2); 256 else if(sc != 0) 257 write(kbinfd, s+1, 1); 258 } 259 } 260 261 static void 262 repeatproc(void*) 263 { 264 ulong l; 265 uchar esc1, sc; 266 267 assert(sizeof(int) <= sizeof(void*)); 268 269 for(;;){ 270 l = recvul(repeatc); /* wait for work*/ 271 if(l == 0xdeaddead) 272 continue; 273 esc1 = l >> 8; 274 sc = l; 275 for(;;){ 276 putscan(esc1, sc); 277 sleep(80); 278 l = nbrecvul(repeatc); 279 if(l != 0){ /* stop repeating*/ 280 if(l != Awakemsg) 281 fprint(2, "kb: race: should be awake mesg\n"); 282 break; 283 } 284 } 285 } 286 } 287 288 289 #define hasesc1(sc) (((sc) > 0x47) || ((sc) == 0x38)) 290 291 static void 292 putmod(uchar mods, uchar omods, uchar mask, uchar esc, uchar sc) 293 { 294 if((mods&mask) && !(omods&mask)) 295 putscan(esc, sc); 296 if(!(mods&mask) && (omods&mask)) 297 putscan(esc, Keyup|sc); 298 } 299 300 /* 301 * This routine diffs the state with the last known state 302 * and invents the scan codes that would have been sent 303 * by a non-usb keyboard in that case. This also requires supplying 304 * the extra esc1 byte as well as keyup flags. 305 * The aim is to allow future addition of other keycode pages 306 * for other keyboards. 307 */ 308 static void 309 putkeys(uchar buf[], uchar obuf[], int n) 310 { 311 int i, j; 312 uchar sc; 313 static int repeating = 0, times = 0; 314 static uchar last = 0; 315 316 putmod(buf[0], obuf[0], Mctrl, 0, SCctrl); 317 putmod(buf[0], obuf[0], (1<<Mlshift), 0, SClshift); 318 putmod(buf[0], obuf[0], (1<<Mrshift), 0, SCrshift); 319 putmod(buf[0], obuf[0], Mcompose, 0, SCcompose); 320 putmod(buf[0], obuf[0], Maltgr, 1, SCcompose); 321 322 /* 323 * If we get three times the same (single) key, we start 324 * repeating. Otherwise, we stop repeating and 325 * perform normal processing. 326 */ 327 if(buf[2] != 0 && buf[3] == 0 && buf[2] == last){ 328 if(repeating) 329 return; /* already being done */ 330 times++; 331 if(times >= 2){ 332 repeating = 1; 333 sc = sctab[buf[2]]; 334 startrepeat(hasesc1(sc), sc); 335 return; 336 } 337 } else 338 times = 0; 339 last = buf[2]; 340 if(repeating){ 341 repeating = 0; 342 stoprepeat(); 343 } 344 345 /* Report key downs */ 346 for(i = 2; i < n; i++){ 347 for(j = 2; j < n; j++) 348 if(buf[i] == obuf[j]) 349 break; 350 if(j == n && buf[i] != 0){ 351 sc = sctab[buf[i]]; 352 putscan(hasesc1(sc), sc); 353 } 354 } 355 356 /* Report key ups */ 357 for(i = 2; i < n; i++){ 358 for(j = 2; j < n; j++) 359 if(obuf[i] == buf[j]) 360 break; 361 if(j == n && obuf[i] != 0){ 362 sc = sctab[obuf[i]]; 363 putscan(hasesc1(sc), sc|Keyup); 364 } 365 } 366 } 367 368 static int 369 kbdbusy(uchar* buf, int n) 370 { 371 int i; 372 373 for(i = 1; i < n; i++) 374 if(buf[i] == 0 || buf[i] != buf[0]) 375 return 0; 376 return 1; 377 } 378 379 void 380 kbdwork(void *a) 381 { 382 int c, i, kbdfd; 383 uchar buf[64], lbuf[64]; 384 Dev *f = a; 385 386 kbdfd = f->fd; 387 if(kbdfd < 0) 388 return; 389 if(f->msz < 3 || f->msz > sizeof buf) 390 sysfatal("bug: ptrwork: bad kbd maxpkt"); 391 repeatc = chancreate(sizeof(ulong), 0); 392 if(repeatc == nil) 393 sysfatal("repeat chan: %r"); 394 proccreate(repeatproc, nil, 32*1024); 395 memset(lbuf, 0, sizeof lbuf); 396 for(;;) { 397 memset(buf, 0, sizeof buf); 398 c = robustread(kbdfd, buf, f->msz); 399 if(c == 0) 400 fprint(2, "%s: %s: eof\n", argv0, f->name); 401 if(c < 0) 402 fprint(2, "%s: %s: read: %r\n", argv0, f->name); 403 if(c <= 0){ 404 if(!dryrun) 405 close(kbinfd); 406 close(f->fd); 407 threadexits("read"); 408 } 409 if(c < 3) 410 continue; 411 if(kbdbusy(buf + 2, c - 2)) 412 continue; 413 if(hdebug > 1){ 414 fprint(2, "kbd mod %x: ", buf[0]); 415 for(i = 2; i < c; i++) 416 fprint(2, "kc %x ", buf[i]); 417 fprint(2, "\n"); 418 } 419 putkeys(buf, lbuf, f->msz); 420 memmove(lbuf, buf, c); 421 } 422 } 423 424 static int 425 probeif(Dev* f, int ctlrno, int i, int kcsp, int csp, int, int) 426 { 427 int found, n, sfd; 428 char buf[256], cspstr[50], kcspstr[50]; 429 430 seprint(cspstr, cspstr + sizeof cspstr, "0x%0.06x", csp); 431 seprint(buf, buf + sizeof buf, "/dev/usb%d/%d/status", ctlrno, i); 432 sfd = open(buf, OREAD); 433 if(sfd < 0) 434 return -1; 435 n = read(sfd, buf, sizeof buf - 1); 436 if(n <= 0){ 437 close(sfd); 438 return -1; 439 } 440 buf[n] = 0; 441 close(sfd); 442 /* 443 * Mouse + keyboard combos may report the interface as Kbdcsp, 444 * because it's the endpoint the one with the right csp. 445 */ 446 sprint(cspstr, "Enabled 0x%0.06x", csp); 447 found = (strncmp(buf, cspstr, strlen(cspstr)) == 0); 448 if(!found){ 449 sprint(cspstr, " 0x%0.06x", csp); 450 sprint(kcspstr, "Enabled 0x%0.06x", kcsp); 451 if(strncmp(buf, kcspstr, strlen(kcspstr)) == 0 && 452 strstr(buf, cspstr) != nil) 453 found = 1; 454 } 455 if(found){ 456 f->ctlrno = ctlrno; 457 f->id = i; 458 f->enabled = 1; 459 if(hdebug) 460 fprint(2, "%s: csp 0x%x at /dev/usb%d/%d\n", 461 f->name, csp, f->ctlrno, f->id); 462 return 0; 463 } 464 if(hdebug) 465 fprint(2, "%s: not found %s\n", f->name, cspstr); 466 return -1; 467 468 } 469 470 static int 471 probedev(Dev* f, int kcsp, int csp, int vid, int did) 472 { 473 int c, i; 474 475 for(c = 0; c < 16; c++) 476 if(f->ctlrno == 0 || c == f->ctlrno) 477 for(i = 1; i < 128; i++) 478 if(f->id == 0 || i == f->id) 479 if(probeif(f, c, i, kcsp, csp, vid, did) != -1){ 480 f->csp = csp; 481 return 0; 482 } 483 f->enabled = 0; 484 if(hdebug || verbose) 485 fprint(2, "%s: csp 0x%x: not found\n", f->name, csp); 486 return -1; 487 } 488 489 static void 490 initdev(Dev* f) 491 { 492 int i; 493 494 f->dev = opendev(f->ctlrno, f->id); 495 if(f->dev == nil || describedevice(f->dev) < 0) { 496 fprint(2, "init failed: %s: %r\n", f->name); 497 f->enabled = 0; 498 f->ctlrno = f->id = -1; 499 return; 500 } 501 memset(f->dev->config, 0, sizeof f->dev->config); 502 for(i = 0; i < f->dev->nconf; i++){ 503 f->dev->config[i] = mallocz(sizeof *f->dev->config[i], 1); 504 loadconfig(f->dev, i); 505 } 506 if(verbose || hdebug){ 507 fprint(2, "%s found: ctlrno=%d id=%d\n", 508 f->name, f->ctlrno, f->id); 509 // printdevice(f->dev); // TODO 510 } 511 } 512 513 static int 514 setbootproto(Dev* f) 515 { 516 int r, id; 517 Endpt* ep; 518 519 ep = f->dev->ep[0]; 520 r = RH2D | Rclass | Rinterface; 521 id = f->dev->ep[f->ep]->iface->interface; 522 return setupreq(ep, r, SET_PROTO, BOOT_PROTO, id, 0); 523 } 524 525 static void 526 startdev(Dev* f) 527 { 528 int i; 529 char buf[128]; 530 Endpt* ep; 531 532 f->ep = -1; 533 ep = nil; 534 for(i = 0; i < Nendpt; i++) 535 if((ep = f->dev->ep[i]) != nil && 536 ep->csp == f->csp && ep->type == Eintr && ep->dir == Ein){ 537 f->ep = i; 538 f->msz = ep->maxpkt; 539 break; 540 } 541 if(ep == nil){ 542 fprint(2, "%s: %s: bug: no endpoint\n", argv0, f->name); 543 return; 544 } 545 sprint(buf, "ep %d 10 r %d", f->ep, f->msz); 546 if(hdebug) 547 fprint(2, "%s: %s: ep %d: ctl %s\n", argv0, f->name, f->ep, buf); 548 if(write(f->dev->ctl, buf, strlen(buf)) != strlen(buf)){ 549 fprint(2, "%s: %s: startdev: %r\n", argv0, f->name); 550 return; 551 } 552 sprint(buf, "/dev/usb%d/%d/ep%ddata", f->ctlrno, f->id, f->ep); 553 f->fd = open(buf, OREAD); 554 if(f->fd < 0){ 555 fprint(2, "%s: opening %s: %s: %r", argv0, f->name, buf); 556 return; 557 } 558 if(setbootproto(f) < 0) 559 fprint(2, "%s: %s: setbootproto: %r\n", argv0, f->name); 560 if(hdebug) 561 fprint(2, "starting %s\n", f->name); 562 proccreate(f->proc, f, 32*1024); 563 } 564 565 static void 566 usage(void) 567 { 568 fprint(2, "usage: %s [-dkmn] [-a n] [ctlrno usbport]\n", argv0); 569 threadexitsall("usage"); 570 } 571 572 void 573 threadmain(int argc, char **argv) 574 { 575 576 quotefmtinstall(); 577 usbfmtinit(); 578 579 pf.enabled = kf.enabled = 1; 580 ARGBEGIN{ 581 case 'a': 582 accel = strtol(EARGF(usage()), nil, 0); 583 break; 584 case 'd': 585 hdebug++; 586 usbdebug++; 587 break; 588 case 'k': 589 kf.enabled = 1; 590 pf.enabled = 0; 591 break; 592 case 'm': 593 kf.enabled = 0; 594 pf.enabled = 1; 595 break; 596 case 'n': 597 dryrun = 1; 598 break; 599 default: 600 usage(); 601 }ARGEND; 602 603 switch(argc){ 604 case 0: 605 break; 606 case 2: 607 pf.ctlrno = kf.ctlrno = atoi(argv[0]); 608 pf.id = kf.id = atoi(argv[1]); 609 break; 610 default: 611 usage(); 612 } 613 threadnotify(robusthandler, 1); 614 615 kf.name = "kbd"; 616 kf.proc = kbdwork; 617 pf.name = "mouse"; 618 pf.proc = ptrwork; 619 620 if(kf.enabled) 621 probedev(&kf, KbdCSP, KbdCSP, 0, 0); 622 if(kf.enabled) 623 initdev(&kf); 624 if(pf.enabled) 625 probedev(&pf, KbdCSP, PtrCSP, 0, 0); 626 if(pf.enabled) 627 if(kf.enabled && pf.ctlrno == kf.ctlrno && pf.id == kf.id) 628 pf.dev = kf.dev; 629 else 630 initdev(&pf); 631 rfork(RFNOTEG); 632 if(kf.enabled) 633 startdev(&kf); 634 if(pf.enabled) 635 startdev(&pf); 636 threadexits(nil); 637 } 638