1 /* 2 * Copyright 2011-2019, Haiku Inc. All rights reserved. 3 * Distributed under the terms of the MIT License. 4 * 5 * Authors: 6 * Augustin Cavalier <waddlesplash> 7 * Michael Lotz <mmlr@mlotz.ch> 8 * Jian Chiang <j.jian.chiang@gmail.com> 9 * Jérôme Duval <jerome.duval@gmail.com> 10 */ 11 #ifndef XHCI_H 12 #define XHCI_H 13 14 15 #include "usb_private.h" 16 #include "xhci_hardware.h" 17 18 19 struct pci_info; 20 struct pci_module_info; 21 struct pci_x86_module_info; 22 struct xhci_td; 23 struct xhci_device; 24 struct xhci_endpoint; 25 class XHCIRootHub; 26 27 28 enum xhci_state { 29 XHCI_STATE_DISABLED = 0, 30 XHCI_STATE_ENABLED, 31 XHCI_STATE_DEFAULT, 32 XHCI_STATE_ADDRESSED, 33 XHCI_STATE_CONFIGURED, 34 }; 35 36 #define XHCI_ENDPOINT_RING_SIZE (XHCI_MAX_TRANSFERS * 2 + 1) 37 38 39 typedef struct xhci_td { 40 xhci_trb* trbs; 41 phys_addr_t trb_addr; 42 uint32 trb_count; 43 uint32 trb_used; 44 45 void** buffers; 46 phys_addr_t* buffer_addrs; 47 size_t buffer_size; 48 uint32 buffer_count; 49 50 Transfer* transfer; 51 uint8 trb_completion_code; 52 int32 td_transferred; 53 int32 trb_left; 54 55 xhci_td* next; 56 } xhci_td; 57 58 59 typedef struct xhci_endpoint { 60 mutex lock; 61 62 xhci_device* device; 63 uint8 id; 64 65 uint16 max_burst_payload; 66 67 xhci_td* td_head; 68 uint8 used; 69 uint8 current; 70 71 xhci_trb* trbs; // [XHCI_ENDPOINT_RING_SIZE] 72 phys_addr_t trb_addr; 73 } xhci_endpoint; 74 75 76 typedef struct xhci_device { 77 uint8 slot; 78 uint8 address; 79 enum xhci_state state; 80 area_id trb_area; 81 phys_addr_t trb_addr; 82 struct xhci_trb *trbs; // [XHCI_MAX_ENDPOINTS - 1][XHCI_ENDPOINT_RING_SIZE] 83 84 area_id input_ctx_area; 85 phys_addr_t input_ctx_addr; 86 struct xhci_input_device_ctx *input_ctx; 87 88 area_id device_ctx_area; 89 phys_addr_t device_ctx_addr; 90 struct xhci_device_ctx *device_ctx; 91 92 xhci_endpoint endpoints[XHCI_MAX_ENDPOINTS - 1]; 93 } xhci_device; 94 95 96 class XHCI : public BusManager { 97 public: 98 static status_t AddTo(Stack *stack); 99 100 XHCI(pci_info *info, Stack *stack); 101 ~XHCI(); 102 103 virtual const char * TypeName() const { return "xhci"; } 104 105 status_t Start(); 106 virtual status_t SubmitTransfer(Transfer *transfer); 107 status_t SubmitControlRequest(Transfer *transfer); 108 status_t SubmitNormalRequest(Transfer *transfer); 109 virtual status_t CancelQueuedTransfers(Pipe *pipe, bool force); 110 111 virtual status_t StartDebugTransfer(Transfer *transfer); 112 virtual status_t CheckDebugTransfer(Transfer *transfer); 113 virtual void CancelDebugTransfer(Transfer *transfer); 114 115 virtual status_t NotifyPipeChange(Pipe *pipe, 116 usb_change change); 117 118 virtual Device * AllocateDevice(Hub *parent, 119 int8 hubAddress, uint8 hubPort, 120 usb_speed speed); 121 virtual void FreeDevice(Device *device); 122 123 // Port operations for root hub 124 uint8 PortCount() const { return fPortCount; } 125 status_t GetPortStatus(uint8 index, 126 usb_port_status *status); 127 status_t SetPortFeature(uint8 index, uint16 feature); 128 status_t ClearPortFeature(uint8 index, uint16 feature); 129 130 status_t GetPortSpeed(uint8 index, usb_speed *speed); 131 132 private: 133 // Controller resets 134 status_t ControllerReset(); 135 status_t ControllerHalt(); 136 137 // Interrupt functions 138 static int32 InterruptHandler(void *data); 139 int32 Interrupt(); 140 141 // Endpoint management 142 status_t ConfigureEndpoint(xhci_endpoint* ep, uint8 slot, 143 uint8 number, uint8 type, bool directionIn, 144 uint16 interval, uint16 maxPacketSize, 145 usb_speed speed, uint8 maxBurst, 146 uint16 bytesPerInterval); 147 status_t _InsertEndpointForPipe(Pipe *pipe); 148 status_t _RemoveEndpointForPipe(Pipe *pipe); 149 150 // Event management 151 static int32 EventThread(void *data); 152 void CompleteEvents(); 153 void ProcessEvents(); 154 155 // Transfer management 156 static int32 FinishThread(void *data); 157 void FinishTransfers(); 158 159 // Descriptor management 160 xhci_td * CreateDescriptor(uint32 trbCount, 161 uint32 bufferCount, size_t bufferSize); 162 void FreeDescriptor(xhci_td *descriptor); 163 164 size_t WriteDescriptor(xhci_td *descriptor, 165 iovec *vector, size_t vectorCount); 166 size_t ReadDescriptor(xhci_td *descriptor, 167 iovec *vector, size_t vectorCount); 168 169 status_t _LinkDescriptorForPipe(xhci_td *descriptor, 170 xhci_endpoint *endpoint); 171 status_t _UnlinkDescriptorForPipe(xhci_td *descriptor, 172 xhci_endpoint *endpoint); 173 174 // Command 175 void DumpRing(xhci_trb *trb, uint32 size); 176 void QueueCommand(xhci_trb *trb); 177 void HandleCmdComplete(xhci_trb *trb); 178 void HandleTransferComplete(xhci_trb *trb); 179 status_t DoCommand(xhci_trb *trb); 180 181 // Doorbell 182 void Ring(uint8 slot, uint8 endpoint); 183 184 // Commands 185 status_t Noop(); 186 status_t EnableSlot(uint8 *slot); 187 status_t DisableSlot(uint8 slot); 188 status_t SetAddress(uint64 inputContext, bool bsr, 189 uint8 slot); 190 status_t ConfigureEndpoint(uint64 inputContext, 191 bool deconfigure, uint8 slot); 192 status_t EvaluateContext(uint64 inputContext, 193 uint8 slot); 194 status_t ResetEndpoint(bool preserve, uint8 endpoint, 195 uint8 slot); 196 status_t StopEndpoint(bool suspend, uint8 endpoint, 197 uint8 slot); 198 status_t SetTRDequeue(uint64 dequeue, uint16 stream, 199 uint8 endpoint, uint8 slot); 200 status_t ResetDevice(uint8 slot); 201 202 // Operational register functions 203 inline void WriteOpReg(uint32 reg, uint32 value); 204 inline uint32 ReadOpReg(uint32 reg); 205 inline status_t WaitOpBits(uint32 reg, uint32 mask, uint32 expected); 206 207 // Capability register functions 208 inline uint32 ReadCapReg32(uint32 reg); 209 inline void WriteCapReg32(uint32 reg, uint32 value); 210 211 // Runtime register functions 212 inline uint32 ReadRunReg32(uint32 reg); 213 inline void WriteRunReg32(uint32 reg, uint32 value); 214 215 // Doorbell register functions 216 inline uint32 ReadDoorReg32(uint32 reg); 217 inline void WriteDoorReg32(uint32 reg, uint32 value); 218 219 // Context functions 220 inline addr_t _OffsetContextAddr(addr_t p); 221 inline uint32 _ReadContext(uint32* p); 222 inline void _WriteContext(uint32* p, uint32 value); 223 inline uint64 _ReadContext(uint64* p); 224 inline void _WriteContext(uint64* p, uint64 value); 225 226 void _SwitchIntelPorts(); 227 228 private: 229 static pci_module_info * sPCIModule; 230 static pci_x86_module_info *sPCIx86Module; 231 232 area_id fRegisterArea; 233 uint8 * fRegisters; 234 uint32 fCapabilityRegisterOffset; 235 uint32 fOperationalRegisterOffset; 236 uint32 fRuntimeRegisterOffset; 237 uint32 fDoorbellRegisterOffset; 238 239 pci_info * fPCIInfo; 240 Stack * fStack; 241 uint8 fIRQ; 242 bool fUseMSI; 243 244 area_id fErstArea; 245 xhci_erst_element * fErst; 246 xhci_trb * fEventRing; 247 xhci_trb * fCmdRing; 248 uint64 fCmdAddr; 249 uint32 fCmdResult[2]; 250 251 area_id fDcbaArea; 252 struct xhci_device_context_array * fDcba; 253 254 spinlock fSpinlock; 255 256 sem_id fCmdCompSem; 257 bool fStopThreads; 258 259 // Root Hub 260 XHCIRootHub * fRootHub; 261 uint8 fRootHubAddress; 262 263 // Port management 264 uint8 fPortCount; 265 uint8 fSlotCount; 266 usb_speed fPortSpeeds[XHCI_MAX_PORTS]; 267 uint8 fPortSlots[XHCI_MAX_PORTS]; 268 269 // Scratchpad 270 uint32 fScratchpadCount; 271 area_id fScratchpadArea[XHCI_MAX_SCRATCHPADS]; 272 void * fScratchpad[XHCI_MAX_SCRATCHPADS]; 273 274 // Devices 275 struct xhci_device fDevices[XHCI_MAX_DEVICES]; 276 int32 fContextSizeShift; // 0/1 for 32/64 bytes 277 278 // Transfers 279 mutex fFinishedLock; 280 xhci_td * fFinishedHead; 281 sem_id fFinishTransfersSem; 282 thread_id fFinishThread; 283 284 // Events 285 sem_id fEventSem; 286 thread_id fEventThread; 287 mutex fEventLock; 288 uint16 fEventIdx; 289 uint16 fCmdIdx; 290 uint8 fEventCcs; 291 uint8 fCmdCcs; 292 293 uint32 fExitLatMax; 294 }; 295 296 297 class XHCIRootHub : public Hub { 298 public: 299 XHCIRootHub(Object *rootObject, 300 int8 deviceAddress); 301 302 static status_t ProcessTransfer(XHCI *ehci, 303 Transfer *transfer); 304 }; 305 306 307 #endif // !XHCI_H 308