1 #include <u.h> 2 #include <libc.h> 3 #include <thread.h> 4 #include <bio.h> 5 #include "usb.h" 6 7 static char *type[] = 8 { 9 [Econtrol] "Control", 10 [Eiso] "Isochronous", 11 [Ebulk] "Bulk", 12 [Eintr] "Interrupt", 13 }; 14 15 static char *isotype[] = 16 { 17 [Eunknown] "", 18 [Easync] " (Asynchronous)", 19 [Eadapt] " (Adaptive)", 20 [Esync] " (Synchronous)", 21 }; 22 23 void 24 dumpstring(int fd, char *prefix, Device *d, int index) 25 { 26 char *s; 27 28 if(index == 0) 29 return; 30 s = d->strings[index]; 31 if(s == nil) 32 fprint(fd, "%s<string %d>\n", prefix, index); 33 else 34 fprint(fd, "%s%s\n", prefix, s); 35 } 36 37 void 38 dumpdesc(int fd, char *prefix, Ddesc *desc) 39 { 40 uchar *p; 41 int i, j, len; 42 43 if(desc->ndesc == 0) 44 return; 45 fprint(fd, "%s%d descriptors\n", prefix, desc->ndesc); 46 p = desc->data; 47 for(i = 0; i < desc->ndesc; i++) { 48 fprint(fd, "%s\t", prefix); 49 len = *p++; 50 for(j = 1; j < len; j++) 51 fprint(fd, "%.2ux ", *p++); 52 fprint(fd, "\n"); 53 } 54 } 55 56 void 57 dumpdevice(int fd, Device *d) 58 { 59 int i, j, k; 60 Dconf *c; 61 Dinf *intf; 62 Dalt *alt; 63 Endpt *ep; 64 65 fprint(fd, "device %D: %lud.%lud.%lud %.4x/%.4x\n", 66 d, Class(d->csp), Subclass(d->csp), Proto(d->csp), d->vid, d->did); 67 fprint(fd, "\tUSB version: %x.%.2x\n", d->vers>>8, d->vers&0xff); 68 fprint(fd, "\tmaximum control packet size: %d\n", d->max0); 69 fprint(fd, "\tdevice release: %x.%.2x\n", d->release>>8, d->release&0xff); 70 dumpstring(fd, "\tmanufacturer: ", d, d->manufacturer); 71 dumpstring(fd, "\tproduct: ", d, d->product); 72 dumpstring(fd, "\tserial: ", d, d->serial); 73 fprint(fd, "\tconfigurations: %d\n", d->nconf); 74 for(i = 0; i < d->nconf; i++) { 75 c = &d->config[i]; 76 fprint(fd, "\t\tconfiguration %d: %d interfaces, %dmA required\n", c->cval, c->nif, c->milliamps); 77 dumpstring(fd, "\t\tname: ", d, c->config); 78 fprint(fd, "\t\tattributes:"); 79 if(c->attrib & Cbuspowered) 80 fprint(fd, " buspowered"); 81 if(c->attrib & Cselfpowered) 82 fprint(fd, " selfpowered"); 83 if(c->attrib & Cremotewakeup) 84 fprint(fd, " remotewakeup"); 85 fprint(fd, "\n"); 86 dumpdesc(fd, "\t\t\t", &c->desc); 87 for(j = 0; j < c->nif; j++) { 88 intf = &c->iface[j]; 89 fprint(fd, "\t\tinterface %d: %lud.%lud.%lud\n", j, Class(intf->csp), Subclass(intf->csp), Proto(intf->csp)); 90 dumpstring(fd, "\t\tname: ", d, intf->interface); 91 for(alt = intf->alt; alt != nil; alt = alt->next) { 92 fprint(fd, "\t\t\talternate %d: %d endpoints\n", alt->alt, alt->npt); 93 dumpdesc(fd, "\t\t\t\t", &alt->desc); 94 for(k = 0; k < alt->npt; k++) { 95 ep = &alt->ep[k]; 96 fprint(2, "\t\t\t\tendpoint %d-%s: type %s%s maxpkt %d poll %dms\n", 97 ep->addr, ep->dir == Ein ? "in" : "out", type[ep->type], isotype[ep->isotype], 98 ep->maxpkt, ep->pollms); 99 dumpdesc(fd, "\t\t\t\t\t", &ep->desc); 100 } 101 } 102 } 103 } 104 } 105