1*9a747e4fSDavid du Colombier typedef struct Device Device; 2*9a747e4fSDavid du Colombier typedef struct Dconf Dconf; 3*9a747e4fSDavid du Colombier typedef struct Ddesc Ddesc; 4*9a747e4fSDavid du Colombier typedef struct Dinf Dinf; 5*9a747e4fSDavid du Colombier typedef struct Dalt Dalt; 6*9a747e4fSDavid du Colombier typedef struct Endpt Endpt; 7*9a747e4fSDavid du Colombier 8*9a747e4fSDavid du Colombier struct Device 9*9a747e4fSDavid du Colombier { 10*9a747e4fSDavid du Colombier Ref; 11*9a747e4fSDavid du Colombier int ctlrno; 12*9a747e4fSDavid du Colombier int id; 13*9a747e4fSDavid du Colombier int state; 14*9a747e4fSDavid du Colombier int ctl; 15*9a747e4fSDavid du Colombier int setup; 16*9a747e4fSDavid du Colombier int status; 17*9a747e4fSDavid du Colombier int ls; /* low speed */ 18*9a747e4fSDavid du Colombier 19*9a747e4fSDavid du Colombier int vers; /* USB version supported, in BCD */ 20*9a747e4fSDavid du Colombier ulong csp; /* USB class/subclass/proto */ 21*9a747e4fSDavid du Colombier int max0; /* max packet size for endpoint 0 */ 22*9a747e4fSDavid du Colombier int vid; /* vendor id */ 23*9a747e4fSDavid du Colombier int did; /* product (device) id */ 24*9a747e4fSDavid du Colombier int release; /* device release number, in BCD */ 25*9a747e4fSDavid du Colombier int manufacturer; /* string index */ 26*9a747e4fSDavid du Colombier int product; /* string index */ 27*9a747e4fSDavid du Colombier int serial; /* string index */ 28*9a747e4fSDavid du Colombier int nconf; 29*9a747e4fSDavid du Colombier Dconf* config; 30*9a747e4fSDavid du Colombier char *strings[256]; 31*9a747e4fSDavid du Colombier }; 32*9a747e4fSDavid du Colombier 33*9a747e4fSDavid du Colombier struct Ddesc 34*9a747e4fSDavid du Colombier { 35*9a747e4fSDavid du Colombier int ndesc; /* number of descriptors */ 36*9a747e4fSDavid du Colombier int bytes; /* total size of descriptors */ 37*9a747e4fSDavid du Colombier uchar *data; /* descriptor data */ 38*9a747e4fSDavid du Colombier }; 39*9a747e4fSDavid du Colombier 40*9a747e4fSDavid du Colombier struct Dconf 41*9a747e4fSDavid du Colombier { 42*9a747e4fSDavid du Colombier Device *d; /* owning device */ 43*9a747e4fSDavid du Colombier int x; /* index into Device.config array */ 44*9a747e4fSDavid du Colombier int nif; /* number of interfaces */ 45*9a747e4fSDavid du Colombier int cval; /* value for set configuration request */ 46*9a747e4fSDavid du Colombier int config; /* string index */ 47*9a747e4fSDavid du Colombier int attrib; 48*9a747e4fSDavid du Colombier int milliamps; /* maximum power in this configuration */ 49*9a747e4fSDavid du Colombier Ddesc desc; /* additional descriptors for this configuration */ 50*9a747e4fSDavid du Colombier Dinf* iface; 51*9a747e4fSDavid du Colombier }; 52*9a747e4fSDavid du Colombier 53*9a747e4fSDavid du Colombier struct Dinf 54*9a747e4fSDavid du Colombier { 55*9a747e4fSDavid du Colombier Device *d; /* owning device */ 56*9a747e4fSDavid du Colombier Dconf *conf; /* owning configuration */ 57*9a747e4fSDavid du Colombier int x; /* index into Dconf.iface array */ 58*9a747e4fSDavid du Colombier ulong csp; /* USB class/subclass/proto */ 59*9a747e4fSDavid du Colombier int interface; /* string index */ 60*9a747e4fSDavid du Colombier Dalt *alt; /* linked list of alternatives */ 61*9a747e4fSDavid du Colombier Dinf *next; /* caller-maintained list of interfaces */ 62*9a747e4fSDavid du Colombier }; 63*9a747e4fSDavid du Colombier 64*9a747e4fSDavid du Colombier struct Dalt 65*9a747e4fSDavid du Colombier { 66*9a747e4fSDavid du Colombier Dinf *intf; /* owning interface */ 67*9a747e4fSDavid du Colombier int alt; /* alternate number, used to select this alternate */ 68*9a747e4fSDavid du Colombier int npt; /* number of endpoints */ 69*9a747e4fSDavid du Colombier Endpt* ep; /* endpoints for this interface alternate */ 70*9a747e4fSDavid du Colombier Ddesc desc; /* additional descriptors for this alternate */ 71*9a747e4fSDavid du Colombier Dalt* next; /* next in linked list of alternatives */ 72*9a747e4fSDavid du Colombier }; 73*9a747e4fSDavid du Colombier 74*9a747e4fSDavid du Colombier struct Endpt 75*9a747e4fSDavid du Colombier { 76*9a747e4fSDavid du Colombier uchar addr; /* endpoint address, 0-15 */ 77*9a747e4fSDavid du Colombier uchar dir; /* direction, Ein/Eout */ 78*9a747e4fSDavid du Colombier uchar type; /* Econtrol, Eiso, Ebulk, Eintr */ 79*9a747e4fSDavid du Colombier uchar isotype; /* Eunknown, Easync, Eadapt, Esync */ 80*9a747e4fSDavid du Colombier int maxpkt; /* maximum packet size for endpoint */ 81*9a747e4fSDavid du Colombier int pollms; /* polling interval for interrupts */ 82*9a747e4fSDavid du Colombier Ddesc desc; /* additional descriptors for this endpoint */ 83*9a747e4fSDavid du Colombier }; 84*9a747e4fSDavid du Colombier 85*9a747e4fSDavid du Colombier enum 86*9a747e4fSDavid du Colombier { 87*9a747e4fSDavid du Colombier /* Device.state */ 88*9a747e4fSDavid du Colombier Detached = 0, 89*9a747e4fSDavid du Colombier Attached, 90*9a747e4fSDavid du Colombier Enabled, 91*9a747e4fSDavid du Colombier Assigned, 92*9a747e4fSDavid du Colombier Configured, 93*9a747e4fSDavid du Colombier 94*9a747e4fSDavid du Colombier /* Dconf.attrib */ 95*9a747e4fSDavid du Colombier Cbuspowered = 1<<7, 96*9a747e4fSDavid du Colombier Cselfpowered = 1<<6, 97*9a747e4fSDavid du Colombier Cremotewakeup = 1<<5, 98*9a747e4fSDavid du Colombier 99*9a747e4fSDavid du Colombier /* Endpt.dir */ 100*9a747e4fSDavid du Colombier Ein = 0, 101*9a747e4fSDavid du Colombier Eout, 102*9a747e4fSDavid du Colombier 103*9a747e4fSDavid du Colombier /* Endpt.type */ 104*9a747e4fSDavid du Colombier Econtrol = 0, 105*9a747e4fSDavid du Colombier Eiso, 106*9a747e4fSDavid du Colombier Ebulk, 107*9a747e4fSDavid du Colombier Eintr, 108*9a747e4fSDavid du Colombier 109*9a747e4fSDavid du Colombier /* Endpt.isotype */ 110*9a747e4fSDavid du Colombier Eunknown = 0, 111*9a747e4fSDavid du Colombier Easync, 112*9a747e4fSDavid du Colombier Eadapt, 113*9a747e4fSDavid du Colombier Esync, 114*9a747e4fSDavid du Colombier }; 115*9a747e4fSDavid du Colombier 116*9a747e4fSDavid du Colombier #define Class(csp) ((csp)&0xff) 117*9a747e4fSDavid du Colombier #define Subclass(csp) (((csp)>>8)&0xff) 118*9a747e4fSDavid du Colombier #define Proto(csp) (((csp)>>16)&0xff) 119*9a747e4fSDavid du Colombier #define CSP(c, s, p) ((c) | ((s)<<8) | ((p)<<16)) 120*9a747e4fSDavid du Colombier 121*9a747e4fSDavid du Colombier enum 122*9a747e4fSDavid du Colombier { 123*9a747e4fSDavid du Colombier /* known classes */ 124*9a747e4fSDavid du Colombier CL_AUDIO = 1, 125*9a747e4fSDavid du Colombier CL_COMMS = 2, 126*9a747e4fSDavid du Colombier CL_HID = 3, 127*9a747e4fSDavid du Colombier CL_PRINTER = 7, 128*9a747e4fSDavid du Colombier CL_HUB = 9, 129*9a747e4fSDavid du Colombier CL_DATA = 10, 130*9a747e4fSDavid du Colombier }; 131*9a747e4fSDavid du Colombier 132*9a747e4fSDavid du Colombier /* 133*9a747e4fSDavid du Colombier * interface 134*9a747e4fSDavid du Colombier */ 135*9a747e4fSDavid du Colombier void usbfmtinit(void); 136*9a747e4fSDavid du Colombier Device* opendev(int, int); 137*9a747e4fSDavid du Colombier void closedev(Device*); 138*9a747e4fSDavid du Colombier int describedevice(Device*); 139*9a747e4fSDavid du Colombier void dumpdevice(int, Device*); 140*9a747e4fSDavid du Colombier void loadstr(Device*, int, int); 141*9a747e4fSDavid du Colombier void loadstrings(Device*, int); 142*9a747e4fSDavid du Colombier 143*9a747e4fSDavid du Colombier int setupreq(Device*, int, int, int, int, uchar*, int); 144*9a747e4fSDavid du Colombier 145*9a747e4fSDavid du Colombier void * emalloc(ulong); 146*9a747e4fSDavid du Colombier void * emallocz(ulong, int); 147*9a747e4fSDavid du Colombier 148*9a747e4fSDavid du Colombier #pragma varargck type "D" Device* 149