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