xref: /haiku/src/add-ons/kernel/busses/usb/xhci.h (revision 820dca4df6c7bf955c46e8f6521b9408f50b2900)
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