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