1 typedef struct Altc Altc; 2 typedef struct Conf Conf; 3 typedef struct DConf DConf; 4 typedef struct DDesc DDesc; 5 typedef struct DDev DDev; 6 typedef struct DEp DEp; 7 typedef struct DIface DIface; 8 typedef struct Desc Desc; 9 typedef struct Dev Dev; 10 typedef struct Ep Ep; 11 typedef struct Iface Iface; 12 typedef struct Usbdev Usbdev; 13 14 enum { 15 /* fundamental constants */ 16 Nep = 16, /* max. endpoints per usb device & per interface */ 17 18 /* tunable parameters */ 19 Nconf = 16, /* max. configurations per usb device */ 20 Nddesc = 8*Nep, /* max. device-specific descriptors per usb device */ 21 Niface = 16, /* max. interfaces per configuration */ 22 Naltc = 16, /* max. alt configurations per interface */ 23 Uctries = 4, /* no. of tries for usbcmd */ 24 Ucdelay = 50, /* delay before retrying */ 25 26 /* request type */ 27 Rh2d = 0<<7, /* host to device */ 28 Rd2h = 1<<7, /* device to host */ 29 30 Rstd = 0<<5, /* types */ 31 Rclass = 1<<5, 32 Rvendor = 2<<5, 33 34 Rdev = 0, /* recipients */ 35 Riface = 1, 36 Rep = 2, /* endpoint */ 37 Rother = 3, 38 39 /* standard requests */ 40 Rgetstatus = 0, 41 Rclearfeature = 1, 42 Rsetfeature = 3, 43 Rsetaddress = 5, 44 Rgetdesc = 6, 45 Rsetdesc = 7, 46 Rgetconf = 8, 47 Rsetconf = 9, 48 Rgetiface = 10, 49 Rsetiface = 11, 50 Rsynchframe = 12, 51 52 /* standard requests (USB3.0) */ 53 Rsethubdepth = 12, 54 Rgetporterrcnt = 13, 55 56 Rgetcur = 0x81, 57 Rgetmin = 0x82, 58 Rgetmax = 0x83, 59 Rgetres = 0x84, 60 Rsetcur = 0x01, 61 Rsetmin = 0x02, 62 Rsetmax = 0x03, 63 Rsetres = 0x04, 64 65 /* dev classes */ 66 Clnone = 0, /* not in usb */ 67 Claudio = 1, 68 Clcomms = 2, 69 Clhid = 3, 70 Clprinter = 7, 71 Clstorage = 8, 72 Clhub = 9, 73 Cldata = 10, 74 75 /* standard descriptor sizes */ 76 Ddevlen = 18, 77 Dconflen = 9, 78 Difacelen = 9, 79 Deplen = 7, 80 81 /* descriptor types */ 82 Ddev = 1, 83 Dconf = 2, 84 Dstr = 3, 85 Diface = 4, 86 Dep = 5, 87 Dreport = 0x22, 88 Dfunction = 0x24, 89 Dphysical = 0x23, 90 91 /* feature selectors */ 92 Fdevremotewakeup = 1, 93 Fhalt = 0, 94 95 /* device state */ 96 Detached = 0, 97 Attached, 98 Enabled, 99 Assigned, 100 Configured, 101 102 /* endpoint direction */ 103 Ein = 0, 104 Eout, 105 Eboth, 106 107 /* endpoint type */ 108 Econtrol = 0, 109 Eiso = 1, 110 Ebulk = 2, 111 Eintr = 3, 112 113 /* endpoint isotype */ 114 Eunknown = 0, 115 Easync = 1, 116 Eadapt = 2, 117 Esync = 3, 118 119 /* config attrib */ 120 Cbuspowered = 1<<7, 121 Cselfpowered = 1<<6, 122 Cremotewakeup = 1<<5, 123 124 /* report types */ 125 Tmtype = 3<<2, 126 Tmitem = 0xF0, 127 Tmain = 0<<2, 128 Tinput = 0x80, 129 Toutput = 0x90, 130 Tfeature = 0xB0, 131 Tcoll = 0xA0, 132 Tecoll = 0xC0, 133 Tglobal = 1<<2, 134 Tusagepage = 0x00, 135 Tlmin = 0x10, 136 Tlmax = 0x20, 137 Tpmin = 0x30, 138 Tpmax = 0x40, 139 Tunitexp = 0x50, 140 Tunit = 0x60, 141 Trepsize = 0x70, 142 TrepID = 0x80, 143 Trepcount = 0x90, 144 Tpush = 0xA0, 145 Tpop = 0xB0, 146 Tlocal = 2<<2, 147 Tusage = 0x00, 148 Tumin = 0x10, 149 Tumax = 0x20, 150 Tdindex = 0x30, 151 Tdmin = 0x40, 152 Tdmax = 0x50, 153 Tsindex = 0x70, 154 Tsmin = 0x80, 155 Tsmax = 0x90, 156 Tsetdelim = 0xA0, 157 Treserved = 3<<2, 158 Tlong = 0xFE, 159 160 }; 161 162 /* 163 * Usb device (when used for ep0s) or endpoint. 164 * RC: One ref because of existing, another one per ogoing I/O. 165 * per-driver resources (including FS if any) are released by aux 166 * once the last ref is gone. This may include other Devs using 167 * to access endpoints for actual I/O. 168 */ 169 struct Dev 170 { 171 Ref; 172 char* dir; /* path for the endpoint dir */ 173 int id; /* usb id for device or ep. number */ 174 int dfd; /* descriptor for the data file */ 175 int cfd; /* descriptor for the control file */ 176 int isusb3; /* this is a usb3 device */ 177 int depth; /* hub depth for usb3 hubs */ 178 int maxpkt; /* cached from usb description */ 179 Ref nerrs; /* number of errors in requests */ 180 Usbdev* usb; /* USB description */ 181 void* aux; /* for the device driver */ 182 void (*free)(void*); /* idem. to release aux */ 183 }; 184 185 /* 186 * device description as reported by USB (unpacked). 187 */ 188 struct Usbdev 189 { 190 ulong csp; /* USB class/subclass/proto */ 191 int vid; /* vendor id */ 192 int did; /* product (device) id */ 193 int dno; /* device release number */ 194 char* vendor; 195 char* product; 196 char* serial; 197 int vsid; 198 int psid; 199 int ssid; 200 int class; /* from descriptor */ 201 int nconf; /* from descriptor */ 202 Conf* conf[Nconf]; /* configurations */ 203 Ep* ep[Nep]; /* all endpoints in device */ 204 Desc* ddesc[Nddesc]; /* (raw) device specific descriptors */ 205 }; 206 207 struct Ep 208 { 209 uchar addr; /* endpt address, 0-15 (|0x80 if Ein) */ 210 uchar dir; /* direction, Ein/Eout */ 211 uchar type; /* Econtrol, Eiso, Ebulk, Eintr */ 212 uchar isotype; /* Eunknown, Easync, Eadapt, Esync */ 213 int id; 214 int maxpkt; /* max. packet size */ 215 int ntds; /* nb. of Tds per µframe */ 216 Conf* conf; /* the endpoint belongs to */ 217 Iface* iface; /* the endpoint belongs to */ 218 }; 219 220 struct Altc 221 { 222 int attrib; 223 int interval; 224 void* aux; /* for the driver program */ 225 }; 226 227 struct Iface 228 { 229 int id; /* interface number */ 230 ulong csp; /* USB class/subclass/proto */ 231 Altc* altc[Naltc]; 232 Ep* ep[Nep]; 233 void* aux; /* for the driver program */ 234 }; 235 236 struct Conf 237 { 238 int cval; /* value for set configuration */ 239 int attrib; 240 int milliamps; /* maximum power in this config. */ 241 Iface* iface[Niface]; 242 }; 243 244 /* 245 * Device-specific descriptors. 246 * They show up mixed with other descriptors 247 * within a configuration. 248 * These are unknown to the library but handed to the driver. 249 */ 250 struct DDesc 251 { 252 uchar bLength; 253 uchar bDescriptorType; 254 uchar bbytes[1]; 255 /* extra bytes allocated here to keep the rest of it */ 256 }; 257 258 struct Desc 259 { 260 Conf* conf; /* where this descriptor was read */ 261 Iface* iface; /* last iface before desc in conf. */ 262 Ep* ep; /* last endpt before desc in conf. */ 263 Altc* altc; /* last alt.c. before desc in conf. */ 264 DDesc data; /* unparsed standard USB descriptor */ 265 }; 266 267 /* 268 * layout of standard descriptor types 269 */ 270 struct DDev 271 { 272 uchar bLength; 273 uchar bDescriptorType; 274 uchar bcdUSB[2]; 275 uchar bDevClass; 276 uchar bDevSubClass; 277 uchar bDevProtocol; 278 uchar bMaxPacketSize0; 279 uchar idVendor[2]; 280 uchar idProduct[2]; 281 uchar bcdDev[2]; 282 uchar iManufacturer; 283 uchar iProduct; 284 uchar iSerialNumber; 285 uchar bNumConfigurations; 286 }; 287 288 struct DConf 289 { 290 uchar bLength; 291 uchar bDescriptorType; 292 uchar wTotalLength[2]; 293 uchar bNumInterfaces; 294 uchar bConfigurationValue; 295 uchar iConfiguration; 296 uchar bmAttributes; 297 uchar MaxPower; 298 }; 299 300 struct DIface 301 { 302 uchar bLength; 303 uchar bDescriptorType; 304 uchar bInterfaceNumber; 305 uchar bAlternateSetting; 306 uchar bNumEndpoints; 307 uchar bInterfaceClass; 308 uchar bInterfaceSubClass; 309 uchar bInterfaceProtocol; 310 uchar iInterface; 311 }; 312 313 struct DEp 314 { 315 uchar bLength; 316 uchar bDescriptorType; 317 uchar bEndpointAddress; 318 uchar bmAttributes; 319 uchar wMaxPacketSize[2]; 320 uchar bInterval; 321 }; 322 323 #define Class(csp) ((csp) & 0xff) 324 #define Subclass(csp) (((csp)>>8) & 0xff) 325 #define Proto(csp) (((csp)>>16) & 0xff) 326 #define CSP(c, s, p) ((c) | (s)<<8 | (p)<<16) 327 328 #define GET2(p) (((p)[1] & 0xFF)<<8 | ((p)[0] & 0xFF)) 329 #define PUT2(p,v) {(p)[0] = (v); (p)[1] = (v)>>8;} 330 #define GET4(p) (((p)[3]&0xFF)<<24 | ((p)[2]&0xFF)<<16 | \ 331 ((p)[1]&0xFF)<<8 | ((p)[0]&0xFF)) 332 #define PUT4(p,v) {(p)[0] = (v); (p)[1] = (v)>>8; \ 333 (p)[2] = (v)>>16; (p)[3] = (v)>>24;} 334 335 #define dprint if(usbdebug)fprint 336 #define ddprint if(usbdebug > 1)fprint 337 338 #pragma varargck type "U" Dev* 339 #pragma varargck argpos devctl 2 340 341 int Ufmt(Fmt *f); 342 char* classname(int c); 343 void closedev(Dev *d); 344 int configdev(Dev *d); 345 int devctl(Dev *dev, char *fmt, ...); 346 void* emallocz(ulong size, int zero); 347 char* estrdup(char *s); 348 int matchdevcsp(char *info, void *a); 349 int finddevs(int (*matchf)(char*,void*), void *farg, char** dirs, int ndirs); 350 char* hexstr(void *a, int n); 351 int loaddevconf(Dev *d, int n); 352 int loaddevdesc(Dev *d); 353 char* loaddevstr(Dev *d, int sid); 354 Dev* opendev(char *fn); 355 int opendevdata(Dev *d, int mode); 356 Dev* openep(Dev *d, int id); 357 int parseconf(Usbdev *d, Conf *c, uchar *b, int n); 358 int parsedesc(Usbdev *d, Conf *c, uchar *b, int n); 359 int parsedev(Dev *xd, uchar *b, int n); 360 void startdevs(char *args, char *argv[], int argc, int (*mf)(char*,void*), void*ma, int (*df)(Dev*,int,char**)); 361 int unstall(Dev *dev, Dev *ep, int dir); 362 int usbcmd(Dev *d, int type, int req, int value, int index, uchar *data, int count); 363 364 365 extern int usbdebug; /* more messages for bigger values */ 366 367 368