xref: /haiku/src/add-ons/kernel/busses/usb/xhci.h (revision f290b766707b386d72e2eaadd35cc3d999405077)
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_chain;
46 	struct xhci_td	*next;
47 	Transfer *transfer;
48 	uint8	trb_count;
49 	uint8	trb_completion_code;
50 	uint32	trb_left;
51 } xhci_td __attribute__((__aligned__(16)));
52 
53 
54 typedef struct xhci_endpoint {
55 	xhci_device		*device;
56 	xhci_td 		*td_head;
57 	struct xhci_trb *trbs; // [XHCI_MAX_TRANSFERS]
58 	phys_addr_t trb_addr;
59 	uint8	used;
60 	uint8	current;
61 	mutex	lock;
62 } xhci_endpoint;
63 
64 
65 typedef struct xhci_device {
66 	uint8 slot;
67 	uint8 address;
68 	enum xhci_state state;
69 	area_id trb_area;
70 	phys_addr_t trb_addr;
71 	struct xhci_trb *trbs; // [XHCI_MAX_ENDPOINTS - 1][XHCI_MAX_TRANSFERS]
72 
73 	area_id input_ctx_area;
74 	phys_addr_t input_ctx_addr;
75 	struct xhci_input_device_ctx *input_ctx;
76 
77 	area_id device_ctx_area;
78 	phys_addr_t device_ctx_addr;
79 	struct xhci_device_ctx *device_ctx;
80 
81 	xhci_endpoint endpoints[XHCI_MAX_ENDPOINTS - 1];
82 } xhci_device;
83 
84 
85 class XHCI : public BusManager {
86 public:
87 								XHCI(pci_info *info, Stack *stack);
88 								~XHCI();
89 
90 			status_t			Start();
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);
95 
96 	virtual	status_t			NotifyPipeChange(Pipe *pipe,
97 									usb_change change);
98 
99 	static	status_t			AddTo(Stack *stack);
100 
101 	virtual	Device *			AllocateDevice(Hub *parent,
102 									int8 hubAddress, uint8 hubPort,
103 									usb_speed speed);
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);
109 
110 			status_t			_InsertEndpointForPipe(Pipe *pipe);
111 			status_t			_RemoveEndpointForPipe(Pipe *pipe);
112 
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);
119 
120 			status_t			GetPortSpeed(uint8 index, usb_speed *speed);
121 
122 	virtual	const char *		TypeName() const { return "xhci"; }
123 
124 private:
125 			// Controller resets
126 			status_t			ControllerReset();
127 			status_t			ControllerHalt();
128 
129 			// Interrupt functions
130 	static	int32				InterruptHandler(void *data);
131 			int32				Interrupt();
132 
133 			// Event management
134 	static	int32				EventThread(void *data);
135 			void				CompleteEvents();
136 
137 			// Transfer management
138 	static	int32				FinishThread(void *data);
139 			void				FinishTransfers();
140 
141 			// Descriptor
142 			xhci_td *			CreateDescriptor(size_t bufferSize);
143 			xhci_td *			CreateDescriptorChain(size_t bufferSize,
144 									int32 &trbCount);
145 			void				FreeDescriptor(xhci_td *descriptor);
146 
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);
151 
152 			status_t			_LinkDescriptorForPipe(xhci_td *descriptor,
153 									xhci_endpoint *endpoint);
154 			status_t			_UnlinkDescriptorForPipe(xhci_td *descriptor,
155 									xhci_endpoint *endpoint);
156 
157 			// Command
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);
163 			//Doorbell
164 			void				Ring(uint8 slot, uint8 endpoint);
165 
166 			// Commands
167 			status_t			Noop();
168 			status_t			EnableSlot(uint8 *slot);
169 			status_t			DisableSlot(uint8 slot);
170 			status_t			SetAddress(uint64 inputContext, bool bsr,
171 									uint8 slot);
172 			status_t			ConfigureEndpoint(uint64 inputContext,
173 									bool deconfigure, uint8 slot);
174 			status_t			EvaluateContext(uint64 inputContext,
175 									uint8 slot);
176 			status_t			ResetEndpoint(bool preserve, uint8 endpoint,
177 									uint8 slot);
178 			status_t			StopEndpoint(bool suspend, uint8 endpoint,
179 									uint8 slot);
180 			status_t			SetTRDequeue(uint64 dequeue, uint16 stream,
181 									uint8 endpoint, uint8 slot);
182 			status_t			ResetDevice(uint8 slot);
183 
184 			// Operational register functions
185 	inline	void				WriteOpReg(uint32 reg, uint32 value);
186 	inline	uint32				ReadOpReg(uint32 reg);
187 	inline	status_t			WaitOpBits(uint32 reg, uint32 mask, uint32 expected);
188 
189 			// Capability register functions
190 	inline	uint32				ReadCapReg32(uint32 reg);
191 	inline	void				WriteCapReg32(uint32 reg, uint32 value);
192 
193 			// Runtime register functions
194 	inline	uint32				ReadRunReg32(uint32 reg);
195 	inline	void				WriteRunReg32(uint32 reg, uint32 value);
196 
197 			// Doorbell register functions
198 	inline	uint32				ReadDoorReg32(uint32 reg);
199 	inline	void				WriteDoorReg32(uint32 reg, uint32 value);
200 
201 			// Context functions
202 	inline	addr_t				_OffsetContextAddr(addr_t p);
203 	inline	uint32				_ReadContext(uint32* p);
204 	inline	void				_WriteContext(uint32* p, uint32 value);
205 	inline	uint64				_ReadContext(uint64* p);
206 	inline	void				_WriteContext(uint64* p, uint64 value);
207 
208 			void				_SwitchIntelPorts();
209 
210 	static	pci_module_info *	sPCIModule;
211 	static	pci_x86_module_info *sPCIx86Module;
212 
213 			area_id				fRegisterArea;
214 			uint8 *				fRegisters;
215 			uint32				fCapabilityRegisterOffset;
216 			uint32				fOperationalRegisterOffset;
217 			uint32				fRuntimeRegisterOffset;
218 			uint32				fDoorbellRegisterOffset;
219 
220 			pci_info *			fPCIInfo;
221 			Stack *				fStack;
222 			uint8				fIRQ;
223 			bool				fUseMSI;
224 
225 			area_id				fErstArea;
226 			xhci_erst_element *	fErst;
227 			xhci_trb *			fEventRing;
228 			xhci_trb *			fCmdRing;
229 			uint64				fCmdAddr;
230 			uint32				fCmdResult[2];
231 
232 			area_id				fDcbaArea;
233 			struct xhci_device_context_array * fDcba;
234 
235 			spinlock			fSpinlock;
236 
237 			sem_id				fCmdCompSem;
238 			sem_id				fFinishTransfersSem;
239 			thread_id			fFinishThread;
240 			bool				fStopThreads;
241 
242 			xhci_td	*			fFinishedHead;
243 
244 			// Root Hub
245 			XHCIRootHub *		fRootHub;
246 			uint8				fRootHubAddress;
247 
248 			// Port management
249 			uint8				fPortCount;
250 			uint8				fSlotCount;
251 			usb_speed			fPortSpeeds[XHCI_MAX_PORTS];
252 			uint8				fPortSlots[XHCI_MAX_PORTS];
253 
254 			// Scratchpad
255 			uint32				fScratchpadCount;
256 			area_id				fScratchpadArea[XHCI_MAX_SCRATCHPADS];
257 			void *				fScratchpad[XHCI_MAX_SCRATCHPADS];
258 
259 			// Devices
260 			struct xhci_device	fDevices[XHCI_MAX_DEVICES];
261 			int32				fContextSizeShift; // 0/1 for 32/64 bytes
262 
263 			sem_id				fEventSem;
264 			thread_id			fEventThread;
265 			uint16				fEventIdx;
266 			uint16				fCmdIdx;
267 			uint8				fEventCcs;
268 			uint8				fCmdCcs;
269 
270 			uint32				fExitLatMax;
271 };
272 
273 
274 class XHCIRootHub : public Hub {
275 public:
276 									XHCIRootHub(Object *rootObject,
277 										int8 deviceAddress);
278 
279 static	status_t					ProcessTransfer(XHCI *ehci,
280 										Transfer *transfer);
281 };
282 
283 
284 #endif // !XHCI_H
285