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