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