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