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