1 /* 2 * USB implementation for Plan 9 3 * (c) 1998, 1999 C H Forsyth 4 */ 5 6 enum { 7 Dbginfo = 0x01, 8 Dbgfs = 0x02, 9 Dbgproc = 0x04, 10 Dbgcontrol = 0x08, 11 }; 12 13 extern int debug, debugdebug, verbose; 14 15 typedef uchar byte; 16 17 #ifndef CHANNOP 18 typedef struct Ref Ref; 19 20 #define threadprint fprint 21 #endif 22 23 /* 24 * USB definitions 25 */ 26 27 typedef struct DConfig DConfig; 28 typedef struct DDevice DDevice; 29 typedef struct DEndpoint DEndpoint; 30 typedef struct DHid DHid; 31 typedef struct DHub DHub; 32 typedef struct DInterface DInterface; 33 typedef struct Dconf Dconf; 34 typedef struct Dalt Dalt; 35 typedef struct Device Device; 36 typedef struct Dinf Dinf; 37 typedef struct Endpt Endpt; 38 39 typedef struct Namelist Namelist; 40 41 #ifndef nelem 42 #define nelem(x) (sizeof((x))/sizeof((x)[0])) 43 #endif 44 45 #define GET2(p) ((((p)[1]&0xFF)<<8)|((p)[0]&0xFF)) 46 #define PUT2(p,v) {((p)[0] = (v)); ((p)[1] = (v)>>8);} 47 48 enum 49 { 50 TokIN = 0x69, 51 TokOUT = 0xE1, 52 TokSETUP = 0x2D, 53 54 /* request type */ 55 RH2D = 0<<7, 56 RD2H = 1<<7, 57 Rstandard = 0<<5, 58 Rclass = 1<<5, 59 Rvendor = 2<<5, 60 Rdevice = 0, 61 Rinterface = 1, 62 Rendpt = 2, 63 Rother = 3, 64 65 /* standard requests */ 66 GET_STATUS = 0, 67 CLEAR_FEATURE = 1, 68 SET_FEATURE = 3, 69 SET_ADDRESS = 5, 70 GET_DESCRIPTOR = 6, 71 SET_DESCRIPTOR = 7, 72 GET_CONFIGURATION = 8, 73 SET_CONFIGURATION = 9, 74 GET_INTERFACE = 10, 75 SET_INTERFACE = 11, 76 SYNCH_FRAME = 12, 77 78 GET_CUR = 0x81, 79 GET_MIN = 0x82, 80 GET_MAX = 0x83, 81 GET_RES = 0x84, 82 SET_CUR = 0x01, 83 SET_MIN = 0x02, 84 SET_MAX = 0x03, 85 SET_RES = 0x04, 86 87 /* hub class feature selectors */ 88 C_HUB_LOCAL_POWER = 0, 89 C_HUB_OVER_CURRENT, 90 PORT_CONNECTION = 0, 91 PORT_ENABLE = 1, 92 PORT_SUSPEND = 2, 93 PORT_OVER_CURRENT = 3, 94 PORT_RESET = 4, 95 PORT_POWER = 8, 96 PORT_LOW_SPEED = 9, 97 C_PORT_CONNECTION = 16, 98 C_PORT_ENABLE, 99 C_PORT_SUSPEND, 100 C_PORT_OVER_CURRENT, 101 C_PORT_RESET, 102 103 /* descriptor types */ 104 DEVICE = 1, 105 CONFIGURATION = 2, 106 STRING = 3, 107 INTERFACE = 4, 108 ENDPOINT = 5, 109 HID = 0x21, 110 REPORT = 0x22, 111 PHYSICAL = 0x23, 112 HUB = 0x29, 113 114 /* feature selectors */ 115 DEVICE_REMOTE_WAKEUP = 1, 116 ENDPOINT_STALL = 0, 117 118 /* report types */ 119 Tmtype = 3<<2, 120 Tmitem = 0xF0, 121 Tmain = 0<<2, 122 Tinput = 0x80, 123 Toutput = 0x90, 124 Tfeature = 0xB0, 125 Tcoll = 0xA0, 126 Tecoll = 0xC0, 127 Tglobal = 1<<2, 128 Tusagepage = 0x00, 129 Tlmin = 0x10, 130 Tlmax = 0x20, 131 Tpmin = 0x30, 132 Tpmax = 0x40, 133 Tunitexp = 0x50, 134 Tunit = 0x60, 135 Trepsize = 0x70, 136 TrepID = 0x80, 137 Trepcount = 0x90, 138 Tpush = 0xA0, 139 Tpop = 0xB0, 140 Tlocal = 2<<2, 141 Tusage = 0x00, 142 Tumin = 0x10, 143 Tumax = 0x20, 144 Tdindex = 0x30, 145 Tdmin = 0x40, 146 Tdmax = 0x50, 147 Tsindex = 0x70, 148 Tsmin = 0x80, 149 Tsmax = 0x90, 150 Tsetdelim = 0xA0, 151 Treserved = 3<<2, 152 Tlong = 0xFE, 153 154 /* parameters */ 155 Nendpt = 16, 156 157 /* device state */ 158 Detached = 0, 159 Attached, 160 Enabled, 161 Assigned, 162 Configured, 163 164 /* classes */ 165 Noclass = 0, 166 Hubclass, 167 Otherclass, 168 169 /* endpoint direction */ 170 Ein = 0, 171 Eout, 172 173 /* endpoint type */ 174 Econtrol = 0, 175 Eiso = 1, 176 Ebulk = 2, 177 Eintr = 3, 178 179 /* endpoint isotype */ 180 Eunknown = 0, 181 Easync = 1, 182 Eadapt = 2, 183 Esync = 3, 184 }; 185 186 enum 187 { 188 CL_AUDIO = 1, 189 CL_COMMS = 2, 190 CL_HID = 3, 191 CL_PRINTER = 7, 192 CL_STORAGE = 8, 193 CL_HUB = 9, 194 CL_DATA = 10, 195 }; 196 197 struct Endpt 198 { 199 uchar addr; /* endpoint address, 0-15 (|0x80 if direction==Ein) */ 200 uchar dir; /* direction, Ein/Eout */ 201 uchar type; /* Econtrol, Eiso, Ebulk, Eintr */ 202 uchar isotype; /* Eunknown, Easync, Eadapt, Esync */ 203 int id; 204 int class; 205 ulong csp; 206 int maxpkt; 207 Device* dev; 208 Dconf* conf; 209 Dinf* iface; 210 }; 211 212 struct Dalt 213 { 214 int attrib; 215 int interval; 216 void* devspec; /* device specific settings */ 217 }; 218 219 struct Dinf 220 { 221 int interface; /* interface number */ 222 ulong csp; /* USB class/subclass/proto */ 223 Dalt* dalt[16]; 224 Endpt* endpt[16]; 225 }; 226 227 struct Dconf 228 { 229 ulong csp; /* USB class/subclass/proto */ 230 int nif; /* number of interfaces */ 231 int cval; /* value for set configuration */ 232 int attrib; 233 int milliamps; /* maximum power in this configuration */ 234 Dinf* iface[16]; /* up to 16 interfaces */ 235 }; 236 237 /* Dconf.attrib */ 238 enum 239 { 240 Cbuspowered = 1<<7, 241 Cselfpowered = 1<<6, 242 Cremotewakeup = 1<<5, 243 }; 244 245 struct Device 246 { 247 Ref; 248 int ctlrno; 249 int ctl; 250 int setup; 251 int status; 252 int state; 253 int id; 254 int class; 255 int npt; 256 int ls; /* low speed */ 257 ulong csp; /* USB class/subclass/proto */ 258 int nconf; 259 int nif; /* number of interfaces (sum of per-conf `nif's) */ 260 int vid; /* vendor id */ 261 int did; /* product (device) id */ 262 Dconf* config[16]; 263 Endpt* ep[Nendpt]; 264 }; 265 266 /* 267 * layout of standard descriptor types 268 */ 269 struct DDevice 270 { 271 byte bLength; 272 byte bDescriptorType; 273 byte bcdUSB[2]; 274 byte bDeviceClass; 275 byte bDeviceSubClass; 276 byte bDeviceProtocol; 277 byte bMaxPacketSize0; 278 byte idVendor[2]; 279 byte idProduct[2]; 280 byte bcdDevice[2]; 281 byte iManufacturer; 282 byte iProduct; 283 byte iSerialNumber; 284 byte bNumConfigurations; 285 }; 286 #define DDEVLEN 18 287 288 struct DConfig 289 { 290 byte bLength; 291 byte bDescriptorType; 292 byte wTotalLength[2]; 293 byte bNumInterfaces; 294 byte bConfigurationValue; 295 byte iConfiguration; 296 byte bmAttributes; 297 byte MaxPower; 298 }; 299 #define DCONFLEN 9 300 301 struct DInterface 302 { 303 byte bLength; 304 byte bDescriptorType; 305 byte bInterfaceNumber; 306 byte bAlternateSetting; 307 byte bNumEndpoints; 308 byte bInterfaceClass; 309 byte bInterfaceSubClass; 310 byte bInterfaceProtocol; 311 byte iInterface; 312 }; 313 #define DINTERLEN 9 314 315 struct DEndpoint 316 { 317 byte bLength; 318 byte bDescriptorType; 319 byte bEndpointAddress; 320 byte bmAttributes; 321 byte wMaxPacketSize[2]; 322 byte bInterval; 323 }; 324 #define DENDPLEN 7 325 326 struct DHid 327 { 328 byte bLength; 329 byte bDescriptorType; 330 byte bcdHID[2]; 331 byte bCountryCode; 332 byte bNumDescriptors; 333 byte bClassDescriptorType; 334 byte wItemLength[2]; 335 }; 336 #define DHIDLEN 9 337 338 struct DHub 339 { 340 byte bLength; 341 byte bDescriptorType; 342 byte bNbrPorts; 343 byte wHubCharacteristics[2]; 344 byte bPwrOn2PwrGood; 345 byte bHubContrCurrent; 346 byte DeviceRemovable[1]; /* variable length */ 347 /* byte PortPwrCtrlMask; /* variable length, deprecated in USB v1.1 */ 348 }; 349 #define DHUBLEN 9 350 351 struct Namelist 352 { 353 short index; 354 char *name; 355 }; 356 357 typedef struct Drivetab 358 { 359 ulong csp; 360 void (*driver)(Device *d); 361 } Drivetab; 362 363 #define Class(csp) ((csp)&0xff) 364 #define Subclass(csp) (((csp)>>8)&0xff) 365 #define Proto(csp) (((csp)>>16)&0xff) 366 #define CSP(c, s, p) ((c) | ((s)<<8) | ((p)<<16)) 367 368 extern void (*dprinter[0x100])(Device *, int, ulong, void *b, int n); 369 370 /* 371 * format routines 372 */ 373 void pdesc (Device *, int, ulong, byte *, int); 374 void preport (Device *, int, ulong, byte *, int); 375 void pstring (Device *, int, ulong, void *, int); 376 void phub (Device *, int, ulong, void *, int); 377 void pdevice (Device *, int, ulong, void *, int); 378 void phid (Device *, int, ulong, void *, int); 379 void pcs_raw(char *tag, byte *b, int n); 380 381 /* 382 * interface 383 */ 384 void usbfmtinit(void); 385 Device* opendev(int, int); 386 void closedev(Device*); 387 int describedevice(Device*); 388 int loadconfig(Device *d, int n); 389 Endpt * newendpt(Device *d, int id, ulong csp); 390 int setupcmd(Endpt*, int, int, int, int, byte*, int); 391 int setupreq(Endpt*, int, int, int, int, int); 392 int setupreply(Endpt*, void*, int); 393 void setdevclass(Device *d, int n); 394 void * emalloc(ulong); 395 void * emallocz(ulong, int); 396 397 char * namefor(Namelist *, int); 398 399 #pragma varargck type "D" Device* 400