vfs: check userland buffers before reading them.
[haiku.git] / src / add-ons / kernel / busses / usb / xhci.h
blob4f54fd16b1d3e7ed2ec9a45275aa3ef70ccb3312
1 /*
2 * Copyright 2006-2012, Haiku Inc. All rights reserved.
3 * Distributed under the terms of the MIT License.
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
14 #include "usb_private.h"
15 #include "xhci_hardware.h"
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;
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,
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
43 uint8 buffer_count;
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)));
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;
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]
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];
82 } xhci_device;
85 class XHCI : public BusManager {
86 public:
87 XHCI(pci_info *info, Stack *stack);
88 ~XHCI();
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);
96 virtual status_t NotifyPipeChange(Pipe *pipe,
97 usb_change change);
99 static status_t AddTo(Stack *stack);
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);
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"; }
124 private:
125 // Controller resets
126 status_t ControllerReset();
127 status_t ControllerHalt();
129 // Interrupt functions
130 static int32 InterruptHandler(void *data);
131 int32 Interrupt();
133 // Event management
134 static int32 EventThread(void *data);
135 void CompleteEvents();
137 // Transfer management
138 static int32 FinishThread(void *data);
139 void FinishTransfers();
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);
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);
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);
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);
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);
200 // Context functions
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;
220 pci_info * fPCIInfo;
221 Stack * fStack;
222 uint8 fIRQ;
223 bool fUseMSI;
225 area_id fErstArea;
226 xhci_erst_element * fErst;
227 xhci_trb * fEventRing;
228 xhci_trb * fCmdRing;
229 uint64 fCmdAddr;
230 uint32 fCmdResult[2];
232 area_id fDcbaArea;
233 struct xhci_device_context_array * fDcba;
235 spinlock fSpinlock;
237 sem_id fCmdCompSem;
238 sem_id fFinishTransfersSem;
239 thread_id fFinishThread;
240 bool fStopThreads;
242 xhci_td * fFinishedHead;
244 // Root Hub
245 XHCIRootHub * fRootHub;
246 uint8 fRootHubAddress;
248 // Port management
249 uint8 fPortCount;
250 uint8 fSlotCount;
251 usb_speed fPortSpeeds[XHCI_MAX_PORTS];
252 uint8 fPortSlots[XHCI_MAX_PORTS];
254 // Scratchpad
255 uint32 fScratchpadCount;
256 area_id fScratchpadArea[XHCI_MAX_SCRATCHPADS];
257 void * fScratchpad[XHCI_MAX_SCRATCHPADS];
259 // Devices
260 struct xhci_device fDevices[XHCI_MAX_DEVICES];
261 int32 fContextSizeShift; // 0/1 for 32/64 bytes
263 sem_id fEventSem;
264 thread_id fEventThread;
265 uint16 fEventIdx;
266 uint16 fCmdIdx;
267 uint8 fEventCcs;
268 uint8 fCmdCcs;
270 uint32 fExitLatMax;
274 class XHCIRootHub : public Hub {
275 public:
276 XHCIRootHub(Object *rootObject,
277 int8 deviceAddress);
279 static status_t ProcessTransfer(XHCI *ehci,
280 Transfer *transfer);
284 #endif // !XHCI_H