2 * Copyright 2006-2012, Haiku Inc. All rights reserved.
3 * Distributed under the terms of the MIT License.
6 * Michael Lotz <mmlr@mlotz.ch>
7 * Jian Chiang <j.jian.chiang@gmail.com>
8 * Jérôme Duval <jerome.duval@gmail.com>
14 #include "usb_private.h"
15 #include "xhci_hardware.h"
19 struct pci_module_info
;
20 struct pci_x86_module_info
;
28 XHCI_STATE_DISABLED
= 0,
32 XHCI_STATE_CONFIGURED
,
36 typedef struct xhci_td
{
37 struct xhci_trb trbs
[XHCI_MAX_TRBS_PER_TD
];
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
45 struct xhci_td
*next_chain
;
49 uint8 trb_completion_code
;
51 } xhci_td
__attribute__((__aligned__(16)));
54 typedef struct xhci_endpoint
{
57 struct xhci_trb
*trbs
; // [XHCI_MAX_TRANSFERS]
65 typedef struct xhci_device
{
68 enum xhci_state state
;
71 struct xhci_trb (*trbs
); // [XHCI_MAX_ENDPOINTS - 1][XHCI_MAX_TRANSFERS]
73 area_id input_ctx_area
;
74 phys_addr_t input_ctx_addr
;
75 struct xhci_input_device_ctx
*input_ctx
;
77 area_id device_ctx_area
;
78 phys_addr_t device_ctx_addr
;
79 struct xhci_device_ctx
*device_ctx
;
81 xhci_endpoint endpoints
[XHCI_MAX_ENDPOINTS
- 1];
85 class XHCI
: public BusManager
{
87 XHCI(pci_info
*info
, Stack
*stack
);
91 virtual status_t
SubmitTransfer(Transfer
*transfer
);
92 status_t
SubmitControlRequest(Transfer
*transfer
);
93 status_t
SubmitNormalRequest(Transfer
*transfer
);
94 virtual status_t
CancelQueuedTransfers(Pipe
*pipe
, bool force
);
96 virtual status_t
NotifyPipeChange(Pipe
*pipe
,
99 static status_t
AddTo(Stack
*stack
);
101 virtual Device
* AllocateDevice(Hub
*parent
,
102 int8 hubAddress
, uint8 hubPort
,
104 status_t
ConfigureEndpoint(uint8 slot
, uint8 number
,
105 uint8 type
, uint64 ringAddr
,
106 uint16 interval
, uint16 maxPacketSize
,
107 uint16 maxFrameSize
, usb_speed speed
);
108 virtual void FreeDevice(Device
*device
);
110 status_t
_InsertEndpointForPipe(Pipe
*pipe
);
111 status_t
_RemoveEndpointForPipe(Pipe
*pipe
);
113 // Port operations for root hub
114 uint8
PortCount() const { return fPortCount
; }
115 status_t
GetPortStatus(uint8 index
,
116 usb_port_status
*status
);
117 status_t
SetPortFeature(uint8 index
, uint16 feature
);
118 status_t
ClearPortFeature(uint8 index
, uint16 feature
);
120 status_t
GetPortSpeed(uint8 index
, usb_speed
*speed
);
122 virtual const char * TypeName() const { return "xhci"; }
126 status_t
ControllerReset();
127 status_t
ControllerHalt();
129 // Interrupt functions
130 static int32
InterruptHandler(void *data
);
134 static int32
EventThread(void *data
);
135 void CompleteEvents();
137 // Transfer management
138 static int32
FinishThread(void *data
);
139 void FinishTransfers();
142 xhci_td
* CreateDescriptor(size_t bufferSize
);
143 xhci_td
* CreateDescriptorChain(size_t bufferSize
,
145 void FreeDescriptor(xhci_td
*descriptor
);
147 size_t WriteDescriptorChain(xhci_td
*descriptor
,
148 iovec
*vector
, size_t vectorCount
);
149 size_t ReadDescriptorChain(xhci_td
*descriptor
,
150 iovec
*vector
, size_t vectorCount
);
152 status_t
_LinkDescriptorForPipe(xhci_td
*descriptor
,
153 xhci_endpoint
*endpoint
);
154 status_t
_UnlinkDescriptorForPipe(xhci_td
*descriptor
,
155 xhci_endpoint
*endpoint
);
158 void DumpRing(xhci_trb
*trb
, uint32 size
);
159 void QueueCommand(xhci_trb
*trb
);
160 void HandleCmdComplete(xhci_trb
*trb
);
161 void HandleTransferComplete(xhci_trb
*trb
);
162 status_t
DoCommand(xhci_trb
*trb
);
164 void Ring(uint8 slot
, uint8 endpoint
);
168 status_t
EnableSlot(uint8
*slot
);
169 status_t
DisableSlot(uint8 slot
);
170 status_t
SetAddress(uint64 inputContext
, bool bsr
,
172 status_t
ConfigureEndpoint(uint64 inputContext
,
173 bool deconfigure
, uint8 slot
);
174 status_t
EvaluateContext(uint64 inputContext
,
176 status_t
ResetEndpoint(bool preserve
, uint8 endpoint
,
178 status_t
StopEndpoint(bool suspend
, uint8 endpoint
,
180 status_t
SetTRDequeue(uint64 dequeue
, uint16 stream
,
181 uint8 endpoint
, uint8 slot
);
182 status_t
ResetDevice(uint8 slot
);
184 // Operational register functions
185 inline void WriteOpReg(uint32 reg
, uint32 value
);
186 inline uint32
ReadOpReg(uint32 reg
);
188 // Capability register functions
189 inline uint32
ReadCapReg32(uint32 reg
);
190 inline void WriteCapReg32(uint32 reg
, uint32 value
);
192 // Runtime register functions
193 inline uint32
ReadRunReg32(uint32 reg
);
194 inline void WriteRunReg32(uint32 reg
, uint32 value
);
196 // Doorbell register functions
197 inline uint32
ReadDoorReg32(uint32 reg
);
198 inline void WriteDoorReg32(uint32 reg
, uint32 value
);
201 inline addr_t
_OffsetContextAddr(addr_t p
);
202 inline uint32
_ReadContext(uint32
* p
);
203 inline void _WriteContext(uint32
* p
, uint32 value
);
204 inline uint64
_ReadContext(uint64
* p
);
205 inline void _WriteContext(uint64
* p
, uint64 value
);
207 void _SwitchIntelPorts();
209 static pci_module_info
* sPCIModule
;
210 static pci_x86_module_info
*sPCIx86Module
;
212 uint8
* fCapabilityRegisters
;
213 uint32 fCapabilityLength
;
214 uint8
* fOperationalRegisters
;
215 uint32 fOperationalLength
;
216 uint8
* fRuntimeRegisters
;
217 uint32 fRuntimeLength
;
218 uint8
* fDoorbellRegisters
;
219 area_id fRegisterArea
;
226 xhci_erst_element
* fErst
;
227 xhci_trb
* fEventRing
;
230 uint32 fCmdResult
[2];
233 struct xhci_device_context_array
* fDcba
;
238 sem_id fFinishTransfersSem
;
239 thread_id fFinishThread
;
242 xhci_td
* fFinishedHead
;
245 XHCIRootHub
* fRootHub
;
246 uint8 fRootHubAddress
;
251 usb_speed fPortSpeeds
[XHCI_MAX_PORTS
];
252 uint8 fPortSlots
[XHCI_MAX_PORTS
];
255 uint32 fScratchpadCount
;
256 area_id fScratchpadArea
[XHCI_MAX_SCRATCHPADS
];
257 void * fScratchpad
[XHCI_MAX_SCRATCHPADS
];
260 struct xhci_device fDevices
[XHCI_MAX_DEVICES
];
261 int32 fContextSizeShift
; // 0/1 for 32/64 bytes
264 thread_id fEventThread
;
274 class XHCIRootHub
: public Hub
{
276 XHCIRootHub(Object
*rootObject
,
279 static status_t
ProcessTransfer(XHCI
*ehci
,