Minor fixes to comments.
[AROS.git] / rom / usb / poseidon / PsdDevLister.c
blobce7f44764d34b4fa29f886b14cacf05ae64c26b0
1 /*
2 ** PsdDevLister by Chris Hodges <chrisly@platon42.de>
3 */
5 #include <stdio.h>
6 #include <stdlib.h>
7 #include <string.h>
8 #include <exec/exec.h>
9 #include <libraries/poseidon.h>
10 #include <dos/dos.h>
12 #include <proto/poseidon.h>
13 #include <proto/exec.h>
14 #include <proto/dos.h>
16 #define ARGS_SHOWROOT 0
17 #define ARGS_QUICK 1
18 #define ARGS_STRINGS 2
19 #define ARGS_SIZEOF 3
21 static const char *template = "SHOWROOT/S,QUICK/S,STRINGS/S";
22 const char *version = "$VER: PsdDevLister 4.0 (03.06.09) by Chris Hodges <chrisly@platon42.de>";
23 static IPTR ArgsArray[ARGS_SIZEOF];
24 static struct RDArgs *ArgsHook = NULL;
26 void fail(char *str)
28 if(ArgsHook)
30 FreeArgs(ArgsHook);
31 ArgsHook = NULL;
33 if(str)
35 PutStr(str);
36 exit(20);
38 exit(0);
41 int main(int argc, char *argv[])
43 struct Library *ps;
44 STRPTR errmsg = NULL;
45 APTR pd;
46 APTR pp;
47 struct MsgPort *mp;
48 IPTR devadr;
49 IPTR devhubport;
50 struct Node *devhub;
51 IPTR devusbvers;
52 IPTR devclass;
53 IPTR devsubclass;
54 IPTR devproto;
55 IPTR devvendorid;
56 IPTR devprodid;
57 IPTR devversion;
58 STRPTR devmanufact;
59 STRPTR devprodname;
60 STRPTR devserial;
61 STRPTR devidstr;
62 STRPTR devhubname;
63 IPTR devcurrlang;
64 IPTR devclonecount;
65 UWORD *devlangarray;
66 IPTR devislowspeed;
67 IPTR devishighspeed;
68 IPTR devisconnected;
69 IPTR devhasaddress;
70 IPTR devhasdevdesc;
71 IPTR devisconfigured;
72 IPTR devissuspended;
73 IPTR devneedssplit;
74 IPTR devnumcfgs;
75 IPTR devlowpower;
76 IPTR devpoweravail;
77 IPTR devpowerdrain;
78 IPTR devmaxpktsize0;
79 IPTR devhubthinktime;
80 #ifdef AROS_USB30_CODE
81 IPTR devissuperspeed;
82 #endif
84 struct List *cfgs;
85 struct Node *pc;
86 IPTR cfgselfpow;
87 IPTR cfgremwake;
88 IPTR cfgnum;
89 IPTR cfgmaxpower;
90 STRPTR cfgname;
91 IPTR cfgnumifs;
93 struct List *ifs;
94 struct Node *pif;
95 struct Node *altpif;
96 struct List *altpiflist;
98 struct List *descriptors = NULL;
99 struct Node *pdd;
100 IPTR desctype;
101 UBYTE *descdata;
102 IPTR desclen;
103 UWORD cnt;
104 STRPTR descname;
106 IPTR ifnum;
107 IPTR ifaltnum;
108 IPTR ifclass;
109 IPTR ifsubclass;
110 IPTR ifproto;
111 STRPTR ifname;
112 STRPTR ifidstr;
113 IPTR ifnumeps;
115 APTR binding;
116 IPTR hasappbinding;
117 struct Task *apptask;
118 struct Library *bindingcls;
120 struct List *eps;
121 struct Node *pep;
122 IPTR episin;
123 IPTR epnum;
124 IPTR eptranstype;
125 IPTR epmaxpktsize;
126 IPTR epinterval;
127 IPTR epnumtransmu;
128 IPTR epsynctype;
129 IPTR epusagetype;
131 STRPTR strdesc;
132 STRPTR strthinktime;
134 if(!(ArgsHook = ReadArgs(template, ArgsArray, NULL)))
136 fail("Wrong arguments!\n");
139 if((ps = OpenLibrary("poseidon.library", 4)))
141 pd = NULL;
142 mp = CreateMsgPort();
143 psdLockReadPBase();
144 while((pd = psdGetNextDevice(pd)))
146 psdLockReadDevice(pd);
147 devhubport = 0;
148 devneedssplit = 0;
149 devlowpower = 0;
150 devpoweravail = 0;
151 devpowerdrain = 0;
152 devmaxpktsize0 = 0;
153 devhubthinktime = 0;
154 devissuspended = 0;
155 psdGetAttrs(PGA_DEVICE, pd,
156 DA_Address, &devadr,
157 DA_HubDevice, &devhub,
158 DA_HubThinkTime, &devhubthinktime,
159 DA_AtHubPortNumber, &devhubport,
160 DA_UsbVersion, &devusbvers,
161 DA_MaxPktSize0, &devmaxpktsize0,
162 DA_Class, &devclass,
163 DA_SubClass, &devsubclass,
164 DA_Protocol, &devproto,
165 DA_VendorID, &devvendorid,
166 DA_ProductID, &devprodid,
167 DA_Version, &devversion,
168 DA_Manufacturer, &devmanufact,
169 DA_ProductName, &devprodname,
170 DA_SerialNumber, &devserial,
171 DA_CloneCount, &devclonecount,
172 DA_IDString, &devidstr,
173 DA_CurrLangID, &devcurrlang,
174 DA_LangIDArray, &devlangarray,
175 DA_IsLowspeed, &devislowspeed,
176 DA_IsHighspeed, &devishighspeed,
177 #ifdef AROS_USB30_CODE
178 DA_IsSuperspeed, &devissuperspeed,
179 #endif
180 DA_IsConnected, &devisconnected,
181 DA_NeedsSplitTrans, &devneedssplit,
182 DA_HasAddress, &devhasaddress,
183 DA_HasDevDesc, &devhasdevdesc,
184 DA_IsConfigured, &devisconfigured,
185 DA_IsSuspended, &devissuspended,
186 DA_NumConfigs, &devnumcfgs,
187 DA_ConfigList, &cfgs,
188 DA_Binding, &binding,
189 DA_BindingClass, &bindingcls,
190 DA_HasAppBinding, &hasappbinding,
191 DA_LowPower, &devlowpower,
192 DA_PowerDrained, &devpowerdrain,
193 DA_PowerSupply, &devpoweravail,
194 DA_DescriptorList, &descriptors,
195 TAG_END);
196 if(devhub)
198 psdGetAttrs(PGA_DEVICE, devhub,
199 DA_ProductName, &devhubname,
200 TAG_END);
201 } else {
202 devhubname = "Root";
203 if(!ArgsArray[ARGS_SHOWROOT])
205 Printf("Skipping '%s' (use SHOWROOT to list)\n", devidstr);
206 PutStr("---------------------------------------------------------------------------\n");
207 psdUnlockDevice(pd);
208 continue;
211 strthinktime = "";
212 if((devclass == HUB_CLASSCODE) && devishighspeed)
214 switch(devhubthinktime)
216 case 0:
217 strthinktime = " (Hub Think Time: 8 bit times)";
218 break;
219 case 1:
220 strthinktime = " (Hub Think Time: 16 bit times)";
221 break;
222 case 2:
223 strthinktime = " (Hub Think Time: 24 bit times)";
224 break;
225 case 3:
226 strthinktime = " (Hub Think Time: 32 bit times)";
227 break;
230 Printf(" Poseidon DevID : '%s'\n"
231 " Product Name : '%s' (ID: %04lx, Vers: %04lx)\n"
232 " Manufacturer : '%s' (Vendor: %04lx (%s))\n"
233 " Serial Number : '%s' (USBVers: %04lx)\n"
234 " Device State : %s%s%s%s%s%s%s\n"
235 " Device Address : %ld (Port %ld at %s)\n"
236 " Class/Sub/Proto : %ld/%ld/%ld (%s)\n"
237 " MaxPktSize EP 0 : %ld%s\n"
238 " Power Check : Supply = %ldmA, Drain = %ldmA%s\n"
239 " Current Language: %s\n",
240 devidstr,
241 devprodname, devprodid, devversion,
242 devmanufact, devvendorid,
243 psdNumToStr(NTS_VENDORID, (LONG) devvendorid, "unknown"),
244 devserial, devusbvers,
245 #ifdef AROS_USB30_CODE
246 devislowspeed ? "lowspeed " : (devissuperspeed ? "superspeed " : (devishighspeed ? "highspeed " : "fullspeed ")),
247 #else
248 devislowspeed ? "lowspeed " : (devishighspeed ? "highspeed " : "fullspeed "),
249 #endif
250 devisconnected ? "connected " : "disconnected ",
251 devhasaddress ? "hasaddress " : "",
252 devhasdevdesc ? "hasdevdesc " : "",
253 devisconfigured ? "configured " : "",
254 devissuspended ? "suspended " : "",
255 devneedssplit ? "\n SplitTransaction: USB1.1 at USB2.0 port!" : "",
256 devadr,
257 devhubport, devhubname,
258 devclass, devsubclass, devproto,
259 psdNumToStr(NTS_COMBOCLASS, (devclass<<NTSCCS_CLASS)|(devsubclass<<NTSCCS_SUBCLASS)|(devproto<<NTSCCS_PROTO)|
260 NTSCCF_CLASS|NTSCCF_SUBCLASS|NTSCCF_PROTO, "<unknown>"),
261 devmaxpktsize0, strthinktime,
262 devpoweravail, devpowerdrain,
263 devlowpower ? " LOWPOWER!" : "",
264 psdNumToStr(NTS_LANGID, devcurrlang, "<unknown>"));
265 if(devlangarray && (!ArgsArray[ARGS_QUICK]))
267 UWORD *wptr = devlangarray;
268 ULONG perline = 0;
269 PutStr(" Supported Langs : ");
270 while(*wptr)
272 PutStr(psdNumToStr(NTS_LANGID, (ULONG) *wptr, "<unknown>"));
273 wptr++;
274 if(*wptr)
276 PutStr(", ");
278 if(++perline > 2)
280 PutStr("\n ");
281 perline = 0;
284 PutStr("\n");
285 if(ArgsArray[ARGS_STRINGS])
287 ULONG idx = 1;
288 pp = psdAllocPipe(pd, mp, NULL);
289 while(pp)
291 strdesc = psdGetStringDescriptor(pp, idx);
292 if(strdesc)
294 Printf(" String descriptor %04ld: '%s'\n", idx, strdesc);
295 psdFreeVec(strdesc);
296 } else {
297 if(idx > 10)
299 break;
302 idx++;
303 if(idx > 100)
305 PutStr(" ... aborting\n");
306 break;
309 psdFreePipe(pp);
312 if(binding)
314 if(hasappbinding)
316 psdGetAttrs(PGA_APPBINDING, binding,
317 ABA_Task, &apptask,
318 TAG_END);
319 Printf("\n This device is bound to application %s with context %08lx.\n",
320 apptask->tc_Node.ln_Name, binding);
321 } else {
322 Printf("\n This device is bound to %s, context %08lx.\n",
323 bindingcls->lib_Node.ln_Name, binding);
326 Printf("\n %ld configuration(s):\n", devnumcfgs);
327 pc = cfgs->lh_Head;
328 while(pc->ln_Succ)
330 psdGetAttrs(PGA_CONFIG, pc,
331 CA_SelfPowered, &cfgselfpow,
332 CA_RemoteWakeup, &cfgremwake,
333 CA_ConfigNum, &cfgnum,
334 CA_MaxPower, &cfgmaxpower,
335 CA_ConfigName, &cfgname,
336 CA_NumInterfaces, &cfgnumifs,
337 CA_InterfaceList, &ifs,
338 TAG_END);
339 Printf("\n · Config %ld (%s)\n"
340 " Attrs : %s %s\n"
341 " MaxPower: %ld mA\n",
342 cfgnum, cfgname,
343 cfgselfpow ? "self-powered " : "bus-powered ",
344 cfgremwake ? "remote-wakeup" : "",
345 cfgmaxpower);
346 Printf("\n %ld interface(s) for this config:", cfgnumifs);
347 pif = ifs->lh_Head;
348 while(pif->ln_Succ)
350 altpif = pif;
353 psdGetAttrs(PGA_INTERFACE, altpif,
354 IFA_InterfaceNum, &ifnum,
355 IFA_AlternateNum, &ifaltnum,
356 IFA_Class, &ifclass,
357 IFA_SubClass, &ifsubclass,
358 IFA_Protocol, &ifproto,
359 IFA_InterfaceName, &ifname,
360 IFA_IDString, &ifidstr,
361 IFA_NumEndpoints, &ifnumeps,
362 IFA_EndpointList, &eps,
363 IFA_AlternateIfList, &altpiflist,
364 IFA_Binding, &binding,
365 IFA_BindingClass, &bindingcls,
366 TAG_END);
367 Printf("\n · Interface %ld (%s) (ID: '%s')\n"
368 " Alternate Setting: %ld\n"
369 " Class/Sub/Proto : %ld/%ld/%ld (%s)\n",
370 ifnum, ifname, ifidstr,
371 ifaltnum,
372 ifclass, ifsubclass, ifproto,
373 psdNumToStr(NTS_COMBOCLASS, (ifclass<<NTSCCS_CLASS)|(ifsubclass<<NTSCCS_SUBCLASS)|(ifproto<<NTSCCS_PROTO)|
374 NTSCCF_CLASS|NTSCCF_SUBCLASS|NTSCCF_PROTO, "<unknown>"));
375 if(binding)
377 Printf("\n This interface is bound to %s, context %08lx.\n",
378 bindingcls->lib_Node.ln_Name, binding);
380 if(ArgsArray[ARGS_QUICK])
382 Printf("\n %ld endpoint(s).\n", ifnumeps);
383 } else {
384 Printf("\n %ld endpoint(s) for this interface:\n", ifnumeps);
385 pep = eps->lh_Head;
386 while(pep->ln_Succ)
388 epnumtransmu = 0;
389 epsynctype = 0;
390 epusagetype = 0;
391 psdGetAttrs(PGA_ENDPOINT, pep,
392 EA_IsIn, &episin,
393 EA_EndpointNum, &epnum,
394 EA_TransferType, &eptranstype,
395 EA_MaxPktSize, &epmaxpktsize,
396 EA_Interval, &epinterval,
397 EA_NumTransMuFrame, &epnumtransmu,
398 EA_SyncType, &epsynctype,
399 EA_UsageType, &epusagetype,
400 TAG_END);
401 Printf(" · Endpoint %ld (%s %s)\n"
402 " MaxPktSize: %s%ld\n",
403 epnum, psdNumToStr(NTS_TRANSTYPE, eptranstype, "?"),
404 episin ? "<-[ IN" : "OUT ]->",
405 (epnumtransmu == 2) ? "2x " : ((epnumtransmu == 3) ? "3x " : ""),
406 epmaxpktsize);
408 if(devishighspeed || ((eptranstype != USEAF_CONTROL) && (eptranstype != USEAF_BULK)))
410 Printf(" %s : %ld %s\n",
411 (((eptranstype == USEAF_CONTROL) || (eptranstype == USEAF_BULK)) && devishighspeed) ? "NAK-Rate" : "Interval",
412 epinterval,
413 devishighspeed ? "µFrames" : "ms");
415 if(eptranstype == USEAF_ISOCHRONOUS)
417 Printf(" SyncType : %s\n"
418 " UsageType : %s\n",
419 psdNumToStr(NTS_SYNCTYPE, epsynctype, "?"),
420 psdNumToStr(NTS_USAGETYPE, epusagetype, "?"));
422 pep = pep->ln_Succ;
425 if(altpif == pif)
427 altpif = (struct Node *) altpiflist->lh_Head;
428 /* check for alternate settings */
429 if(!altpif->ln_Succ)
431 Printf("\n No alternate settings.\n");
432 break;
434 Printf("\n Alternate settings:\n");
435 } else {
436 altpif = altpif->ln_Succ;
437 if(!altpif->ln_Succ)
439 break;
442 } while(TRUE);
443 pif = pif->ln_Succ;
445 pc = pc->ln_Succ;
447 if(descriptors && (!ArgsArray[ARGS_QUICK]))
449 pdd = descriptors->lh_Head;
450 PutStr("\n Standard Descriptors:");
451 while(pdd->ln_Succ)
453 pc = NULL;
454 pif = NULL;
455 pep = NULL;
456 ifclass = 0;
457 descname = NULL;
458 psdGetAttrs(PGA_DESCRIPTOR, pdd,
459 DDA_Config, &pc,
460 DDA_Interface, &pif,
461 DDA_Endpoint, &pep,
462 DDA_DescriptorType, &desctype,
463 DDA_DescriptorLength, &desclen,
464 DDA_DescriptorData, &descdata,
465 DDA_Name, &descname,
466 TAG_END);
467 if(pif)
469 psdGetAttrs(PGA_INTERFACE, pif,
470 IFA_Class, &ifclass,
471 TAG_END);
473 if(!descname)
475 descname = psdNumToStr(NTS_DESCRIPTOR, desctype|(ifclass<<8), NULL);
477 if(!descname)
479 descname = psdNumToStr(NTS_DESCRIPTOR, desctype, "<unknown>");
481 Printf("\n Desc. %02lx (%s), %ld bytes",
482 desctype,
483 descname,
484 desclen);
485 if(pc)
487 psdGetAttrs(PGA_CONFIG, pc,
488 CA_ConfigNum, &cfgnum,
489 TAG_END);
490 if(pif)
492 psdGetAttrs(PGA_INTERFACE, pif,
493 IFA_InterfaceNum, &ifnum,
494 IFA_AlternateNum, &ifaltnum,
495 TAG_END);
496 if(pep)
498 psdGetAttrs(PGA_ENDPOINT, pep,
499 EA_EndpointNum, &epnum,
500 TAG_END);
501 Printf(" (EP %ld, IF %ld/%ld, Cfg %ld)", epnum, ifnum, ifaltnum, cfgnum);
502 } else {
503 Printf(" (Iface %ld/%ld, Cfg %ld)", ifnum, ifaltnum, cfgnum);
505 } else {
506 Printf(" (Config %ld)", cfgnum);
509 // skip basic descriptors
510 if(!((desctype >= UDT_DEVICE) && (desctype <= UDT_ENDPOINT)))
512 PutStr("\n");
513 cnt = 0;
514 while(desclen--)
516 if(!(cnt & 15))
518 Printf(" %02lx:", cnt);
520 Printf(" %02lx", *descdata++);
521 if((!(++cnt & 15)) && desclen)
523 PutStr("\n");
527 pdd = pdd->ln_Succ;
529 PutStr("\n");
531 Printf("\n Google: http://www.google.com/search?q=usb+0x%04lx+0x%04lx\n",
532 devvendorid, devprodid);
533 psdUnlockDevice(pd);
534 PutStr("---------------------------------------------------------------------------\n");
536 psdUnlockPBase();
537 DeleteMsgPort(mp);
538 CloseLibrary(ps);
539 } else {
540 errmsg = "Unable to open poseidon.library\n";
543 fail(errmsg);
544 return(0); // never gets here, just to shut the compiler up