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 // Device* setupfd; /* for usbprobe */ 265 // Device* cfd; /* for usbprobe */ 266 }; 267 268 /* 269 * layout of standard descriptor types 270 */ 271 struct DDevice 272 { 273 byte bLength; 274 byte bDescriptorType; 275 byte bcdUSB[2]; 276 byte bDeviceClass; 277 byte bDeviceSubClass; 278 byte bDeviceProtocol; 279 byte bMaxPacketSize0; 280 byte idVendor[2]; 281 byte idProduct[2]; 282 byte bcdDevice[2]; 283 byte iManufacturer; 284 byte iProduct; 285 byte iSerialNumber; 286 byte bNumConfigurations; 287 }; 288 #define DDEVLEN 18 289 290 struct DConfig 291 { 292 byte bLength; 293 byte bDescriptorType; 294 byte wTotalLength[2]; 295 byte bNumInterfaces; 296 byte bConfigurationValue; 297 byte iConfiguration; 298 byte bmAttributes; 299 byte MaxPower; 300 }; 301 #define DCONFLEN 9 302 303 struct DInterface 304 { 305 byte bLength; 306 byte bDescriptorType; 307 byte bInterfaceNumber; 308 byte bAlternateSetting; 309 byte bNumEndpoints; 310 byte bInterfaceClass; 311 byte bInterfaceSubClass; 312 byte bInterfaceProtocol; 313 byte iInterface; 314 }; 315 #define DINTERLEN 9 316 317 struct DEndpoint 318 { 319 byte bLength; 320 byte bDescriptorType; 321 byte bEndpointAddress; 322 byte bmAttributes; 323 byte wMaxPacketSize[2]; 324 byte bInterval; 325 }; 326 #define DENDPLEN 7 327 328 struct DHid 329 { 330 byte bLength; 331 byte bDescriptorType; 332 byte bcdHID[2]; 333 byte bCountryCode; 334 byte bNumDescriptors; 335 byte bClassDescriptorType; 336 byte wItemLength[2]; 337 }; 338 #define DHIDLEN 9 339 340 struct DHub 341 { 342 byte bLength; 343 byte bDescriptorType; 344 byte bNbrPorts; 345 byte wHubCharacteristics[2]; 346 byte bPwrOn2PwrGood; 347 byte bHubContrCurrent; 348 byte DeviceRemovable[1]; /* variable length */ 349 /* byte PortPwrCtrlMask; /* variable length, deprecated in USB v1.1 */ 350 }; 351 #define DHUBLEN 9 352 353 struct Namelist 354 { 355 short index; 356 char *name; 357 }; 358 359 typedef struct Drivetab 360 { 361 ulong csp; 362 void (*driver)(Device *d); 363 } Drivetab; 364 365 #define Class(csp) ((csp)&0xff) 366 #define Subclass(csp) (((csp)>>8)&0xff) 367 #define Proto(csp) (((csp)>>16)&0xff) 368 #define CSP(c, s, p) ((c) | ((s)<<8) | ((p)<<16)) 369 370 extern void (*dprinter[0x100])(Device *, int, ulong, void *b, int n); 371 372 /* 373 * format routines 374 */ 375 void pdesc (Device *, int, ulong, byte *, int); 376 void preport (Device *, int, ulong, byte *, int); 377 void pstring (Device *, int, ulong, void *, int); 378 void phub (Device *, int, ulong, void *, int); 379 void pdevice (Device *, int, ulong, void *, int); 380 void phid (Device *, int, ulong, void *, int); 381 void pcs_raw(char *tag, byte *b, int n); 382 383 /* 384 * interface 385 */ 386 void usbfmtinit(void); 387 Device* opendev(int, int); 388 void closedev(Device*); 389 int describedevice(Device*); 390 int loadconfig(Device *d, int n); 391 Endpt * newendpt(Device *d, int id, ulong csp); 392 int setupcmd(Endpt*, int, int, int, int, byte*, int); 393 int setupreq(Endpt*, int, int, int, int, int); 394 int setupreply(Endpt*, void*, int); 395 void setdevclass(Device *d, int n); 396 void * emalloc(ulong); 397 void * emallocz(ulong, int); 398 399 char * namefor(Namelist *, int); 400 401 #pragma varargck type "D" Device* 402