Subversion Repositories planix.SVN

Rev

Rev 34 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 1
.TH USB 2
2
.SH NAME
3
usbcmd,
4
classname,
5
closedev,
6
configdev,
7
devctl,
8
finddevs,
9
loaddevstr,
10
matchdevcsp,
11
opendev,
12
opendevdata,
13
openep,
14
startdevs,
15
unstall,
16
class,
17
subclass,
18
proto,
19
CSP \- USB device driver library
20
.SH SYNOPSIS
21
.EX
22
.ta 8n +8n +8n +8n +8n +8n +8n
23
#include <u.h>
24
#include <libc.h>
25
#include <thread.h>
26
#include "../lib/usb.h"
27
.sp 0.3v
28
struct Dev {
29
	Ref;
30
	char*	dir;		/* path for the endpoint dir */
31
	int	id;		/* usb id for device or ep. number */
32
	int	dfd;		/* descriptor for the data file */
33
	int	cfd;		/* descriptor for the control file */
34
	int	maxpkt;		/* cached from usb description */
35
	Usbdev*	usb;		/* USB description */
36
	void*	aux;		/* for the device driver */
37
	void	(*free)(void*);	/* idem. to release aux */
38
};
39
.sp 0.3v
40
struct Usbdev {
41
	ulong	csp;		/* USB class/subclass/proto */
42
	int	vid;		/* vendor id */
43
	int	did;		/* product (device) id */
44
	int	dno;		/* device release number */
45
	char*	vendor;
46
	char*	product;
47
	char*	serial;
48
	int	ls;		/* low speed */
49
	int	class;		/* from descriptor */
50
	int	nconf;		/* from descriptor */
51
	Conf*	conf[Nconf];	/* configurations */
52
	Ep*	ep[Nep];	/* all endpoints in device */
53
	Desc*	ddesc[Nddesc];	/* (raw) device specific descriptors */
54
};
55
.sp 0.3v
56
struct Ep {
57
	uchar	addr;		/* endpt address */
58
	uchar	dir;		/* direction, Ein/Eout */
59
	uchar	type;		/* Econtrol, Eiso, Ebulk, Eintr */
60
	uchar	isotype;	/* Eunknown, Easync, Eadapt, Esync */
61
	int	id;
62
	int	maxpkt;		/* max. packet size */
63
	Conf*	conf;		/* the endpoint belongs to */
64
	Iface*	iface;		/* the endpoint belongs to */
65
};
66
.sp 0.3v
67
struct Altc {
68
	int	attrib;
69
	int	interval;
70
	void*	aux;		/* for the driver program */
71
};
72
.sp 0.3v
73
struct Iface {
74
	int 	id;		/* interface number */
75
	ulong	csp;		/* USB class/subclass/proto */
76
	Altc*	altc[Naltc];
77
	Ep*	ep[Nep];
78
	void*	aux;		/* for the driver program */
79
};
80
.sp 0.3v
81
struct Conf {
82
	int	cval;		/* value for set configuration */
83
	int	attrib;
84
	int	milliamps;	/* maximum power in this config. */
85
	Iface*	iface[Niface];	/* up to 16 interfaces */
86
};
87
.sp 0.3v
88
struct Desc {
89
	Conf*	conf;		/* where this descriptor was read */
90
	Iface*	iface;		/* last iface before desc in conf. */
91
	Ep*	ep;		/* last endpt before desc in conf. */
92
	Altc*	altc;		/* last alt.c. before desc in conf. */
93
	DDesc	data;		/* unparsed standard USB descriptor */
94
};
95
.sp 0.3v
96
struct DDesc {
97
	uchar	bLength;
98
	uchar	bDescriptorType;
99
	uchar	bbytes[1];
100
	/* extra bytes allocated here to keep the rest of it */
101
};
102
.sp 0.3v
103
#define Class(csp)	((csp)&0xff)
104
#define Subclass(csp)	(((csp)>>8)&0xff)
105
#define Proto(csp)	(((csp)>>16)&0xff)
106
#define CSP(c, s, p)	((c) | ((s)<<8) | ((p)<<16))
107
#define	GET2(p)		...
108
#define	PUT2(p,v)	...
109
#define	GET4(p)		...
110
#define	PUT4(p,v)	...
111
#define dprint	 if(usbdebug)fprint
112
#define ddprint if(usbdebug > 1)fprint
113
.sp 0.3v
114
int	Ufmt(Fmt *f);
115
char*	classname(int c);
116
void	closedev(Dev *d);
117
int	configdev(Dev *d);
118
int	devctl(Dev *dev, char *fmt, ...);
119
void*	emallocz(ulong size, int zero);
120
char*	estrdup(char *s);
121
int	finddevs(int (*matchf)(char*,void*), void *farg, char** dirs, int ndirs);
122
char*	hexstr(void *a, int n);
123
char*	loaddevstr(Dev *d, int sid);
124
int	matchdevcsp(char *info, void *a);
125
Dev*	opendev(char *fn);
126
int	opendevdata(Dev *d, int mode);
127
Dev*	openep(Dev *d, int id);
128
void	startdevs(char *args, char *argv[], int argc,
129
		int (*mf)(char*,void*), void*ma, int (*df)(Dev*,int,char**));
130
int	unstall(Dev *dev, Dev *ep, int dir);
131
int	usbcmd(Dev *d, int type, int req,
132
		int value, int index, uchar *data, int count);
133
.sp 0.3v
134
extern int usbdebug;	/* more messages for bigger values */
135
.EE
136
.SH DESCRIPTION
137
This library provides convenience structures and functions to write
138
USB device drivers.
139
It is not intended for user programs using USB devices.
140
See
141
.IR usb (3)
142
for a description of the interfaces provided for that purpose.
143
For drivers that provide a file system and may be embedded into
144
.IR usbd ,
145
the library includes a file system implementation toolkit described in
146
.IR usbfs (2).
147
.PP
148
Usb drivers rely on
149
.IR usb (3)
150
to perform I/O through USB as well as on
151
.IR usbd (4)
152
to perform the initial configuration for the device's setup endpoint.
153
The rest of the work is up to the driver and is where this library may help.
154
.PP
155
In most cases, a driver locates the devices of interest and configures them
156
by calling
157
.I startdevs
158
and
159
then sets up additional endpoints as needed (by calling
160
.IR openep )
161
to finally perform I/O by reading and writing the
162
data files for the endpoints.
163
.PP
164
An endpoint as provided by
165
.IR usb (3)
166
is represented by a
167
.B Dev
168
data structure.
169
The setup endpoint for a
170
device represents the USB device, because it is the means to
171
configure and operate the device.
172
This structure is reference counted.
173
Functions creating
174
.B Devs
175
adjust the number of references to one, initially.
176
The driver is free to call
177
.IR incref
178
(in
179
.IR lock (2))
180
to add references and
181
.I closedev
182
to drop references (and release resources when the last one vanishes).
183
As an aid to the driver, the field
184
.B aux
185
may keep driver-specific data and the function
186
.B free
187
will be called (if not null) to release the
188
.B aux
189
structure when the reference count goes down to zero.
190
.PP
191
.I Dev.dir
192
holds the path for the endpoint's directory.
193
.PP
194
The field
195
.B id
196
keeps the device number for setup endpoints and the endpoint number
197
for all other endpoints.
198
For example, it would be
199
.B 3
200
for
201
.B /dev/usb/ep3.0
202
and
203
.B 1
204
for
205
.BR /dev/usb/ep3.1 .
206
It is easy to remember this because the former is created to operate
207
on the device, while the later has been created as a particular endpoint
208
to perform I/O.
209
.PP
210
Fields
211
.B dfd
212
and
213
.B cfd
214
keep the data and
215
control file descriptors, respectively.
216
When a
217
.B Dev
218
is created the control file is open, initially.
219
Opening the data
220
file requires calling
221
.I opendevdata
222
with the appropriate mode.
223
.PP
224
When the device configuration information has been loaded (see below),
225
.B maxpkt
226
holds the maximum packet size (in bytes) for the endpoint and
227
.B usb
228
keeps the rest of the USB information.
229
.PP
230
Most of the information in
231
.B usb
232
comes from parsing
233
various device and configuration descriptors provided by the device,
234
by calling one of the functions described later.
235
Only descriptors unknown
236
to the library are kept unparsed at
237
.B usb.ddesc
238
as an aid for the driver
239
(which should know how to parse them and what to do with the information).
240
.SS Configuration
241
.I Startdevs
242
is a wrapper that locates devices of interest, loads their configuration
243
information, and starts a
244
.IR thread (2)'s
245
.I proc
246
for each device located so that it executes
247
.I f
248
as its main entry point. The entry point is called with a pointer to
249
the
250
.B Dev
251
for the device it has to process,
252
.BR argc ,
253
and
254
.BR argv .
255
Devices are located either from the arguments (after options) in
256
.IR argv ,
257
if any,
258
or by calling the helper function
259
.I mf
260
with the argument
261
.I ma
262
to determine (for each device available) if the device belongs to
263
the driver or not. If the function returns -1 then the device is not for us.
264
.PP
265
In many cases,
266
.I matchdevcsp
267
may be supplied as
268
.I mf
269
along with a (null terminated) vector of CSP values supplied as
270
.IR ma .
271
This function returns 0 for any device with a CSP matching one in the
272
vector supplied as an argument and -1 otherwise.
273
In other cases (eg., when a particular vendor and device ids are the
274
ones identifying the device) the driver must include its own function
275
and supply it as an argument to
276
.IR startdevs .
277
The first argument of the function corresponds to the information
278
known about the device (the second line in its
279
.B ctl
280
file).
281
.I Openep
282
creates the endpoint number
283
.I id
284
for the device
285
.I d
286
and returns a
287
.B Dev
288
structure to operate on it (with just the control file open).
289
.PP
290
.I Opendev
291
creates a
292
.B Dev
293
for the endpoint with directory
294
.IR fn .
295
Usually, the endpoint is a setup endpoint representing a device. The endpoint
296
control file is open, but the data file is not. The USB description is void.
297
In most cases drivers call
298
.I startdevs
299
and
300
.I openep
301
and do not call this function directly.
302
.PP
303
.I Configdev
304
opens the data file for the device supplied and
305
loads and parses its configuration information.
306
After calling it, the device is ready for I/O and the USB description in
307
.B Dev.usb
308
is valid.
309
When using
310
.IR startdevs
311
it is not desirable to call this function (because
312
.IR startdevs
313
already calls it).
314
.PP
315
Control requests for an endpoint may be written by calling
316
.I devctl
317
in the style of
318
.IR print (2).
319
It is better not to call
320
.I print
321
directly because the control request should be issued as a single
322
.I write
323
system call.
324
See
325
.IR usb (3)
326
for a list of available control requests (not to be confused with
327
USB control transfers performed on a control endpoint).
328
.SS Input/Output
329
.I Opendevdata
330
opens the data file for the device according to the given
331
.IR mode .
332
The mode must match that of the endpoint, doing otherwise is considered
333
an error.
334
Actual I/O is performed by reading/writing the descriptor kept in the
335
.B dfd
336
field of
337
.BR Dev .
338
.PP
339
For control endpoints,
340
it is not necessary to call
341
.I read
342
and
343
.I write
344
directly.
345
Instead,
346
.I usbcmd
347
issues a USB control request to the device
348
.I d
349
(not to be confused with a
350
.IR usb (3)
351
control request sent to its control file).
352
.I Usbcmd
353
retries the control request several times upon failure because some devices
354
require it.
355
The format of requests is fixed per the USB standard:
356
.I type
357
is the type of request and
358
.I req
359
identifies the request. Arguments
360
.I value
361
and
362
.I index
363
are parameters to the request and the last two arguments,
364
.I data
365
and
366
.IR count ,
367
are similar to
368
.I read
369
and
370
.I write
371
arguments.
372
However,
373
.I data
374
may be
375
.B nil
376
if no transfer (other than the control request) has to take place.
377
The library header file includes numerous symbols defined to help writing
378
the type and arguments for a request.
379
.PP
380
The return value from
381
.I usbcmd
382
is the number of bytes transferred, zero to indicate a stall and -1
383
to indicate an error.
384
.PP
385
A common request is to unstall an endpoint that has been stalled
386
due to some reason by the device (eg., when read or write indicate
387
a count of zero bytes read or written on the endpoint). The function
388
.I unstall
389
does this.
390
It is given the device that stalled the endpoint,
391
.IR dev ,
392
the
393
stalled endpoint,
394
.IR ep ,
395
and the direction of the stall (one of
396
.B Ein
397
or
398
.BR Eout ).
399
The function takes care of notifying the device of the unstall as well
400
as notifying the kernel.
401
.SS Tools
402
.I Class
403
returns the class part of the number given, representing a CSP.
404
.I Subclass
405
does the same for the device subclass and
406
.I Proto
407
for the protocol.
408
The counterpart is
409
.IR CSP ,
410
which builds a CSP from the device class, subclass, and protocol.
411
For some classes,
412
.I classname
413
knows the name (for those with constants in the library header file).
414
.PP
415
The macros
416
.I GET2
417
and
418
.I PUT2
419
get and put a (little-endian) two-byte value and are useful to
420
parse descriptors and replies for control requests.
421
.PP
422
Functions
423
.I emallocz
424
and
425
.I estrdup
426
are similar to
427
.I mallocz
428
and
429
.I strdup
430
but abort program operation upon failure.
431
.PP
432
The function
433
.I Ufmt
434
is a format routine suitable for
435
.IR fmtinstall (2)
436
to print a
437
.B Dev
438
data structure.
439
The auxiliary
440
.I hexstr
441
returns a string representing a dump (in hexadecimal) of
442
.I n
443
bytes starting at
444
.IR a .
445
The string is allocated using
446
.IR malloc (2)
447
and memory must be released by the caller.
448
.PP
449
.I Loaddevstr
450
returns the string obtained by reading the device string descriptor number
451
.IR sid .
452
.SH SOURCE
453
.B /sys/src/cmd/usb/lib
454
.SH "SEE ALSO"
455
.IR usbfs (2),
456
.IR usb (3),
457
.IR usb (4),
458
.IR usbd (4).
459
.SH BUGS
460
Not heavily exercised yet.