dump.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587
  1. #include <u.h>
  2. #include <libc.h>
  3. #include <thread.h>
  4. #include <bio.h>
  5. #include "usb.h"
  6. int verbose;
  7. typedef struct Flags Flags;
  8. typedef struct Classes Classes;
  9. struct Flags {
  10. int bit;
  11. char* name0;
  12. char* name1;
  13. };
  14. struct Classes {
  15. char* name;
  16. struct {
  17. char* name;
  18. char* proto[4];
  19. } subclass[4];
  20. };
  21. static Classes classname[] = {
  22. [CL_AUDIO] {"audio", {[1]{"control"}, [2]{"stream"}, [3]{"midi"}}},
  23. [CL_COMMS] {"comms", {[1] {"abstract", {[1]"AT"}}}},
  24. [CL_HID] {"hid", {[1] {"boot", {[1]"kbd", [2]"mouse"}}}},
  25. [CL_PRINTER] {"printer", {[1]"printer", {[1]"uni", [2]"bi"}}},
  26. [CL_HUB] {"hub", {[1]{"hub"}}},
  27. [CL_DATA] {"data"},
  28. };
  29. static void pflag(Flags*, uint);
  30. char *
  31. sclass(ulong csp)
  32. {
  33. Classes *cs;
  34. int n;
  35. static char buf[64];
  36. int c, s, p;
  37. c = Class(csp);
  38. s = Subclass(csp);
  39. p = Proto(csp);
  40. if(c < 0 || c >= nelem(classname) || (cs = &classname[c])->name == nil){
  41. sprint(buf, "%d.%d.%d", c, s, p);
  42. return buf;
  43. }
  44. n = sprint(buf, "%s.", cs->name);
  45. if(s < 0 || s >= nelem(cs->subclass) || cs->subclass[s].name == nil)
  46. sprint(buf+n, "%d.%d", s, p);
  47. else{
  48. n += sprint(buf+n, "%s.", cs->subclass[s].name);
  49. if(p < 0 || p >= nelem(cs->subclass[s].proto) || cs->subclass[s].proto[p] == nil)
  50. sprint(buf+n, "%d", p);
  51. else
  52. sprint(buf+n, "%s", cs->subclass[s].proto[p]);
  53. }
  54. return buf;
  55. }
  56. void
  57. pdevice(Device *, int, ulong, void *b, int n)
  58. {
  59. DDevice *d;
  60. if(n < DDEVLEN)
  61. return;
  62. d = b;
  63. if (debug & Dbginfo) {
  64. fprint(2, "usb (bcd)%c%c%c%c",
  65. '0'+((d->bcdUSB[1]>>4)&0xf), '0'+(d->bcdUSB[1]&0xf),
  66. '0'+((d->bcdUSB[0]>>4)&0xf), '0'+(d->bcdUSB[0]&0xf));
  67. fprint(2, " class %d subclass %d proto %d [%s] max0 %d",
  68. d->bDeviceClass, d->bDeviceSubClass, d->bDeviceProtocol,
  69. sclass(CSP(d->bDeviceClass, d->bDeviceSubClass, d->bDeviceProtocol)),
  70. d->bMaxPacketSize0);
  71. fprint(2, " vendor %#x product %#x device (bcd)%c%c%c%c",
  72. GET2(d->idVendor), GET2(d->idProduct),
  73. '0'+((d->bcdDevice[1]>>4)&0xf), '0'+(d->bcdDevice[1]&0xf),
  74. '0'+((d->bcdDevice[0]>>4)&0xf), '0'+(d->bcdDevice[0]&0xf));
  75. fprint(2, " man %d prod %d serial %d nconfig %d",
  76. d->iManufacturer, d->iProduct, d->iSerialNumber,
  77. d->bNumConfigurations);
  78. }
  79. }
  80. void
  81. phid(Device *, int, ulong, void *b, int n)
  82. {
  83. DHid *d;
  84. if(n < DHIDLEN){
  85. fprint(2, "%s: hid too short\n", argv0);
  86. return;
  87. }
  88. d = b;
  89. if (debug & Dbginfo)
  90. fprint(2, "HID (bcd)%c%c%c%c country %d nhidclass %d classdtype %#x dlen %d\n",
  91. '0'+((d->bcdHID[1]>>4)&0xf), '0'+(d->bcdHID[1]&0xf),
  92. '0'+((d->bcdHID[0]>>4)&0xf), '0'+(d->bcdHID[0]&0xf),
  93. d->bCountryCode, d->bNumDescriptors,
  94. d->bClassDescriptorType, GET2(d->wItemLength));
  95. }
  96. static Flags ioflags[] = {
  97. {0, "Data", "Constant"},
  98. {1, "Array", "Variable"},
  99. {2, "Absolute", "Relative"},
  100. {3, "NoWrap", "Wrap"},
  101. {4, "Linear", "NonLinear"},
  102. {5, "PreferredState", "No Preferred State"},
  103. {6, "No Null position", "Null state"},
  104. {7, "Non Volatile", "Volatile"},
  105. {8, "Bit Field", "Buffered Bytes"},
  106. {-1, nil, nil},
  107. };
  108. static void
  109. pflag(Flags *tab, uint v)
  110. {
  111. char buf[200], *s;
  112. int n;
  113. n = 0;
  114. buf[0] = 0;
  115. for(; tab->name0 != nil; tab++){
  116. if(v & (1<<tab->bit))
  117. s = tab->name1;
  118. else
  119. s = tab->name0;
  120. if(s != nil && *s)
  121. n += snprint(buf+n, sizeof(buf)-n, ", %s", s);
  122. }
  123. if((debug & Dbginfo) && buf[0])
  124. fprint(2, "[%s]", buf+2);
  125. }
  126. void
  127. preport(Device *, int, ulong, byte *b, int n)
  128. {
  129. byte *s, *es;
  130. int tag, nb, i, indent;
  131. int v;
  132. Flags *tab;
  133. s = b+2;
  134. es = b+n;
  135. indent = 0;
  136. while(s < es){
  137. for(i=0; i<indent; i++)
  138. fprint(2, " ");
  139. tag = *s++;
  140. if(tag == Tlong){
  141. fprint(2, "long report tag");
  142. return;
  143. }
  144. if((nb = tag&3) == 3)
  145. nb = 4;
  146. v = 0;
  147. for(i=0; i<nb; i++)
  148. v |= s[i] << (i*8);
  149. switch(tag & Tmtype){
  150. case Treserved:
  151. if(tag == Tlong){
  152. fprint(2, "long report tag");
  153. return;
  154. }
  155. fprint(2, "illegal tag");
  156. return;
  157. case Tmain:
  158. tab = nil;
  159. if (debug & Dbginfo) {
  160. switch(tag & Tmitem){
  161. case Tinput:
  162. fprint(2, "Input");
  163. tab = ioflags;
  164. break;
  165. case Toutput:
  166. fprint(2, "Output");
  167. tab = ioflags;
  168. break;
  169. case Tfeature:
  170. fprint(2, "Feature");
  171. tab = ioflags;
  172. break;
  173. case Tcoll:
  174. fprint(2, "Collection");
  175. indent++;
  176. break;
  177. case Tecoll:
  178. fprint(2, "End Collection");
  179. indent--;
  180. break;
  181. default:
  182. fprint(2, "unexpected item %.2x", tag);
  183. }
  184. fprint(2, "=%#ux", v);
  185. if(tab != nil)
  186. pflag(tab, v);
  187. }
  188. break;
  189. case Tglobal:
  190. if (debug & Dbginfo) {
  191. fprint(2, "Global %#ux: ", v);
  192. switch(tag & Tmitem){
  193. case Tusagepage:
  194. fprint(2, "Usage Page %#ux", v);
  195. break;
  196. case Tlmin:
  197. fprint(2, "Logical Min %d", v);
  198. break;
  199. case Tlmax:
  200. fprint(2, "Logical Max %d", v);
  201. break;
  202. case Tpmin:
  203. fprint(2, "Physical Min %d", v);
  204. break;
  205. case Tpmax:
  206. fprint(2, "Physical Max %d", v);
  207. break;
  208. case Tunitexp:
  209. fprint(2, "Unit Exponent %d", v);
  210. break;
  211. case Tunit:
  212. fprint(2, "Unit %d", v);
  213. break;
  214. case Trepsize:
  215. fprint(2, "Report size %d", v);
  216. break;
  217. case TrepID:
  218. fprint(2, "Report ID %#x", v);
  219. break;
  220. case Trepcount:
  221. fprint(2, "Report Count %d", v);
  222. break;
  223. case Tpush:
  224. fprint(2, "Push %d", v);
  225. break;
  226. case Tpop:
  227. fprint(2, "Pop %d", v);
  228. break;
  229. default:
  230. fprint(2, "Unknown %#ux", v);
  231. break;
  232. }
  233. }
  234. break;
  235. case Tlocal:
  236. if (debug & Dbginfo) {
  237. fprint(2, "Local %#ux: ", v);
  238. switch(tag & Tmitem){
  239. case Tusage:
  240. fprint(2, "Usage %d", v);
  241. break;
  242. case Tumin:
  243. fprint(2, "Usage min %d", v);
  244. break;
  245. case Tumax:
  246. fprint(2, "Usage max %d", v);
  247. break;
  248. case Tdindex:
  249. fprint(2, "Designator index %d", v);
  250. break;
  251. case Tdmin:
  252. fprint(2, "Designator min %d", v);
  253. break;
  254. case Tdmax:
  255. fprint(2, "Designator max %d", v);
  256. break;
  257. case Tsindex:
  258. fprint(2, "String index %d", v);
  259. break;
  260. case Tsmin:
  261. fprint(2, "String min %d", v);
  262. break;
  263. case Tsmax:
  264. fprint(2, "String max %d", v);
  265. break;
  266. case Tsetdelim:
  267. fprint(2, "Set delim %#ux", v);
  268. break;
  269. default:
  270. fprint(2, "Unknown %#ux", v);
  271. break;
  272. }
  273. }
  274. break;
  275. }
  276. fprint(2, "\n");
  277. s += nb;
  278. }
  279. }
  280. void
  281. phub(Device *, int, ulong, void *b, int n)
  282. {
  283. DHub *d;
  284. if(n < DHUBLEN)
  285. return;
  286. d = b;
  287. if (debug & Dbginfo)
  288. fprint(2, "nport %d charac %#.4x pwr %dms current %dmA remov %#.2x",
  289. d->bNbrPorts, GET2(d->wHubCharacteristics),
  290. d->bPwrOn2PwrGood*2, d->bHubContrCurrent,
  291. d->DeviceRemovable[0]);
  292. }
  293. void
  294. pstring(Device *, int, ulong, void *b, int n)
  295. {
  296. byte *rb;
  297. char *s;
  298. Rune r;
  299. int l;
  300. if(n <= 2){
  301. fprint(2, "\"\"");
  302. return;
  303. }
  304. if(n & 1){
  305. fprint(2, "illegal count\n");
  306. return;
  307. }
  308. n = (n - 2)/2;
  309. rb = (byte*)b + 2;
  310. s = malloc(n*UTFmax+1);
  311. for(l=0; --n >= 0; rb += 2){
  312. r = GET2(rb);
  313. l += runetochar(s+l, &r);
  314. }
  315. s[l] = 0;
  316. fprint(2, "\"%s\"", s);
  317. free(s);
  318. }
  319. void
  320. pcs_raw(char *tag, byte *b, int n)
  321. {
  322. int i;
  323. if (debug & Dbginfo) {
  324. fprint(2, "%s", tag);
  325. for(i=2; i<n; i++)
  326. fprint(2, " %.2x", b[i]);
  327. }
  328. }
  329. static void
  330. pcs_config(Device *, int, ulong, void *b, int n)
  331. {
  332. pcs_raw("CS_CONFIG", b, n);
  333. }
  334. static void
  335. pcs_string(Device *, ulong, void *b, int n)
  336. {
  337. pcs_raw("CS_STRING", b, n);
  338. }
  339. static void
  340. pcs_endpoint(Device *, int, ulong, void *bb, int n)
  341. {
  342. byte *b = bb;
  343. if (debug & Dbginfo) {
  344. switch(b[2]) {
  345. case 0x01:
  346. fprint(2,
  347. "CS_ENDPOINT for TerminalID %d, delay %d, format_tag %#ux\n",
  348. b[3], b[4], b[5] | (b[6]<<8));
  349. break;
  350. case 0x02:
  351. fprint(2,
  352. "CS_INTERFACE FORMAT_TYPE %d, channels %d, subframesize %d, resolution %d, freqtype %d, ",
  353. b[3], b[4], b[5], b[6], b[7]);
  354. fprint(2, "freq0 %d, freq1 %d\n",
  355. b[8] | b[9]<<8 | b[10]<<16,
  356. b[11] | b[12]<<8 | b[13]<<16);
  357. break;
  358. default:
  359. pcs_raw("CS_INTERFACE", bb, n);
  360. }
  361. }
  362. }
  363. static void
  364. pcs_interface(Device *, int n, ulong, void *bb, int nb)
  365. {
  366. if ((debug & Dbginfo) && n >= 0)
  367. pcs_raw("CS_INTERFACE", bb, nb);
  368. }
  369. void
  370. pdesc(Device *d, int c, ulong csp, byte *b, int n)
  371. {
  372. int class, subclass, proto, dalt = -1, i, ep, ifc = -1;
  373. DConfig *dc;
  374. DEndpoint *de;
  375. DInterface *di;
  376. Dinf *dif;
  377. Endpt *dep;
  378. void (*f)(Device *, int, ulong, void*, int);
  379. class = Class(csp);
  380. if (c >= nelem(d->config)) {
  381. fprint(2, "Too many interfaces (%d of %d)\n",
  382. c, nelem(d->config));
  383. return;
  384. }
  385. if (debug & Dbginfo)
  386. fprint(2, "pdesc %d.%d [%d]\n", d->id, c, n);
  387. for(; n > 2 && b[0] && b[0] <= n; b += b[0]){
  388. if (debug & Dbginfo)
  389. fprint(2, "desc %d.%d [%d] %#2.2x: ", d->id, c, b[0], b[1]);
  390. switch (b[1]) {
  391. case CONFIGURATION:
  392. if(b[0] < DCONFLEN)
  393. return;
  394. dc = (DConfig*)b;
  395. d->config[c]->nif = dc->bNumInterfaces;
  396. d->config[c]->cval = dc->bConfigurationValue;
  397. d->config[c]->attrib = dc->bmAttributes;
  398. d->config[c]->milliamps = dc->MaxPower*2;
  399. d->nif += d->config[c]->nif;
  400. if (debug & Dbginfo)
  401. fprint(2, "config %d: tdlen %d ninterface %d iconfig %d attr %#.2x power %dmA\n",
  402. dc->bConfigurationValue,
  403. GET2(dc->wTotalLength),
  404. dc->bNumInterfaces, dc->iConfiguration,
  405. dc->bmAttributes, dc->MaxPower*2);
  406. break;
  407. case INTERFACE:
  408. if(n < DINTERLEN)
  409. return;
  410. di = (DInterface *)b;
  411. class = di->bInterfaceClass;
  412. subclass = di->bInterfaceSubClass;
  413. proto = di->bInterfaceProtocol;
  414. csp = CSP(class, subclass, proto);
  415. if (debug & Dbginfo)
  416. fprint(2, "interface %d: alt %d nept %d class %#x subclass %#x proto %d [%s] iinterface %d\n",
  417. di->bInterfaceNumber,
  418. di->bAlternateSetting,
  419. di->bNumEndpoints, class, subclass,
  420. proto, sclass(csp), di->iInterface);
  421. if (c < 0) {
  422. fprint(2, "Unexpected INTERFACE message\n");
  423. return;
  424. }
  425. ifc = di->bInterfaceNumber;
  426. dalt = di->bAlternateSetting;
  427. if (ifc < 0 || ifc >= nelem(d->config[c]->iface))
  428. sysfatal("Bad interface number %d", ifc);
  429. if (dalt < 0 ||
  430. dalt >= nelem(d->config[c]->iface[ifc]->dalt))
  431. sysfatal("Bad alternate number %d", dalt);
  432. if (d->config[c] == nil)
  433. sysfatal("No config");
  434. if (ifc == 0) {
  435. if (c == 0)
  436. d->ep[0]->csp = csp;
  437. d->config[c]->csp = csp;
  438. }
  439. dif = d->config[c]->iface[ifc];
  440. if (dif == nil) {
  441. d->config[c]->iface[ifc] = dif =
  442. mallocz(sizeof(Dinf), 1);
  443. dif->csp = csp;
  444. }
  445. dif->interface = di->bInterfaceNumber;
  446. break;
  447. case ENDPOINT:
  448. if(n < DENDPLEN)
  449. return;
  450. de = (DEndpoint *)b;
  451. if (debug & Dbginfo) {
  452. fprint(2, "addr %#2.2x attrib %#2.2x maxpkt %d interval %dms",
  453. de->bEndpointAddress, de->bmAttributes,
  454. GET2(de->wMaxPacketSize), de->bInterval);
  455. if(de->bEndpointAddress & 0x80)
  456. fprint(2, " [IN]");
  457. else
  458. fprint(2, " [OUT]");
  459. switch(de->bmAttributes&0x33){
  460. case 0:
  461. fprint(2, " [Control]");
  462. break;
  463. case 1:
  464. fprint(2, " [Iso]");
  465. switch(de->bmAttributes&0xc){
  466. case 0x4:
  467. fprint(2, " [Asynchronous]");
  468. break;
  469. case 0x8:
  470. fprint(2, " [Adaptive]");
  471. break;
  472. case 0xc:
  473. fprint(2, " [Synchronous]");
  474. break;
  475. }
  476. break;
  477. case 2:
  478. fprint(2, " [Bulk]");
  479. break;
  480. case 3:
  481. fprint(2, " [Interrupt]");
  482. break;
  483. }
  484. if(b[0] == 9)
  485. fprint(2, "refresh %d synchaddress %d",
  486. b[7], b[8]);
  487. fprint(2, "\n");
  488. }
  489. if (c < 0 || ifc < 0 || dalt < 0) {
  490. fprint(2, "Unexpected ENDPOINT message\n");
  491. return;
  492. }
  493. dif = d->config[c]->iface[ifc];
  494. if (dif == nil)
  495. sysfatal("d->config[%d]->iface[%d] == nil",
  496. c, ifc);
  497. if (dif->dalt[dalt] == nil)
  498. dif->dalt[dalt] = mallocz(sizeof(Dalt),1);
  499. dif->dalt[dalt]->attrib = de->bmAttributes;
  500. dif->dalt[dalt]->interval = de->bInterval;
  501. ep = de->bEndpointAddress & 0xf;
  502. dep = d->ep[ep];
  503. if (debug)
  504. fprint(2, "%s: endpoint addr %d\n", argv0, ep);
  505. if (dep == nil) {
  506. d->ep[ep] = dep = newendpt(d, ep, class);
  507. dep->dir = (de->bEndpointAddress & 0x80)?
  508. Ein: Eout;
  509. } else if ((dep->addr&0x80) !=
  510. (de->bEndpointAddress&0x80))
  511. dep->dir = Eboth;
  512. else
  513. fprint(2, "%s: endpoint %d already in use!\n",
  514. argv0, ep); // DEBUG
  515. if(dep->maxpkt < GET2(de->wMaxPacketSize))
  516. dep->maxpkt = GET2(de->wMaxPacketSize);
  517. dep->addr = de->bEndpointAddress;
  518. dep->type = de->bmAttributes & 0x03;
  519. dep->isotype = (de->bmAttributes>>2) & 0x03;
  520. dep->csp = csp;
  521. dep->conf = d->config[c];
  522. dep->iface = dif;
  523. for(i = 0; i < nelem(dif->endpt); i++)
  524. if(dif->endpt[i] == nil){
  525. dif->endpt[i] = dep;
  526. break;
  527. }
  528. if(i == nelem(dif->endpt))
  529. fprint(2, "Too many endpoints\n");
  530. if (d->nif <= ep)
  531. d->nif = ep+1;
  532. break;
  533. default:
  534. assert(nelem(dprinter) == 0x100);
  535. f = dprinter[b[1]];
  536. if(f != nil) {
  537. (*f)(d, c, dalt<<24 | ifc<<16 | (csp&0xffff),
  538. b, b[0]);
  539. if (debug & Dbginfo)
  540. fprint(2, "\n");
  541. } else
  542. if (verbose) {
  543. int i;
  544. fprint(2, "(unknown type)");
  545. for(i=1; i<b[0]; i++)
  546. fprint(2, " %.2x", b[i]);
  547. fprint(2, "\n");
  548. } else if (debug & Dbginfo)
  549. fprint(2, "\n");
  550. break;
  551. }
  552. n -= b[0];
  553. }
  554. }