kb.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773
  1. /*
  2. * This file is part of the UCB release of Plan 9. It is subject to the license
  3. * terms in the LICENSE file found in the top-level directory of this
  4. * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
  5. * part of the UCB release of Plan 9, including this file, may be copied,
  6. * modified, propagated, or distributed except according to the terms contained
  7. * in the LICENSE file.
  8. */
  9. /*
  10. * USB Human Interaction Device: keyboard and mouse.
  11. *
  12. * If there's no usb keyboard, it tries to setup the mouse, if any.
  13. * It should be started at boot time.
  14. *
  15. * Mouse events are converted to the format of mouse(3)'s mousein file.
  16. * Keyboard keycodes are translated to scan codes and sent to kbin(3).
  17. *
  18. * If there is no keyboard, it tries to setup the mouse properly, else it falls
  19. * back to boot protocol.
  20. */
  21. #include <u.h>
  22. #include <libc.h>
  23. #include <thread.h>
  24. #include <usb/usb.h>
  25. #include <usb/hid.h>
  26. enum
  27. {
  28. Awakemsg= 0xdeaddead,
  29. Diemsg = 0xbeefbeef,
  30. Dwcidle = 8,
  31. };
  32. typedef struct KDev KDev;
  33. typedef struct Kin Kin;
  34. struct KDev
  35. {
  36. Dev* dev; /* usb device*/
  37. Dev* ep; /* endpoint to get events */
  38. Kin* in; /* used to send events to kernel */
  39. int idle; /* min time between reports (× 4ms) */
  40. Channel*repeatc; /* only for keyboard */
  41. int accel; /* only for mouse */
  42. int bootp; /* has associated keyboard */
  43. int debug;
  44. HidRepTempl templ;
  45. int (*ptrvals)(KDev *kd, Chain *ch, int *px, int *py, int *pb);
  46. };
  47. /*
  48. * Kbdin and mousein files must be shared among all instances.
  49. */
  50. struct Kin
  51. {
  52. int ref;
  53. int fd;
  54. char* name;
  55. };
  56. /*
  57. * Map for the logitech bluetooth mouse with 8 buttons and wheels.
  58. * { ptr ->mouse}
  59. * { 0x01, 0x01 }, // left
  60. * { 0x04, 0x02 }, // middle
  61. * { 0x02, 0x04 }, // right
  62. * { 0x40, 0x08 }, // up
  63. * { 0x80, 0x10 }, // down
  64. * { 0x10, 0x08 }, // side up
  65. * { 0x08, 0x10 }, // side down
  66. * { 0x20, 0x02 }, // page
  67. * besides wheel and regular up/down report the 4th byte as 1/-1
  68. */
  69. /*
  70. * key code to scan code; for the page table used by
  71. * the logitech bluetooth keyboard.
  72. */
  73. static char sctab[256] =
  74. {
  75. [0x00] = 0x0, 0x0, 0x0, 0x0, 0x1e, 0x30, 0x2e, 0x20,
  76. [0x08] = 0x12, 0x21, 0x22, 0x23, 0x17, 0x24, 0x25, 0x26,
  77. [0x10] = 0x32, 0x31, 0x18, 0x19, 0x10, 0x13, 0x1f, 0x14,
  78. [0x18] = 0x16, 0x2f, 0x11, 0x2d, 0x15, 0x2c, 0x2, 0x3,
  79. [0x20] = 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa, 0xb,
  80. [0x28] = 0x1c, 0x1, 0xe, 0xf, 0x39, 0xc, 0xd, 0x1a,
  81. [0x30] = 0x1b, 0x2b, 0x2b, 0x27, 0x28, 0x29, 0x33, 0x34,
  82. [0x38] = 0x35, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 0x40,
  83. [0x40] = 0x41, 0x42, 0x43, 0x44, 0x57, 0x58, 0x63, 0x46,
  84. [0x48] = 0x77, 0x52, 0x47, 0x49, 0x53, 0x4f, 0x51, 0x4d,
  85. [0x50] = 0x4b, 0x50, 0x48, 0x45, 0x35, 0x37, 0x4a, 0x4e,
  86. [0x58] = 0x1c, 0x4f, 0x50, 0x51, 0x4b, 0x4c, 0x4d, 0x47,
  87. [0x60] = 0x48, 0x49, 0x52, 0x53, 0x56, 0x7f, 0x74, 0x75,
  88. [0x68] = 0x55, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
  89. [0x70] = 0x78, 0x79, 0x7a, 0x7b, 0x0, 0x0, 0x0, 0x0,
  90. [0x78] = 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x71,
  91. [0x80] = 0x73, 0x72, 0x0, 0x0, 0x0, 0x7c, 0x0, 0x0,
  92. [0x88] = 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
  93. [0x90] = 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
  94. [0x98] = 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
  95. [0xa0] = 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
  96. [0xa8] = 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
  97. [0xb0] = 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
  98. [0xb8] = 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
  99. [0xc0] = 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
  100. [0xc8] = 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
  101. [0xd0] = 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
  102. [0xd8] = 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
  103. [0xe0] = 0x1d, 0x2a, 0x38, 0x7d, 0x61, 0x36, 0x64, 0x7e,
  104. [0xe8] = 0x0, 0x0, 0x0, 0x0, 0x0, 0x73, 0x72, 0x71,
  105. [0xf0] = 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
  106. [0xf8] = 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
  107. };
  108. static QLock inlck;
  109. static Kin kbdin =
  110. {
  111. .ref = 0,
  112. .name = "#j/kbin",
  113. .fd = -1,
  114. };
  115. static Kin ptrin =
  116. {
  117. .ref = 0,
  118. .name = "#m/mousein",
  119. .fd = -1,
  120. };
  121. static int ptrbootpvals(KDev *kd, Chain *ch, int *px, int *py, int *pb);
  122. static int ptrrepvals(KDev *kd, Chain *ch, int *px, int *py, int *pb);
  123. static int
  124. setbootproto(KDev* f, int eid, uint8_t *_1, int _2)
  125. {
  126. int nr, r, id;
  127. f->ptrvals = ptrbootpvals;
  128. r = Rh2d|Rclass|Riface;
  129. dprint(2, "setting boot protocol\n");
  130. id = f->dev->usb->ep[eid]->iface->id;
  131. nr = usbcmd(f->dev, r, Setproto, Bootproto, id, nil, 0);
  132. if(nr < 0)
  133. return -1;
  134. usbcmd(f->dev, r, Setidle, f->idle<<8, id, nil, 0);
  135. return nr;
  136. }
  137. static uint8_t ignoredesc[128];
  138. static int
  139. setfirstconfig(KDev* f, int eid, uint8_t *desc, int descsz)
  140. {
  141. int nr, r, id, i;
  142. dprint(2, "setting first config\n");
  143. if(desc == nil){
  144. descsz = sizeof ignoredesc;
  145. desc = ignoredesc;
  146. }
  147. id = f->dev->usb->ep[eid]->iface->id;
  148. r = Rh2d | Rstd | Rdev;
  149. nr = usbcmd(f->dev, r, Rsetconf, 1, 0, nil, 0);
  150. if(nr < 0)
  151. return -1;
  152. r = Rh2d | Rclass | Riface;
  153. nr = usbcmd(f->dev, r, Setidle, f->idle<<8, id, nil, 0);
  154. if(nr < 0)
  155. return -1;
  156. r = Rd2h | Rstd | Riface;
  157. nr=usbcmd(f->dev, r, Rgetdesc, Dreport<<8, id, desc, descsz);
  158. if(nr <= 0)
  159. return -1;
  160. if(f->debug){
  161. fprint(2, "report descriptor:");
  162. for(i = 0; i < nr; i++){
  163. if(i%8 == 0)
  164. fprint(2, "\n\t");
  165. fprint(2, "%#2.2x ", desc[i]);
  166. }
  167. fprint(2, "\n");
  168. }
  169. f->ptrvals = ptrrepvals;
  170. return nr;
  171. }
  172. /*
  173. * Try to recover from a babble error. A port reset is the only way out.
  174. * BUG: we should be careful not to reset a bundle with several devices.
  175. */
  176. static void
  177. recoverkb(KDev *f)
  178. {
  179. int i;
  180. close(f->dev->dfd); /* it's for usbd now */
  181. devctl(f->dev, "reset");
  182. for(i = 0; i < 10; i++){
  183. if(i == 5)
  184. f->bootp++;
  185. sleep(500);
  186. if(opendevdata(f->dev, ORDWR) >= 0){
  187. if(f->bootp)
  188. /* TODO func pointer */
  189. setbootproto(f, f->ep->id, nil, 0);
  190. else
  191. setfirstconfig(f, f->ep->id, nil, 0);
  192. break;
  193. }
  194. /* else usbd still working... */
  195. }
  196. }
  197. static void
  198. kbfatal(KDev *kd, char *sts)
  199. {
  200. Dev *dev;
  201. if(sts != nil)
  202. fprint(2, "kb: fatal: %s\n", sts);
  203. else
  204. fprint(2, "kb: exiting\n");
  205. if(kd->repeatc != nil)
  206. nbsendul(kd->repeatc, Diemsg);
  207. dev = kd->dev;
  208. kd->dev = nil;
  209. if(kd->ep != nil)
  210. closedev(kd->ep);
  211. kd->ep = nil;
  212. devctl(dev, "detach");
  213. closedev(dev);
  214. /*
  215. * free(kd); done by closedev.
  216. */
  217. threadexits(sts);
  218. }
  219. static int
  220. scale(KDev *f, int x)
  221. {
  222. int sign = 1;
  223. if(x < 0){
  224. sign = -1;
  225. x = -x;
  226. }
  227. switch(x){
  228. case 0:
  229. case 1:
  230. case 2:
  231. case 3:
  232. break;
  233. case 4:
  234. x = 6 + (f->accel>>2);
  235. break;
  236. case 5:
  237. x = 9 + (f->accel>>1);
  238. break;
  239. default:
  240. x *= MaxAcc;
  241. break;
  242. }
  243. return sign*x;
  244. }
  245. /*
  246. * ps2 mouse is processed mostly at interrupt time.
  247. * for usb we do what we can.
  248. */
  249. static void
  250. sethipri(void)
  251. {
  252. char fn[30];
  253. int fd;
  254. snprint(fn, sizeof fn, "/proc/%d/ctl", getpid());
  255. fd = open(fn, OWRITE);
  256. if(fd >= 0) {
  257. fprint(fd, "pri 13");
  258. close(fd);
  259. }
  260. }
  261. static int
  262. ptrrepvals(KDev *kd, Chain *ch, int *px, int *py, int *pb)
  263. {
  264. int i, x, y, b, c;
  265. static char buts[] = {0x0, 0x2, 0x1};
  266. c = ch->e / 8;
  267. /* sometimes there is a report id, sometimes not */
  268. if(c == kd->templ.sz + 1) {
  269. if(ch->buf[0] == kd->templ.id)
  270. ch->b += 8;
  271. else
  272. return -1;
  273. }
  274. parsereport(&kd->templ, ch);
  275. if(kd->debug > 1)
  276. dumpreport(&kd->templ);
  277. if(c < 3)
  278. return -1;
  279. x = hidifcval(&kd->templ, KindX, 0);
  280. y = hidifcval(&kd->templ, KindY, 0);
  281. b = 0;
  282. for(i = 0; i<sizeof buts; i++)
  283. b |= (hidifcval(&kd->templ, KindButtons, i) & 1) << buts[i];
  284. if(c > 3 && hidifcval(&kd->templ, KindWheel, 0) > 0) /* up */
  285. b |= 0x08;
  286. if(c > 3 && hidifcval(&kd->templ, KindWheel, 0) < 0) /* down */
  287. b |= 0x10;
  288. *px = x;
  289. *py = y;
  290. *pb = b;
  291. return 0;
  292. }
  293. static int
  294. ptrbootpvals(KDev *kd, Chain *ch, int *px, int *py, int *pb)
  295. {
  296. int b, c;
  297. char x, y;
  298. static char maptab[] = {0x0, 0x1, 0x4, 0x5, 0x2, 0x3, 0x6, 0x7};
  299. c = ch->e / 8;
  300. if(c < 3)
  301. return -1;
  302. if(kd->templ.nifcs){
  303. x = hidifcval(&kd->templ, KindX, 0);
  304. y = hidifcval(&kd->templ, KindY, 0);
  305. }else{
  306. /* no report descriptor for boot protocol */
  307. x = ((signed char*)ch->buf)[1];
  308. y = ((signed char*)ch->buf)[2];
  309. }
  310. b = maptab[ch->buf[0] & 0x7];
  311. if(c > 3 && ch->buf[3] == 1) /* up */
  312. b |= 0x08;
  313. if(c > 3 && ch->buf[3] == 0xff) /* down */
  314. b |= 0x10;
  315. *px = x;
  316. *py = y;
  317. *pb = b;
  318. return 0;
  319. }
  320. static void
  321. ptrwork(void* a)
  322. {
  323. int hipri, mfd, nerrs, x, y, b, c, ptrfd;
  324. char mbuf[80];
  325. Chain ch;
  326. KDev* f = a;
  327. threadsetname("ptr %s", f->ep->dir);
  328. hipri = nerrs = 0;
  329. ptrfd = f->ep->dfd;
  330. mfd = f->in->fd;
  331. if(f->ep->maxpkt < 3 || f->ep->maxpkt > MaxChLen)
  332. kbfatal(f, "weird mouse maxpkt");
  333. for(;;){
  334. memset(ch.buf, 0, MaxChLen);
  335. if(f->ep == nil)
  336. kbfatal(f, nil);
  337. c = read(ptrfd, ch.buf, f->ep->maxpkt);
  338. assert(f->dev != nil);
  339. assert(f->ep != nil);
  340. if(c < 0){
  341. dprint(2, "kb: mouse: %s: read: %r\n", f->ep->dir);
  342. if(++nerrs < 3){
  343. recoverkb(f);
  344. continue;
  345. }
  346. }
  347. if(c <= 0)
  348. kbfatal(f, nil);
  349. ch.b = 0;
  350. ch.e = 8 * c;
  351. if(f->ptrvals(f, &ch, &x, &y, &b) < 0)
  352. continue;
  353. if(f->accel){
  354. x = scale(f, x);
  355. y = scale(f, y);
  356. }
  357. if(f->debug > 1)
  358. fprint(2, "kb: m%11d %11d %11d\n", x, y, b);
  359. seprint(mbuf, mbuf+sizeof(mbuf), "m%11d %11d %11d", x, y,b);
  360. if(write(mfd, mbuf, strlen(mbuf)) < 0)
  361. kbfatal(f, "mousein i/o");
  362. if(hipri == 0){
  363. sethipri();
  364. hipri = 1;
  365. }
  366. }
  367. }
  368. static void
  369. stoprepeat(KDev *f)
  370. {
  371. sendul(f->repeatc, Awakemsg);
  372. }
  373. static void
  374. startrepeat(KDev *f, uint8_t esc1, uint8_t sc)
  375. {
  376. uint32_t c;
  377. if(esc1)
  378. c = SCesc1 << 8 | (sc & 0xff);
  379. else
  380. c = sc;
  381. sendul(f->repeatc, c);
  382. }
  383. static void
  384. putscan(KDev *f, uint8_t esc, uint8_t sc)
  385. {
  386. int kbinfd;
  387. uint8_t s[2] = {SCesc1, 0};
  388. kbinfd = f->in->fd;
  389. if(sc == 0x41){
  390. f->debug += 2;
  391. return;
  392. }
  393. if(sc == 0x42){
  394. f->debug = 0;
  395. return;
  396. }
  397. if(f->debug > 1)
  398. fprint(2, "sc: %x %x\n", (esc? SCesc1: 0), sc);
  399. s[1] = sc;
  400. if(esc && sc != 0)
  401. write(kbinfd, s, 2);
  402. else if(sc != 0)
  403. write(kbinfd, s+1, 1);
  404. }
  405. static void
  406. repeatproc(void* a)
  407. {
  408. KDev *f;
  409. Channel *repeatc;
  410. uint32_t l, t, i;
  411. uint8_t esc1, sc;
  412. threadsetname("kbd repeat");
  413. /*
  414. * too many jumps here.
  415. * Rewrite instead of debug, if needed.
  416. */
  417. f = a;
  418. repeatc = f->repeatc;
  419. l = Awakemsg;
  420. Repeat:
  421. if(l == Diemsg)
  422. goto Abort;
  423. while(l == Awakemsg)
  424. l = recvul(repeatc);
  425. if(l == Diemsg)
  426. goto Abort;
  427. esc1 = l >> 8;
  428. sc = l;
  429. t = 160;
  430. for(;;){
  431. for(i = 0; i < t; i += 5){
  432. if((l = nbrecvul(repeatc)) != 0)
  433. goto Repeat;
  434. sleep(5);
  435. }
  436. putscan(f, esc1, sc);
  437. t = 30;
  438. }
  439. Abort:
  440. chanfree(repeatc);
  441. threadexits("aborted");
  442. }
  443. #define hasesc1(sc) ((sc) >= 0x47 || (sc) == 0x38)
  444. static void
  445. putmod(KDev *f, uint8_t mods, uint8_t omods, uint8_t mask, uint8_t esc,
  446. uint8_t sc)
  447. {
  448. /* BUG: Should be a single write */
  449. if((mods&mask) && !(omods&mask))
  450. putscan(f, esc, sc);
  451. if(!(mods&mask) && (omods&mask))
  452. putscan(f, esc, Keyup|sc);
  453. }
  454. /*
  455. * This routine diffs the state with the last known state
  456. * and invents the scan codes that would have been sent
  457. * by a non-usb keyboard in that case. This also requires supplying
  458. * the extra esc1 byte as well as keyup flags.
  459. * The aim is to allow future addition of other keycode pages
  460. * for other keyboards.
  461. */
  462. static uint8_t
  463. putkeys(KDev *f, uint8_t buf[], uint8_t obuf[], int n, uint8_t dk)
  464. {
  465. int i, j;
  466. uint8_t uk;
  467. putmod(f, buf[0], obuf[0], Mctrl, 0, SCctrl);
  468. putmod(f, buf[0], obuf[0], (1<<Mlshift), 0, SClshift);
  469. putmod(f, buf[0], obuf[0], (1<<Mrshift), 0, SCrshift);
  470. putmod(f, buf[0], obuf[0], Mcompose, 0, SCcompose);
  471. putmod(f, buf[0], obuf[0], Maltgr, 1, SCcompose);
  472. /* Report key downs */
  473. for(i = 2; i < n; i++){
  474. for(j = 2; j < n; j++)
  475. if(buf[i] == obuf[j])
  476. break;
  477. if(j == n && buf[i] != 0){
  478. dk = sctab[buf[i]];
  479. putscan(f, hasesc1(dk), dk);
  480. startrepeat(f, hasesc1(dk), dk);
  481. }
  482. }
  483. /* Report key ups */
  484. uk = 0;
  485. for(i = 2; i < n; i++){
  486. for(j = 2; j < n; j++)
  487. if(obuf[i] == buf[j])
  488. break;
  489. if(j == n && obuf[i] != 0){
  490. uk = sctab[obuf[i]];
  491. putscan(f, hasesc1(uk), uk|Keyup);
  492. }
  493. }
  494. if(uk && (dk == 0 || dk == uk)){
  495. stoprepeat(f);
  496. dk = 0;
  497. }
  498. return dk;
  499. }
  500. static int
  501. kbdbusy(uint8_t* buf, int n)
  502. {
  503. int i;
  504. for(i = 1; i < n; i++)
  505. if(buf[i] == 0 || buf[i] != buf[0])
  506. return 0;
  507. return 1;
  508. }
  509. static void
  510. kbdwork(void *a)
  511. {
  512. int c, i, kbdfd, nerrs;
  513. uint8_t dk, buf[64], lbuf[64];
  514. char err[128];
  515. KDev *f = a;
  516. threadsetname("kbd %s", f->ep->dir);
  517. kbdfd = f->ep->dfd;
  518. if(f->ep->maxpkt < 3 || f->ep->maxpkt > sizeof buf)
  519. kbfatal(f, "weird maxpkt");
  520. f->repeatc = chancreate(sizeof(uint32_t), 0);
  521. if(f->repeatc == nil)
  522. kbfatal(f, "chancreate failed");
  523. proccreate(repeatproc, f, Stack);
  524. memset(lbuf, 0, sizeof lbuf);
  525. dk = nerrs = 0;
  526. for(;;){
  527. memset(buf, 0, sizeof buf);
  528. c = read(kbdfd, buf, f->ep->maxpkt);
  529. assert(f->dev != nil);
  530. assert(f->ep != nil);
  531. if(c < 0){
  532. rerrstr(err, sizeof(err));
  533. fprint(2, "kb: %s: read: %s\n", f->ep->dir, err);
  534. if(strstr(err, "babble") != 0 && ++nerrs < 3){
  535. recoverkb(f);
  536. continue;
  537. }
  538. }
  539. if(c <= 0)
  540. kbfatal(f, nil);
  541. if(c < 3)
  542. continue;
  543. if(kbdbusy(buf + 2, c - 2))
  544. continue;
  545. if(usbdebug > 2 || f->debug > 1){
  546. fprint(2, "kbd mod %x: ", buf[0]);
  547. for(i = 2; i < c; i++)
  548. fprint(2, "kc %x ", buf[i]);
  549. fprint(2, "\n");
  550. }
  551. dk = putkeys(f, buf, lbuf, f->ep->maxpkt, dk);
  552. memmove(lbuf, buf, c);
  553. nerrs = 0;
  554. }
  555. }
  556. static void
  557. freekdev(void *a)
  558. {
  559. KDev *kd;
  560. kd = a;
  561. if(kd->in != nil){
  562. qlock(&inlck);
  563. if(--kd->in->ref == 0){
  564. close(kd->in->fd);
  565. kd->in->fd = -1;
  566. }
  567. qunlock(&inlck);
  568. }
  569. dprint(2, "freekdev\n");
  570. free(kd);
  571. }
  572. static void
  573. kbstart(Dev *d, Ep *ep, Kin *in, void (*f)(void*), KDev *kd)
  574. {
  575. uint8_t desc[512];
  576. int n, res;
  577. qlock(&inlck);
  578. if(in->fd < 0){
  579. in->fd = open(in->name, OWRITE);
  580. if(in->fd < 0){
  581. fprint(2, "kb: %s: %r\n", in->name);
  582. qunlock(&inlck);
  583. return;
  584. }
  585. }
  586. in->ref++; /* for kd->in = in */
  587. qunlock(&inlck);
  588. d->free = freekdev;
  589. kd->in = in;
  590. kd->dev = d;
  591. res = -1;
  592. kd->ep = openep(d, ep->id);
  593. if(kd->ep == nil){
  594. fprint(2, "kb: %s: openep %d: %r\n", d->dir, ep->id);
  595. return;
  596. }
  597. if(in == &kbdin){
  598. /*
  599. * DWC OTG controller misses some split transaction inputs.
  600. * Set nonzero idle time to return more frequent reports
  601. * of keyboard state, to avoid losing key up/down events.
  602. */
  603. n = read(d->cfd, desc, sizeof desc - 1);
  604. if(n > 0){
  605. desc[n] = 0;
  606. if(strstr((char*)desc, "dwcotg") != nil)
  607. kd->idle = Dwcidle;
  608. }
  609. }
  610. if(!kd->bootp)
  611. res= setfirstconfig(kd, ep->id, desc, sizeof desc);
  612. if(res > 0)
  613. res = parsereportdesc(&kd->templ, desc, sizeof desc);
  614. /* if we could not set the first config, we give up */
  615. if(kd->bootp || res < 0){
  616. kd->bootp = 1;
  617. if(setbootproto(kd, ep->id, nil, 0) < 0){
  618. fprint(2, "kb: %s: bootproto: %r\n", d->dir);
  619. return;
  620. }
  621. }else if(kd->debug)
  622. dumpreport(&kd->templ);
  623. if(opendevdata(kd->ep, OREAD) < 0){
  624. fprint(2, "kb: %s: opendevdata: %r\n", kd->ep->dir);
  625. closedev(kd->ep);
  626. kd->ep = nil;
  627. return;
  628. }
  629. incref(&d->Ref);
  630. proccreate(f, kd, Stack);
  631. }
  632. static int
  633. usage(void)
  634. {
  635. werrstr("usage: usb/kb [-bdkm] [-a n] [-N nb]");
  636. return -1;
  637. }
  638. int
  639. kbmain(Dev *d, int argc, char* argv[])
  640. {
  641. int bootp, i, kena, pena, accel, devid, debug;
  642. Ep *ep;
  643. KDev *kd;
  644. Usbdev *ud;
  645. kena = pena = 1;
  646. bootp = 0;
  647. accel = 0;
  648. debug = 0;
  649. devid = d->id;
  650. ARGBEGIN{
  651. case 'a':
  652. accel = strtol(EARGF(usage()), nil, 0);
  653. break;
  654. case 'd':
  655. debug++;
  656. break;
  657. case 'k':
  658. kena = 1;
  659. pena = 0;
  660. break;
  661. case 'm':
  662. kena = 0;
  663. pena = 1;
  664. break;
  665. case 'N':
  666. devid = atoi(EARGF(usage())); /* ignore dev number */
  667. break;
  668. case 'b':
  669. bootp++;
  670. break;
  671. default:
  672. return usage();
  673. }ARGEND;
  674. if(argc != 0)
  675. return usage();
  676. USED(devid);
  677. ud = d->usb;
  678. d->aux = nil;
  679. dprint(2, "kb: main: dev %s ref %ld\n", d->dir, d->Ref.ref);
  680. if(kena) {
  681. for(i = 0; i < nelem(ud->ep); i++)
  682. if((ep = ud->ep[i]) == nil)
  683. break;
  684. else if(ep->iface->csp == KbdCSP)
  685. bootp = 1;
  686. }
  687. for(i = 0; i < nelem(ud->ep); i++){
  688. if((ep = ud->ep[i]) == nil)
  689. continue;
  690. if(kena && ep->type == Eintr && ep->dir == Ein &&
  691. ep->iface->csp == KbdCSP){
  692. kd = d->aux = emallocz(sizeof(KDev), 1);
  693. kd->accel = 0;
  694. kd->bootp = 1;
  695. kd->debug = debug;
  696. kbstart(d, ep, &kbdin, kbdwork, kd);
  697. }
  698. if(pena && ep->type == Eintr && ep->dir == Ein &&
  699. ep->iface->csp == PtrCSP){
  700. kd = d->aux = emallocz(sizeof(KDev), 1);
  701. kd->accel = accel;
  702. kd->bootp = bootp;
  703. kd->debug = debug;
  704. kbstart(d, ep, &ptrin, ptrwork, kd);
  705. }
  706. }
  707. return 0;
  708. }