xref: /plan9-contrib/sys/src/cmd/usb/lib/usb.h (revision 153f606ad9382553f9e0f9c1629a40ac883a54a7)
1 typedef struct Altc Altc;
2 typedef struct Conf Conf;
3 typedef struct DConf DConf;
4 typedef struct DDesc DDesc;
5 typedef struct DDev DDev;
6 typedef struct DEp DEp;
7 typedef struct DIface DIface;
8 typedef struct Desc Desc;
9 typedef struct Dev Dev;
10 typedef struct Ep Ep;
11 typedef struct Iface Iface;
12 typedef struct Usbdev Usbdev;
13 
14 enum {
15 	/* fundamental constants */
16 	Nep	= 16,	/* max. endpoints per usb device & per interface */
17 
18 	/* tunable parameters */
19 	Nconf	= 16,	/* max. configurations per usb device */
20 	Nddesc	= 8*Nep, /* max. device-specific descriptors per usb device */
21 	Niface	= 16,	/* max. interfaces per configuration */
22 	Naltc	= 16,	/* max. alt configurations per interface */
23 	Uctries	= 4,	/* no. of tries for usbcmd */
24 	Ucdelay	= 50,	/* delay before retrying */
25 
26 	/* request type */
27 	Rh2d	= 0<<7,		/* host to device */
28 	Rd2h	= 1<<7,		/* device to host */
29 
30 	Rstd	= 0<<5,		/* types */
31 	Rclass	= 1<<5,
32 	Rvendor	= 2<<5,
33 
34 	Rdev	= 0,		/* recipients */
35 	Riface	= 1,
36 	Rep	= 2,		/* endpoint */
37 	Rother	= 3,
38 
39 	/* standard requests */
40 	Rgetstatus	= 0,
41 	Rclearfeature	= 1,
42 	Rsetfeature	= 3,
43 	Rsetaddress	= 5,
44 	Rgetdesc	= 6,
45 	Rsetdesc	= 7,
46 	Rgetconf	= 8,
47 	Rsetconf	= 9,
48 	Rgetiface	= 10,
49 	Rsetiface	= 11,
50 	Rsynchframe	= 12,
51 
52 	/* standard requests (USB3.0) */
53 	Rsethubdepth	= 12,
54 	Rgetporterrcnt	= 13,
55 
56 	Rgetcur	= 0x81,
57 	Rgetmin	= 0x82,
58 	Rgetmax	= 0x83,
59 	Rgetres	= 0x84,
60 	Rsetcur	= 0x01,
61 	Rsetmin	= 0x02,
62 	Rsetmax	= 0x03,
63 	Rsetres	= 0x04,
64 
65 	/* dev classes */
66 	Clnone		= 0,		/* not in usb */
67 	Claudio		= 1,
68 	Clcomms		= 2,
69 	Clhid		= 3,
70 	Clprinter	= 7,
71 	Clstorage	= 8,
72 	Clhub		= 9,
73 	Cldata		= 10,
74 
75 	/* standard descriptor sizes */
76 	Ddevlen		= 18,
77 	Dconflen	= 9,
78 	Difacelen	= 9,
79 	Deplen		= 7,
80 
81 	/* descriptor types */
82 	Ddev		= 1,
83 	Dconf		= 2,
84 	Dstr		= 3,
85 	Diface		= 4,
86 	Dep		= 5,
87 	Dreport		= 0x22,
88 	Dfunction	= 0x24,
89 	Dphysical	= 0x23,
90 
91 	/* feature selectors */
92 	Fdevremotewakeup = 1,
93 	Fhalt 	= 0,
94 
95 	/* device state */
96 	Detached = 0,
97 	Attached,
98 	Enabled,
99 	Assigned,
100 	Configured,
101 
102 	/* endpoint direction */
103 	Ein = 0,
104 	Eout,
105 	Eboth,
106 
107 	/* endpoint type */
108 	Econtrol = 0,
109 	Eiso = 1,
110 	Ebulk = 2,
111 	Eintr = 3,
112 
113 	/* endpoint isotype */
114 	Eunknown = 0,
115 	Easync = 1,
116 	Eadapt = 2,
117 	Esync = 3,
118 
119 	/* config attrib */
120 	Cbuspowered = 1<<7,
121 	Cselfpowered = 1<<6,
122 	Cremotewakeup = 1<<5,
123 
124 	/* report types */
125 	Tmtype	= 3<<2,
126 	Tmitem	= 0xF0,
127 	Tmain	= 0<<2,
128 		Tinput	= 0x80,
129 		Toutput	= 0x90,
130 		Tfeature = 0xB0,
131 		Tcoll	= 0xA0,
132 		Tecoll	= 0xC0,
133 	 Tglobal	= 1<<2,
134 		Tusagepage = 0x00,
135 		Tlmin	= 0x10,
136 		Tlmax	= 0x20,
137 		Tpmin	= 0x30,
138 		Tpmax	= 0x40,
139 		Tunitexp	= 0x50,
140 		Tunit	= 0x60,
141 		Trepsize	= 0x70,
142 		TrepID	= 0x80,
143 		Trepcount = 0x90,
144 		Tpush	= 0xA0,
145 		Tpop	= 0xB0,
146 	 Tlocal	= 2<<2,
147 		Tusage	= 0x00,
148 		Tumin	= 0x10,
149 		Tumax	= 0x20,
150 		Tdindex	= 0x30,
151 		Tdmin	= 0x40,
152 		Tdmax	= 0x50,
153 		Tsindex	= 0x70,
154 		Tsmin	= 0x80,
155 		Tsmax	= 0x90,
156 		Tsetdelim = 0xA0,
157 	 Treserved	= 3<<2,
158 	 Tlong	= 0xFE,
159 
160 };
161 
162 /*
163  * Usb device (when used for ep0s) or endpoint.
164  * RC: One ref because of existing, another one per ogoing I/O.
165  * per-driver resources (including FS if any) are released by aux
166  * once the last ref is gone. This may include other Devs using
167  * to access endpoints for actual I/O.
168  */
169 struct Dev
170 {
171 	Ref;
172 	char*	dir;		/* path for the endpoint dir */
173 	int	id;		/* usb id for device or ep. number */
174 	int	dfd;		/* descriptor for the data file */
175 	int	cfd;		/* descriptor for the control file */
176 	int	isusb3;		/* this is a usb3 device */
177 	int	depth;		/* hub depth for usb3 hubs */
178 	int	maxpkt;		/* cached from usb description */
179 	Ref	nerrs;		/* number of errors in requests */
180 	Usbdev*	usb;		/* USB description */
181 	void*	aux;		/* for the device driver */
182 	void	(*free)(void*);	/* idem. to release aux */
183 };
184 
185 /*
186  * device description as reported by USB (unpacked).
187  */
188 struct Usbdev
189 {
190 	ulong	csp;		/* USB class/subclass/proto */
191 	int	vid;		/* vendor id */
192 	int	did;		/* product (device) id */
193 	int	dno;		/* device release number */
194 	char*	vendor;
195 	char*	product;
196 	char*	serial;
197 	int	vsid;
198 	int	psid;
199 	int	ssid;
200 	int	class;		/* from descriptor */
201 	int	nconf;		/* from descriptor */
202 	Conf*	conf[Nconf];	/* configurations */
203 	Ep*	ep[Nep];	/* all endpoints in device */
204 	Desc*	ddesc[Nddesc];	/* (raw) device specific descriptors */
205 };
206 
207 struct Ep
208 {
209 	uchar	addr;		/* endpt address, 0-15 (|0x80 if Ein) */
210 	uchar	dir;		/* direction, Ein/Eout */
211 	uchar	type;		/* Econtrol, Eiso, Ebulk, Eintr */
212 	uchar	isotype;		/* Eunknown, Easync, Eadapt, Esync */
213 	int	id;
214 	int	maxpkt;		/* max. packet size */
215 	int	ntds;		/* nb. of Tds per µframe */
216 	Conf*	conf;		/* the endpoint belongs to */
217 	Iface*	iface;		/* the endpoint belongs to */
218 };
219 
220 struct Altc
221 {
222 	int	attrib;
223 	int	interval;
224 	void*	aux;		/* for the driver program */
225 };
226 
227 struct Iface
228 {
229 	int 	id;		/* interface number */
230 	ulong	csp;		/* USB class/subclass/proto */
231 	Altc*	altc[Naltc];
232 	Ep*	ep[Nep];
233 	void*	aux;		/* for the driver program */
234 };
235 
236 struct Conf
237 {
238 	int	cval;		/* value for set configuration */
239 	int	attrib;
240 	int	milliamps;	/* maximum power in this config. */
241 	Iface*	iface[Niface];
242 };
243 
244 /*
245  * Device-specific descriptors.
246  * They show up mixed with other descriptors
247  * within a configuration.
248  * These are unknown to the library but handed to the driver.
249  */
250 struct DDesc
251 {
252 	uchar	bLength;
253 	uchar	bDescriptorType;
254 	uchar	bbytes[1];
255 	/* extra bytes allocated here to keep the rest of it */
256 };
257 
258 struct Desc
259 {
260 	Conf*	conf;		/* where this descriptor was read */
261 	Iface*	iface;		/* last iface before desc in conf. */
262 	Ep*	ep;		/* last endpt before desc in conf. */
263 	Altc*	altc;		/* last alt.c. before desc in conf. */
264 	DDesc	data;		/* unparsed standard USB descriptor */
265 };
266 
267 /*
268  * layout of standard descriptor types
269  */
270 struct DDev
271 {
272 	uchar	bLength;
273 	uchar	bDescriptorType;
274 	uchar	bcdUSB[2];
275 	uchar	bDevClass;
276 	uchar	bDevSubClass;
277 	uchar	bDevProtocol;
278 	uchar	bMaxPacketSize0;
279 	uchar	idVendor[2];
280 	uchar	idProduct[2];
281 	uchar	bcdDev[2];
282 	uchar	iManufacturer;
283 	uchar	iProduct;
284 	uchar	iSerialNumber;
285 	uchar	bNumConfigurations;
286 };
287 
288 struct DConf
289 {
290 	uchar	bLength;
291 	uchar	bDescriptorType;
292 	uchar	wTotalLength[2];
293 	uchar	bNumInterfaces;
294 	uchar	bConfigurationValue;
295 	uchar	iConfiguration;
296 	uchar	bmAttributes;
297 	uchar	MaxPower;
298 };
299 
300 struct DIface
301 {
302 	uchar	bLength;
303 	uchar	bDescriptorType;
304 	uchar	bInterfaceNumber;
305 	uchar	bAlternateSetting;
306 	uchar	bNumEndpoints;
307 	uchar	bInterfaceClass;
308 	uchar	bInterfaceSubClass;
309 	uchar	bInterfaceProtocol;
310 	uchar	iInterface;
311 };
312 
313 struct DEp
314 {
315 	uchar	bLength;
316 	uchar	bDescriptorType;
317 	uchar	bEndpointAddress;
318 	uchar	bmAttributes;
319 	uchar	wMaxPacketSize[2];
320 	uchar	bInterval;
321 };
322 
323 #define Class(csp)	((csp) & 0xff)
324 #define Subclass(csp)	(((csp)>>8) & 0xff)
325 #define Proto(csp)	(((csp)>>16) & 0xff)
326 #define CSP(c, s, p)	((c) | (s)<<8 | (p)<<16)
327 
328 #define	GET2(p)		(((p)[1] & 0xFF)<<8 | ((p)[0] & 0xFF))
329 #define	PUT2(p,v)	{(p)[0] = (v); (p)[1] = (v)>>8;}
330 #define	GET4(p)		(((p)[3]&0xFF)<<24 | ((p)[2]&0xFF)<<16 | \
331 			 ((p)[1]&0xFF)<<8  | ((p)[0]&0xFF))
332 #define	PUT4(p,v)	{(p)[0] = (v);     (p)[1] = (v)>>8; \
333 			 (p)[2] = (v)>>16; (p)[3] = (v)>>24;}
334 
335 #define dprint if(usbdebug)fprint
336 #define ddprint if(usbdebug > 1)fprint
337 
338 #pragma	varargck	type  "U"	Dev*
339 #pragma	varargck	argpos	devctl	2
340 
341 int	Ufmt(Fmt *f);
342 char*	classname(int c);
343 void	closedev(Dev *d);
344 int	configdev(Dev *d);
345 int	devctl(Dev *dev, char *fmt, ...);
346 void*	emallocz(ulong size, int zero);
347 char*	estrdup(char *s);
348 int	matchdevcsp(char *info, void *a);
349 int	finddevs(int (*matchf)(char*,void*), void *farg, char** dirs, int ndirs);
350 char*	hexstr(void *a, int n);
351 int	loaddevconf(Dev *d, int n);
352 int	loaddevdesc(Dev *d);
353 char*	loaddevstr(Dev *d, int sid);
354 Dev*	opendev(char *fn);
355 int	opendevdata(Dev *d, int mode);
356 Dev*	openep(Dev *d, int id);
357 int	parseconf(Usbdev *d, Conf *c, uchar *b, int n);
358 int	parsedesc(Usbdev *d, Conf *c, uchar *b, int n);
359 int	parsedev(Dev *xd, uchar *b, int n);
360 void	startdevs(char *args, char *argv[], int argc, int (*mf)(char*,void*), void*ma, int (*df)(Dev*,int,char**));
361 int	unstall(Dev *dev, Dev *ep, int dir);
362 int	usbcmd(Dev *d, int type, int req, int value, int index, uchar *data, int count);
363 
364 
365 extern int usbdebug;	/* more messages for bigger values */
366 
367 
368