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