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