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 113 /* feature selectors */ 114 DEVICE_REMOTE_WAKEUP = 1, 115 ENDPOINT_STALL = 0, 116 117 /* report types */ 118 Tmtype = 3<<2, 119 Tmitem = 0xF0, 120 Tmain = 0<<2, 121 Tinput = 0x80, 122 Toutput = 0x90, 123 Tfeature = 0xB0, 124 Tcoll = 0xA0, 125 Tecoll = 0xC0, 126 Tglobal = 1<<2, 127 Tusagepage = 0x00, 128 Tlmin = 0x10, 129 Tlmax = 0x20, 130 Tpmin = 0x30, 131 Tpmax = 0x40, 132 Tunitexp = 0x50, 133 Tunit = 0x60, 134 Trepsize = 0x70, 135 TrepID = 0x80, 136 Trepcount = 0x90, 137 Tpush = 0xA0, 138 Tpop = 0xB0, 139 Tlocal = 2<<2, 140 Tusage = 0x00, 141 Tumin = 0x10, 142 Tumax = 0x20, 143 Tdindex = 0x30, 144 Tdmin = 0x40, 145 Tdmax = 0x50, 146 Tsindex = 0x70, 147 Tsmin = 0x80, 148 Tsmax = 0x90, 149 Tsetdelim = 0xA0, 150 Treserved = 3<<2, 151 Tlong = 0xFE, 152 153 /* parameters */ 154 Nendpt = 16, 155 156 /* device state */ 157 Detached = 0, 158 Attached, 159 Enabled, 160 Assigned, 161 Configured, 162 163 /* classes */ 164 Noclass = 0, 165 Hubclass, 166 Otherclass, 167 168 /* endpoint direction */ 169 Ein = 0, 170 Eout, 171 172 /* endpoint type */ 173 Econtrol = 0, 174 Eiso = 1, 175 Ebulk = 2, 176 Eintr = 3, 177 178 /* endpoint isotype */ 179 Eunknown = 0, 180 Easync = 1, 181 Eadapt = 2, 182 Esync = 3, 183 }; 184 185 enum 186 { 187 CL_AUDIO = 1, 188 CL_COMMS = 2, 189 CL_HID = 3, 190 CL_PRINTER = 7, 191 CL_STORAGE = 8, 192 CL_HUB = 9, 193 CL_DATA = 10, 194 }; 195 196 struct Endpt 197 { 198 uchar addr; /* endpoint address, 0-15 (|0x80 if direction==Ein) */ 199 uchar dir; /* direction, Ein/Eout */ 200 uchar type; /* Econtrol, Eiso, Ebulk, Eintr */ 201 uchar isotype; /* Eunknown, Easync, Eadapt, Esync */ 202 int id; 203 int class; 204 ulong csp; 205 int maxpkt; 206 Device* dev; 207 Dconf* conf; 208 Dinf* iface; 209 }; 210 211 struct Dalt 212 { 213 int attrib; 214 int interval; 215 void* devspec; /* device specific settings */ 216 }; 217 218 struct Dinf 219 { 220 int interface; /* interface number */ 221 ulong csp; /* USB class/subclass/proto */ 222 Dalt* dalt[16]; 223 Endpt* endpt[16]; 224 }; 225 226 struct Dconf 227 { 228 ulong csp; /* USB class/subclass/proto */ 229 int nif; /* number of interfaces */ 230 int cval; /* value for set configuration */ 231 int attrib; 232 int milliamps; /* maximum power in this configuration */ 233 Dinf* iface[16]; /* up to 16 interfaces */ 234 }; 235 236 /* Dconf.attrib */ 237 enum 238 { 239 Cbuspowered = 1<<7, 240 Cselfpowered = 1<<6, 241 Cremotewakeup = 1<<5, 242 }; 243 244 struct Device 245 { 246 Ref; 247 int ctlrno; 248 int ctl; 249 int setup; 250 int status; 251 int state; 252 int id; 253 int class; 254 int npt; 255 int ls; /* low speed */ 256 ulong csp; /* USB class/subclass/proto */ 257 int nconf; 258 int nif; /* number of interfaces (sum of per-conf `nif's) */ 259 int vid; /* vendor id */ 260 int did; /* product (device) id */ 261 Dconf* config[16]; 262 Endpt* ep[Nendpt]; 263 }; 264 265 /* 266 * layout of standard descriptor types 267 */ 268 struct DDevice 269 { 270 byte bLength; 271 byte bDescriptorType; 272 byte bcdUSB[2]; 273 byte bDeviceClass; 274 byte bDeviceSubClass; 275 byte bDeviceProtocol; 276 byte bMaxPacketSize0; 277 byte idVendor[2]; 278 byte idProduct[2]; 279 byte bcdDevice[2]; 280 byte iManufacturer; 281 byte iProduct; 282 byte iSerialNumber; 283 byte bNumConfigurations; 284 }; 285 #define DDEVLEN 18 286 287 struct DConfig 288 { 289 byte bLength; 290 byte bDescriptorType; 291 byte wTotalLength[2]; 292 byte bNumInterfaces; 293 byte bConfigurationValue; 294 byte iConfiguration; 295 byte bmAttributes; 296 byte MaxPower; 297 }; 298 #define DCONFLEN 9 299 300 struct DInterface 301 { 302 byte bLength; 303 byte bDescriptorType; 304 byte bInterfaceNumber; 305 byte bAlternateSetting; 306 byte bNumEndpoints; 307 byte bInterfaceClass; 308 byte bInterfaceSubClass; 309 byte bInterfaceProtocol; 310 byte iInterface; 311 }; 312 #define DINTERLEN 9 313 314 struct DEndpoint 315 { 316 byte bLength; 317 byte bDescriptorType; 318 byte bEndpointAddress; 319 byte bmAttributes; 320 byte wMaxPacketSize[2]; 321 byte bInterval; 322 }; 323 #define DENDPLEN 7 324 325 struct DHid 326 { 327 byte bLength; 328 byte bDescriptorType; 329 byte bcdHID[2]; 330 byte bCountryCode; 331 byte bNumDescriptors; 332 byte bClassDescriptorType; 333 byte wItemLength[2]; 334 }; 335 #define DHIDLEN 9 336 337 struct DHub 338 { 339 byte bLength; 340 byte bDescriptorType; 341 byte bNbrPorts; 342 byte wHubCharacteristics[2]; 343 byte bPwrOn2PwrGood; 344 byte bHubContrCurrent; 345 byte DeviceRemovable[1]; /* variable length */ 346 /* byte PortPwrCtrlMask; /* variable length, deprecated in USB v1.1 */ 347 }; 348 #define DHUBLEN 9 349 350 struct Namelist 351 { 352 short index; 353 char *name; 354 }; 355 356 typedef struct Drivetab 357 { 358 ulong csp; 359 void (*driver)(Device *d); 360 } Drivetab; 361 362 #define Class(csp) ((csp)&0xff) 363 #define Subclass(csp) (((csp)>>8)&0xff) 364 #define Proto(csp) (((csp)>>16)&0xff) 365 #define CSP(c, s, p) ((c) | ((s)<<8) | ((p)<<16)) 366 367 extern void (*dprinter[0x100])(Device *, int, ulong, void *b, int n); 368 369 /* 370 * format routines 371 */ 372 void pdesc (Device *, int, ulong, byte *, int); 373 void preport (Device *, int, ulong, byte *, int); 374 void pstring (Device *, int, ulong, void *, int); 375 void phub (Device *, int, ulong, void *, int); 376 void pdevice (Device *, int, ulong, void *, int); 377 void phid (Device *, int, ulong, void *, int); 378 void pcs_raw(char *tag, byte *b, int n); 379 380 /* 381 * interface 382 */ 383 void usbfmtinit(void); 384 Device* opendev(int, int); 385 void closedev(Device*); 386 int describedevice(Device*); 387 int loadconfig(Device *d, int n); 388 Endpt * newendpt(Device *d, int id, ulong csp); 389 int setupcmd(Endpt*, int, int, int, int, byte*, int); 390 int setupreq(Endpt*, int, int, int, int, int); 391 int setupreply(Endpt*, void*, int); 392 void setdevclass(Device *d, int n); 393 void * emalloc(ulong); 394 void * emallocz(ulong, int); 395 396 char * namefor(Namelist *, int); 397 398 #pragma varargck type "D" Device* 399