xref: /plan9-contrib/sys/src/9/bcm/usb.h (revision 5c47fe09a0cc86dfb02c0ea4a2b6aec7eda2361f)
1 /*
2  * common USB definitions.
3  */
4 #define dprint		if(debug)print
5 #define ddprint		if(debug>1)print
6 #define deprint		if(debug || ep->debug)print
7 #define ddeprint	if(debug>1 || ep->debug>1)print
8 
9 #define	GET2(p)		((((p)[1]&0xFF)<<8)|((p)[0]&0xFF))
10 #define	PUT2(p,v)	{((p)[0] = (v)); ((p)[1] = (v)>>8);}
11 
12 typedef struct Udev Udev;	/* USB device */
13 typedef struct Ep Ep;		/* Endpoint */
14 typedef struct Hci Hci;		/* Host Controller Interface */
15 typedef struct Hciimpl Hciimpl;	/* Link to the controller impl. */
16 
17 enum
18 {
19 	/* fundamental constants */
20 	Ndeveps	= 16,		/* max nb. of endpoints per device */
21 
22 	/* tunable parameters */
23 	Nhcis	= 16,		/* max nb. of HCIs */
24 	Neps	= 128,		/* max nb. of endpoints */
25 	Maxctllen = 32*1024, /* max allowed sized for ctl. xfers; see Maxdevconf */
26 	Xfertmout = 2000,	/* default request time out (ms) */
27 
28 	/* transfer types. keep this order */
29 	Tnone = 0,		/* no tranfer type configured */
30 	Tctl,			/* wr req + rd/wr data + wr/rd sts */
31 	Tiso,			/* stream rd or wr (real time) */
32 	Tbulk,			/* stream rd or wr */
33 	Tintr,			/* msg rd or wr */
34 	Nttypes,		/* number of transfer types */
35 
36 	Epmax	= 0xF,		/* max ep. addr */
37 	Devmax	= 0x7F,		/* max dev. addr */
38 
39 	/* Speeds */
40 	Fullspeed = 0,
41 	Lowspeed,
42 	Highspeed,
43 	Nospeed,
44 	Superspeed,
45 
46 	/* request type */
47 	Rh2d = 0<<7,
48 	Rd2h = 1<<7,
49 	Rstd = 0<<5,
50 	Rclass =  1<<5,
51 	Rdev = 0,
52 	Rep = 2,
53 	Rother = 3,
54 
55 	/* req offsets */
56 	Rtype	= 0,
57 	Rreq	= 1,
58 	Rvalue	= 2,
59 	Rindex	= 4,
60 	Rcount	= 6,
61 	Rsetuplen = 8,
62 
63 	/* standard requests */
64 	Rgetstatus	= 0,
65 	Rclearfeature	= 1,
66 	Rsetfeature	= 3,
67 	Rsetaddr	= 5,
68 	Rgetdesc	= 6,
69 
70 	/* device states */
71 	Dconfig	 = 0,		/* configuration in progress */
72 	Denabled,		/* address assigned */
73 	Ddetach,		/* device is detached */
74 	Dreset,			/* its port is being reset */
75 
76 	/* (root) Hub reply to port status (reported to usbd) */
77 	HPpresent	= 0x1,
78 	HPenable	= 0x2,
79 	HPsuspend	= 0x4,
80 	HPovercurrent	= 0x8,
81 	HPreset		= 0x10,
82 	HPpower		= 0x100,
83 	HPslow		= 0x200,
84 	HPhigh		= 0x400,
85 	HPstatuschg	= 0x10000,
86 	HPchange	= 0x20000,
87 };
88 
89 /*
90  * Services provided by the driver.
91  * epopen allocates hardware structures to prepare the endpoint
92  * for I/O. This happens when the user opens the data file.
93  * epclose releases them. This happens when the data file is closed.
94  * epwrite tries to write the given bytes, waiting until all of them
95  * have been written (or failed) before returning; but not for Iso.
96  * epread does the same for reading.
97  * It can be assumed that endpoints are DMEXCL but concurrent
98  * read/writes may be issued and the controller must take care.
99  * For control endpoints, device-to-host requests must be followed by
100  * a read of the expected length if needed.
101  * The port requests are called when usbd issues commands for root
102  * hubs. Port status must return bits as a hub request would do.
103  * Toggle handling and other details are left for the controller driver
104  * to avoid mixing too much the controller and the comon device.
105  * While an endpoint is closed, its toggles are saved in the Ep struct.
106  */
107 struct Hciimpl
108 {
109 	void	*aux;				/* for controller info */
110 	void	(*init)(Hci*);			/* init. controller */
111 	void	(*dump)(Hci*);			/* debug */
112 	void	(*interrupt)(Ureg*, void*);	/* service interrupt */
113 	void	(*epopen)(Ep*);			/* prepare ep. for I/O */
114 	void	(*epclose)(Ep*);		/* terminate I/O on ep. */
115 	long	(*epread)(Ep*,void*,long);	/* transmit data for ep */
116 	long	(*epwrite)(Ep*,void*,long);	/* receive data for ep */
117 	char*	(*seprintep)(char*,char*,Ep*);	/* debug */
118 	int	(*portenable)(Hci*, int, int);	/* enable/disable port */
119 	int	(*portreset)(Hci*, int, int);	/* set/clear port reset */
120 	int	(*portstatus)(Hci*, int);	/* get port status */
121 	void	(*shutdown)(Hci*);		/* shutdown for reboot */
122 	void	(*debug)(Hci*, int);		/* set/clear debug flag */
123 };
124 
125 struct Hci
126 {
127 	ISAConf;				/* hardware info */
128 	int	tbdf;				/* type+busno+devno+funcno */
129 	int	ctlrno;				/* controller number */
130 	int	nports;				/* number of ports in hub */
131 	int	highspeed;
132 	uint	superspeed;			/* bitmap of superspeed ports */
133 	Hciimpl;					/* HCI driver  */
134 };
135 
136 /*
137  * USB endpoint.
138  * All endpoints are kept in a global array. The first
139  * block of fields is constant after endpoint creation.
140  * The rest is configuration information given to all controllers.
141  * The first endpoint for a device (known as ep0) represents the
142  * device and is used to configure it and create other endpoints.
143  * Its QLock also protects per-device data in dev.
144  * See Hciimpl for clues regarding how this is used by controllers.
145  */
146 struct Ep
147 {
148 	Ref;			/* one per fid (and per dev ep for ep0s) */
149 
150 	/* const once inited. */
151 	int	idx;		/* index in global eps array */
152 	int	nb;		/* endpoint number in device */
153 	Hci*	hp;		/* HCI it belongs to */
154 	Udev*	dev;		/* device for the endpoint */
155 	Ep*	ep0;		/* control endpoint for its device */
156 
157 	QLock;			/* protect fields below */
158 	char*	name;		/* for ep file names at #u/ */
159 	int	inuse;		/* endpoint is open */
160 	int	mode;		/* OREAD, OWRITE, or ORDWR */
161 	int	clrhalt;	/* true if halt was cleared on ep. */
162 	int	debug;		/* per endpoint debug flag */
163 	char*	info;		/* for humans to read */
164 	long	maxpkt;		/* maximum packet size */
165 	int	ttype;		/* tranfer type */
166 	ulong	load;		/* in µs, for a fransfer of maxpkt bytes */
167 	void*	aux;		/* for controller specific info */
168 	u64int	rhrepl;		/* fake root hub replies */
169 	int	toggle[2];	/* saved toggles (while ep is not in use) */
170 	long	pollival;		/* poll interval ([µ]frames; intr/iso) */
171 	long	hz;		/* poll frequency (iso) */
172 	long	samplesz;	/* sample size (iso) */
173 	int	ntds;		/* nb. of Tds per µframe */
174 	int	tmout;		/* 0 or timeout for transfers (ms) */
175 };
176 
177 /*
178  * Per-device configuration and cached list of endpoints.
179  * eps[0]->QLock protects it.
180  */
181 struct Udev
182 {
183 	int	nb;		/* USB device number */
184 	int	state;		/* state for the device */
185 	int	ishub;		/* hubs can allocate devices */
186 	int	isroot;		/* is a root hub */
187 	int	speed;		/* Full/Low/High/No -speed */
188 	int	hub;		/* dev number for the parent hub */
189 	int	port;		/* port number in the parent hub */
190 	Ep*	eps[Ndeveps];	/* end points for this device (cached) */
191 	int	addr;		/* device address */
192 	int	depth;		/* hub depth from root port */
193 	int	rootport;	/* port number on root hub */
194 	int	routestr;	/* route string */
195 
196 	void	*aux;
197 	void	(*free)(void*);
198 
199 };
200 
201 void	addhcitype(char *type, int (*reset)(Hci*));
202 
203 extern char *usbmodename[];
204 
205 extern char *seprintdata(char*,char*,uchar*,int);
206