1 /*
2  * Contains commonly used types and procedures, for HCD handling/initialization
3  * If possible, everything OS specific (IPC, virtual memory...) should be here
4  */
5 
6 #ifndef _HCD_COMMON_H_
7 #define _HCD_COMMON_H_
8 
9 #include <ddekit/thread.h>
10 #include <ddekit/semaphore.h>
11 #include <ddekit/usb.h>
12 
13 /* TODO: usb.h is for DDEKit's IPC and should not be used here */
14 #include <minix/usb.h>				/* for setup structures */
15 #include <minix/usb_ch9.h>			/* for descriptor structures */
16 
17 #include <sys/cdefs.h>				/* for __aligned() */
18 
19 
20 /*===========================================================================*
21  *    USB register handling defines                                          *
22  *===========================================================================*/
23 /* Helper type used for register bitwise access */
24 #define HCD_BIT(num)				(0x01u << (num))
25 
26 /* Unsigned type that can hold all possible addresses */
27 typedef unsigned long				hcd_addr;
28 
29 /* Register types */
30 typedef unsigned long				hcd_reg4;
31 typedef unsigned short				hcd_reg2;
32 typedef unsigned char				hcd_reg1;
33 
34 /* For register dereferencing */
35 #define _HCD_REG4 				volatile hcd_reg4 *
36 #define _HCD_REG2 				volatile hcd_reg2 *
37 #define _HCD_REG1 				volatile hcd_reg1 *
38 
39 /* Scalar address to dereference */
40 #define _HCD_ADDR(base, off)			(((hcd_addr)(base))+(off))
41 
42 /* Defines for fixed size register access
43  * May cause unaligned memory access */
44 #define HCD_WR4(base, off, val)	(*((_HCD_REG4)_HCD_ADDR(base, off)) = (val))
45 #define HCD_WR2(base, off, val)	(*((_HCD_REG2)_HCD_ADDR(base, off)) = (val))
46 #define HCD_WR1(base, off, val)	(*((_HCD_REG1)_HCD_ADDR(base, off)) = (val))
47 #define HCD_RD4(base, off)	(*((_HCD_REG4)_HCD_ADDR(base, off)))
48 #define HCD_RD2(base, off)	(*((_HCD_REG2)_HCD_ADDR(base, off)))
49 #define HCD_RD1(base, off)	(*((_HCD_REG1)_HCD_ADDR(base, off)))
50 
51 /* Other useful defines */
52 #define HCD_SET(val, bits)	((val)|=(bits))
53 #define HCD_CLR(val, bits)	((val)&=~(bits))
54 
55 /* Alignment safe conversion from 'bytes' array to a word */
56 #define HCD_8TO32(bytes)	(((bytes)[0])		|		\
57 				(((bytes)[1])<<8)	|		\
58 				(((bytes)[2])<<16)	|		\
59 				(((bytes)[3])<<24))
60 
61 /* Convert type's 'sizeof' to 4-byte words count */
62 #define HCD_SIZEOF_TO_4(type)	((sizeof(type)+3)/4)
63 
64 
65 /*===========================================================================*
66  *    USB descriptor types                                                   *
67  *===========================================================================*/
68 typedef usb_descriptor_t			hcd_descriptor;
69 typedef usb_device_descriptor_t			hcd_device_descriptor;
70 typedef usb_config_descriptor_t			hcd_config_descriptor;
71 typedef usb_interface_descriptor_t		hcd_interface_descriptor;
72 typedef usb_endpoint_descriptor_t		hcd_endpoint_descriptor;
73 typedef usb_string_descriptor_t			hcd_string_descriptor;
74 
75 
76 /*===========================================================================*
77  *    HCD descriptor tree types                                              *
78  *===========================================================================*/
79 typedef struct hcd_endpoint {
80 
81 	hcd_endpoint_descriptor descriptor;
82 }
83 hcd_endpoint;
84 
85 typedef struct hcd_interface {
86 
87 	hcd_interface_descriptor descriptor;
88 	hcd_endpoint * endpoint;
89 	int num_endpoints;
90 }
91 hcd_interface;
92 
93 typedef struct hcd_configuration {
94 
95 	hcd_config_descriptor descriptor;
96 	hcd_interface * interface;
97 	int num_interfaces;
98 }
99 hcd_configuration;
100 
101 
102 /*===========================================================================*
103  *    HCD enumerations                                                       *
104  *===========================================================================*/
105 /* Possible USB transfer types */
106 typedef enum {
107 
108 	HCD_TRANSFER_CONTROL		= UE_CONTROL,
109 	HCD_TRANSFER_ISOCHRONOUS	= UE_ISOCHRONOUS,
110 	HCD_TRANSFER_BULK		= UE_BULK,
111 	HCD_TRANSFER_INTERRUPT		= UE_INTERRUPT
112 }
113 hcd_transfer;
114 
115 /* Possible USB transfer directions */
116 typedef enum {
117 
118 	HCD_DIRECTION_OUT		= 0,
119 	HCD_DIRECTION_IN		= 1,
120 	HCD_DIRECTION_UNUSED		= 0xFF
121 }
122 hcd_direction;
123 
124 /* Possible asynchronous HCD events */
125 typedef enum {
126 
127 	HCD_EVENT_CONNECTED = 0,	/* Device connected directly to root */
128 	HCD_EVENT_DISCONNECTED,		/* Directly connected device removed */
129 	HCD_EVENT_PORT_LS_CONNECTED,	/* Low speed device connected to hub */
130 	HCD_EVENT_PORT_FS_CONNECTED,	/* Full speed device connected to hub */
131 	HCD_EVENT_PORT_HS_CONNECTED,	/* High speed device connected to hub */
132 	HCD_EVENT_PORT_DISCONNECTED,	/* Device disconnected from hub */
133 	HCD_EVENT_ENDPOINT,		/* Something happened at endpoint */
134 	HCD_EVENT_URB,			/* URB was submitted by device driver */
135 	HCD_EVENT_INVALID = 0xFF
136 }
137 hcd_event;
138 
139 /* Possible device states */
140 typedef enum {
141 
142 	HCD_STATE_DISCONNECTED = 0,		/* default for initialization */
143 	HCD_STATE_CONNECTION_PENDING,
144 	HCD_STATE_CONNECTED
145 }
146 hcd_state;
147 
148 /* USB speeds */
149 typedef enum {
150 
151 	HCD_SPEED_LOW,
152 	HCD_SPEED_FULL,
153 	HCD_SPEED_HIGH,
154 }
155 hcd_speed;
156 
157 /* Possible data toggle values (at least for bulk transfer) */
158 typedef enum {
159 
160 	HCD_DATATOG_DATA0 = 0,
161 	HCD_DATATOG_DATA1 = 1
162 }
163 hcd_datatog;
164 
165 
166 /*===========================================================================*
167  *    HCD threading/device/URB types                                         *
168  *===========================================================================*/
169 typedef					void (*hcd_thread_function)(void *);
170 typedef ddekit_thread_t			hcd_thread;
171 typedef ddekit_sem_t			hcd_lock;
172 typedef struct hcd_driver_state		hcd_driver_state;
173 typedef struct usb_ctrlrequest		hcd_ctrlrequest;
174 
175 /* Largest value that can be transfered by this driver at a time
176  * see MAXPAYLOAD in TXMAXP/RXMAXP */
177 #define MAX_WTOTALLENGTH 		1024u
178 
179 /* TODO: This has corresponding redefinition in hub driver */
180 /* Limit of child devices for each parent */
181 #define HCD_CHILDREN			8u
182 
183 /* Total number of endpoints available in USB 2.0 */
184 #define HCD_TOTAL_EP			16u
185 
186 /* Forward declarations */
187 typedef struct hcd_datarequest		hcd_datarequest;
188 typedef struct hcd_urb			hcd_urb;
189 typedef struct hcd_device_state		hcd_device_state;
190 
191 /* Non-control transfer request structure */
192 struct hcd_datarequest {
193 
194 	hcd_reg1 * data;		/* RX/TX buffer */
195 	int data_left;			/* Amount of data to transfer (may
196 					 * become negative in case of error
197 					 * thus 'int') */
198 	hcd_reg2 max_packet_size;	/* Read from EP descriptor */
199 	hcd_reg1 endpoint;		/* EP number */
200 	hcd_reg1 interval;		/* Should match one in EP descriptor */
201 	hcd_direction direction;	/* Should match one in EP descriptor */
202 	hcd_speed speed;		/* Decided during device reset */
203 	hcd_transfer type;		/* Should match one in EP descriptor */
204 };
205 
206 /* HCD's URB structure */
207 struct hcd_urb {
208 
209 	/* Basic */
210 	void * original_urb;
211 	hcd_device_state * target_device;
212 	void (*handled)(hcd_urb *);	/* URB handled callback */
213 
214 	/* Transfer (in/out signifies what may be overwritten by HCD) */
215 	hcd_ctrlrequest * in_setup;
216 	hcd_reg1 * inout_data;
217 	hcd_reg4 in_size;
218 	hcd_reg4 out_size;
219 	int inout_status;	/* URB submission/validity status */
220 
221 	/* Transfer control */
222 	hcd_transfer type;
223 	hcd_direction direction;
224 	hcd_reg1 endpoint;
225 	hcd_reg1 interval;
226 };
227 
228 /* Current state of attached device */
229 struct hcd_device_state {
230 
231 	hcd_device_state * parent;		/* In case of hub attachment */
232 	hcd_device_state * child[HCD_CHILDREN];	/* In case of being hub */
233 	hcd_device_state * _next;		/* To allow device lists */
234 	hcd_driver_state * driver;		/* Specific HCD driver object */
235 	hcd_thread * thread;
236 	hcd_lock * lock;
237 	void * data;
238 
239 	hcd_urb * urb;				/* URB to be used by device */
240 	hcd_event wait_event;			/* Expected event */
241 	hcd_reg1 wait_ep;			/* Expected event's endpoint */
242 	hcd_device_descriptor device_desc;
243 	hcd_configuration config_tree;
244 	hcd_reg1 max_packet_size;
245 	hcd_speed speed;
246 	hcd_state state;
247 	hcd_reg1 reserved_address;
248 	hcd_reg1 current_address;
249 	hcd_datatog ep_tx_tog[HCD_TOTAL_EP];
250 	hcd_datatog ep_rx_tog[HCD_TOTAL_EP];
251 
252 	/*
253 	 * Control transfer's local data:
254 	 */
255 
256 	/* Number of bytes received/transmitted in last control transfer (may
257 	 * become negative in case of error thus 'int') */
258 	int control_len;
259 
260 	/* Word aligned buffer for each device to hold transfered data */
261 	hcd_reg1 control_data[MAX_WTOTALLENGTH] __aligned(sizeof(hcd_reg4));
262 };
263 
264 
265 /*===========================================================================*
266  *    Other definitions                                                      *
267  *===========================================================================*/
268 #define HCD_MILI			1000
269 #define HCD_MICRO			1000000
270 #define HCD_NANO			1000000000
271 #define HCD_NANOSLEEP_SEC(sec)		((sec)  * HCD_NANO)
272 #define HCD_NANOSLEEP_MSEC(msec)	((msec) * HCD_MICRO)
273 #define HCD_NANOSLEEP_USEC(usec)	((usec) * HCD_MILI)
274 
275 /* Default USB communication parameters */
276 #define HCD_DEFAULT_EP			0x00u
277 #define HCD_DEFAULT_ADDR		0x00u
278 #define HCD_DEFAULT_CONFIG		0x00u
279 #define HCD_FIRST_ADDR			0x01u
280 #define HCD_LAST_ADDR			0x7Fu
281 #define HCD_TOTAL_ADDR			0x80u
282 #define HCD_LAST_EP			0x0Fu
283 #define HCD_UNUSED_VAL			0xFFu	/* When number not needed */
284 #define HCD_DEFAULT_NAKLIMIT		0x10u
285 
286 
287 /* Legal interval values */
288 #define HCD_LOWEST_INTERVAL		0x00u
289 #define HCD_HIGHEST_INTERVAL		0xFFu
290 
291 /* Translates configuration number for 'set configuration' */
292 #define HCD_SET_CONFIG_NUM(num)		((num)+0x01u)
293 
294 /* Default MaxPacketSize for control transfer */
295 #define HCD_LS_MAXPACKETSIZE		8u	/* Low-speed, Full-speed */
296 #define HCD_HS_MAXPACKETSIZE		64u	/* High-speed */
297 #define HCD_MAX_MAXPACKETSIZE		1024u
298 
299 
300 /*===========================================================================*
301  *    Operating system specific                                              *
302  *===========================================================================*/
303 /* Generic method for registering interrupts */
304 int hcd_os_interrupt_attach(int irq, void (*init)(void *),
305 				void (*isr)(void *), void *priv);
306 
307 /* Generic method for unregistering interrupts */
308 void hcd_os_interrupt_detach(int);
309 
310 /* Generic method for enabling interrupts */
311 void hcd_os_interrupt_enable(int);
312 
313 /* Generic method for disabling interrupts */
314 void hcd_os_interrupt_disable(int);
315 
316 /* Returns pointer to memory mapped for given arguments */
317 void * hcd_os_regs_init(hcd_addr, unsigned long);
318 
319 /* Unregisters mapped memory */
320 int hcd_os_regs_deinit(hcd_addr, unsigned long);
321 
322 /* Configure clocking */
323 int hcd_os_clkconf(unsigned long, unsigned long, unsigned long);
324 
325 /* Release clocking */
326 int hcd_os_clkconf_release(void);
327 
328 /* OS's sleep wrapper */
329 void hcd_os_nanosleep(int);
330 
331 
332 /*===========================================================================*
333  *    Device handling calls                                                  *
334  *===========================================================================*/
335 /* Initializes device threading on connection */
336 int hcd_connect_device(hcd_device_state *, hcd_thread_function);
337 
338 /* Cleans after device disconnection */
339 void hcd_disconnect_device(hcd_device_state *);
340 
341 /* Locks device thread until 'hcd_device_continue' */
342 void hcd_device_wait(hcd_device_state *, hcd_event, hcd_reg1);
343 
344 /* Unlocks device thread halted by 'hcd_device_wait' */
345 void hcd_device_continue(hcd_device_state *, hcd_event, hcd_reg1);
346 
347 /* Allocation/deallocation of device structures */
348 hcd_device_state * hcd_new_device(void);
349 void hcd_delete_device(hcd_device_state *);
350 void hcd_dump_devices(void);
351 int hcd_check_device(hcd_device_state *);
352 
353 
354 /*===========================================================================*
355  *    Descriptor tree calls                                                  *
356  *===========================================================================*/
357 /* Creates descriptor tree based on given buffer */
358 int hcd_buffer_to_tree(hcd_reg1 *, int, hcd_configuration *);
359 
360 /* Frees descriptor tree */
361 void hcd_tree_cleanup(hcd_configuration *);
362 
363 /* Find EP in a tree */
364 hcd_endpoint * hcd_tree_find_ep(hcd_configuration *, hcd_reg1);
365 
366 
367 #endif /* !_HCD_COMMON_H_ */
368