hid.c 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243
  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. #include <u.h>
  10. #include <libc.h>
  11. #include <thread.h>
  12. #include <usb/usb.h>
  13. #include <usb/hid.h>
  14. /*
  15. * Rough hid descriptor parsing and interpretation for mice
  16. *
  17. * Chain and its operations build the infrastructure needed
  18. * to manipulate non-aligned fields, which do appear (sigh!).
  19. */
  20. /* Get, at most, 8 bits*/
  21. static uint8_t
  22. get8bits(Chain *ch, int nbits)
  23. {
  24. int b, nbyb, nbib, nlb;
  25. uint8_t low, high;
  26. b = ch->b + nbits - 1;
  27. nbib = ch->b % 8;
  28. nbyb = ch->b / 8;
  29. nlb = 8 - nbib;
  30. if(nlb > nbits)
  31. nlb = nbits;
  32. low = MSK(nlb) & (ch->buf[nbyb] >> nbib);
  33. if(IsCut(ch->b, b))
  34. high = (ch->buf[nbyb + 1] & MSK(nbib)) << nlb;
  35. else
  36. high = 0;
  37. ch->b += nbits;
  38. return MSK(nbits)&(high | low);
  39. }
  40. static void
  41. getbits(void *p, Chain *ch, int nbits)
  42. {
  43. int nby, nbi, i;
  44. uint8_t *vp;
  45. assert(ch->e >= ch->b);
  46. nby = nbits / 8;
  47. nbi = nbits % 8;
  48. vp = p;
  49. for(i = 0; i < nby; i++)
  50. *vp++ = get8bits(ch, 8);
  51. if(nbi != 0)
  52. *vp = get8bits(ch, nbi);
  53. }
  54. int
  55. parsereportdesc(HidRepTempl *temp, uint8_t *repdesc, int repsz)
  56. {
  57. int i, j, l, n, isptr, hasxy, hasbut, nk, ncoll, dsize;
  58. uint8_t ks[MaxVals+1];
  59. HidInterface *ifs;
  60. ifs = temp->ifcs;
  61. isptr = 0;
  62. hasxy = hasbut = 0;
  63. ncoll = 0;
  64. n = 0;
  65. nk = 0;
  66. memset(ifs, 0, sizeof *ifs * MaxIfc);
  67. for(i = 0; i < repsz; i += dsize+1){
  68. dsize = (1 << (repdesc[i] & 03)) >> 1;
  69. if(nk > MaxVals){
  70. fprint(2, "bad report: too many input types\n");
  71. return -1;
  72. }
  73. if(n == MaxIfc)
  74. break;
  75. if(repdesc[i] == HidEnd){
  76. ncoll--;
  77. if(ncoll == 0)
  78. break;
  79. }
  80. switch(repdesc[i]){
  81. case HidReportId:
  82. switch(repdesc[i+1]){
  83. case HidReportIdPtr:
  84. temp->id = repdesc[i+1];
  85. break;
  86. default:
  87. fprint(2, "report type %#x bad\n",
  88. repdesc[i+1]);
  89. return -1;
  90. }
  91. break;
  92. case HidTypeUsg:
  93. switch(repdesc[i+1]){
  94. case HidX:
  95. hasxy++;
  96. ks[nk++] = KindX;
  97. break;
  98. case HidY:
  99. hasxy++;
  100. ks[nk++] = KindY;
  101. break;
  102. case HidZ:
  103. ks[nk++] = KindPad;
  104. break;
  105. case HidWheel:
  106. ks[nk++] = KindWheel;
  107. break;
  108. case HidPtr:
  109. isptr++;
  110. break;
  111. }
  112. break;
  113. case HidTypeUsgPg:
  114. switch(repdesc[i+1]){
  115. case HidPgButts:
  116. hasbut++;
  117. ks[nk++] = KindButtons;
  118. break;
  119. }
  120. break;
  121. case HidTypeRepSz:
  122. ifs[n].nbits = repdesc[i+1];
  123. break;
  124. case HidTypeCnt:
  125. ifs[n].count = repdesc[i+1];
  126. break;
  127. case HidInput:
  128. if(ifs[n].count > MaxVals){
  129. fprint(2, "bad report: input count too big\n");
  130. return -1;
  131. }
  132. for(j = 0; j <nk; j++)
  133. ifs[n].kind[j] = ks[j];
  134. if(nk != 0 && nk < ifs[n].count)
  135. for(l = j; l <ifs[n].count; l++)
  136. ifs[n].kind[l] = ks[j-1];
  137. n++;
  138. if(n < MaxIfc){
  139. ifs[n].count = ifs[n-1].count; /* inherit values */
  140. ifs[n].nbits = ifs[n-1].nbits;
  141. if(ifs[n].nbits == 0)
  142. ifs[n].nbits = 1;
  143. }
  144. nk = 0;
  145. break;
  146. case HidCollection:
  147. ncoll++;
  148. break;
  149. }
  150. }
  151. temp->nifcs = n;
  152. for(i = 0; i < n; i++)
  153. temp->sz += temp->ifcs[i].nbits * temp->ifcs[i].count;
  154. temp->sz = (temp->sz + 7) / 8;
  155. if(isptr && hasxy && hasbut)
  156. return 0;
  157. fprint(2, "bad report: isptr %d, hasxy %d, hasbut %d\n",
  158. isptr, hasxy, hasbut);
  159. return -1;
  160. }
  161. int
  162. parsereport(HidRepTempl *templ, Chain *rep)
  163. {
  164. int i, j, k, ifssz;
  165. uint32_t u;
  166. uint8_t *p;
  167. HidInterface *ifs;
  168. ifssz = templ->nifcs;
  169. ifs = templ->ifcs;
  170. for(i = 0; i < ifssz; i++)
  171. for(j = 0; j < ifs[i].count; j++){
  172. if(ifs[i].nbits > 8 * sizeof ifs[i].v[0]){
  173. fprint(2, "ptr: bad bits in parsereport");
  174. return -1;
  175. }
  176. u =0;
  177. getbits(&u, rep, ifs[i].nbits);
  178. p = (uint8_t *)&u;
  179. /* le to host */
  180. ifs[i].v[j] = p[3]<<24 | p[2]<<16 | p[1]<<8 | p[0]<<0;
  181. k = ifs[i].kind[j];
  182. if(k == KindX || k == KindY || k == KindWheel){
  183. /* propagate sign */
  184. if(ifs[i].v[j] & (1 << (ifs[i].nbits - 1)))
  185. ifs[i].v[j] |= ~MSK(ifs[i].nbits);
  186. }
  187. }
  188. return 0;
  189. }
  190. /* TODO: fmt representation */
  191. void
  192. dumpreport(HidRepTempl *templ)
  193. {
  194. int i, j, ifssz;
  195. HidInterface *ifs;
  196. ifssz = templ->nifcs;
  197. ifs = templ->ifcs;
  198. for(i = 0; i < ifssz; i++){
  199. fprint(2, "\tcount %#x", ifs[i].count);
  200. fprint(2, " nbits %d ", ifs[i].nbits);
  201. fprint(2, "\n");
  202. for(j = 0; j < ifs[i].count; j++){
  203. fprint(2, "\t\tkind %#x ", ifs[i].kind[j]);
  204. fprint(2, "v %#lx\n", ifs[i].v[j]);
  205. }
  206. fprint(2, "\n");
  207. }
  208. fprint(2, "\n");
  209. }
  210. /* could precalculate indices after parsing the descriptor */
  211. int
  212. hidifcval(HidRepTempl *templ, int kind, int n)
  213. {
  214. int i, j, ifssz;
  215. HidInterface *ifs;
  216. ifssz = templ->nifcs;
  217. ifs = templ->ifcs;
  218. assert(n <= nelem(ifs[i].v));
  219. for(i = 0; i < ifssz; i++)
  220. for(j = 0; j < ifs[i].count; j++)
  221. if(ifs[i].kind[j] == kind && n-- == 0)
  222. return (int)ifs[i].v[j];
  223. return 0; /* least damage (no buttons, no movement) */
  224. }