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