xref: /illumos-gate/usr/src/uts/common/sys/usb/hcd/xhci/xhci.h (revision 0ae0ab6f)
1993e3fafSRobert Mustacchi /*
2993e3fafSRobert Mustacchi  * This file and its contents are supplied under the terms of the
3993e3fafSRobert Mustacchi  * Common Development and Distribution License ("CDDL"), version 1.0.
4993e3fafSRobert Mustacchi  * You may only use this file in accordance with the terms of version
5993e3fafSRobert Mustacchi  * 1.0 of the CDDL.
6993e3fafSRobert Mustacchi  *
7993e3fafSRobert Mustacchi  * A full copy of the text of the CDDL should have accompanied this
8993e3fafSRobert Mustacchi  * source.  A copy of the CDDL is also available via the Internet at
9993e3fafSRobert Mustacchi  * http://www.illumos.org/license/CDDL.
10993e3fafSRobert Mustacchi  */
11993e3fafSRobert Mustacchi 
12993e3fafSRobert Mustacchi /*
132aba3acdSRobert Mustacchi  * Copyright (c) 2018, Joyent, Inc.
14ec82ef79SMatthias Scheler  * Copyright (c) 2019 by Western Digital Corporation
15*0ae0ab6fSJoshua M. Clulow  * Copyright 2022 Oxide Computer Company
16993e3fafSRobert Mustacchi  */
17993e3fafSRobert Mustacchi 
18993e3fafSRobert Mustacchi #ifndef _SYS_USB_XHCI_XHCI_H
19993e3fafSRobert Mustacchi #define	_SYS_USB_XHCI_XHCI_H
20993e3fafSRobert Mustacchi 
21993e3fafSRobert Mustacchi /*
22993e3fafSRobert Mustacchi  * Extensible Host Controller Interface (xHCI) USB Driver
23993e3fafSRobert Mustacchi  */
24993e3fafSRobert Mustacchi 
25993e3fafSRobert Mustacchi #include <sys/conf.h>
26993e3fafSRobert Mustacchi #include <sys/ddi.h>
27993e3fafSRobert Mustacchi #include <sys/sunddi.h>
28993e3fafSRobert Mustacchi #include <sys/taskq_impl.h>
29993e3fafSRobert Mustacchi #include <sys/sysmacros.h>
30993e3fafSRobert Mustacchi #include <sys/usb/hcd/xhci/xhcireg.h>
31993e3fafSRobert Mustacchi 
32993e3fafSRobert Mustacchi #include <sys/usb/usba.h>
33993e3fafSRobert Mustacchi #include <sys/usb/usba/hcdi.h>
34993e3fafSRobert Mustacchi #include <sys/usb/hubd/hub.h>
35993e3fafSRobert Mustacchi #include <sys/usb/usba/hubdi.h>
36993e3fafSRobert Mustacchi #include <sys/usb/hubd/hubdvar.h>
37993e3fafSRobert Mustacchi 
38993e3fafSRobert Mustacchi 
39993e3fafSRobert Mustacchi #ifdef __cplusplus
40993e3fafSRobert Mustacchi extern "C" {
41993e3fafSRobert Mustacchi #endif
42993e3fafSRobert Mustacchi 
43993e3fafSRobert Mustacchi /*
44993e3fafSRobert Mustacchi  * The base segment for DMA attributes was determined to be 4k based on xHCI 1.1
45993e3fafSRobert Mustacchi  * / table 54: Data Structure Max Size, Boundary, and Alignment Requirement
46993e3fafSRobert Mustacchi  * Summary.  This indicates that the required alignment for most things is
47993e3fafSRobert Mustacchi  * PAGESIZE, which in our current implementation is required to be 4K. We
48993e3fafSRobert Mustacchi  * provide the ring segment value below for the things which need 64K alignment
49993e3fafSRobert Mustacchi  *
50993e3fafSRobert Mustacchi  * Similarly, in the same table, the maximum required alignment is 64 bytes,
51993e3fafSRobert Mustacchi  * hence we use that for everything.
52993e3fafSRobert Mustacchi  *
53993e3fafSRobert Mustacchi  * Next is the scatter/gather lengths. For most of the data structures, we only
54993e3fafSRobert Mustacchi  * want to have a single SGL entry, e.g. just a simple flat mapping. For many of
55993e3fafSRobert Mustacchi  * our transfers, we use the same logic to simplify the implementation of the
56993e3fafSRobert Mustacchi  * driver. However, for bulk transfers, which are the largest by far, we want to
57993e3fafSRobert Mustacchi  * be able to leverage SGLs to give us more DMA flexibility.
58993e3fafSRobert Mustacchi  *
59993e3fafSRobert Mustacchi  * We can transfer up to 64K in one transfer request block (TRB) which
60993e3fafSRobert Mustacchi  * corresponds to a single SGL entry. Each ring we create is a single page in
612aba3acdSRobert Mustacchi  * size and will support at most 256 TRBs. To try and give the operating system
622aba3acdSRobert Mustacchi  * flexibility when allocating DMA transfers, we've opted to allow up to 63
632aba3acdSRobert Mustacchi  * SGLs. Because there isn't a good way to support DMA windows with the xHCI
642aba3acdSRobert Mustacchi  * controller design, if this number is too small then DMA allocations and
652aba3acdSRobert Mustacchi  * binding might fail. If the DMA binding fails, the transfer will fail.
662aba3acdSRobert Mustacchi  *
672aba3acdSRobert Mustacchi  * The reason that we use 63 SGLs and not the expected 64 is that we always need
682aba3acdSRobert Mustacchi  * to allocate an additional TRB for the event data. This leaves us with a
692aba3acdSRobert Mustacchi  * nicely divisible number of entries.
702aba3acdSRobert Mustacchi  *
712aba3acdSRobert Mustacchi  * The final piece of this is the maximum sized transfer that the driver
722aba3acdSRobert Mustacchi  * advertises to the broader framework. This is currently sized at 512 KiB. For
732aba3acdSRobert Mustacchi  * reference the ehci driver sized this value at 640 KiB. It's important to
742aba3acdSRobert Mustacchi  * understand that this isn't reflected in the DMA attribute limitation, because
752aba3acdSRobert Mustacchi  * it's not an attribute of the hardware. Experimentally, this has proven to be
762aba3acdSRobert Mustacchi  * sufficient for most of the drivers that we support today. When considering
772aba3acdSRobert Mustacchi  * increasing this number, please note the impact that might have on the
782aba3acdSRobert Mustacchi  * required number of DMA SGL entries required to satisfy the allocation.
792aba3acdSRobert Mustacchi  *
802aba3acdSRobert Mustacchi  * The value of 512 KiB was originally based on the number of SGLs we supported
812aba3acdSRobert Mustacchi  * multiplied by the maximum transfer size. The original number of
822aba3acdSRobert Mustacchi  * XHCI_TRANSFER_DMA_SGL was 8. The 512 KiB value was based upon taking the
832aba3acdSRobert Mustacchi  * number of SGLs and assuming that each TRB used its maximum transfer size of
842aba3acdSRobert Mustacchi  * 64 KiB.
85993e3fafSRobert Mustacchi  */
862aba3acdSRobert Mustacchi #define	XHCI_TRB_MAX_TRANSFER	65536	/* 64 KiB */
87993e3fafSRobert Mustacchi #define	XHCI_DMA_ALIGN		64
88993e3fafSRobert Mustacchi #define	XHCI_DEF_DMA_SGL	1
892aba3acdSRobert Mustacchi #define	XHCI_TRANSFER_DMA_SGL	63
902aba3acdSRobert Mustacchi #define	XHCI_MAX_TRANSFER	524288	/* 512 KiB */
91993e3fafSRobert Mustacchi 
92993e3fafSRobert Mustacchi /*
93993e3fafSRobert Mustacchi  * Properties and values for rerouting ehci ports to xhci.
94993e3fafSRobert Mustacchi  */
95993e3fafSRobert Mustacchi #define	XHCI_PROP_REROUTE_DISABLE	0
96993e3fafSRobert Mustacchi #define	XHCI_PROP_REROUTE_DEFAULT	1
97993e3fafSRobert Mustacchi 
98993e3fafSRobert Mustacchi /*
99993e3fafSRobert Mustacchi  * This number is a bit made up. Truthfully, the API here isn't the most useful
100993e3fafSRobert Mustacchi  * for what we need to define as it should really be based on the endpoint that
101993e3fafSRobert Mustacchi  * we're interested in rather than the device as a whole.
102993e3fafSRobert Mustacchi  *
103993e3fafSRobert Mustacchi  * We're basically being asked how many TRBs we're willing to schedule in one
104993e3fafSRobert Mustacchi  * go. There's no great way to come up with this number, so we basically are
105993e3fafSRobert Mustacchi  * making up something such that we use up a good portion of a ring, but not too
106993e3fafSRobert Mustacchi  * much of it.
107993e3fafSRobert Mustacchi  */
108993e3fafSRobert Mustacchi #define	XHCI_ISOC_MAX_TRB	64
109993e3fafSRobert Mustacchi 
110993e3fafSRobert Mustacchi #ifdef	DEBUG
111993e3fafSRobert Mustacchi #define	XHCI_DMA_SYNC(dma, flag)	VERIFY0(ddi_dma_sync( \
112993e3fafSRobert Mustacchi 					    (dma).xdb_dma_handle, 0, 0, \
113993e3fafSRobert Mustacchi 					    (flag)))
114993e3fafSRobert Mustacchi #else
115993e3fafSRobert Mustacchi #define	XHCI_DMA_SYNC(dma, flag)	((void) ddi_dma_sync( \
116993e3fafSRobert Mustacchi 					    (dma).xdb_dma_handle, 0, 0, \
117993e3fafSRobert Mustacchi 					    (flag)))
118993e3fafSRobert Mustacchi #endif
119993e3fafSRobert Mustacchi 
1202aba3acdSRobert Mustacchi /*
1212aba3acdSRobert Mustacchi  * TRBs need to indicate the number of remaining USB packets in the overall
1222aba3acdSRobert Mustacchi  * transfer. This is a 5-bit value, which means that the maximum value we can
1232aba3acdSRobert Mustacchi  * store in that TRD field is 31.
1242aba3acdSRobert Mustacchi  */
1252aba3acdSRobert Mustacchi #define	XHCI_MAX_TDSIZE		31
1262aba3acdSRobert Mustacchi 
127993e3fafSRobert Mustacchi /*
128993e3fafSRobert Mustacchi  * This defines a time in 2-ms ticks that is required to wait for the controller
129993e3fafSRobert Mustacchi  * to be ready to go. Section 5.4.8 of the XHCI specification in the description
130993e3fafSRobert Mustacchi  * of the PORTSC register indicates that the upper bound is 20 ms. Therefore the
131993e3fafSRobert Mustacchi  * number of ticks is 10.
132993e3fafSRobert Mustacchi  */
133993e3fafSRobert Mustacchi #define	XHCI_POWER_GOOD	10
134993e3fafSRobert Mustacchi 
135993e3fafSRobert Mustacchi /*
136993e3fafSRobert Mustacchi  * Definitions to determine the default number of interrupts. Note that we only
137993e3fafSRobert Mustacchi  * bother with a single interrupt at this time, though we've arranged the driver
138993e3fafSRobert Mustacchi  * to make it possible to request more if, for some unlikely reason, it becomes
139993e3fafSRobert Mustacchi  * necessary.
140993e3fafSRobert Mustacchi  */
141993e3fafSRobert Mustacchi #define	XHCI_NINTR	1
142993e3fafSRobert Mustacchi 
143993e3fafSRobert Mustacchi /*
144993e3fafSRobert Mustacchi  * Default interrupt modulation value. This enables us to have 4000 interrupts /
145993e3fafSRobert Mustacchi  * second. This is supposed to be the default value of the controller. See xHCI
146993e3fafSRobert Mustacchi  * 1.1 / 4.17.2 for more information.
147993e3fafSRobert Mustacchi  */
1482aba3acdSRobert Mustacchi #define	XHCI_IMOD_DEFAULT	0x000003F8U
149993e3fafSRobert Mustacchi 
150993e3fafSRobert Mustacchi /*
151993e3fafSRobert Mustacchi  * Definitions that surround the default values used in various contexts. These
152993e3fafSRobert Mustacchi  * come from various parts of the xHCI specification. In general, see xHCI 1.1 /
153993e3fafSRobert Mustacchi  * 4.8.2. Note that the MPS_MASK is used for ISOCH and INTR endpoints which have
154993e3fafSRobert Mustacchi  * different sizes.
155993e3fafSRobert Mustacchi  *
156993e3fafSRobert Mustacchi  * The burst member is a bit more complicated. By default for USB 2 devices, it
157993e3fafSRobert Mustacchi  * only matters for ISOCH and INTR endpoints and so we use the macros below to
158993e3fafSRobert Mustacchi  * pull it out of the endpoint description's max packet field. For USB 3, it
159993e3fafSRobert Mustacchi  * matters for non-control endpoints. However, it comes out of a companion
160993e3fafSRobert Mustacchi  * description.
161993e3fafSRobert Mustacchi  *
162993e3fafSRobert Mustacchi  * By default the mult member is zero for all cases except for super speed
163993e3fafSRobert Mustacchi  * ISOCH endpoints, where it comes from the companion descriptor.
164993e3fafSRobert Mustacchi  */
165993e3fafSRobert Mustacchi #define	XHCI_CONTEXT_DEF_CERR		3
166993e3fafSRobert Mustacchi #define	XHCI_CONTEXT_ISOCH_CERR		0
167993e3fafSRobert Mustacchi #define	XHCI_CONTEXT_MPS_MASK		0x07ff
168993e3fafSRobert Mustacchi #define	XHCI_CONTEXT_BURST_MASK		0x1800
169993e3fafSRobert Mustacchi #define	XHCI_CONTEXT_BURST_SHIFT	11
170993e3fafSRobert Mustacchi #define	XHCI_CONTEXT_DEF_MULT		0
171993e3fafSRobert Mustacchi #define	XHCI_CONTEXT_DEF_MAX_ESIT	0
172993e3fafSRobert Mustacchi #define	XHCI_CONTEXT_DEF_CTRL_ATL	8
173993e3fafSRobert Mustacchi 
174993e3fafSRobert Mustacchi /*
175993e3fafSRobert Mustacchi  * This number represents the number of transfers that we'll set up for a given
176993e3fafSRobert Mustacchi  * interrupt transfer. Note that the idea here is that we'll want to allocate a
177993e3fafSRobert Mustacchi  * certain number of transfers to basically ensure that we'll always be able to
178993e3fafSRobert Mustacchi  * have a transfer available, even if the system is a bit caught up in trying to
179993e3fafSRobert Mustacchi  * process it and for some reason we can't fire the interrupt. As such, we
180993e3fafSRobert Mustacchi  * basically want to have enough available that at the fastest interval (125 us)
181993e3fafSRobert Mustacchi  * that we have enough. So in this case we choose 8, with the assumption that we
182993e3fafSRobert Mustacchi  * should be able to process at least one in a given millisecond. Note that this
183993e3fafSRobert Mustacchi  * is not based in fact and is really just as much a guess and a hope.
184993e3fafSRobert Mustacchi  *
185993e3fafSRobert Mustacchi  * While we could then use less resources for other interrupt transfers that are
186993e3fafSRobert Mustacchi  * slower, starting with uniform resource usage will make things a bit easier.
187993e3fafSRobert Mustacchi  */
188993e3fafSRobert Mustacchi #define	XHCI_INTR_IN_NTRANSFERS	8
189993e3fafSRobert Mustacchi 
190993e3fafSRobert Mustacchi /*
191993e3fafSRobert Mustacchi  * This number represents the number of xhci_transfer_t structures that we'll
192993e3fafSRobert Mustacchi  * set up for a given isochronous transfer polling request. A given isochronous
193993e3fafSRobert Mustacchi  * transfer may actually have multiple units of time associated with it. As
194993e3fafSRobert Mustacchi  * such, we basically want to treat this like a case of classic double
195993e3fafSRobert Mustacchi  * buffering. We have one ready to go while the other is being filled up. This
196993e3fafSRobert Mustacchi  * will compensate for additional latency in the system. This is smaller than
197993e3fafSRobert Mustacchi  * the Interrupt IN transfer case above as many callers may ask for multiple
198993e3fafSRobert Mustacchi  * intervals in a single request.
199993e3fafSRobert Mustacchi  */
200993e3fafSRobert Mustacchi #define	XHCI_ISOC_IN_NTRANSFERS	2
201993e3fafSRobert Mustacchi 
202993e3fafSRobert Mustacchi #define	XHCI_PERIODIC_IN_NTRANSFERS					\
203993e3fafSRobert Mustacchi 	MAX(XHCI_ISOC_IN_NTRANSFERS, XHCI_INTR_IN_NTRANSFERS)
204993e3fafSRobert Mustacchi 
205993e3fafSRobert Mustacchi /*
206993e3fafSRobert Mustacchi  * Mask for a route string which is a 20-bit value.
207993e3fafSRobert Mustacchi  */
208993e3fafSRobert Mustacchi #define	XHCI_ROUTE_MASK(x)	((x) & 0xfffff)
209993e3fafSRobert Mustacchi 
210993e3fafSRobert Mustacchi /*
211993e3fafSRobert Mustacchi  * This is the default tick that we use for timeouts while endpoints have
212993e3fafSRobert Mustacchi  * outstanding, active, non-periodic transfers. We choose one second as the USBA
213993e3fafSRobert Mustacchi  * specifies timeouts in units of seconds. Note that this is in microseconds, so
214993e3fafSRobert Mustacchi  * it can be fed into drv_usectohz().
215993e3fafSRobert Mustacchi  */
216993e3fafSRobert Mustacchi #define	XHCI_TICK_TIMEOUT_US	(MICROSEC)
217993e3fafSRobert Mustacchi 
218993e3fafSRobert Mustacchi /*
219993e3fafSRobert Mustacchi  * Set of bits that we need one of to indicate that this port has something
220993e3fafSRobert Mustacchi  * interesting on it.
221993e3fafSRobert Mustacchi  */
222993e3fafSRobert Mustacchi #define	XHCI_HUB_INTR_CHANGE_MASK	(XHCI_PS_CSC | XHCI_PS_PEC | \
223993e3fafSRobert Mustacchi     XHCI_PS_WRC | XHCI_PS_OCC | XHCI_PS_PRC | XHCI_PS_PLC | XHCI_PS_CEC)
224993e3fafSRobert Mustacchi 
225993e3fafSRobert Mustacchi /*
226993e3fafSRobert Mustacchi  * These represent known issues with various xHCI controllers.
227993e3fafSRobert Mustacchi  *
2282aba3acdSRobert Mustacchi  *	XHCI_QUIRK_NO_MSI	MSI support on this controller is known to be
2292aba3acdSRobert Mustacchi  *				broken.
230993e3fafSRobert Mustacchi  *
2312aba3acdSRobert Mustacchi  *	XHCI_QUIRK_32_ONLY	Only use 32-bit DMA addreses with this
2322aba3acdSRobert Mustacchi  *				controller.
233993e3fafSRobert Mustacchi  *
2342aba3acdSRobert Mustacchi  *	XHCI_QUIRK_INTC_EHCI	This is an Intel platform which supports
2352aba3acdSRobert Mustacchi  *				rerouting ports between EHCI and xHCI
2362aba3acdSRobert Mustacchi  *				controllers on the platform.
237993e3fafSRobert Mustacchi  */
238993e3fafSRobert Mustacchi typedef enum xhci_quirk {
239993e3fafSRobert Mustacchi 	XHCI_QUIRK_NO_MSI	= 0x01,
240993e3fafSRobert Mustacchi 	XHCI_QUIRK_32_ONLY	= 0x02,
241993e3fafSRobert Mustacchi 	XHCI_QUIRK_INTC_EHCI	= 0x04
242993e3fafSRobert Mustacchi } xhci_quirk_t;
243993e3fafSRobert Mustacchi 
244993e3fafSRobert Mustacchi /*
245993e3fafSRobert Mustacchi  * xHCI capability parameter flags. These are documented in xHCI 1.1 / 5.3.6.
246993e3fafSRobert Mustacchi  */
247993e3fafSRobert Mustacchi typedef enum xhci_cap_flags {
2482aba3acdSRobert Mustacchi 	XCAP_AC64	= 0x001,
249993e3fafSRobert Mustacchi 	XCAP_BNC	= 0x002,
250993e3fafSRobert Mustacchi 	XCAP_CSZ	= 0x004,
251993e3fafSRobert Mustacchi 	XCAP_PPC	= 0x008,
252993e3fafSRobert Mustacchi 	XCAP_PIND	= 0x010,
253993e3fafSRobert Mustacchi 	XCAP_LHRC	= 0x020,
254993e3fafSRobert Mustacchi 	XCAP_LTC	= 0x040,
255993e3fafSRobert Mustacchi 	XCAP_NSS	= 0x080,
256993e3fafSRobert Mustacchi 	XCAP_PAE	= 0x100,
257993e3fafSRobert Mustacchi 	XCAP_SPC	= 0x200,
258993e3fafSRobert Mustacchi 	XCAP_SEC	= 0x400,
259993e3fafSRobert Mustacchi 	XCAP_CFC	= 0x800
260993e3fafSRobert Mustacchi } xchi_cap_flags_t;
261993e3fafSRobert Mustacchi 
262993e3fafSRobert Mustacchi /*
263993e3fafSRobert Mustacchi  * Second set of capabilities, these are documented in xHCI 1.1 / 5.3.9.
264993e3fafSRobert Mustacchi  */
265993e3fafSRobert Mustacchi typedef enum xhci_cap2_flags {
266993e3fafSRobert Mustacchi 	XCAP2_U3C	= 0x01,
267993e3fafSRobert Mustacchi 	XCAP2_CMC	= 0x02,
268993e3fafSRobert Mustacchi 	XCAP2_FMC	= 0x04,
269993e3fafSRobert Mustacchi 	XCAP2_CTC	= 0x08,
270993e3fafSRobert Mustacchi 	XCAP2_LEC	= 0x10,
271993e3fafSRobert Mustacchi 	XCAP2_CIC	= 0x20
272993e3fafSRobert Mustacchi } xhci_cap2_flags_t;
273993e3fafSRobert Mustacchi 
274993e3fafSRobert Mustacchi /*
275993e3fafSRobert Mustacchi  * These represent and store the various capability registers that we'll need to
276993e3fafSRobert Mustacchi  * use. In addition, we stash a few other versioning related bits here. Note
277993e3fafSRobert Mustacchi  * that we cache more information than we might need so that we have it for
278993e3fafSRobert Mustacchi  * debugging purposes.
279993e3fafSRobert Mustacchi  */
280993e3fafSRobert Mustacchi typedef struct xhci_capability {
281993e3fafSRobert Mustacchi 	uint8_t			xcap_usb_vers;
282993e3fafSRobert Mustacchi 	uint16_t		xcap_hci_vers;
283993e3fafSRobert Mustacchi 	uint32_t		xcap_pagesize;
284993e3fafSRobert Mustacchi 	uint8_t			xcap_max_slots;
285993e3fafSRobert Mustacchi 	uint16_t		xcap_max_intrs;
286993e3fafSRobert Mustacchi 	uint8_t			xcap_max_ports;
287993e3fafSRobert Mustacchi 	boolean_t		xcap_ist_micro;
288993e3fafSRobert Mustacchi 	uint8_t			xcap_ist;
289993e3fafSRobert Mustacchi 	uint16_t		xcap_max_esrt;
290993e3fafSRobert Mustacchi 	boolean_t		xcap_scratch_restore;
291993e3fafSRobert Mustacchi 	uint16_t		xcap_max_scratch;
292993e3fafSRobert Mustacchi 	uint8_t			xcap_u1_lat;
293993e3fafSRobert Mustacchi 	uint16_t		xcap_u2_lat;
294993e3fafSRobert Mustacchi 	xchi_cap_flags_t	xcap_flags;
295993e3fafSRobert Mustacchi 	uint8_t			xcap_max_psa;
296993e3fafSRobert Mustacchi 	uint16_t		xcap_xecp_off;
297993e3fafSRobert Mustacchi 	xhci_cap2_flags_t	xcap_flags2;
298993e3fafSRobert Mustacchi 	int			xcap_intr_types;
299993e3fafSRobert Mustacchi } xhci_capability_t;
300993e3fafSRobert Mustacchi 
301993e3fafSRobert Mustacchi /*
302993e3fafSRobert Mustacchi  * This represents a single logical DMA allocation. For the vast majority of
303993e3fafSRobert Mustacchi  * non-transfer cases, it only represents a single DMA buffer and not a
304993e3fafSRobert Mustacchi  * scatter-gather list.
305993e3fafSRobert Mustacchi  */
306993e3fafSRobert Mustacchi typedef struct xhci_dma_buffer {
307993e3fafSRobert Mustacchi 	caddr_t			xdb_va;		/* Buffer VA */
308993e3fafSRobert Mustacchi 	size_t			xdb_len;	/* Buffer logical len */
309993e3fafSRobert Mustacchi 	ddi_acc_handle_t	xdb_acc_handle;	/* Access handle */
310993e3fafSRobert Mustacchi 	ddi_dma_handle_t	xdb_dma_handle;	/* DMA handle */
311993e3fafSRobert Mustacchi 	int			xdb_ncookies;	/* Number of actual cookies */
312993e3fafSRobert Mustacchi 	ddi_dma_cookie_t	xdb_cookies[XHCI_TRANSFER_DMA_SGL];
313993e3fafSRobert Mustacchi } xhci_dma_buffer_t;
314993e3fafSRobert Mustacchi 
315993e3fafSRobert Mustacchi /*
316993e3fafSRobert Mustacchi  * This is a single transfer descriptor. It's packed to match the hardware
317993e3fafSRobert Mustacchi  * layout.
318993e3fafSRobert Mustacchi  */
319993e3fafSRobert Mustacchi #pragma pack(1)
320993e3fafSRobert Mustacchi typedef struct xhci_trb {
321993e3fafSRobert Mustacchi 	uint64_t	trb_addr;
322993e3fafSRobert Mustacchi 	uint32_t	trb_status;
323993e3fafSRobert Mustacchi 	uint32_t	trb_flags;
324993e3fafSRobert Mustacchi } xhci_trb_t;
325993e3fafSRobert Mustacchi #pragma pack()
326993e3fafSRobert Mustacchi 
327993e3fafSRobert Mustacchi /*
328993e3fafSRobert Mustacchi  * This represents a single transfer that we want to allocate and perform.
329993e3fafSRobert Mustacchi  */
330993e3fafSRobert Mustacchi typedef struct xhci_transfer {
331993e3fafSRobert Mustacchi 	list_node_t		xt_link;
332993e3fafSRobert Mustacchi 	hrtime_t		xt_sched_time;
333993e3fafSRobert Mustacchi 	xhci_dma_buffer_t	xt_buffer;
334993e3fafSRobert Mustacchi 	uint_t			xt_ntrbs;
335993e3fafSRobert Mustacchi 	uint_t			xt_short;
336993e3fafSRobert Mustacchi 	uint_t			xt_timeout;
337993e3fafSRobert Mustacchi 	usb_cr_t		xt_cr;
338993e3fafSRobert Mustacchi 	boolean_t		xt_data_tohost;
339993e3fafSRobert Mustacchi 	xhci_trb_t		*xt_trbs;
3402aba3acdSRobert Mustacchi 	uint64_t		*xt_trbs_pa;
341993e3fafSRobert Mustacchi 	usb_isoc_pkt_descr_t	*xt_isoc;
342993e3fafSRobert Mustacchi 	usb_opaque_t		xt_usba_req;
343993e3fafSRobert Mustacchi } xhci_transfer_t;
344993e3fafSRobert Mustacchi 
345993e3fafSRobert Mustacchi /*
346993e3fafSRobert Mustacchi  * This represents a ring in xHCI, upon which event, transfer, and command TRBs
347993e3fafSRobert Mustacchi  * are scheduled.
348993e3fafSRobert Mustacchi  */
349993e3fafSRobert Mustacchi typedef struct xhci_ring {
350993e3fafSRobert Mustacchi 	xhci_dma_buffer_t	xr_dma;
351993e3fafSRobert Mustacchi 	uint_t			xr_ntrb;
352993e3fafSRobert Mustacchi 	xhci_trb_t		*xr_trb;
353993e3fafSRobert Mustacchi 	uint_t			xr_head;
354993e3fafSRobert Mustacchi 	uint_t			xr_tail;
355993e3fafSRobert Mustacchi 	uint8_t			xr_cycle;
356993e3fafSRobert Mustacchi } xhci_ring_t;
357993e3fafSRobert Mustacchi 
358993e3fafSRobert Mustacchi /*
359993e3fafSRobert Mustacchi  * This structure is used to represent the xHCI Device Context Base Address
360993e3fafSRobert Mustacchi  * Array. It's defined in section 6.1 of the specification and is required for
361993e3fafSRobert Mustacchi  * the controller to start.
362993e3fafSRobert Mustacchi  *
363993e3fafSRobert Mustacchi  * The maximum number of slots supported is always 256, therefore we size this
364993e3fafSRobert Mustacchi  * structure at its maximum.
365993e3fafSRobert Mustacchi  */
366993e3fafSRobert Mustacchi #define	XHCI_MAX_SLOTS	256
367993e3fafSRobert Mustacchi #define	XHCI_DCBAA_SCRATCHPAD_INDEX	0
368993e3fafSRobert Mustacchi 
369993e3fafSRobert Mustacchi typedef struct xhci_dcbaa {
370993e3fafSRobert Mustacchi 	uint64_t		*xdc_base_addrs;
371993e3fafSRobert Mustacchi 	xhci_dma_buffer_t	xdc_dma;
372993e3fafSRobert Mustacchi } xhci_dcbaa_t;
373993e3fafSRobert Mustacchi 
374993e3fafSRobert Mustacchi typedef struct xhci_scratchpad {
375993e3fafSRobert Mustacchi 	uint64_t		*xsp_addrs;
376993e3fafSRobert Mustacchi 	xhci_dma_buffer_t	xsp_addr_dma;
377993e3fafSRobert Mustacchi 	xhci_dma_buffer_t	*xsp_scratch_dma;
378993e3fafSRobert Mustacchi } xhci_scratchpad_t;
379993e3fafSRobert Mustacchi 
380993e3fafSRobert Mustacchi /*
381993e3fafSRobert Mustacchi  * Contexts. These structures are inserted into the DCBAA above and are used for
382993e3fafSRobert Mustacchi  * describing the state of the system. Note, that while many of these are
383993e3fafSRobert Mustacchi  * 32-bytes in size, the xHCI specification defines that they'll be extended to
384993e3fafSRobert Mustacchi  * 64-bytes with all the extra bytes as zeros if the CSZ flag is set in the
385993e3fafSRobert Mustacchi  * HCCPARAMS1 register, e.g. we have the flag XCAP_CSZ set.
386993e3fafSRobert Mustacchi  *
387993e3fafSRobert Mustacchi  * The device context covers the slot context and 31 endpoints.
388993e3fafSRobert Mustacchi  */
389993e3fafSRobert Mustacchi #define	XHCI_DEVICE_CONTEXT_32	1024
390993e3fafSRobert Mustacchi #define	XHCI_DEVICE_CONTEXT_64	2048
391993e3fafSRobert Mustacchi #define	XHCI_NUM_ENDPOINTS	31
392993e3fafSRobert Mustacchi #define	XHCI_DEFAULT_ENDPOINT	0
393993e3fafSRobert Mustacchi 
394993e3fafSRobert Mustacchi #pragma pack(1)
395993e3fafSRobert Mustacchi typedef struct xhci_slot_context {
396993e3fafSRobert Mustacchi 	uint32_t	xsc_info;
397993e3fafSRobert Mustacchi 	uint32_t	xsc_info2;
398993e3fafSRobert Mustacchi 	uint32_t	xsc_tt;
399993e3fafSRobert Mustacchi 	uint32_t	xsc_state;
400993e3fafSRobert Mustacchi 	uint32_t	xsc_reserved[4];
401993e3fafSRobert Mustacchi } xhci_slot_context_t;
402993e3fafSRobert Mustacchi 
403993e3fafSRobert Mustacchi typedef struct xhci_endpoint_context {
404993e3fafSRobert Mustacchi 	uint32_t	xec_info;
405993e3fafSRobert Mustacchi 	uint32_t	xec_info2;
406993e3fafSRobert Mustacchi 	uint64_t	xec_dequeue;
407993e3fafSRobert Mustacchi 	uint32_t	xec_txinfo;
408993e3fafSRobert Mustacchi 	uint32_t	xec_reserved[3];
409993e3fafSRobert Mustacchi } xhci_endpoint_context_t;
410993e3fafSRobert Mustacchi 
411993e3fafSRobert Mustacchi typedef struct xhci_input_context {
412993e3fafSRobert Mustacchi 	uint32_t	xic_drop_flags;
413993e3fafSRobert Mustacchi 	uint32_t	xic_add_flags;
414993e3fafSRobert Mustacchi 	uint32_t	xic_reserved[6];
415993e3fafSRobert Mustacchi } xhci_input_context_t;
416993e3fafSRobert Mustacchi #pragma pack()
417993e3fafSRobert Mustacchi 
418993e3fafSRobert Mustacchi /*
419993e3fafSRobert Mustacchi  * Definitions and structures for maintaining the event ring.
420993e3fafSRobert Mustacchi  */
421993e3fafSRobert Mustacchi #define	XHCI_EVENT_NSEGS	1
422993e3fafSRobert Mustacchi 
423993e3fafSRobert Mustacchi #pragma pack(1)
424993e3fafSRobert Mustacchi typedef struct xhci_event_segment {
425993e3fafSRobert Mustacchi 	uint64_t	xes_addr;
426993e3fafSRobert Mustacchi 	uint16_t	xes_size;
427993e3fafSRobert Mustacchi 	uint16_t	xes_rsvd0;
428993e3fafSRobert Mustacchi 	uint32_t	xes_rsvd1;
429993e3fafSRobert Mustacchi } xhci_event_segment_t;
430993e3fafSRobert Mustacchi #pragma pack()
431993e3fafSRobert Mustacchi 
432993e3fafSRobert Mustacchi typedef struct xhci_event_ring {
433993e3fafSRobert Mustacchi 	xhci_event_segment_t	*xev_segs;
434993e3fafSRobert Mustacchi 	xhci_dma_buffer_t	xev_dma;
435993e3fafSRobert Mustacchi 	xhci_ring_t		xev_ring;
436993e3fafSRobert Mustacchi } xhci_event_ring_t;
437993e3fafSRobert Mustacchi 
438993e3fafSRobert Mustacchi typedef enum xhci_command_ring_state {
439993e3fafSRobert Mustacchi 	XHCI_COMMAND_RING_IDLE		= 0x00,
440993e3fafSRobert Mustacchi 	XHCI_COMMAND_RING_RUNNING	= 0x01,
441993e3fafSRobert Mustacchi 	XHCI_COMMAND_RING_ABORTING	= 0x02,
442993e3fafSRobert Mustacchi 	XHCI_COMMAND_RING_ABORT_DONE	= 0x03
443993e3fafSRobert Mustacchi } xhci_command_ring_state_t;
444993e3fafSRobert Mustacchi 
445993e3fafSRobert Mustacchi typedef struct xhci_command_ring {
446993e3fafSRobert Mustacchi 	xhci_ring_t			xcr_ring;
447993e3fafSRobert Mustacchi 	kmutex_t			xcr_lock;
448993e3fafSRobert Mustacchi 	kcondvar_t			xcr_cv;
449993e3fafSRobert Mustacchi 	list_t				xcr_commands;
450993e3fafSRobert Mustacchi 	timeout_id_t			xcr_timeout;
451993e3fafSRobert Mustacchi 	xhci_command_ring_state_t	xcr_state;
452993e3fafSRobert Mustacchi } xhci_command_ring_t;
453993e3fafSRobert Mustacchi 
454993e3fafSRobert Mustacchi /*
455993e3fafSRobert Mustacchi  * Individual command states.
456993e3fafSRobert Mustacchi  *
457993e3fafSRobert Mustacchi  * XHCI_COMMAND_S_INIT		The command has yet to be inserted into the
4582aba3acdSRobert Mustacchi  *				command ring.
459993e3fafSRobert Mustacchi  *
460993e3fafSRobert Mustacchi  * XHCI_COMMAND_S_QUEUED	The command is queued in the command ring.
461993e3fafSRobert Mustacchi  *
462993e3fafSRobert Mustacchi  * XHCI_COMMAND_S_RECEIVED	A command completion for this was received.
463993e3fafSRobert Mustacchi  *
464993e3fafSRobert Mustacchi  * XHCI_COMMAND_S_DONE		The command has been executed. Note that it may
4652aba3acdSRobert Mustacchi  *				have been aborted.
466993e3fafSRobert Mustacchi  *
467993e3fafSRobert Mustacchi  * XHCI_COMMAND_S_RESET		The ring is being reset due to a fatal error and
4682aba3acdSRobert Mustacchi  *				this command has been removed from the ring.
4692aba3acdSRobert Mustacchi  *				This means it has been aborted, but it was not
4702aba3acdSRobert Mustacchi  *				the cause of the abort.
471993e3fafSRobert Mustacchi  *
472993e3fafSRobert Mustacchi  * Note, when adding states, anything after XHCI_COMMAND_S_DONE implies that
473993e3fafSRobert Mustacchi  * upon reaching this state, it is no longer in the ring.
474993e3fafSRobert Mustacchi  */
475993e3fafSRobert Mustacchi typedef enum xhci_command_state {
476993e3fafSRobert Mustacchi 	XHCI_COMMAND_S_INIT	= 0x00,
477993e3fafSRobert Mustacchi 	XHCI_COMMAND_S_QUEUED	= 0x01,
478993e3fafSRobert Mustacchi 	XHCI_COMMAND_S_RECEIVED = 0x02,
479993e3fafSRobert Mustacchi 	XHCI_COMMAND_S_DONE	= 0x03,
480993e3fafSRobert Mustacchi 	XHCI_COMMAND_S_RESET	= 0x04
481993e3fafSRobert Mustacchi } xhci_command_state_t;
482993e3fafSRobert Mustacchi 
483993e3fafSRobert Mustacchi /*
484993e3fafSRobert Mustacchi  * The TRB contents here are always kept in host byte order and are transformed
485993e3fafSRobert Mustacchi  * to little endian when actually scheduled on the ring.
486993e3fafSRobert Mustacchi  */
487993e3fafSRobert Mustacchi typedef struct xhci_command {
488993e3fafSRobert Mustacchi 	list_node_t		xco_link;
489993e3fafSRobert Mustacchi 	kcondvar_t		xco_cv;
490993e3fafSRobert Mustacchi 	xhci_trb_t		xco_req;
491993e3fafSRobert Mustacchi 	xhci_trb_t		xco_res;
492993e3fafSRobert Mustacchi 	xhci_command_state_t	xco_state;
493993e3fafSRobert Mustacchi } xhci_command_t;
494993e3fafSRobert Mustacchi 
495993e3fafSRobert Mustacchi typedef enum xhci_endpoint_state {
496993e3fafSRobert Mustacchi 	XHCI_ENDPOINT_PERIODIC		= 0x01,
497993e3fafSRobert Mustacchi 	XHCI_ENDPOINT_HALTED		= 0x02,
498993e3fafSRobert Mustacchi 	XHCI_ENDPOINT_QUIESCE		= 0x04,
499993e3fafSRobert Mustacchi 	XHCI_ENDPOINT_TIMED_OUT		= 0x08,
500993e3fafSRobert Mustacchi 	/*
501993e3fafSRobert Mustacchi 	 * This enpdoint is being torn down and should make sure it de-schedules
502993e3fafSRobert Mustacchi 	 * itself.
503993e3fafSRobert Mustacchi 	 */
504ec82ef79SMatthias Scheler 	XHCI_ENDPOINT_TEARDOWN		= 0x10,
505ec82ef79SMatthias Scheler 	/*
506ec82ef79SMatthias Scheler 	 * This endpoint is currently used in polled I/O mode by the
507ec82ef79SMatthias Scheler 	 * kernel debugger.
508ec82ef79SMatthias Scheler 	 */
509*0ae0ab6fSJoshua M. Clulow 	XHCI_ENDPOINT_POLLED		= 0x20,
510*0ae0ab6fSJoshua M. Clulow 	/*
511*0ae0ab6fSJoshua M. Clulow 	 * This endpoint is open and in use by a pipe.
512*0ae0ab6fSJoshua M. Clulow 	 */
513*0ae0ab6fSJoshua M. Clulow 	XHCI_ENDPOINT_OPEN		= 0x40,
514993e3fafSRobert Mustacchi } xhci_endpoint_state_t;
515993e3fafSRobert Mustacchi 
516*0ae0ab6fSJoshua M. Clulow /*
517*0ae0ab6fSJoshua M. Clulow  * This is a composite of states that we need to watch for. We don't
518*0ae0ab6fSJoshua M. Clulow  * want to allow ourselves to set one of these flags while one of them
519*0ae0ab6fSJoshua M. Clulow  * is currently active.
520*0ae0ab6fSJoshua M. Clulow  */
521*0ae0ab6fSJoshua M. Clulow #define	XHCI_ENDPOINT_SERIALIZE		(XHCI_ENDPOINT_QUIESCE |	\
522*0ae0ab6fSJoshua M. Clulow 					XHCI_ENDPOINT_TIMED_OUT)
523*0ae0ab6fSJoshua M. Clulow 
524*0ae0ab6fSJoshua M. Clulow /*
525*0ae0ab6fSJoshua M. Clulow  * This is a composite of states that we need to make sure that if set, we do
526*0ae0ab6fSJoshua M. Clulow  * not schedule activity on the ring.
527*0ae0ab6fSJoshua M. Clulow  */
528*0ae0ab6fSJoshua M. Clulow #define	XHCI_ENDPOINT_DONT_SCHEDULE	(XHCI_ENDPOINT_HALTED |		\
529*0ae0ab6fSJoshua M. Clulow 					XHCI_ENDPOINT_QUIESCE |		\
530*0ae0ab6fSJoshua M. Clulow 					XHCI_ENDPOINT_TIMED_OUT)
531*0ae0ab6fSJoshua M. Clulow 
532993e3fafSRobert Mustacchi /*
533993e3fafSRobert Mustacchi  * Forwards required for the endpoint
534993e3fafSRobert Mustacchi  */
535993e3fafSRobert Mustacchi struct xhci_device;
536993e3fafSRobert Mustacchi struct xhci;
537993e3fafSRobert Mustacchi 
538*0ae0ab6fSJoshua M. Clulow typedef struct xhci_endpoint_params {
539*0ae0ab6fSJoshua M. Clulow 	boolean_t		xepp_configured;
540*0ae0ab6fSJoshua M. Clulow 	uint_t			xepp_eptype;
541*0ae0ab6fSJoshua M. Clulow 	uint_t			xepp_burst;
542*0ae0ab6fSJoshua M. Clulow 	uint_t			xepp_ival;
543*0ae0ab6fSJoshua M. Clulow 	uint_t			xepp_max_esit;
544*0ae0ab6fSJoshua M. Clulow 	uint_t			xepp_avgtrb;
545*0ae0ab6fSJoshua M. Clulow 	uint_t			xepp_mps;
546*0ae0ab6fSJoshua M. Clulow 	uint_t			xepp_mult;
547*0ae0ab6fSJoshua M. Clulow 	uint_t			xepp_cerr;
548*0ae0ab6fSJoshua M. Clulow } xhci_endpoint_params_t;
549*0ae0ab6fSJoshua M. Clulow 
550993e3fafSRobert Mustacchi typedef struct xhci_endpoint {
551993e3fafSRobert Mustacchi 	struct xhci		*xep_xhci;
552993e3fafSRobert Mustacchi 	struct xhci_device	*xep_xd;
553993e3fafSRobert Mustacchi 	uint_t			xep_num;
554993e3fafSRobert Mustacchi 	uint_t			xep_type;
555993e3fafSRobert Mustacchi 	xhci_endpoint_state_t	xep_state;
556993e3fafSRobert Mustacchi 	kcondvar_t		xep_state_cv;
557993e3fafSRobert Mustacchi 	timeout_id_t		xep_timeout;
558993e3fafSRobert Mustacchi 	list_t			xep_transfers;
559993e3fafSRobert Mustacchi 	usba_pipe_handle_data_t	*xep_pipe;
560993e3fafSRobert Mustacchi 	xhci_ring_t		xep_ring;
561*0ae0ab6fSJoshua M. Clulow 	xhci_endpoint_params_t	xep_params;
562993e3fafSRobert Mustacchi } xhci_endpoint_t;
563993e3fafSRobert Mustacchi 
564993e3fafSRobert Mustacchi typedef struct xhci_device {
565993e3fafSRobert Mustacchi 	list_node_t		xd_link;
566993e3fafSRobert Mustacchi 	usb_port_t		xd_port;
567993e3fafSRobert Mustacchi 	uint8_t			xd_slot;
568993e3fafSRobert Mustacchi 	boolean_t		xd_addressed;
569993e3fafSRobert Mustacchi 	usba_device_t		*xd_usbdev;
570993e3fafSRobert Mustacchi 	xhci_dma_buffer_t	xd_ictx;
571993e3fafSRobert Mustacchi 	kmutex_t		xd_imtx;	/* Protects input contexts */
572993e3fafSRobert Mustacchi 	xhci_input_context_t	*xd_input;
573993e3fafSRobert Mustacchi 	xhci_slot_context_t	*xd_slotin;
574993e3fafSRobert Mustacchi 	xhci_endpoint_context_t	*xd_endin[XHCI_NUM_ENDPOINTS];
575993e3fafSRobert Mustacchi 	xhci_dma_buffer_t	xd_octx;
576993e3fafSRobert Mustacchi 	xhci_slot_context_t	*xd_slotout;
577993e3fafSRobert Mustacchi 	xhci_endpoint_context_t	*xd_endout[XHCI_NUM_ENDPOINTS];
578993e3fafSRobert Mustacchi 	xhci_endpoint_t		*xd_endpoints[XHCI_NUM_ENDPOINTS];
579993e3fafSRobert Mustacchi } xhci_device_t;
580993e3fafSRobert Mustacchi 
581993e3fafSRobert Mustacchi typedef enum xhci_periodic_state {
582993e3fafSRobert Mustacchi 	XHCI_PERIODIC_POLL_IDLE	= 0x0,
583993e3fafSRobert Mustacchi 	XHCI_PERIODIC_POLL_ACTIVE,
584993e3fafSRobert Mustacchi 	XHCI_PERIODIC_POLL_NOMEM,
585993e3fafSRobert Mustacchi 	XHCI_PERIODIC_POLL_STOPPING
586993e3fafSRobert Mustacchi } xhci_periodic_state_t;
587993e3fafSRobert Mustacchi 
588993e3fafSRobert Mustacchi typedef struct xhci_periodic_pipe {
589993e3fafSRobert Mustacchi 	xhci_periodic_state_t	xpp_poll_state;
590993e3fafSRobert Mustacchi 	usb_opaque_t		xpp_usb_req;
591993e3fafSRobert Mustacchi 	size_t			xpp_tsize;
592993e3fafSRobert Mustacchi 	uint_t			xpp_ntransfers;
593993e3fafSRobert Mustacchi 	xhci_transfer_t		*xpp_transfers[XHCI_PERIODIC_IN_NTRANSFERS];
594993e3fafSRobert Mustacchi } xhci_periodic_pipe_t;
595993e3fafSRobert Mustacchi 
596993e3fafSRobert Mustacchi typedef struct xhci_pipe {
597993e3fafSRobert Mustacchi 	list_node_t		xp_link;
598993e3fafSRobert Mustacchi 	hrtime_t		xp_opentime;
599993e3fafSRobert Mustacchi 	usba_pipe_handle_data_t	*xp_pipe;
600993e3fafSRobert Mustacchi 	xhci_endpoint_t		*xp_ep;
601993e3fafSRobert Mustacchi 	xhci_periodic_pipe_t	xp_periodic;
602993e3fafSRobert Mustacchi } xhci_pipe_t;
603993e3fafSRobert Mustacchi 
604993e3fafSRobert Mustacchi typedef struct xhci_usba {
605993e3fafSRobert Mustacchi 	usba_hcdi_ops_t		*xa_ops;
606993e3fafSRobert Mustacchi 	ddi_dma_attr_t		xa_dma_attr;
607993e3fafSRobert Mustacchi 	usb_dev_descr_t		xa_dev_descr;
608993e3fafSRobert Mustacchi 	usb_ss_hub_descr_t	xa_hub_descr;
609993e3fafSRobert Mustacchi 	usba_pipe_handle_data_t	*xa_intr_cb_ph;
610993e3fafSRobert Mustacchi 	usb_intr_req_t		*xa_intr_cb_req;
611993e3fafSRobert Mustacchi 	list_t			xa_devices;
612993e3fafSRobert Mustacchi 	list_t			xa_pipes;
613993e3fafSRobert Mustacchi } xhci_usba_t;
614993e3fafSRobert Mustacchi 
615993e3fafSRobert Mustacchi typedef enum xhci_attach_seq {
616993e3fafSRobert Mustacchi 	XHCI_ATTACH_FM		= 0x1 << 0,
617993e3fafSRobert Mustacchi 	XHCI_ATTACH_PCI_CONFIG	= 0x1 << 1,
618993e3fafSRobert Mustacchi 	XHCI_ATTACH_REGS_MAP	= 0x1 << 2,
619993e3fafSRobert Mustacchi 	XHCI_ATTACH_INTR_ALLOC	= 0x1 << 3,
620993e3fafSRobert Mustacchi 	XHCI_ATTACH_INTR_ADD	= 0x1 << 4,
621993e3fafSRobert Mustacchi 	XHCI_ATTACH_SYNCH	= 0x1 << 5,
622993e3fafSRobert Mustacchi 	XHCI_ATTACH_INTR_ENABLE	= 0x1 << 6,
623993e3fafSRobert Mustacchi 	XHCI_ATTACH_STARTED	= 0x1 << 7,
624993e3fafSRobert Mustacchi 	XHCI_ATTACH_USBA	= 0x1 << 8,
625993e3fafSRobert Mustacchi 	XHCI_ATTACH_ROOT_HUB	= 0x1 << 9
626993e3fafSRobert Mustacchi } xhci_attach_seq_t;
627993e3fafSRobert Mustacchi 
628993e3fafSRobert Mustacchi typedef enum xhci_state_flags {
629993e3fafSRobert Mustacchi 	XHCI_S_ERROR		= 0x1 << 0
630993e3fafSRobert Mustacchi } xhci_state_flags_t;
631993e3fafSRobert Mustacchi 
632993e3fafSRobert Mustacchi typedef struct xhci {
633993e3fafSRobert Mustacchi 	dev_info_t		*xhci_dip;
634993e3fafSRobert Mustacchi 	xhci_attach_seq_t	xhci_seq;
635993e3fafSRobert Mustacchi 	int			xhci_fm_caps;
636993e3fafSRobert Mustacchi 	ddi_acc_handle_t	xhci_cfg_handle;
637993e3fafSRobert Mustacchi 	uint16_t		xhci_vendor_id;
638993e3fafSRobert Mustacchi 	uint16_t		xhci_device_id;
639993e3fafSRobert Mustacchi 	caddr_t			xhci_regs_base;
640993e3fafSRobert Mustacchi 	ddi_acc_handle_t	xhci_regs_handle;
641993e3fafSRobert Mustacchi 	uint_t			xhci_regs_capoff;
642993e3fafSRobert Mustacchi 	uint_t			xhci_regs_operoff;
643993e3fafSRobert Mustacchi 	uint_t			xhci_regs_runoff;
644993e3fafSRobert Mustacchi 	uint_t			xhci_regs_dooroff;
645993e3fafSRobert Mustacchi 	xhci_capability_t	xhci_caps;
646993e3fafSRobert Mustacchi 	xhci_quirk_t		xhci_quirks;
647993e3fafSRobert Mustacchi 	ddi_intr_handle_t	xhci_intr_hdl;
648993e3fafSRobert Mustacchi 	int			xhci_intr_num;
649993e3fafSRobert Mustacchi 	int			xhci_intr_type;
650993e3fafSRobert Mustacchi 	uint_t			xhci_intr_pri;
651993e3fafSRobert Mustacchi 	int			xhci_intr_caps;
652993e3fafSRobert Mustacchi 	xhci_dcbaa_t		xhci_dcbaa;
653993e3fafSRobert Mustacchi 	xhci_scratchpad_t	xhci_scratchpad;
654993e3fafSRobert Mustacchi 	xhci_command_ring_t	xhci_command;
655993e3fafSRobert Mustacchi 	xhci_event_ring_t	xhci_event;
656993e3fafSRobert Mustacchi 	taskq_ent_t		xhci_tqe;
657993e3fafSRobert Mustacchi 	kmutex_t		xhci_lock;
658993e3fafSRobert Mustacchi 	kcondvar_t		xhci_statecv;
659993e3fafSRobert Mustacchi 	xhci_state_flags_t	xhci_state;
660993e3fafSRobert Mustacchi 	xhci_usba_t		xhci_usba;
661993e3fafSRobert Mustacchi } xhci_t;
662993e3fafSRobert Mustacchi 
663993e3fafSRobert Mustacchi /*
664993e3fafSRobert Mustacchi  * The xHCI memory mapped registers come in four different categories. The
665993e3fafSRobert Mustacchi  * offset to them is variable. These represent the given register set that we're
666993e3fafSRobert Mustacchi  * after.
667993e3fafSRobert Mustacchi  */
668993e3fafSRobert Mustacchi typedef enum xhci_reg_type {
669993e3fafSRobert Mustacchi 	XHCI_R_CAP,
670993e3fafSRobert Mustacchi 	XHCI_R_OPER,
671993e3fafSRobert Mustacchi 	XHCI_R_RUN,
672993e3fafSRobert Mustacchi 	XHCI_R_DOOR
673993e3fafSRobert Mustacchi } xhci_reg_type_t;
674993e3fafSRobert Mustacchi 
675ec82ef79SMatthias Scheler /*
676ec82ef79SMatthias Scheler  * Polled I/O data structure
677ec82ef79SMatthias Scheler  */
678ec82ef79SMatthias Scheler typedef struct xhci_polled {
679ec82ef79SMatthias Scheler 	/*
680ec82ef79SMatthias Scheler 	 * Pointer to the xhcip structure for the device that is to  be
681ec82ef79SMatthias Scheler 	 * used as input in polled mode.
682ec82ef79SMatthias Scheler 	 */
683ec82ef79SMatthias Scheler 	xhci_t			*xhci_polled_xhci;
684ec82ef79SMatthias Scheler 
685ec82ef79SMatthias Scheler 	/*
686ec82ef79SMatthias Scheler 	 * Pipe handle for the pipe that is to be used as input device
687ec82ef79SMatthias Scheler 	 * in POLLED mode.
688ec82ef79SMatthias Scheler 	 */
689ec82ef79SMatthias Scheler 	usba_pipe_handle_data_t	*xhci_polled_input_pipe_handle;
690ec82ef79SMatthias Scheler 
691ec82ef79SMatthias Scheler 	/* Endpoint for the above */
692ec82ef79SMatthias Scheler 	xhci_endpoint_t		*xhci_polled_endpoint;
693ec82ef79SMatthias Scheler 
694ec82ef79SMatthias Scheler 	/*
695ec82ef79SMatthias Scheler 	 * The buffer that the USB HDI scan codes are copied into.
696ec82ef79SMatthias Scheler 	 * A USB keyboard will report up to 8 bytes consisting of the
697ec82ef79SMatthias Scheler 	 * modifier status, a reserved byte and up to 6 key presses.
698ec82ef79SMatthias Scheler 	 * This buffer is sized to be large enough for one such report.
699ec82ef79SMatthias Scheler 	 */
700ec82ef79SMatthias Scheler 	uchar_t			xhci_polled_buf[8];
701ec82ef79SMatthias Scheler 
702ec82ef79SMatthias Scheler 	/*
703ec82ef79SMatthias Scheler 	 * Track how many times xhci_polled_input_enter() and
704ec82ef79SMatthias Scheler 	 * xhci_polled_input_exit() have been called so that the host
705ec82ef79SMatthias Scheler 	 * controller isn't switched back to OS mode prematurely.
706ec82ef79SMatthias Scheler 	 */
707ec82ef79SMatthias Scheler 	uint_t			xhci_polled_entry;
708ec82ef79SMatthias Scheler 
709ec82ef79SMatthias Scheler 	/*
710ec82ef79SMatthias Scheler 	 * Remember persistent errors that will prevent us from reading
711ec82ef79SMatthias Scheler 	 * further input to avoid repeatedly polling to no avail
712ec82ef79SMatthias Scheler 	 */
713ec82ef79SMatthias Scheler 	int			xhci_polled_persistent_error;
714ec82ef79SMatthias Scheler } xhci_polled_t;
715ec82ef79SMatthias Scheler 
716ec82ef79SMatthias Scheler /*
717ec82ef79SMatthias Scheler  * Helper functions
718ec82ef79SMatthias Scheler  */
719ec82ef79SMatthias Scheler extern xhci_t *xhci_hcdi_get_xhcip_from_dev(usba_device_t *);
720ec82ef79SMatthias Scheler extern xhci_device_t *xhci_device_lookup_by_slot(xhci_t *, int);
721ec82ef79SMatthias Scheler 
722993e3fafSRobert Mustacchi /*
723993e3fafSRobert Mustacchi  * Quirks related functions
724993e3fafSRobert Mustacchi  */
725993e3fafSRobert Mustacchi extern void xhci_quirks_populate(xhci_t *);
726993e3fafSRobert Mustacchi extern void xhci_reroute_intel(xhci_t *);
727993e3fafSRobert Mustacchi 
728993e3fafSRobert Mustacchi /*
729993e3fafSRobert Mustacchi  * Interrupt related functions
730993e3fafSRobert Mustacchi  */
731993e3fafSRobert Mustacchi extern uint_t xhci_intr(caddr_t, caddr_t);
732993e3fafSRobert Mustacchi extern boolean_t xhci_ddi_intr_disable(xhci_t *);
733993e3fafSRobert Mustacchi extern boolean_t xhci_ddi_intr_enable(xhci_t *);
734993e3fafSRobert Mustacchi extern int xhci_intr_conf(xhci_t *);
735993e3fafSRobert Mustacchi 
736993e3fafSRobert Mustacchi /*
737993e3fafSRobert Mustacchi  * DMA related functions
738993e3fafSRobert Mustacchi  */
739993e3fafSRobert Mustacchi extern int xhci_check_dma_handle(xhci_t *, xhci_dma_buffer_t *);
740993e3fafSRobert Mustacchi extern void xhci_dma_acc_attr(xhci_t *, ddi_device_acc_attr_t *);
741993e3fafSRobert Mustacchi extern void xhci_dma_dma_attr(xhci_t *, ddi_dma_attr_t *);
742993e3fafSRobert Mustacchi extern void xhci_dma_scratchpad_attr(xhci_t *, ddi_dma_attr_t *);
743993e3fafSRobert Mustacchi extern void xhci_dma_transfer_attr(xhci_t *, ddi_dma_attr_t *, uint_t);
744993e3fafSRobert Mustacchi extern void xhci_dma_free(xhci_dma_buffer_t *);
745993e3fafSRobert Mustacchi extern boolean_t xhci_dma_alloc(xhci_t *, xhci_dma_buffer_t *, ddi_dma_attr_t *,
746993e3fafSRobert Mustacchi     ddi_device_acc_attr_t *, boolean_t, size_t, boolean_t);
747993e3fafSRobert Mustacchi extern uint64_t xhci_dma_pa(xhci_dma_buffer_t *);
748993e3fafSRobert Mustacchi 
749993e3fafSRobert Mustacchi /*
750993e3fafSRobert Mustacchi  * DMA Transfer Ring functions
751993e3fafSRobert Mustacchi  */
752993e3fafSRobert Mustacchi extern xhci_transfer_t *xhci_transfer_alloc(xhci_t *, xhci_endpoint_t *, size_t,
7532aba3acdSRobert Mustacchi     uint_t, int);
754993e3fafSRobert Mustacchi extern void xhci_transfer_free(xhci_t *, xhci_transfer_t *);
755993e3fafSRobert Mustacchi extern void xhci_transfer_copy(xhci_transfer_t *, void *, size_t, boolean_t);
756993e3fafSRobert Mustacchi extern int xhci_transfer_sync(xhci_t *, xhci_transfer_t *, uint_t);
757993e3fafSRobert Mustacchi extern void xhci_transfer_trb_fill_data(xhci_endpoint_t *, xhci_transfer_t *,
758993e3fafSRobert Mustacchi     int, boolean_t);
759993e3fafSRobert Mustacchi extern void xhci_transfer_calculate_isoc(xhci_device_t *, xhci_endpoint_t *,
760993e3fafSRobert Mustacchi     uint_t, uint_t *, uint_t *);
761993e3fafSRobert Mustacchi 
762993e3fafSRobert Mustacchi /*
763993e3fafSRobert Mustacchi  * Context (DCBAA, Scratchpad, Slot) functions
764993e3fafSRobert Mustacchi  */
765993e3fafSRobert Mustacchi extern int xhci_context_init(xhci_t *);
766993e3fafSRobert Mustacchi extern void xhci_context_fini(xhci_t *);
767993e3fafSRobert Mustacchi extern boolean_t xhci_context_slot_output_init(xhci_t *, xhci_device_t *);
768993e3fafSRobert Mustacchi extern void xhci_context_slot_output_fini(xhci_t *, xhci_device_t *);
769993e3fafSRobert Mustacchi 
770993e3fafSRobert Mustacchi /*
771993e3fafSRobert Mustacchi  * Command Ring Functions
772993e3fafSRobert Mustacchi  */
773993e3fafSRobert Mustacchi extern int xhci_command_ring_init(xhci_t *);
774993e3fafSRobert Mustacchi extern void xhci_command_ring_fini(xhci_t *);
775993e3fafSRobert Mustacchi extern boolean_t xhci_command_event_callback(xhci_t *, xhci_trb_t *trb);
776993e3fafSRobert Mustacchi 
777993e3fafSRobert Mustacchi extern void xhci_command_init(xhci_command_t *);
778993e3fafSRobert Mustacchi extern void xhci_command_fini(xhci_command_t *);
779993e3fafSRobert Mustacchi 
780993e3fafSRobert Mustacchi extern int xhci_command_enable_slot(xhci_t *, uint8_t *);
781993e3fafSRobert Mustacchi extern int xhci_command_disable_slot(xhci_t *, uint8_t);
782993e3fafSRobert Mustacchi extern int xhci_command_set_address(xhci_t *, xhci_device_t *, boolean_t);
783993e3fafSRobert Mustacchi extern int xhci_command_configure_endpoint(xhci_t *, xhci_device_t *);
784993e3fafSRobert Mustacchi extern int xhci_command_evaluate_context(xhci_t *, xhci_device_t *);
785993e3fafSRobert Mustacchi extern int xhci_command_reset_endpoint(xhci_t *, xhci_device_t *,
786993e3fafSRobert Mustacchi     xhci_endpoint_t *);
787993e3fafSRobert Mustacchi extern int xhci_command_set_tr_dequeue(xhci_t *, xhci_device_t *,
788993e3fafSRobert Mustacchi     xhci_endpoint_t *);
789993e3fafSRobert Mustacchi extern int xhci_command_stop_endpoint(xhci_t *, xhci_device_t *,
790993e3fafSRobert Mustacchi     xhci_endpoint_t *);
791993e3fafSRobert Mustacchi 
792993e3fafSRobert Mustacchi /*
793993e3fafSRobert Mustacchi  * Event Ring Functions
794993e3fafSRobert Mustacchi  */
795993e3fafSRobert Mustacchi extern int xhci_event_init(xhci_t *);
796993e3fafSRobert Mustacchi extern void xhci_event_fini(xhci_t *);
797ec82ef79SMatthias Scheler extern boolean_t xhci_event_process_trb(xhci_t *, xhci_trb_t *);
798993e3fafSRobert Mustacchi extern boolean_t xhci_event_process(xhci_t *);
799993e3fafSRobert Mustacchi 
800993e3fafSRobert Mustacchi /*
801993e3fafSRobert Mustacchi  * General Ring functions
802993e3fafSRobert Mustacchi  */
803993e3fafSRobert Mustacchi extern void xhci_ring_free(xhci_ring_t *);
804993e3fafSRobert Mustacchi extern int xhci_ring_reset(xhci_t *, xhci_ring_t *);
805993e3fafSRobert Mustacchi extern int xhci_ring_alloc(xhci_t *, xhci_ring_t *);
806993e3fafSRobert Mustacchi 
807993e3fafSRobert Mustacchi /*
808993e3fafSRobert Mustacchi  * Event Ring (Consumer) oriented functions.
809993e3fafSRobert Mustacchi  */
810993e3fafSRobert Mustacchi extern xhci_trb_t *xhci_ring_event_advance(xhci_ring_t *);
811993e3fafSRobert Mustacchi 
812993e3fafSRobert Mustacchi 
813993e3fafSRobert Mustacchi /*
814993e3fafSRobert Mustacchi  * Command and Transfer Ring (Producer) oriented functions.
815993e3fafSRobert Mustacchi  */
816993e3fafSRobert Mustacchi extern boolean_t xhci_ring_trb_tail_valid(xhci_ring_t *, uint64_t);
817993e3fafSRobert Mustacchi extern int xhci_ring_trb_valid_range(xhci_ring_t *, uint64_t, uint_t);
818993e3fafSRobert Mustacchi 
819993e3fafSRobert Mustacchi extern boolean_t xhci_ring_trb_space(xhci_ring_t *, uint_t);
8202aba3acdSRobert Mustacchi extern void xhci_ring_trb_fill(xhci_ring_t *, uint_t, xhci_trb_t *, uint64_t *,
8212aba3acdSRobert Mustacchi     boolean_t);
822993e3fafSRobert Mustacchi extern void xhci_ring_trb_produce(xhci_ring_t *, uint_t);
823993e3fafSRobert Mustacchi extern boolean_t xhci_ring_trb_consumed(xhci_ring_t *, uint64_t);
824993e3fafSRobert Mustacchi extern void xhci_ring_trb_put(xhci_ring_t *, xhci_trb_t *);
825993e3fafSRobert Mustacchi extern void xhci_ring_skip(xhci_ring_t *);
826993e3fafSRobert Mustacchi extern void xhci_ring_skip_transfer(xhci_ring_t *, xhci_transfer_t *);
827993e3fafSRobert Mustacchi 
828993e3fafSRobert Mustacchi /*
829993e3fafSRobert Mustacchi  * MMIO related functions. Note callers are responsible for checking with FM
830993e3fafSRobert Mustacchi  * after accessing registers.
831993e3fafSRobert Mustacchi  */
832993e3fafSRobert Mustacchi extern int xhci_check_regs_acc(xhci_t *);
833993e3fafSRobert Mustacchi 
834993e3fafSRobert Mustacchi extern uint8_t xhci_get8(xhci_t *, xhci_reg_type_t, uintptr_t);
835993e3fafSRobert Mustacchi extern uint16_t xhci_get16(xhci_t *, xhci_reg_type_t, uintptr_t);
836993e3fafSRobert Mustacchi extern uint32_t xhci_get32(xhci_t *, xhci_reg_type_t, uintptr_t);
837993e3fafSRobert Mustacchi extern uint64_t xhci_get64(xhci_t *, xhci_reg_type_t, uintptr_t);
838993e3fafSRobert Mustacchi 
839993e3fafSRobert Mustacchi extern void xhci_put8(xhci_t *, xhci_reg_type_t, uintptr_t, uint8_t);
840993e3fafSRobert Mustacchi extern void xhci_put16(xhci_t *, xhci_reg_type_t, uintptr_t, uint16_t);
841993e3fafSRobert Mustacchi extern void xhci_put32(xhci_t *, xhci_reg_type_t, uintptr_t, uint32_t);
842993e3fafSRobert Mustacchi extern void xhci_put64(xhci_t *, xhci_reg_type_t, uintptr_t, uint64_t);
843993e3fafSRobert Mustacchi 
844993e3fafSRobert Mustacchi /*
845993e3fafSRobert Mustacchi  * Runtime FM related functions
846993e3fafSRobert Mustacchi  */
847993e3fafSRobert Mustacchi extern void xhci_fm_runtime_reset(xhci_t *);
848993e3fafSRobert Mustacchi 
849993e3fafSRobert Mustacchi /*
850993e3fafSRobert Mustacchi  * Endpoint related functions
851993e3fafSRobert Mustacchi  */
852993e3fafSRobert Mustacchi extern int xhci_endpoint_init(xhci_t *, xhci_device_t *,
853993e3fafSRobert Mustacchi     usba_pipe_handle_data_t *);
854*0ae0ab6fSJoshua M. Clulow extern int xhci_endpoint_reinit(xhci_t *, xhci_device_t *,
855*0ae0ab6fSJoshua M. Clulow     xhci_endpoint_t *, usba_pipe_handle_data_t *);
856*0ae0ab6fSJoshua M. Clulow extern void xhci_endpoint_release(xhci_t *, xhci_endpoint_t *);
857993e3fafSRobert Mustacchi extern void xhci_endpoint_fini(xhci_device_t *, int);
858993e3fafSRobert Mustacchi extern int xhci_endpoint_update_default(xhci_t *, xhci_device_t *,
859993e3fafSRobert Mustacchi     xhci_endpoint_t *);
860*0ae0ab6fSJoshua M. Clulow extern void xhci_endpoint_timeout_cancel(xhci_t *, xhci_endpoint_t *);
861993e3fafSRobert Mustacchi 
862993e3fafSRobert Mustacchi extern int xhci_endpoint_setup_default_context(xhci_t *, xhci_device_t *,
863993e3fafSRobert Mustacchi     xhci_endpoint_t *);
864993e3fafSRobert Mustacchi 
865993e3fafSRobert Mustacchi extern uint_t xhci_endpoint_pipe_to_epid(usba_pipe_handle_data_t *);
866993e3fafSRobert Mustacchi extern boolean_t xhci_endpoint_is_periodic_in(xhci_endpoint_t *);
867993e3fafSRobert Mustacchi 
868*0ae0ab6fSJoshua M. Clulow extern void xhci_endpoint_serialize(xhci_t *, xhci_endpoint_t *);
869993e3fafSRobert Mustacchi extern int xhci_endpoint_quiesce(xhci_t *, xhci_device_t *, xhci_endpoint_t *);
870993e3fafSRobert Mustacchi extern int xhci_endpoint_schedule(xhci_t *, xhci_device_t *, xhci_endpoint_t *,
871993e3fafSRobert Mustacchi     xhci_transfer_t *, boolean_t);
872993e3fafSRobert Mustacchi extern int xhci_endpoint_ring(xhci_t *, xhci_device_t *, xhci_endpoint_t *);
873993e3fafSRobert Mustacchi extern boolean_t xhci_endpoint_transfer_callback(xhci_t *, xhci_trb_t *);
874993e3fafSRobert Mustacchi 
875ec82ef79SMatthias Scheler extern xhci_transfer_t *xhci_endpoint_determine_transfer(xhci_t *,
876ec82ef79SMatthias Scheler     xhci_endpoint_t *, xhci_trb_t *, uint_t *);
877ec82ef79SMatthias Scheler 
878993e3fafSRobert Mustacchi /*
879993e3fafSRobert Mustacchi  * USB Framework related functions
880993e3fafSRobert Mustacchi  */
881993e3fafSRobert Mustacchi extern int xhci_hcd_init(xhci_t *);
882993e3fafSRobert Mustacchi extern void xhci_hcd_fini(xhci_t *);
883993e3fafSRobert Mustacchi 
884993e3fafSRobert Mustacchi /*
885993e3fafSRobert Mustacchi  * Root hub related functions
886993e3fafSRobert Mustacchi  */
887993e3fafSRobert Mustacchi extern int xhci_root_hub_init(xhci_t *);
888993e3fafSRobert Mustacchi extern int xhci_root_hub_fini(xhci_t *);
889993e3fafSRobert Mustacchi extern int xhci_root_hub_ctrl_req(xhci_t *, usba_pipe_handle_data_t *,
890993e3fafSRobert Mustacchi     usb_ctrl_req_t *);
891993e3fafSRobert Mustacchi extern void xhci_root_hub_psc_callback(xhci_t *);
892993e3fafSRobert Mustacchi extern int xhci_root_hub_intr_root_enable(xhci_t *, usba_pipe_handle_data_t *,
893993e3fafSRobert Mustacchi     usb_intr_req_t *);
894993e3fafSRobert Mustacchi extern void xhci_root_hub_intr_root_disable(xhci_t *);
895993e3fafSRobert Mustacchi 
896ec82ef79SMatthias Scheler /*
897ec82ef79SMatthias Scheler  * Polled I/O functions
898ec82ef79SMatthias Scheler  */
899ec82ef79SMatthias Scheler extern int xhci_hcdi_console_input_init(usba_pipe_handle_data_t *, uchar_t **,
900ec82ef79SMatthias Scheler     usb_console_info_impl_t *);
901ec82ef79SMatthias Scheler extern int xhci_hcdi_console_input_fini(usb_console_info_impl_t *);
902ec82ef79SMatthias Scheler extern int xhci_hcdi_console_input_enter(usb_console_info_impl_t *);
903ec82ef79SMatthias Scheler extern int xhci_hcdi_console_read(usb_console_info_impl_t *, uint_t *);
904ec82ef79SMatthias Scheler extern int xhci_hcdi_console_input_exit(usb_console_info_impl_t *);
905ec82ef79SMatthias Scheler extern int xhci_hcdi_console_output_init(usba_pipe_handle_data_t *,
906ec82ef79SMatthias Scheler     usb_console_info_impl_t *);
907ec82ef79SMatthias Scheler extern int xhci_hcdi_console_output_fini(usb_console_info_impl_t *);
908ec82ef79SMatthias Scheler extern int xhci_hcdi_console_output_enter(usb_console_info_impl_t *);
909ec82ef79SMatthias Scheler extern int xhci_hcdi_console_write(usb_console_info_impl_t *, uchar_t *,
910ec82ef79SMatthias Scheler     uint_t, uint_t *);
911ec82ef79SMatthias Scheler extern int xhci_hcdi_console_output_exit(usb_console_info_impl_t *);
912ec82ef79SMatthias Scheler 
913993e3fafSRobert Mustacchi /*
914993e3fafSRobert Mustacchi  * Logging functions
915993e3fafSRobert Mustacchi  */
916993e3fafSRobert Mustacchi extern void xhci_log(xhci_t *xhcip, const char *fmt, ...) __KPRINTFLIKE(2);
917993e3fafSRobert Mustacchi extern void xhci_error(xhci_t *xhcip, const char *fmt, ...) __KPRINTFLIKE(2);
918993e3fafSRobert Mustacchi 
919993e3fafSRobert Mustacchi /*
920993e3fafSRobert Mustacchi  * Misc. data
921993e3fafSRobert Mustacchi  */
922993e3fafSRobert Mustacchi extern void *xhci_soft_state;
923993e3fafSRobert Mustacchi 
924993e3fafSRobert Mustacchi #ifdef __cplusplus
925993e3fafSRobert Mustacchi }
926993e3fafSRobert Mustacchi #endif
927993e3fafSRobert Mustacchi 
928993e3fafSRobert Mustacchi #endif /* _SYS_USB_XHCI_XHCI_H */
929