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 169 enum 170 { 171 CL_AUDIO = 1, 172 CL_COMMS = 2, 173 CL_HID = 3, 174 CL_PRINTER = 7, 175 CL_HUB = 9, 176 CL_DATA = 10, 177 }; 178 179 struct Endpt 180 { 181 int id; 182 int class; 183 ulong csp; 184 int maxpkt; 185 Device* dev; 186 Dconf* conf; 187 Dinf* iface; 188 }; 189 190 struct Dalt 191 { 192 int maxpkt; /* max packet size */ 193 int attrib; 194 int interval; 195 void* devspec; /* device specific settings */ 196 }; 197 198 struct Dinf 199 { 200 int interface; /* interface number */ 201 int addr; /* endpoint number */ 202 ulong csp; /* USB class/subclass/proto */ 203 Dalt* dalt[16]; 204 }; 205 206 struct Dconf 207 { 208 ulong csp; /* USB class/subclass/proto */ 209 int nif; /* number of interfaces */ 210 int cval; /* value for set configuration */ 211 int attrib; 212 int milliamps; /* maximum power in this configuration */ 213 Dinf* iface[16]; /* up to 16 interfaces */ 214 }; 215 216 /* Dconf.attrib */ 217 enum 218 { 219 Cbuspowered = 1<<7, 220 Cselfpowered = 1<<6, 221 Cremotewakeup = 1<<5, 222 }; 223 224 struct Device 225 { 226 Ref; 227 int ctlrno; 228 int ctl; 229 int setup; 230 int status; 231 int state; 232 int id; 233 int class; 234 int npt; 235 int ls; /* low speed */ 236 ulong csp; /* USB class/subclass/proto */ 237 int nconf; 238 int nif; /* number of interfaces (sum of per-conf `nif's) */ 239 int vid; /* vendor id */ 240 int did; /* product (device) id */ 241 Dconf* config[16]; 242 Endpt* ep[Nendpt]; 243 }; 244 245 /* 246 * layout of standard descriptor types 247 */ 248 struct DDevice 249 { 250 byte bLength; 251 byte bDescriptorType; 252 byte bcdUSB[2]; 253 byte bDeviceClass; 254 byte bDeviceSubClass; 255 byte bDeviceProtocol; 256 byte bMaxPacketSize0; 257 byte idVendor[2]; 258 byte idProduct[2]; 259 byte bcdDevice[2]; 260 byte iManufacturer; 261 byte iProduct; 262 byte iSerialNumber; 263 byte bNumConfigurations; 264 }; 265 #define DDEVLEN 18 266 267 struct DConfig 268 { 269 byte bLength; 270 byte bDescriptorType; 271 byte wTotalLength[2]; 272 byte bNumInterfaces; 273 byte bConfigurationValue; 274 byte iConfiguration; 275 byte bmAttributes; 276 byte MaxPower; 277 }; 278 #define DCONFLEN 9 279 280 struct DInterface 281 { 282 byte bLength; 283 byte bDescriptorType; 284 byte bInterfaceNumber; 285 byte bAlternateSetting; 286 byte bNumEndpoints; 287 byte bInterfaceClass; 288 byte bInterfaceSubClass; 289 byte bInterfaceProtocol; 290 byte iInterface; 291 }; 292 #define DINTERLEN 9 293 294 struct DEndpoint 295 { 296 byte bLength; 297 byte bDescriptorType; 298 byte bEndpointAddress; 299 byte bmAttributes; 300 byte wMaxPacketSize[2]; 301 byte bInterval; 302 }; 303 #define DENDPLEN 7 304 305 struct DHid 306 { 307 byte bLength; 308 byte bDescriptorType; 309 byte bcdHID[2]; 310 byte bCountryCode; 311 byte bNumDescriptors; 312 byte bClassDescriptorType; 313 byte wItemLength[2]; 314 }; 315 #define DHIDLEN 9 316 317 struct DHub 318 { 319 byte bLength; 320 byte bDescriptorType; 321 byte bNbrPorts; 322 byte wHubCharacteristics[2]; 323 byte bPwrOn2PwrGood; 324 byte bHubContrCurrent; 325 byte DeviceRemovable[1]; /* variable length */ 326 /* byte PortPwrCtrlMask; /* variable length, deprecated in USB v1.1 */ 327 }; 328 #define DHUBLEN 9 329 330 struct Namelist 331 { 332 short index; 333 char *name; 334 }; 335 336 typedef struct Drivetab 337 { 338 ulong csp; 339 void (*driver)(Device *d); 340 } Drivetab; 341 342 #define Class(csp) ((csp)&0xff) 343 #define Subclass(csp) (((csp)>>8)&0xff) 344 #define Proto(csp) (((csp)>>16)&0xff) 345 #define CSP(c, s, p) ((c) | ((s)<<8) | ((p)<<16)) 346 347 extern void (*dprinter[0x100])(Device *, int, ulong, void *b, int n); 348 349 /* 350 * format routines 351 */ 352 void pdesc (Device *, int, ulong, byte *, int); 353 void preport (Device *, int, ulong, byte *, int); 354 void pstring (Device *, int, ulong, void *, int); 355 void phub (Device *, int, ulong, void *, int); 356 void pdevice (Device *, int, ulong, void *, int); 357 void phid (Device *, int, ulong, void *, int); 358 void pcs_raw(char *tag, byte *b, int n); 359 360 /* 361 * interface 362 */ 363 void usbfmtinit(void); 364 Device* opendev(int, int); 365 void closedev(Device*); 366 int describedevice(Device*); 367 int loadconfig(Device *d, int n); 368 Endpt * newendpt(Device *d, int id, ulong csp); 369 int setupcmd(Endpt*, int, int, int, int, byte*, int); 370 int setupreq(Endpt*, int, int, int, int, int); 371 int setupreply(Endpt*, void*, int); 372 void setdevclass(Device *d, int n); 373 void * emalloc(ulong); 374 void * emallocz(ulong, int); 375 376 char * namefor(Namelist *, int); 377 378 #pragma varargck type "D" Device* 379