xref: /aosp_15_r20/external/coreboot/payloads/libpayload/drivers/usb/xhci_private.h (revision b9411a12aaaa7e1e6a6fb7c5e057f44ee179a49c)
1 /*
2  *
3  * Copyright (C) 2010 Patrick Georgi
4  * Copyright (C) 2013 secunet Security Networks AG
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  * 3. The name of the author may not be used to endorse or promote products
15  *    derived from this software without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27  * SUCH DAMAGE.
28  */
29 
30 #ifndef __XHCI_PRIVATE_H
31 #define __XHCI_PRIVATE_H
32 
33 //#define USB_DEBUG
34 #include <usb/usb.h>
35 #include <arch/barrier.h>
36 #include <kconfig.h>
37 
38 //#define XHCI_DUMPS
39 #define xhci_debug(fmt, args...) usb_debug("%s: " fmt, __func__, ## args)
40 #ifdef XHCI_SPEW_DEBUG
41 # define xhci_spew(fmt, args...) xhci_debug(fmt, ##args)
42 #else
43 # define xhci_spew(fmt, args...) do {} while (0)
44 #endif
45 
46 #define MASK(startbit, lenbit) (((1<<(lenbit))-1)<<(startbit))
47 
48 /* Make these high enough to not collide with negative XHCI CCs */
49 #define TIMEOUT			-65
50 #define CONTROLLER_ERROR	-66
51 #define COMMUNICATION_ERROR	-67
52 #define OUT_OF_MEMORY		-68
53 #define DRIVER_ERROR		-69
54 
55 #define CC_SUCCESS			 1
56 #define CC_TRB_ERROR			 5
57 #define CC_STALL_ERROR			 6
58 #define CC_RESOURCE_ERROR		 7
59 #define CC_BANDWIDTH_ERROR		 8
60 #define CC_NO_SLOTS_AVAILABLE		 9
61 #define CC_SHORT_PACKET			13
62 #define CC_EVENT_RING_FULL_ERROR	21
63 #define CC_COMMAND_RING_STOPPED		24
64 #define CC_COMMAND_ABORTED		25
65 #define CC_STOPPED			26
66 #define CC_STOPPED_LENGTH_INVALID	27
67 
68 enum {
69 	TRB_NORMAL = 1,
70 	TRB_SETUP_STAGE = 2, TRB_DATA_STAGE = 3, TRB_STATUS_STAGE = 4,
71 	TRB_LINK = 6, TRB_EVENT_DATA = 7,
72 	TRB_CMD_ENABLE_SLOT = 9, TRB_CMD_DISABLE_SLOT = 10, TRB_CMD_ADDRESS_DEV = 11,
73 	TRB_CMD_CONFIGURE_EP = 12, TRB_CMD_EVAL_CTX = 13, TRB_CMD_RESET_EP = 14,
74 	TRB_CMD_STOP_EP = 15, TRB_CMD_SET_TR_DQ = 16, TRB_CMD_NOOP = 23,
75 	TRB_EV_TRANSFER = 32, TRB_EV_CMD_CMPL = 33, TRB_EV_PORTSC = 34, TRB_EV_HOST = 37,
76 };
77 enum { TRB_TRT_NO_DATA = 0, TRB_TRT_OUT_DATA = 2, TRB_TRT_IN_DATA = 3 };
78 enum { TRB_DIR_OUT = 0, TRB_DIR_IN = 1 };
79 
80 #define TRB_PORT_FIELD		ptr_low
81 #define TRB_PORT_START		24
82 #define TRB_PORT_LEN		8
83 #define TRB_TL_FIELD		status		/* TL - Transfer Length */
84 #define TRB_TL_START		0
85 #define TRB_TL_LEN		17
86 #define TRB_EVTL_FIELD		status		/* EVTL - (Event TRB) Transfer Length */
87 #define TRB_EVTL_START		0
88 #define TRB_EVTL_LEN		24
89 #define TRB_TDS_FIELD		status		/* TDS - TD Size */
90 #define TRB_TDS_START		17
91 #define TRB_TDS_LEN		5
92 #define TRB_CC_FIELD		status		/* CC - Completion Code */
93 #define TRB_CC_START		24
94 #define TRB_CC_LEN		8
95 #define TRB_C_FIELD		control		/* C - Cycle Bit */
96 #define TRB_C_START		0
97 #define TRB_C_LEN		1
98 #define TRB_TC_FIELD		control		/* TC - Toggle Cycle */
99 #define TRB_TC_START		1
100 #define TRB_TC_LEN		1
101 #define TRB_ENT_FIELD		control		/* ENT - Evaluate Next TRB */
102 #define TRB_ENT_START		1
103 #define TRB_ENT_LEN		1
104 #define TRB_ISP_FIELD		control		/* ISP - Interrupt-on Short Packet */
105 #define TRB_ISP_START		2
106 #define TRB_ISP_LEN		1
107 #define TRB_CH_FIELD		control		/* CH - Chain Bit */
108 #define TRB_CH_START		4
109 #define TRB_CH_LEN		1
110 #define TRB_IOC_FIELD		control		/* IOC - Interrupt On Completion */
111 #define TRB_IOC_START		5
112 #define TRB_IOC_LEN		1
113 #define TRB_IDT_FIELD		control		/* IDT - Immediate Data */
114 #define TRB_IDT_START		6
115 #define TRB_IDT_LEN		1
116 #define TRB_DC_FIELD		control		/* DC - Deconfigure */
117 #define TRB_DC_START		9
118 #define TRB_DC_LEN		1
119 #define TRB_TT_FIELD		control		/* TT - TRB Type */
120 #define TRB_TT_START		10
121 #define TRB_TT_LEN		6
122 #define TRB_TRT_FIELD		control		/* TRT - Transfer Type */
123 #define TRB_TRT_START		16
124 #define TRB_TRT_LEN		2
125 #define TRB_DIR_FIELD		control		/* DIR - Direction */
126 #define TRB_DIR_START		16
127 #define TRB_DIR_LEN		1
128 #define TRB_EP_FIELD		control		/* EP - Endpoint ID */
129 #define TRB_EP_START		16
130 #define TRB_EP_LEN		5
131 #define TRB_ID_FIELD		control		/* ID - Slot ID */
132 #define TRB_ID_START		24
133 #define TRB_ID_LEN		8
134 #define TRB_MASK(tok)		MASK(TRB_##tok##_START, TRB_##tok##_LEN)
135 #define TRB_GET(tok, trb)	(((trb)->TRB_##tok##_FIELD & TRB_MASK(tok)) \
136 				 >> TRB_##tok##_START)
137 #define TRB_SET(tok, trb, to)	(trb)->TRB_##tok##_FIELD = \
138 				(((trb)->TRB_##tok##_FIELD & ~TRB_MASK(tok)) | \
139 				 (((to) << TRB_##tok##_START) & TRB_MASK(tok)))
140 #define TRB_DUMP(tok, trb)	usb_debug(" "#tok"\t0x%04"PRIx32"\n", TRB_GET(tok, trb))
141 
142 #define TRB_CYCLE		(1 << 0)
143 typedef volatile struct trb {
144 	u32 ptr_low;
145 	u32 ptr_high;
146 	u32 status;
147 	u32 control;
148 } trb_t;
149 
150 #define TRB_MAX_TD_SIZE	0x1F			/* bits 21:17 of TD Size in TRB */
151 
152 #define EVENT_RING_SIZE 64
153 typedef struct {
154 	trb_t *ring;
155 	trb_t *cur;
156 	trb_t *last;
157 	u8 ccs;
158 	u8 adv;
159 } event_ring_t;
160 
161 /* Never raise this above 256 to prevent transfer event length overflow! */
162 #define TRANSFER_RING_SIZE 32
163 typedef struct {
164 	trb_t *ring;
165 	trb_t *cur;
166 	u8 pcs;
167 } __packed transfer_ring_t;
168 
169 #define COMMAND_RING_SIZE 4
170 typedef transfer_ring_t command_ring_t;
171 
172 #define SC_ROUTE_FIELD		f1		/* ROUTE - Route String */
173 #define SC_ROUTE_START		0
174 #define SC_ROUTE_LEN		20
175 #define SC_SPEED1_FIELD		f1		/* SPEED - Port speed plus one (compared to usb_speed enum) */
176 #define SC_SPEED1_START		20
177 #define SC_SPEED1_LEN		4
178 #define SC_MTT_FIELD		f1		/* MTT - Multi Transaction Translator */
179 #define SC_MTT_START		25
180 #define SC_MTT_LEN		1
181 #define SC_HUB_FIELD		f1		/* HUB - Is this a hub? */
182 #define SC_HUB_START		26
183 #define SC_HUB_LEN		1
184 #define SC_CTXENT_FIELD		f1		/* CTXENT - Context Entries (number of following ep contexts) */
185 #define SC_CTXENT_START		27
186 #define SC_CTXENT_LEN		5
187 #define SC_RHPORT_FIELD		f2		/* RHPORT - Root Hub Port Number */
188 #define SC_RHPORT_START		16
189 #define SC_RHPORT_LEN		8
190 #define SC_NPORTS_FIELD		f2		/* NPORTS - Number of Ports */
191 #define SC_NPORTS_START		24
192 #define SC_NPORTS_LEN		8
193 #define SC_TTID_FIELD		f3		/* TTID - TT Hub Slot ID */
194 #define SC_TTID_START		0
195 #define SC_TTID_LEN		8
196 #define SC_TTPORT_FIELD		f3		/* TTPORT - TT Port Number */
197 #define SC_TTPORT_START		8
198 #define SC_TTPORT_LEN		8
199 #define SC_TTT_FIELD		f3		/* TTT - TT Think Time */
200 #define SC_TTT_START		16
201 #define SC_TTT_LEN		2
202 #define SC_UADDR_FIELD		f4		/* UADDR - USB Device Address */
203 #define SC_UADDR_START		0
204 #define SC_UADDR_LEN		8
205 #define SC_STATE_FIELD		f4		/* STATE - Slot State */
206 #define SC_STATE_START		27
207 #define SC_STATE_LEN		5
208 #define SC_MASK(tok)		MASK(SC_##tok##_START, SC_##tok##_LEN)
209 #define SC_GET(tok, sc)		(((sc)->SC_##tok##_FIELD & SC_MASK(tok)) \
210 				 >> SC_##tok##_START)
211 #define SC_SET(tok, sc, to)	(sc)->SC_##tok##_FIELD = \
212 				(((sc)->SC_##tok##_FIELD & ~SC_MASK(tok)) | \
213 				 (((to) << SC_##tok##_START) & SC_MASK(tok)))
214 #define SC_DUMP(tok, sc)	usb_debug(" "#tok"\t0x%04"PRIx32"\n", SC_GET(tok, sc))
215 typedef volatile struct slotctx {
216 	u32 f1;
217 	u32 f2;
218 	u32 f3;
219 	u32 f4;
220 	u32 rsvd[4];
221 } slotctx_t;
222 
223 #define EC_STATE_FIELD		f1		/* STATE - Endpoint State */
224 #define EC_STATE_START		0
225 #define EC_STATE_LEN		3
226 #define EC_INTVAL_FIELD		f1		/* INTVAL - Interval */
227 #define EC_INTVAL_START		16
228 #define EC_INTVAL_LEN		8
229 #define EC_CERR_FIELD		f2		/* CERR - Error Count */
230 #define EC_CERR_START		1
231 #define EC_CERR_LEN		2
232 #define EC_TYPE_FIELD		f2		/* TYPE - EP Type */
233 #define EC_TYPE_START		3
234 #define EC_TYPE_LEN		3
235 #define EC_MBS_FIELD		f2		/* MBS - Max Burst Size */
236 #define EC_MBS_START		8
237 #define EC_MBS_LEN		8
238 #define EC_MPS_FIELD		f2		/* MPS - Max Packet Size */
239 #define EC_MPS_START		16
240 #define EC_MPS_LEN		16
241 #define EC_DCS_FIELD		tr_dq_low	/* DCS - Dequeue Cycle State */
242 #define EC_DCS_START		0
243 #define EC_DCS_LEN		1
244 #define EC_AVRTRB_FIELD		f5		/* AVRTRB - Average TRB Length */
245 #define EC_AVRTRB_START		0
246 #define EC_AVRTRB_LEN		16
247 #define EC_MXESIT_FIELD		f5		/* MXESIT - Max ESIT Payload */
248 #define EC_MXESIT_START		16
249 #define EC_MXESIT_LEN		16
250 #define EC_BPKTS_FIELD		rsvd[0]		/* BPKTS - packets tx in scheduled uframe */
251 #define EC_BPKTS_START		0
252 #define EC_BPKTS_LEN		6
253 #define EC_BBM_FIELD		rsvd[0]		/* BBM - burst mode for scheduling */
254 #define EC_BBM_START		11
255 #define EC_BBM_LEN		1
256 
257 #define EC_MASK(tok)		MASK(EC_##tok##_START, EC_##tok##_LEN)
258 #define EC_GET(tok, ec)		(((ec)->EC_##tok##_FIELD & EC_MASK(tok)) \
259 				 >> EC_##tok##_START)
260 #define EC_SET(tok, ec, to)	(ec)->EC_##tok##_FIELD = \
261 				(((ec)->EC_##tok##_FIELD & ~EC_MASK(tok)) | \
262 				 (((to) << EC_##tok##_START) & EC_MASK(tok)))
263 #define EC_DUMP(tok, ec)	usb_debug(" "#tok"\t0x%04"PRIx32"\n", EC_GET(tok, ec))
264 enum { EP_ISOC_OUT = 1, EP_BULK_OUT = 2, EP_INTR_OUT = 3,
265 	EP_CONTROL = 4, EP_ISOC_IN = 5, EP_BULK_IN = 6, EP_INTR_IN = 7 };
266 typedef volatile struct epctx {
267 	u32 f1;
268 	u32 f2;
269 	u32 tr_dq_low;
270 	u32 tr_dq_high;
271 	u32 f5;
272 	u32 rsvd[3];
273 } epctx_t;
274 
275 #define NUM_EPS 32
276 
277 typedef union devctx {
278 	/* set of pointers, so we can dynamically adjust Slot/EP context size */
279 	struct {
280 		union {
281 			slotctx_t *slot;
282 			void *raw;	/* Pointer to the whole dev context. */
283 		};
284 		epctx_t *ep0;
285 		epctx_t *eps1_30[NUM_EPS - 2];
286 	};
287 	epctx_t *ep[NUM_EPS];	/* At index 0 it's actually the slotctx,
288 					we have it like that so we can use
289 					the ep_id directly as index. */
290 } devctx_t;
291 
292 typedef struct inputctx {
293 	union {		    /* The drop flags are located at the start of the */
294 		u32 *drop;  /* structure, so a pointer to them is equivalent */
295 		void *raw;  /* to a pointer to the whole (raw) input context. */
296 	};
297 	u32 *add;
298 	devctx_t dev;
299 } inputctx_t;
300 
301 typedef struct intrq {
302 	size_t size;	/* Size of each transfer */
303 	size_t count;	/* The number of TRBs to fill at once */
304 	trb_t *next;	/* The next TRB expected to be processed by the controller */
305 	trb_t *ready;	/* The last TRB in the transfer ring processed by the controller */
306 	endpoint_t *ep;
307 } intrq_t;
308 
309 typedef struct devinfo {
310 	devctx_t ctx;
311 	transfer_ring_t *transfer_rings[NUM_EPS];
312 	intrq_t *interrupt_queues[NUM_EPS];
313 } devinfo_t;
314 
315 typedef struct erst_entry {
316 	u32 seg_base_lo;
317 	u32 seg_base_hi;
318 	u32 seg_size;
319 	u32 rsvd;
320 } erst_entry_t;
321 
322 #define CAP_CAPLEN_FIELD		hciparams
323 #define CAP_CAPLEN_START		0
324 #define CAP_CAPLEN_LEN			8
325 #define CAP_CAPVER_FIELD		hciparams
326 #define CAP_CAPVER_START		16
327 #define CAP_CAPVER_LEN			16
328 #define CAP_CAPVER_HI_FIELD		hciparams
329 #define CAP_CAPVER_HI_START		24
330 #define CAP_CAPVER_HI_LEN		8
331 #define CAP_CAPVER_LO_FIELD		hciparams
332 #define CAP_CAPVER_LO_START		16
333 #define CAP_CAPVER_LO_LEN		8
334 #define CAP_MAXSLOTS_FIELD		hcsparams1
335 #define CAP_MAXSLOTS_START		0
336 #define CAP_MAXSLOTS_LEN		7
337 #define CAP_MAXINTRS_FIELD		hcsparams1
338 #define CAP_MAXINTRS_START		7
339 #define CAP_MAXINTRS_LEN		11
340 #define CAP_MAXPORTS_FIELD		hcsparams1
341 #define CAP_MAXPORTS_START		24
342 #define CAP_MAXPORTS_LEN		8
343 #define CAP_IST_FIELD			hcsparams2
344 #define CAP_IST_START			0
345 #define CAP_IST_LEN			4
346 #define CAP_ERST_MAX_FIELD		hcsparams2
347 #define CAP_ERST_MAX_START		4
348 #define CAP_ERST_MAX_LEN		4
349 #define CAP_MAX_SCRATCH_BUFS_HI_FIELD	hcsparams2
350 #define CAP_MAX_SCRATCH_BUFS_HI_START	21
351 #define CAP_MAX_SCRATCH_BUFS_HI_LEN	5
352 #define CAP_MAX_SCRATCH_BUFS_LO_FIELD	hcsparams2
353 #define CAP_MAX_SCRATCH_BUFS_LO_START	27
354 #define CAP_MAX_SCRATCH_BUFS_LO_LEN	5
355 #define CAP_U1_LATENCY_FIELD		hcsparams3
356 #define CAP_U1_LATENCY_START		0
357 #define CAP_U1_LATENCY_LEN		8
358 #define CAP_U2_LATENCY_FIELD		hcsparams3
359 #define CAP_U2_LATENCY_START		16
360 #define CAP_U2_LATENCY_LEN		16
361 #define CAP_CSZ_FIELD			hccparams
362 #define CAP_CSZ_START			2
363 #define CAP_CSZ_LEN			1
364 
365 #define CAP_MASK(tok)		MASK(CAP_##tok##_START, CAP_##tok##_LEN)
366 #define CAP_GET(tok, cap)	((read32(&(cap)->CAP_##tok##_FIELD) & CAP_MASK(tok)) \
367 				 >> CAP_##tok##_START)
368 
369 #define CTXSIZE(xhci) (CAP_GET(CSZ, (xhci)->capreg) ? 64 : 32)
370 
371 typedef struct xhci {
372 	struct capreg {
373 		u32 hciparams;
374 		u32 hcsparams1;
375 		u32 hcsparams2;
376 		u32 hcsparams3;
377 		u32 hccparams;
378 		u32 dboff;
379 		u32 rtsoff;
380 	} __packed * capreg;
381 
382 	/* opreg is R/W is most places, so volatile access is necessary.
383 	   volatile means that the compiler seeks byte writes if possible,
384 	   making bitfields unusable for MMIO register blocks. Yay C :-( */
385 	volatile struct opreg {
386 		u32 usbcmd; /* 0x00 */
387 #define USBCMD_RS (1 << 0)
388 #define USBCMD_HCRST (1 << 1)
389 #define USBCMD_INTE (1 << 2)
390 		u32 usbsts; /* 0x04 */
391 #define USBSTS_HCH (1 << 0)
392 #define USBSTS_HSE (1 << 2)
393 #define USBSTS_EINT (1 << 3)
394 #define USBSTS_PCD (1 << 4)
395 #define USBSTS_CNR (1 << 11)
396 #define USBSTS_PRSRV_MASK ((1 << 1) | 0xffffe000)
397 		u32 pagesize; /* 0x08 */
398 		u8 res1[0x13-0x0c+1]; /* 0x0C */
399 		u32 dnctrl; /* 0x14 */
400 		u32 crcr_lo; /* 0x18 */
401 		u32 crcr_hi; /* 0x1C */
402 #define CRCR_RCS (1 << 0)
403 #define CRCR_CS (1 << 1)
404 #define CRCR_CA (1 << 2)
405 #define CRCR_CRR (1 << 3)
406 		u8 res2[0x2f-0x20+1]; /* 0x20 */
407 		u32 dcbaap_lo; /* 0x30 */
408 		u32 dcbaap_hi; /* 0x34 */
409 		u32 config; /* 0x38 */
410 #define CONFIG_LP_MASK_MaxSlotsEn 0xff
411 		u8 res3[0x3ff-0x3c+1]; /* 0x3C */
412 		struct {
413 			u32 portsc; /* 0x400 + 4 * port */
414 #define PORTSC_CCS (1 << 0)
415 #define PORTSC_PED (1 << 1)
416 	// BIT 2 rsvdZ
417 #define PORTSC_OCA (1 << 3)
418 #define PORTSC_PR (1 << 4)
419 #define PORTSC_PLS (1 << 5)
420 #define PORTSC_PLS_MASK MASK(5, 4)
421 #define PORTSC_PP (1 << 9)
422 #define PORTSC_PORT_SPEED_START 10
423 #define PORTSC_PORT_SPEED (1 << PORTSC_PORT_SPEED_START)
424 #define PORTSC_PORT_SPEED_MASK MASK(PORTSC_PORT_SPEED_START, 4)
425 #define PORTSC_PIC (1 << 14)
426 #define PORTSC_PIC_MASK MASK(14, 2)
427 #define PORTSC_LWS (1 << 16)
428 #define PORTSC_CSC (1 << 17)
429 #define PORTSC_PEC (1 << 18)
430 #define PORTSC_WRC (1 << 19)
431 #define PORTSC_OCC (1 << 20)
432 #define PORTSC_PRC (1 << 21)
433 #define PORTSC_PLC (1 << 22)
434 #define PORTSC_CEC (1 << 23)
435 #define PORTSC_CAS (1 << 24)
436 #define PORTSC_WCE (1 << 25)
437 #define PORTSC_WDE (1 << 26)
438 #define PORTSC_WOE (1 << 27)
439 	// BIT 29:28 rsvdZ
440 #define PORTSC_DR (1 << 30)
441 #define PORTSC_WPR (1 << 31)
442 #define PORTSC_RW_MASK (PORTSC_PR | PORTSC_PLS_MASK | PORTSC_PP | PORTSC_PIC_MASK | PORTSC_LWS | PORTSC_WCE | PORTSC_WDE | PORTSC_WOE)
443 			u32 portpmsc; /* 0x404 + 4 * port */
444 			u32 portli; /* 0x408 + 4 * port */
445 			u32 res; /* 0x40C + 4 * port */
446 		} __packed prs[];
447 	} __packed * opreg;
448 
449 	/* R/W, volatile, MMIO -> no bitfields */
450 	volatile struct hcrreg {
451 		u32 mfindex;
452 		u8 res1[0x20-0x4];
453 		struct {
454 			u32 iman;
455 			u32 imod;
456 			u32 erstsz;
457 			u32 res;
458 			u32 erstba_lo;
459 			u32 erstba_hi;
460 			u32 erdp_lo;
461 			u32 erdp_hi;
462 		} __packed intrrs[]; // up to 1024, but maximum host specific, given in capreg->MaxIntrs
463 	} __packed * hcrreg;
464 
465 	/* R/W, volatile, MMIO -> no bitfields */
466 	volatile u32 *dbreg;
467 
468 	/* R/W, volatile, Memory -> bitfields allowed */
469 	u64 *dcbaa;	/* pointers to sp_ptrs and output (device) contexts */
470 	u64 *sp_ptrs;	/* pointers to scratchpad buffers */
471 
472 	command_ring_t cr;
473 	event_ring_t er;
474 	volatile erst_entry_t *ev_ring_table;
475 
476 	usbdev_t *roothub;
477 
478 	u8 max_slots_en;
479 	devinfo_t *dev;	/* array of devinfos by slot_id */
480 
481 #define DMA_SIZE (64 * 1024)
482 	void *dma_buffer;
483 } xhci_t;
484 
485 #define XHCI_INST(controller) ((xhci_t*)((controller)->instance))
486 
487 void *xhci_align(const size_t min_align, const size_t size);
488 void xhci_init_cycle_ring(transfer_ring_t *, const size_t ring_size);
489 usbdev_t *xhci_set_address(hci_t *, usb_speed speed, int hubport, int hubaddr);
490 int xhci_finish_device_config(usbdev_t *);
491 void xhci_destroy_dev(hci_t *, int slot_id);
492 
493 void xhci_reset_event_ring(event_ring_t *);
494 void xhci_advance_event_ring(xhci_t *);
495 void xhci_update_event_dq(xhci_t *);
496 void xhci_handle_events(xhci_t *);
497 int xhci_wait_for_command_aborted(xhci_t *, const trb_t *);
498 int xhci_wait_for_command_done(xhci_t *, const trb_t *, int clear_event);
499 int xhci_wait_for_transfer(xhci_t *, const int slot_id, const int ep_id);
500 
501 void xhci_clear_trb(trb_t *, int pcs);
502 
503 trb_t *xhci_next_command_trb(xhci_t *);
504 void xhci_post_command(xhci_t *);
505 int xhci_cmd_enable_slot(xhci_t *, int *slot_id);
506 int xhci_cmd_disable_slot(xhci_t *, int slot_id);
507 int xhci_cmd_address_device(xhci_t *, int slot_id, inputctx_t *);
508 int xhci_cmd_configure_endpoint(xhci_t *, int slot_id, int config_id, inputctx_t *);
509 int xhci_cmd_evaluate_context(xhci_t *, int slot_id, inputctx_t *);
510 int xhci_cmd_reset_endpoint(xhci_t *, int slot_id, int ep);
511 int xhci_cmd_stop_endpoint(xhci_t *, int slot_id, int ep);
512 int xhci_cmd_set_tr_dq(xhci_t *, int slot_id, int ep, trb_t *, int dcs);
513 
xhci_ep_id(const endpoint_t * const ep)514 static inline int xhci_ep_id(const endpoint_t *const ep) {
515 	return ((ep->endpoint & 0x7f) * 2) + (ep->direction != OUT);
516 }
517 
518 #ifdef XHCI_DUMPS
519 void xhci_dump_slotctx(const slotctx_t *);
520 void xhci_dump_epctx(const epctx_t *);
521 void xhci_dump_devctx(const devctx_t *, const u32 ctx_mask);
522 void xhci_dump_inputctx(const inputctx_t *);
523 void xhci_dump_transfer_trb(const trb_t *);
524 void xhci_dump_transfer_trbs(const trb_t *first, const trb_t *last);
525 #else
526 #define xhci_dump_slotctx(args...)		do {} while (0)
527 #define xhci_dump_epctx(args...)		do {} while (0)
528 #define xhci_dump_devctx(args...)		do {} while (0)
529 #define xhci_dump_inputctx(args...)		do {} while (0)
530 #define xhci_dump_transfer_trb(args...)		do {} while (0)
531 #define xhci_dump_transfer_trbs(args...)	do {} while (0)
532 #endif
533 
534 #endif
535