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