UsbInfo.Mod 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591
  1. MODULE UsbInfo; (** AUTHOR "staubesv"; PURPOSE "USB topology info" *)
  2. (**
  3. * This Module doesn't add any functionality to the USB system software. Its purpose is to represent the current state of
  4. * the USB system software and to control trace options.
  5. *
  6. * Usage:
  7. *
  8. * (* Information *)
  9. * UsbInfo.Show ~ will display the current USB topology
  10. * UsbInfo.Show details ~ will display the current USB topology with all available information (descriptors, configurations,...)
  11. * UsbInfo.ShowDrivers ~ will display information about registered USB device drivers and their instances
  12. * UsbInfo.ShowHc ~ will display all registered USB host controllers
  13. * UsbInfo.ShowHc details ~ will display diagnostic information of all registered USB host controllers
  14. * UsbInfo.ShowHc schedule ~ will display the scheduling data structures of all host controllers
  15. * UsbInfo.ShowHc pipes ~ will display all allocated pipes
  16. * UsbInfo.ShowHc pipemore ~ will display all allocated pipes including their QH/TDs
  17. * UsbInfo.ShowHc all ~ will display both the HC diagnostic information and its scheduling data structures
  18. *
  19. * (* Trace options *)
  20. * UsbInfo.TraceAll ~ enables all trace options
  21. * UsbInfo.TraceNone ~ disables all trace options
  22. * UsbInfo.TraceShow ~ show state of trace options
  23. *
  24. * (* See UsbDebug.Mod for a description of the individual trace optinos *)
  25. * UsbInfo.TraceOn Dm~ UsbInfo.TraceOff Dm~
  26. * UsbInfo.TraceOn Parsing~ UsbInfo.TraceOff Parsing~
  27. * UsbInfo.TraceOn DeviceStates~ UsbInfo.TraceOff DeviceStates~
  28. * UsbInfo.TraceOn Control~ UsbInfo.TraceOff Control~
  29. * UsbInfo.TraceOn ControlData~ UsbInfo.TraceOff ControlData~
  30. * UsbInfo.TraceOn Transfers~ UsbInfo.TraceOff Transfers~
  31. * UsbInfo.TraceOn Failed~ UsbInfo.TraceOff Failed~
  32. * UsbInfo.TraceOn ShortPackets ~ UsbInfo.TraceOff ShortPackets ~
  33. * UsbInfo.TraceOn Pipes~ UsbInfo.TraceOff Pipes~
  34. * UsbInfo.TraceOn Copying~ UsbInfo.TraceOff Copying~
  35. * UsbInfo.TraceOn Ioc~ UsbInfo.TraceOff Ioc~
  36. * UsbInfo.TraceOn Init~ UsbInfo.TraceOff Init~
  37. * UsbInfo.TraceOn Interrupts~ UsbInfo.TraceOff Interrupts~
  38. * UsbInfo.TraceOn Queuing~ UsbInfo.TraceOff Queuing~
  39. * UsbInfo.TraceOn HubRequests~ UsbInfo.TraceOff HubRequests~
  40. * UsbInfo.TraceOn Suspend~ UsbInfo.TraceOff Suspend~
  41. * UsbInfo.TraceOn Connects~ UsbInfo.TraceOff Connects~
  42. * UsbInfo.TraceOn Info~ UsbInfo.TraceOff Info~
  43. * UsbInfo.TraceOn Sensing~ UsbInfo.TraceOff Sensing~
  44. * UsbInfo.TraceOn ScRequests~ UsbInfo.TraceOff ScRequests~
  45. * UsbInfo.TraceOn ScTransfers~ UsbInfo.TraceOff ScTransfers~
  46. * UsbInfo.TraceOn CSWs~ UsbInfo.TraceOff CSWs~
  47. * UsbInfo.TraceOn CBWs~ UsbInfo.TraceOff CBWs~
  48. * UsbInfo.TraceOn ScInit~ UsbInfo.TraceOff ScInit~
  49. * UsbInfo.TraceOn Custom~ UsbInfo.TraceOff Custom~
  50. *
  51. * UsbInfo.TraceOn Info Sensing ScRequests ScTransfers CSWs CBWs ScInit~ turns on all mass storage device related trace options
  52. * UsbInfo.TraceOff Info Sensing ScRequests ScTransfers CSWs CBWs ScInit~ turns off ...
  53. *
  54. * UsbInfo.TraceOn Dm Parsing DeviceStates Failed Pipes Init HubRequests Connects Info ~ is interesting when connecting devices
  55. *
  56. * SystemTools.Free UsbInfo ~
  57. *
  58. * History:
  59. *
  60. * 17.11.2005 Created (staubesv)
  61. * 12.12.2005 Added schedule, pipes & all parameter to ShowHc (staubesv)
  62. * 01.02.2006 Adapted ShowHc to UsbHcdi changes (staubesv)
  63. * 06.02.2006 Added trace option control (staubesv)
  64. * 26.02.2006 Added Custom trace option (staubesv)
  65. * 28.06.2006 Adapted to modified Usb.GetRootHubs procedure (staubesv)
  66. * 04.07.2006 Added ShowHc pipemore (staubesv)
  67. * 05.01.2007 Added ShortPackets trace option, call ShowConfiguration in ShowDevice (staubesv)
  68. *)
  69. IMPORT
  70. SYSTEM,
  71. Streams, Commands, Plugins, Strings,
  72. UsbHcdi, Usb, Usbdi, UsbDebug;
  73. PROCEDURE ShowDeviceName(dev : Usb.UsbDevice; out : Streams.Writer);
  74. VAR descriptor : Usb.DeviceDescriptor;
  75. BEGIN
  76. descriptor := dev.descriptor (Usb.DeviceDescriptor);
  77. IF (descriptor # NIL) & (descriptor.sManufacturer # NIL) OR (descriptor.sProduct # NIL) THEN
  78. IF descriptor.sManufacturer # NIL THEN out.String(descriptor.sManufacturer^); out.Char(" "); END;
  79. IF descriptor.sProduct # NIL THEN out.String(descriptor.sProduct^); END;
  80. ELSE
  81. out.String("unknown device");
  82. END;
  83. END ShowDeviceName;
  84. (* Shows device descriptor / qualifier information and all configurations including its interfaces and endpoints. *)
  85. PROCEDURE ShowDevice(dev : Usb.UsbDevice; indent : LONGINT; details : BOOLEAN; out : Streams.Writer);
  86. VAR a, c, e, i : LONGINT;
  87. BEGIN
  88. IF dev.hubFlag THEN
  89. IF dev.parent = dev THEN out.String("Root "); END;
  90. out.String("Hub with "); out.Int(dev.nbrOfPorts, 0); out.String(" ports: ");
  91. END;
  92. ShowDeviceName(dev, out);
  93. IF ~details OR (dev.hubFlag & (dev.parent = dev)) THEN RETURN END;
  94. out.String("(S/N: ");
  95. IF dev.descriptor(Usb.DeviceDescriptor).sSerialNumber # NIL THEN out.String(dev.descriptor(Usb.DeviceDescriptor).sSerialNumber^); out.String(")");
  96. ELSE out.String("Not available)");
  97. END;
  98. out.Ln;
  99. Indent(indent+4, out);
  100. out.String("Address: "); out.Int(dev.address, 0); out.String(" ");
  101. IF dev.speed = UsbHcdi.LowSpeed THEN out.String(" [LowSpeed]");
  102. ELSIF dev.speed = UsbHcdi.FullSpeed THEN out.String(" [FullSpeed]");
  103. ELSIF dev.speed = UsbHcdi.HighSpeed THEN out.String(" [HighSpeed]");
  104. ELSE out.String(" [UnknownSpeed!!!]");
  105. END;
  106. out.Ln;
  107. Indent(indent+4, out); out.String("Device descriptor information: ");
  108. out.Ln;
  109. ShowDescriptor(dev.descriptor (Usb.DeviceDescriptor), indent+8, out);
  110. (* List all configurations *)
  111. FOR c := 0 TO dev.descriptor.bNumConfigurations-1 DO
  112. Indent(indent+12, out);
  113. out.String("Configuration "); out.Int(c, 0); out.String(":");
  114. IF dev.configurations[c](Usb.ConfigurationDescriptor).sConfiguration # NIL THEN out.String(dev.configurations[c](Usb.ConfigurationDescriptor).sConfiguration^); END;
  115. IF dev.actConfiguration = dev.configurations[c] THEN out.String(" [active]"); END; out.Ln;
  116. ShowConfiguration(dev.configurations[c](Usb.ConfigurationDescriptor), indent + 16, out);
  117. out.Ln;
  118. (* List all interfaces *)
  119. FOR i := 0 TO dev.configurations[c].bNumInterfaces - 1 DO
  120. Indent(indent+16, out);
  121. out.String("Interface "); out.Int(i, 0); out.String(": "); out.Ln;
  122. ShowInterface(dev.configurations[c].interfaces[i] (Usb.InterfaceDescriptor), indent+20, out); out.Ln;
  123. (* List all endpoints *)
  124. FOR e := 0 TO dev.configurations[c].interfaces[i].bNumEndpoints-1 DO
  125. ShowEndpoint(dev.configurations[c].interfaces[i].endpoints[e] (Usb.EndpointDescriptor), indent+24, out);
  126. END;
  127. (* List alternate interface if available *)
  128. Indent(indent+20, out);
  129. out.String("Alternate interface: ");
  130. IF dev.configurations[c].interfaces[i].numAlternateInterfaces = 0 THEN out.String("n/a"); out.Ln;
  131. ELSE
  132. FOR a := 0 TO dev.configurations[c].interfaces[i].numAlternateInterfaces-1 DO
  133. Indent(indent+20, out); out.String("Alternate Interface "); out.Int(a, 0); out.String(": ");
  134. ShowInterface(dev.configurations[c].interfaces[i].alternateInterfaces[a] (Usb.InterfaceDescriptor), indent+20, out); out.Ln;
  135. (* List all endpoints *)
  136. FOR e := 0 TO dev.configurations[c].interfaces[i].bNumEndpoints-1 DO
  137. ShowEndpoint(dev.configurations[c].interfaces[i].alternateInterfaces[a].endpoints[e] (Usb.EndpointDescriptor), indent+24, out);
  138. END;
  139. END;
  140. out.Ln;
  141. END;
  142. END;
  143. END;
  144. Indent(indent+4, out);
  145. out.String("Device qualifier information: ");
  146. IF dev.qualifier = NIL THEN out.String("n/a"); out.Ln;
  147. ELSE
  148. out.Ln;
  149. ShowDescriptor(dev.qualifier (Usb.DeviceDescriptor), indent + 8, out);
  150. FOR c := 0 TO dev.qualifier.bNumConfigurations-1 DO
  151. Indent(indent+12, out);
  152. out.String("Other-Speed Configuration "); out.Int(c, 0); out.String(":");
  153. IF dev.otherconfigurations[c](Usb.ConfigurationDescriptor).sConfiguration#NIL THEN out.String(dev.configurations[c](Usb.ConfigurationDescriptor).sConfiguration^); END;
  154. (* List all interfaces *)
  155. FOR i := 0 TO dev.otherconfigurations[c].bNumInterfaces - 1 DO
  156. out.Ln; Indent(indent+16, out);
  157. out.String("Interface "); out.Int(i, 0); out.String(": "); out.Ln;
  158. ShowInterface(dev.otherconfigurations[c].interfaces[i] (Usb.InterfaceDescriptor), indent+20, out); out.Ln;
  159. (* List all endpoints *)
  160. FOR e := 0 TO dev.otherconfigurations[c].interfaces[i].bNumEndpoints-1 DO
  161. ShowEndpoint(dev.otherconfigurations[c].interfaces[i].endpoints[e] (Usb.EndpointDescriptor), indent+24, out);
  162. END;
  163. (* List alternate interface if available *)
  164. Indent(indent+16, out);
  165. out.String("Alternate interface: ");
  166. IF dev.otherconfigurations[c].interfaces[i].numAlternateInterfaces = 0 THEN out.String("n/a"); out.Ln;
  167. ELSE
  168. FOR a := 0 TO dev.otherconfigurations[c].interfaces[i].numAlternateInterfaces-1 DO
  169. out.String("Alternate Interface "); out.Int(a, 0); out.String(": "); out.Ln;
  170. ShowInterface(dev.otherconfigurations[c].interfaces[i].alternateInterfaces[a] (Usb.InterfaceDescriptor), indent+20, out); out.Ln;
  171. (* List all endpoints *)
  172. FOR e := 0 TO dev.otherconfigurations[c].interfaces[i].bNumEndpoints-1 DO
  173. ShowEndpoint(dev.otherconfigurations[c].interfaces[i].alternateInterfaces[a].endpoints[e] (Usb.EndpointDescriptor), indent+24, out);
  174. END;
  175. END;
  176. END;
  177. END;
  178. END;
  179. END;
  180. END ShowDevice;
  181. (* Display textual respresenation of device descriptor or device qualifier *)
  182. PROCEDURE ShowDescriptor(d : Usb.DeviceDescriptor; indent : LONGINT; out : Streams.Writer);
  183. BEGIN
  184. Indent(indent, out);
  185. out.String("USB Version: "); PrintHex(LSH(d.bcdUSB, -8), out); out.Char("."); PrintHex(d.bcdUSB MOD 100H, out);
  186. out.String(", Device Class: "); PrintHex(d.bDeviceClass, out);
  187. out.String("H, Subclass: "); PrintHex(d.bDeviceSubClass, out);
  188. out.String("H, Protocol: "); PrintHex(d.bDeviceProtocol, out); out.String("H");
  189. out.Ln;
  190. Indent(indent, out);
  191. out.String("MaxPacketSize0: "); out.Int(d.bMaxPacketSize0, 0); out.String(" Bytes"); out.Ln;
  192. Indent(indent, out);
  193. out.String("idVendor: "); PrintHex(d.idVendor, out);
  194. out.String("H, idProduct: "); PrintHex(d.idProduct, out);
  195. out.String("H, Device Version: "); PrintHex(LSH(d.bcdDevice, -8), out); out.Char("."); PrintHex(d.bcdDevice MOD 100H, out);
  196. out.Ln;
  197. END ShowDescriptor;
  198. (* Display textual respresentation of a USB device configuration *)
  199. PROCEDURE ShowConfiguration(c : Usb.ConfigurationDescriptor; indent : LONGINT; out : Streams.Writer);
  200. BEGIN
  201. Indent(indent, out); out.String("ConfigurationValue: "); out.Int(c.bConfigurationValue, 0); out.Ln;
  202. Indent(indent, out); out.String ("MaxPower: "); out.Int(c.bMaxPower, 0); out.String(" mA "); out.Ln;
  203. Indent(indent, out); out.String("Power support: ");
  204. IF c.bmAttributes * {6} # {} THEN out.String("Self-Powered"); ELSE out.String("Bus-Powered"); END;
  205. out.Ln;
  206. Indent(indent, out); out.String("Remote Wake-up support: ");
  207. IF c.bmAttributes * {5} # {} THEN out.String("Yes"); ELSE out.String("No"); END;
  208. END ShowConfiguration;
  209. (* Display textual representation of a USB device interface *)
  210. PROCEDURE ShowInterface(i : Usb.InterfaceDescriptor; indent : LONGINT; out : Streams.Writer);
  211. VAR drv : Usbdi.Driver;
  212. BEGIN
  213. Indent(indent, out);
  214. IF i.sInterface # NIL THEN out.String(i.sInterface^); out.String(": "); END;
  215. out.String("[Class: "); PrintHex(i.bInterfaceClass, out);
  216. out.String("H Subclass: "); PrintHex(i.bInterfaceSubClass, out);
  217. out.String("H Protocol: "); PrintHex(i.bInterfaceProtocol, out);
  218. out.String("H #Endpoints: "); out.Int(i.bNumEndpoints, 0);
  219. out.String("]"); out.Ln;
  220. Indent(indent, out);
  221. drv := i.driver;
  222. out.String("Driver: ");
  223. IF drv # NIL THEN
  224. out.String("["); out.String(drv.name);
  225. out.String("("); out.String(drv.desc); out.String(")]");
  226. ELSE out.String("[No driver installed for this interface]");
  227. END;
  228. END ShowInterface;
  229. (* Display textual representation of a USB device endpoint *)
  230. PROCEDURE ShowEndpoint(e : Usb.EndpointDescriptor; indent : LONGINT; out : Streams.Writer);
  231. VAR attr : LONGINT;
  232. BEGIN
  233. Indent(indent, out);
  234. out.String("Endpoint "); out.Int(e.bEndpointAddress MOD 16, 0);
  235. out.String(":"); out.String(" [Type: ");
  236. attr := SYSTEM.VAL(LONGINT, e.bmAttributes);
  237. CASE attr OF
  238. 0 : out.String("Control");
  239. |1 : out.String("Isochronous");
  240. |2 : out.String("Bulk");
  241. |3 : out.String("Interrupt");
  242. ELSE
  243. out.String("unknown");
  244. END;
  245. IF (attr#0) & (attr<4) THEN
  246. out.String("(");
  247. IF (SYSTEM.VAL(SET, e.bEndpointAddress) * {7}) # {} THEN out.String("IN"); out.String(")");
  248. ELSE out.String("OUT)");
  249. END;
  250. END;
  251. IF attr = 1 THEN
  252. out.String(", Synchronization: ");
  253. CASE SYSTEM.VAL(LONGINT, LSH(SYSTEM.VAL(SET, attr) * {2..3}, -2)) OF
  254. 0 : out.String("None");
  255. |1: out.String("Asynchronous");
  256. |2: out.String("Adaptive");
  257. |3: out.String("Synchronous");
  258. END;
  259. out.String(", Usage: ");
  260. CASE SYSTEM.VAL(LONGINT, LSH(SYSTEM.VAL(SET, attr) * {2..3}, -2)) OF
  261. 0 : out.String("Data");
  262. |1: out.String("Feedback");
  263. |2: out.String("Implicit Feedback");
  264. |3: out.String("Reserved");
  265. END;
  266. END;
  267. out.String(" MaxPacketSize: "); out.Int(e.wMaxPacketSize, 0);
  268. out.String(" Bytes IRQinterval: "); out.Int(e.bInterval, 0); out.String(" ms]");
  269. out.Ln;
  270. END ShowEndpoint;
  271. (* Display textual representation of the specified device and its descendants *)
  272. PROCEDURE ShowDeviceChain(dev : Usb.UsbDevice; indent : LONGINT; details : BOOLEAN; out : Streams.Writer);
  273. VAR i, j : LONGINT;
  274. BEGIN
  275. IF dev = NIL THEN out.String("No device attached");
  276. ELSIF dev.hubFlag THEN
  277. ShowDevice(dev, indent, details, out); out.Ln;
  278. FOR i := 0 TO dev.nbrOfPorts - 1 DO
  279. FOR j := 0 TO indent - 1 DO out.Char(" "); END;
  280. out.String(" Port "); out.Int(i+1, 0); out.String(": ");
  281. IF dev.deviceAtPort[i] = NIL THEN out.String("No device attached."); out.Ln;
  282. ELSIF dev.portPermanentDisabled[i] THEN out.String("Permanent disable (error)"); out.Ln;
  283. ELSE ShowDeviceChain(dev.deviceAtPort[i], indent+8, details, out);
  284. END;
  285. END;
  286. ELSE ShowDevice(dev, indent, details, out); out.Ln;
  287. END;
  288. END ShowDeviceChain;
  289. PROCEDURE DoShow*(out : Streams.Writer; details: BOOLEAN);
  290. VAR
  291. i : LONGINT;
  292. rootHubs : Usb.RootHubArray;
  293. BEGIN
  294. out.String("Usb: Topology and device information: "); out.Ln;
  295. Usb.GetRootHubs(rootHubs);
  296. BEGIN {EXCLUSIVE}
  297. IF rootHubs # NIL THEN
  298. FOR i := 0 TO LEN(rootHubs)-1 DO
  299. ShowDeviceChain(rootHubs[i], 0, details, out);
  300. rootHubs[i] := NIL;
  301. END;
  302. ELSE out.String("No USB host controllers found."); out.Ln;
  303. END;
  304. END;
  305. END DoShow;
  306. (** Prints information about current usb tree *)
  307. PROCEDURE Show*(context : Commands.Context);
  308. VAR
  309. details : BOOLEAN;
  310. pstr : ARRAY 10 OF CHAR;
  311. BEGIN
  312. context.arg.SkipWhitespace; context.arg.String(pstr);
  313. details := Strings.Match("details", pstr);
  314. DoShow(context.out, details);
  315. END Show;
  316. (** Shows all registered drivers and their instances *)
  317. PROCEDURE ShowDrivers*(context : Commands.Context);
  318. VAR instances : Plugins.Table; i : LONGINT;
  319. BEGIN
  320. Usb.drivers.Show;
  321. context.out.Ln; context.out.String("Usb: Instances of registered device drivers: "); context.out.Ln;
  322. Usb.usbDrivers.GetAll(instances);
  323. IF instances=NIL THEN
  324. context.out.String("no device drivers instances installed"); context.out.Ln;
  325. ELSE
  326. FOR i:=0 TO LEN(instances)-1 DO
  327. context.out.String(" ");
  328. context.out.String(instances[i].name); context.out.String(" (");
  329. context.out.String(instances[i].desc); context.out.String(")");
  330. context.out.Ln;
  331. END;
  332. END;
  333. END ShowDrivers;
  334. (** Shows all registered USB host controllers. *)
  335. PROCEDURE ShowHc*(context : Commands.Context); (* ["details"|"schedule"|"all"] ~ *)
  336. VAR
  337. table : Plugins.Table; hcd : UsbHcdi.Hcd;
  338. pstr : ARRAY 10 OF CHAR;
  339. i : LONGINT;
  340. PROCEDURE ShowPipes(hcd : UsbHcdi.Hcd; details : BOOLEAN);
  341. VAR i, j, k : LONGINT; pipe : UsbHcdi.Pipe;
  342. BEGIN
  343. FOR i := 0 TO 127 DO (* search all addresses ... *)
  344. FOR j := 0 TO 15 DO (* ... and all endpoints for presence of a pipe *)
  345. FOR k := 0 TO 1 DO
  346. pipe := hcd.pipes[i][k][j];
  347. IF pipe # NIL THEN
  348. context.out.String("ADR: "); context.out.Int(i, 0); context.out.String(": "); context.out.Update; pipe.Show(details);
  349. IF details THEN TRACE(hcd); hcd.ShowPipe(pipe) END;
  350. END;
  351. END;
  352. END;
  353. END;
  354. END ShowPipes;
  355. BEGIN
  356. context.arg.SkipWhitespace; context.arg.String(pstr);
  357. UsbHcdi.controllers.GetAll(table);
  358. IF table # NIL THEN
  359. FOR i := 0 TO LEN(table)-1 DO
  360. hcd := table[i] (UsbHcdi.Hcd);
  361. context.out.String("**** "); context.out.String(hcd.name); context.out.String(" ("); context.out.String(hcd.desc); context.out.String(")"); context.out.Ln;
  362. context.out.Update;
  363. IF Strings.Match("schedule", pstr) THEN
  364. IF UsbDebug.Trace THEN hcd.ShowSchedule; ELSE context.out.String("UsbInfo: UsbDebug.Trace is FALSE. Cannot show schedule."); context.out.Ln; END;
  365. ELSIF Strings.Match("details", pstr) THEN
  366. IF UsbDebug.Trace THEN hcd.Diag; ELSE context.out.String("UsbInfo: UsbDebug.Trace is FALSE. Cannot show diagnostics."); context.out.Ln; END;
  367. ELSIF Strings.Match("pipes", pstr) THEN
  368. ShowPipes(hcd, FALSE);
  369. ELSIF Strings.Match("pipemore", pstr) THEN
  370. ShowPipes(hcd, TRUE);
  371. ELSIF Strings.Match("all", pstr) THEN
  372. IF UsbDebug.Trace THEN hcd.Diag; hcd.ShowSchedule;
  373. ELSE
  374. context.out.String("UsbInfo: UsbDebug.Trace is FALSE. Cannot show schedule/diagnostics."); context.out.Ln;
  375. END;
  376. ShowPipes(hcd, TRUE);
  377. END;
  378. context.out.Ln;
  379. END;
  380. ELSE
  381. context.out.String("UsbInfo: No USB host controllers found."); context.out.Ln;
  382. END;
  383. END ShowHc;
  384. (* Helper: Displays the number <was> in hex to the kernel log *)
  385. PROCEDURE PrintHex(was: LONGINT; out : Streams.Writer);
  386. VAR z,d,h,i:LONGINT;
  387. BEGIN
  388. z := 0;
  389. d := 16*16*16*16*16*16*16; (* what a quick hack *)
  390. FOR i:=0 TO 7 DO
  391. h := (was DIV d) MOD 16;
  392. IF (z = 1) OR (h # 0) OR (i = 7) THEN
  393. z := 1;
  394. IF h < 10 THEN out.Int(h,0); ELSE out.Char(CHR(ORD("A")+h-10)); END;
  395. END;
  396. d:=d DIV 16;
  397. END;
  398. END PrintHex;
  399. (* Helper *)
  400. PROCEDURE Indent(indent : LONGINT; out : Streams.Writer);
  401. VAR i : LONGINT;
  402. BEGIN
  403. FOR i := 0 TO indent-1 DO out.Char(" "); END;
  404. END Indent;
  405. (** Trace options interface *)
  406. PROCEDURE TraceAll*(context : Commands.Context);
  407. BEGIN
  408. IF UsbDebug.Trace THEN
  409. context.out.String("UsbInfo: All trace options enabled."); context.out.Ln;
  410. UsbDebug.traceDm := TRUE;
  411. UsbDebug.traceParsing := TRUE;
  412. UsbDebug.traceDeviceStates := TRUE;
  413. UsbDebug.traceControl := TRUE;
  414. UsbDebug.traceControlData := TRUE;
  415. UsbDebug.traceTransfers := TRUE;
  416. UsbDebug.traceFailed := TRUE;
  417. UsbDebug.traceShortPackets := TRUE;
  418. UsbDebug.tracePipes := TRUE;
  419. UsbDebug.traceCopying := TRUE;
  420. UsbDebug.traceIoc := TRUE;
  421. UsbDebug.traceInit := TRUE;
  422. UsbDebug.traceInterrupts := TRUE;
  423. UsbDebug.traceQueuing := TRUE;
  424. UsbDebug.traceHubRequests := TRUE;
  425. UsbDebug.traceSuspend := TRUE;
  426. UsbDebug.traceConnects := TRUE;
  427. UsbDebug.traceInfo := TRUE;
  428. UsbDebug.traceSensing := TRUE;
  429. UsbDebug.traceScRequests := TRUE;
  430. UsbDebug.traceScTransfers := TRUE;
  431. UsbDebug.traceCSWs := TRUE;
  432. UsbDebug.traceCBWs := TRUE;
  433. UsbDebug.traceScInit := TRUE;
  434. UsbDebug.traceCustom := TRUE;
  435. ELSE
  436. context.out.String("UsbInfo: UsbDebug.Trace is FALSE... cannot enable tracing."); context.out.Ln;
  437. END;
  438. END TraceAll;
  439. PROCEDURE TraceNone*(context : Commands.Context);
  440. BEGIN
  441. UsbDebug.traceDm := FALSE;
  442. UsbDebug.traceParsing := FALSE;
  443. UsbDebug.traceDeviceStates := FALSE;
  444. UsbDebug.traceControl := FALSE;
  445. UsbDebug.traceControlData := FALSE;
  446. UsbDebug.traceTransfers := FALSE;
  447. UsbDebug.traceFailed := FALSE;
  448. UsbDebug.traceShortPackets := FALSE;
  449. UsbDebug.tracePipes := FALSE;
  450. UsbDebug.traceCopying := FALSE;
  451. UsbDebug.traceIoc := FALSE;
  452. UsbDebug.traceInit := FALSE;
  453. UsbDebug.traceInterrupts := FALSE;
  454. UsbDebug.traceQueuing := FALSE;
  455. UsbDebug.traceHubRequests := FALSE;
  456. UsbDebug.traceSuspend := FALSE;
  457. UsbDebug.traceConnects := FALSE;
  458. UsbDebug.traceInfo := FALSE;
  459. UsbDebug.traceSensing := FALSE;
  460. UsbDebug.traceScRequests := FALSE;
  461. UsbDebug.traceScTransfers := FALSE;
  462. UsbDebug.traceCSWs := FALSE;
  463. UsbDebug.traceCBWs := FALSE;
  464. UsbDebug.traceScInit := FALSE;
  465. UsbDebug.traceCustom := FALSE;
  466. context.out.String("UsbInfo: All trace options disabled."); context.out.Ln;
  467. END TraceNone;
  468. PROCEDURE TraceShow*(context : Commands.Context);
  469. PROCEDURE ShowOn(on : BOOLEAN);
  470. BEGIN
  471. IF on THEN context.out.String("On"); ELSE context.out.String("Off"); END;
  472. END ShowOn;
  473. BEGIN
  474. context.out.String("UsbInfo: Trace options state: "); context.out.Ln;
  475. context.out.String("UsbDebug.Trace: "); ShowOn(UsbDebug.Trace); context.out.Ln;
  476. context.out.String("traceDm: "); ShowOn(UsbDebug.traceDm); context.out.Ln;
  477. context.out.String("traceParsing: "); ShowOn(UsbDebug.traceParsing); context.out.Ln;
  478. context.out.String("traceDeviceStates: "); ShowOn(UsbDebug.traceDeviceStates); context.out.Ln;
  479. context.out.String("traceControl: "); ShowOn(UsbDebug.traceControl); context.out.Ln;
  480. context.out.String("traceControlData: "); ShowOn(UsbDebug.traceControlData); context.out.Ln;
  481. context.out.String("traceTransfers: "); ShowOn(UsbDebug.traceTransfers); context.out.Ln;
  482. context.out.String("traceFailed: "); ShowOn(UsbDebug.traceFailed); context.out.Ln;
  483. context.out.String("traceShortPackets: "); ShowOn(UsbDebug.traceShortPackets); context.out.Ln;
  484. context.out.String("tracePipes: "); ShowOn(UsbDebug.tracePipes); context.out.Ln;
  485. context.out.String("traceCopying: "); ShowOn(UsbDebug.traceCopying); context.out.Ln;
  486. context.out.String("traceIoc: "); ShowOn(UsbDebug.traceIoc); context.out.Ln;
  487. context.out.String("traceInit: "); ShowOn(UsbDebug.traceInit); context.out.Ln;
  488. context.out.String("traceInterrupts: "); ShowOn(UsbDebug.traceInterrupts); context.out.Ln;
  489. context.out.String("traceQueuing: "); ShowOn(UsbDebug.traceQueuing); context.out.Ln;
  490. context.out.String("traceHubRequests: "); ShowOn(UsbDebug.traceHubRequests); context.out.Ln;
  491. context.out.String("traceSuspend: "); ShowOn(UsbDebug.traceSuspend); context.out.Ln;
  492. context.out.String("traceConnects: "); ShowOn(UsbDebug.traceConnects); context.out.Ln;
  493. context.out.String("traceInfo: "); ShowOn(UsbDebug.traceInfo); context.out.Ln;
  494. context.out.String("traceSensing: "); ShowOn(UsbDebug.traceSensing); context.out.Ln;
  495. context.out.String("traceScRequests: "); ShowOn(UsbDebug.traceScRequests); context.out.Ln;
  496. context.out.String("traceScTransfers: "); ShowOn(UsbDebug.traceScTransfers); context.out.Ln;
  497. context.out.String("traceCSWs: "); ShowOn(UsbDebug.traceCSWs); context.out.Ln;
  498. context.out.String("traceCBWs: "); ShowOn(UsbDebug.traceCBWs); context.out.Ln;
  499. context.out.String("traceScInit: "); ShowOn(UsbDebug.traceScInit); context.out.Ln;
  500. context.out.String("traceCustom: "); ShowOn(UsbDebug.traceCustom); context.out.Ln;
  501. END TraceShow;
  502. PROCEDURE TraceOn*(context : Commands.Context);
  503. BEGIN
  504. IF UsbDebug.Trace THEN
  505. TraceOnOff(context, TRUE);
  506. ELSE
  507. context.out.String("UsbInfo: UsbDebug.Trace is FALSE... cannot use tracing."); context.out.Ln;
  508. END;
  509. END TraceOn;
  510. PROCEDURE TraceOff*(context : Commands.Context);
  511. BEGIN
  512. TraceOnOff(context, FALSE);
  513. END TraceOff;
  514. PROCEDURE TraceOnOff(context : Commands.Context; on : BOOLEAN);
  515. VAR pstr : ARRAY 32 OF CHAR; invalid : BOOLEAN;
  516. BEGIN
  517. WHILE context.arg.GetString(pstr) DO
  518. invalid := FALSE;
  519. IF Strings.Match("Dm", pstr) THEN UsbDebug.traceDm := on;
  520. ELSIF Strings.Match("Parsing", pstr) THEN UsbDebug.traceParsing := on;
  521. ELSIF Strings.Match("DeviceStates", pstr) THEN UsbDebug.traceDeviceStates := on;
  522. ELSIF Strings.Match("Control", pstr) THEN UsbDebug.traceControl := on;
  523. ELSIF Strings.Match("ControlData", pstr) THEN UsbDebug.traceControlData := on;
  524. ELSIF Strings.Match("Transfers", pstr) THEN UsbDebug.traceTransfers := on;
  525. ELSIF Strings.Match("Failed", pstr) THEN UsbDebug.traceFailed := on;
  526. ELSIF Strings.Match("ShortPackets", pstr) THEN UsbDebug.traceShortPackets := on;
  527. ELSIF Strings.Match("Pipes", pstr) THEN UsbDebug.tracePipes := on;
  528. ELSIF Strings.Match("Copying", pstr) THEN UsbDebug.traceCopying := on;
  529. ELSIF Strings.Match("Ioc", pstr) THEN UsbDebug.traceIoc := on;
  530. ELSIF Strings.Match("Init", pstr) THEN UsbDebug.traceInit := on;
  531. ELSIF Strings.Match("Interrupts", pstr) THEN UsbDebug.traceInterrupts := on;
  532. ELSIF Strings.Match("Queuing", pstr) THEN UsbDebug.traceQueuing := on;
  533. ELSIF Strings.Match("HubRequests", pstr) THEN UsbDebug.traceHubRequests := on;
  534. ELSIF Strings.Match("Suspend", pstr) THEN UsbDebug.traceSuspend := on;
  535. ELSIF Strings.Match("Connects", pstr) THEN UsbDebug.traceConnects := on;
  536. ELSIF Strings.Match("Info", pstr) THEN UsbDebug.traceInfo := on;
  537. ELSIF Strings.Match("Sensing", pstr) THEN UsbDebug.traceSensing := on;
  538. ELSIF Strings.Match("ScRequests", pstr) THEN UsbDebug.traceScRequests := on;
  539. ELSIF Strings.Match("ScTransfers", pstr) THEN UsbDebug.traceScTransfers := on;
  540. ELSIF Strings.Match("CSWs", pstr) THEN UsbDebug.traceCSWs := on;
  541. ELSIF Strings.Match("CBWs", pstr) THEN UsbDebug.traceCBWs := on;
  542. ELSIF Strings.Match("ScInit", pstr) THEN UsbDebug.traceScInit := on;
  543. ELSIF Strings.Match("Custom", pstr) THEN UsbDebug.traceCustom := on;
  544. ELSE
  545. context.error.String("Trace option '"); context.error.String(pstr); context.error.String("' not known."); context.error.Ln;
  546. invalid := TRUE;
  547. END;
  548. IF ~invalid THEN
  549. context.out.String("Trace option '"); context.out.String(pstr); context.out.String("' turned ");
  550. IF on THEN context.out.String("on."); ELSE context.out.String("off."); END;
  551. END;
  552. context.out.Ln;
  553. END;
  554. END TraceOnOff;
  555. END UsbInfo.
  556. UsbInfo.Open ~
  557. UsbInfo.Show ~
  558. UsbInfo.Show details ~
  559. UsbInfo.ShowDrivers ~
  560. UsbInfo.ShowHc ~
  561. UsbInfo.ShowHc details ~
  562. SystemTools.Free UsbInfo ~