19a747e4fSDavid du Colombier #include <u.h> 29a747e4fSDavid du Colombier #include <libc.h> 39a747e4fSDavid du Colombier #include <thread.h> 49a747e4fSDavid du Colombier #include <bio.h> 59a747e4fSDavid du Colombier #include "usb.h" 69a747e4fSDavid du Colombier 7*906943f9SDavid du Colombier int usbdebug; 87f0337cdSDavid du Colombier 9*906943f9SDavid du Colombier static char *edir[] = {"in", "out", "inout"}; 10*906943f9SDavid du Colombier static char *etype[] = {"ctl", "iso", "bulk", "intr"}; 11*906943f9SDavid du Colombier static char* cnames[] = 12*906943f9SDavid du Colombier { 13*906943f9SDavid du Colombier "none", "audio", "comms", "hid", "", 14*906943f9SDavid du Colombier "", "", "printer", "storage", "hub", "data" 159a747e4fSDavid du Colombier }; 16*906943f9SDavid du Colombier static char* devstates[] = 17*906943f9SDavid du Colombier { 18*906943f9SDavid du Colombier "detached", "attached", "enabled", "assigned", "configured" 199a747e4fSDavid du Colombier }; 209a747e4fSDavid du Colombier 217f0337cdSDavid du Colombier char* 22*906943f9SDavid du Colombier classname(int c) 237f0337cdSDavid du Colombier { 24*906943f9SDavid du Colombier static char buf[30]; 257f0337cdSDavid du Colombier 26*906943f9SDavid du Colombier if(c >= 0 && c < nelem(cnames)) 27*906943f9SDavid du Colombier return cnames[c]; 287f0337cdSDavid du Colombier else{ 29*906943f9SDavid du Colombier seprint(buf, buf+30, "%d", c); 30*906943f9SDavid du Colombier return buf; 317f0337cdSDavid du Colombier } 329a747e4fSDavid du Colombier } 339a747e4fSDavid du Colombier 34*906943f9SDavid du Colombier char* 35*906943f9SDavid du Colombier hexstr(void *a, int n) 369a747e4fSDavid du Colombier { 37*906943f9SDavid du Colombier int i; 38*906943f9SDavid du Colombier uchar *b; 39*906943f9SDavid du Colombier char *dbuff; 407f0337cdSDavid du Colombier char *s; 41*906943f9SDavid du Colombier char *e; 427f0337cdSDavid du Colombier 43*906943f9SDavid du Colombier b = a; 44*906943f9SDavid du Colombier dbuff = s = emallocz(1024, 0); 45*906943f9SDavid du Colombier *s = 0; 46*906943f9SDavid du Colombier e = s+1024; 47*906943f9SDavid du Colombier for(i=0; i < n; i++) 48*906943f9SDavid du Colombier s = seprint(s, e, " %.2ux", b[i]); 49*906943f9SDavid du Colombier if(s == e) 50*906943f9SDavid du Colombier fprint(2, "%s: usb/lib: hexdump: bug: small buffer\n", argv0); 51*906943f9SDavid du Colombier return dbuff; 527f0337cdSDavid du Colombier } 537f0337cdSDavid du Colombier 54*906943f9SDavid du Colombier static char* 55*906943f9SDavid du Colombier seprintiface(char *s, char *e, Iface *i) 567f0337cdSDavid du Colombier { 57*906943f9SDavid du Colombier int j; 58*906943f9SDavid du Colombier Altc *a; 59*906943f9SDavid du Colombier Ep *ep; 60*906943f9SDavid du Colombier char *eds, *ets; 617f0337cdSDavid du Colombier 62*906943f9SDavid du Colombier s = seprint(s, e, "\t\tiface csp %s.%uld.%uld\n", 63*906943f9SDavid du Colombier classname(Class(i->csp)), Subclass(i->csp), Proto(i->csp)); 64*906943f9SDavid du Colombier for(j = 0; j < Naltc; j++){ 65*906943f9SDavid du Colombier a=i->altc[j]; 66*906943f9SDavid du Colombier if(a == nil) 677f0337cdSDavid du Colombier break; 68*906943f9SDavid du Colombier s = seprint(s, e, "\t\t alt %d attr %d ival %d", 69*906943f9SDavid du Colombier j, a->attrib, a->interval); 70*906943f9SDavid du Colombier if(a->aux != nil) 71*906943f9SDavid du Colombier s = seprint(s, e, " devspec %p\n", a->aux); 727f0337cdSDavid du Colombier else 73*906943f9SDavid du Colombier s = seprint(s, e, "\n"); 747f0337cdSDavid du Colombier } 75*906943f9SDavid du Colombier for(j = 0; j < Nep; j++){ 76*906943f9SDavid du Colombier ep = i->ep[j]; 77*906943f9SDavid du Colombier if(ep == nil) 787f0337cdSDavid du Colombier break; 79*906943f9SDavid du Colombier eds = ets = ""; 80*906943f9SDavid du Colombier if(ep->dir <= nelem(edir)) 81*906943f9SDavid du Colombier eds = edir[ep->dir]; 82*906943f9SDavid du Colombier if(ep->type <= nelem(etype)) 83*906943f9SDavid du Colombier ets = etype[ep->type]; 84*906943f9SDavid du Colombier s = seprint(s, e, "\t\t ep id %d addr %d dir %s type %s" 85*906943f9SDavid du Colombier " itype %d maxpkt %d ntds %d\n", 86*906943f9SDavid du Colombier ep->id, ep->addr, eds, ets, ep->isotype, 87*906943f9SDavid du Colombier ep->maxpkt, ep->ntds); 887f0337cdSDavid du Colombier } 89*906943f9SDavid du Colombier return s; 907f0337cdSDavid du Colombier } 917f0337cdSDavid du Colombier 92*906943f9SDavid du Colombier static char* 93*906943f9SDavid du Colombier seprintconf(char *s, char *e, Usbdev *d, int ci) 94*906943f9SDavid du Colombier { 95*906943f9SDavid du Colombier int i; 96*906943f9SDavid du Colombier Conf *c; 97*906943f9SDavid du Colombier char *hd; 98*906943f9SDavid du Colombier 99*906943f9SDavid du Colombier c = d->conf[ci]; 100*906943f9SDavid du Colombier s = seprint(s, e, "\tconf: cval %d attrib %x %d mA\n", 101*906943f9SDavid du Colombier c->cval, c->attrib, c->milliamps); 102*906943f9SDavid du Colombier for(i = 0; i < Niface; i++) 103*906943f9SDavid du Colombier if(c->iface[i] == nil) 10402c76561SDavid du Colombier break; 105*906943f9SDavid du Colombier else 106*906943f9SDavid du Colombier s = seprintiface(s, e, c->iface[i]); 107*906943f9SDavid du Colombier for(i = 0; i < Nddesc; i++) 108*906943f9SDavid du Colombier if(d->ddesc[i] == nil) 10902c76561SDavid du Colombier break; 110*906943f9SDavid du Colombier else if(d->ddesc[i]->conf == c){ 111*906943f9SDavid du Colombier hd = hexstr((uchar*)&d->ddesc[i]->data, 112*906943f9SDavid du Colombier d->ddesc[i]->data.bLength); 113*906943f9SDavid du Colombier s = seprint(s, e, "\t\tdev desc %x[%d]: %s\n", 114*906943f9SDavid du Colombier d->ddesc[i]->data.bDescriptorType, 115*906943f9SDavid du Colombier d->ddesc[i]->data.bLength, hd); 116*906943f9SDavid du Colombier free(hd); 11702c76561SDavid du Colombier } 118*906943f9SDavid du Colombier return s; 119*906943f9SDavid du Colombier } 120*906943f9SDavid du Colombier 121*906943f9SDavid du Colombier int 122*906943f9SDavid du Colombier Ufmt(Fmt *f) 123*906943f9SDavid du Colombier { 124*906943f9SDavid du Colombier int i; 125*906943f9SDavid du Colombier Dev *d; 126*906943f9SDavid du Colombier Usbdev *ud; 127*906943f9SDavid du Colombier char buf[1024]; 128*906943f9SDavid du Colombier char *s, *e; 129*906943f9SDavid du Colombier 130*906943f9SDavid du Colombier s = buf; 131*906943f9SDavid du Colombier e = buf+sizeof(buf); 132*906943f9SDavid du Colombier d = va_arg(f->args, Dev*); 133*906943f9SDavid du Colombier if(d == nil) 134*906943f9SDavid du Colombier return fmtprint(f, "<nildev>\n"); 135*906943f9SDavid du Colombier s = seprint(s, e, "%s", d->dir); 136*906943f9SDavid du Colombier ud = d->usb; 137*906943f9SDavid du Colombier if(ud == nil) 138*906943f9SDavid du Colombier return fmtprint(f, "%s %ld refs\n", buf, d->ref); 139*906943f9SDavid du Colombier s = seprint(s, e, " csp %s.%uld.%uld", 140*906943f9SDavid du Colombier classname(Class(ud->csp)), Subclass(ud->csp), Proto(ud->csp)); 141*906943f9SDavid du Colombier s = seprint(s, e, " vid %#ux did %#ux", ud->vid, ud->did); 142*906943f9SDavid du Colombier s = seprint(s, e, " refs %ld\n", d->ref); 143*906943f9SDavid du Colombier s = seprint(s, e, "\t%s %s %s\n", ud->vendor, ud->product, ud->serial); 144*906943f9SDavid du Colombier for(i = 0; i < Nconf; i++){ 145*906943f9SDavid du Colombier if(ud->conf[i] == nil) 146208510e1SDavid du Colombier break; 147*906943f9SDavid du Colombier else 148*906943f9SDavid du Colombier s = seprintconf(s, e, ud, i); 1497f0337cdSDavid du Colombier } 150*906943f9SDavid du Colombier return fmtprint(f, "%s", buf); 1519a747e4fSDavid du Colombier } 152*906943f9SDavid du Colombier 153*906943f9SDavid du Colombier char* 154*906943f9SDavid du Colombier estrdup(char *s) 155*906943f9SDavid du Colombier { 156*906943f9SDavid du Colombier char *d; 157*906943f9SDavid du Colombier 158*906943f9SDavid du Colombier d = strdup(s); 159*906943f9SDavid du Colombier if(d == nil) 160*906943f9SDavid du Colombier sysfatal("strdup: %r"); 161*906943f9SDavid du Colombier setmalloctag(d, getcallerpc(&s)); 162*906943f9SDavid du Colombier return d; 1639a747e4fSDavid du Colombier } 164*906943f9SDavid du Colombier 165*906943f9SDavid du Colombier void* 166*906943f9SDavid du Colombier emallocz(ulong size, int zero) 167*906943f9SDavid du Colombier { 168*906943f9SDavid du Colombier void *x; 169*906943f9SDavid du Colombier 170*906943f9SDavid du Colombier x = malloc(size); 171*906943f9SDavid du Colombier if(x == nil) 172*906943f9SDavid du Colombier sysfatal("malloc: %r"); 173*906943f9SDavid du Colombier if(zero) 174*906943f9SDavid du Colombier memset(x, 0, size); 175*906943f9SDavid du Colombier setmalloctag(x, getcallerpc(&size)); 176*906943f9SDavid du Colombier return x; 177*906943f9SDavid du Colombier } 178*906943f9SDavid du Colombier 179