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 struct xhci_trb trbs[XHCI_MAX_TRBS_PER_TD]; 38 39 phys_addr_t this_phy; // A physical pointer to this address 40 phys_addr_t buffer_phy[XHCI_MAX_TRBS_PER_TD]; 41 void *buffer_log[XHCI_MAX_TRBS_PER_TD]; // Pointer to the logical buffer 42 size_t buffer_size[XHCI_MAX_TRBS_PER_TD]; // Size of the buffer 43 uint8 buffer_count; 44 45 struct xhci_td *next; 46 Transfer *transfer; 47 uint8 trb_count; 48 } xhci_td __attribute__((__aligned__(16))); 49 50 51 typedef struct xhci_endpoint { 52 xhci_device *device; 53 xhci_td *td_head; 54 struct xhci_trb *trbs; // [XHCI_MAX_TRANSFERS] 55 phys_addr_t trb_addr; 56 uint8 used; 57 uint8 current; 58 mutex lock; 59 } xhci_endpoint; 60 61 62 typedef struct xhci_device { 63 uint8 slot; 64 uint8 address; 65 enum xhci_state state; 66 area_id trb_area; 67 phys_addr_t trb_addr; 68 struct xhci_trb (*trbs); // [XHCI_MAX_ENDPOINTS - 1][XHCI_MAX_TRANSFERS] 69 70 area_id input_ctx_area; 71 phys_addr_t input_ctx_addr; 72 struct xhci_input_device_ctx *input_ctx; 73 74 area_id device_ctx_area; 75 phys_addr_t device_ctx_addr; 76 struct xhci_device_ctx *device_ctx; 77 78 xhci_endpoint endpoints[XHCI_MAX_ENDPOINTS - 1]; 79 } xhci_device; 80 81 82 class XHCI : public BusManager { 83 public: 84 XHCI(pci_info *info, Stack *stack); 85 ~XHCI(); 86 87 status_t Start(); 88 virtual status_t SubmitTransfer(Transfer *transfer); 89 status_t SubmitControlRequest(Transfer *transfer); 90 status_t SubmitNormalRequest(Transfer *transfer); 91 virtual status_t CancelQueuedTransfers(Pipe *pipe, bool force); 92 93 virtual status_t NotifyPipeChange(Pipe *pipe, 94 usb_change change); 95 96 static status_t AddTo(Stack *stack); 97 98 virtual Device * AllocateDevice(Hub *parent, 99 int8 hubAddress, uint8 hubPort, 100 usb_speed speed); 101 status_t ConfigureEndpoint(uint8 slot, uint8 number, 102 uint8 type, uint64 ringAddr, 103 uint16 interval, uint8 maxPacketCount, 104 uint8 mult, uint8 fpsShift, 105 uint16 maxPacketSize, uint16 maxFrameSize, 106 usb_speed speed); 107 virtual void FreeDevice(Device *device); 108 109 status_t _InsertEndpointForPipe(Pipe *pipe); 110 status_t _RemoveEndpointForPipe(Pipe *pipe); 111 112 // Port operations for root hub 113 uint8 PortCount() const { return fPortCount; } 114 status_t GetPortStatus(uint8 index, 115 usb_port_status *status); 116 status_t SetPortFeature(uint8 index, uint16 feature); 117 status_t ClearPortFeature(uint8 index, uint16 feature); 118 119 status_t GetPortSpeed(uint8 index, usb_speed *speed); 120 121 virtual const char * TypeName() const { return "xhci"; } 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 // Event management 133 static int32 EventThread(void *data); 134 void CompleteEvents(); 135 136 // Transfer management 137 static int32 FinishThread(void *data); 138 void FinishTransfers(); 139 140 // Descriptor 141 xhci_td * CreateDescriptor(size_t bufferSize); 142 xhci_td * CreateDescriptorChain(size_t bufferSize); 143 void FreeDescriptor(xhci_td *descriptor); 144 145 size_t WriteDescriptorChain(xhci_td *descriptor, 146 iovec *vector, size_t vectorCount); 147 size_t ReadDescriptorChain(xhci_td *descriptor, 148 iovec *vector, size_t vectorCount); 149 150 status_t _LinkDescriptorForPipe(xhci_td *descriptor, 151 xhci_endpoint *endpoint); 152 status_t _UnlinkDescriptorForPipe(xhci_td *descriptor, 153 xhci_endpoint *endpoint); 154 155 // Command 156 void QueueCommand(xhci_trb *trb); 157 void HandleCmdComplete(xhci_trb *trb); 158 void HandleTransferComplete(xhci_trb *trb); 159 status_t DoCommand(xhci_trb *trb); 160 //Doorbell 161 void Ring(uint8 slot, uint8 endpoint); 162 163 // Commands 164 status_t Noop(); 165 status_t EnableSlot(uint8 *slot); 166 status_t DisableSlot(uint8 slot); 167 status_t SetAddress(uint64 inputContext, bool bsr, 168 uint8 slot); 169 status_t ConfigureEndpoint(uint64 inputContext, 170 bool deconfigure, uint8 slot); 171 status_t EvaluateContext(uint64 inputContext, 172 uint8 slot); 173 status_t ResetEndpoint(bool preserve, uint8 endpoint, 174 uint8 slot); 175 status_t StopEndpoint(bool suspend, uint8 endpoint, 176 uint8 slot); 177 status_t SetTRDequeue(uint64 dequeue, uint16 stream, 178 uint8 endpoint, uint8 slot); 179 status_t ResetDevice(uint8 slot); 180 181 // Operational register functions 182 inline void WriteOpReg(uint32 reg, uint32 value); 183 inline uint32 ReadOpReg(uint32 reg); 184 185 // Capability register functions 186 inline uint32 ReadCapReg32(uint32 reg); 187 inline void WriteCapReg32(uint32 reg, uint32 value); 188 189 // Runtime register functions 190 inline uint32 ReadRunReg32(uint32 reg); 191 inline void WriteRunReg32(uint32 reg, uint32 value); 192 193 // Doorbell register functions 194 inline uint32 ReadDoorReg32(uint32 reg); 195 inline void WriteDoorReg32(uint32 reg, uint32 value); 196 197 static pci_module_info * sPCIModule; 198 static pci_x86_module_info *sPCIx86Module; 199 200 uint8 * fCapabilityRegisters; 201 uint32 fCapabilityLength; 202 uint8 * fOperationalRegisters; 203 uint32 fOperationalLength; 204 uint8 * fRuntimeRegisters; 205 uint32 fRuntimeLength; 206 uint8 * fDoorbellRegisters; 207 area_id fRegisterArea; 208 pci_info * fPCIInfo; 209 Stack * fStack; 210 uint8 fIRQ; 211 bool fUseMSI; 212 213 area_id fErstArea; 214 xhci_erst_element * fErst; 215 xhci_trb * fEventRing; 216 xhci_trb * fCmdRing; 217 uint64 fCmdAddr; 218 uint32 fCmdResult[2]; 219 220 area_id fDcbaArea; 221 struct xhci_device_context_array * fDcba; 222 223 spinlock fSpinlock; 224 225 sem_id fCmdCompSem; 226 sem_id fFinishTransfersSem; 227 thread_id fFinishThread; 228 bool fStopThreads; 229 230 xhci_td * fFinishedHead; 231 232 // Root Hub 233 XHCIRootHub * fRootHub; 234 uint8 fRootHubAddress; 235 236 // Port management 237 uint8 fPortCount; 238 uint8 fSlotCount; 239 usb_speed fPortSpeeds[XHCI_MAX_PORTS]; 240 uint8 fPortSlots[XHCI_MAX_PORTS]; 241 242 // Scratchpad 243 uint8 fScratchpadCount; 244 area_id fScratchpadArea[XHCI_MAX_SCRATCHPADS]; 245 void * fScratchpad[XHCI_MAX_SCRATCHPADS]; 246 247 // Devices 248 struct xhci_device fDevices[XHCI_MAX_DEVICES]; 249 250 sem_id fEventSem; 251 thread_id fEventThread; 252 uint16 fEventIdx; 253 uint16 fCmdIdx; 254 uint8 fEventCcs; 255 uint8 fCmdCcs; 256 257 uint32 fExitLatMax; 258 }; 259 260 261 class XHCIRootHub : public Hub { 262 public: 263 XHCIRootHub(Object *rootObject, 264 int8 deviceAddress); 265 266 static status_t ProcessTransfer(XHCI *ehci, 267 Transfer *transfer); 268 }; 269 270 271 #endif // !XHCI_H 272