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