vfs: check userland buffers before reading them.
[haiku.git] / src / add-ons / kernel / busses / usb / ehci.h
blob0e7aa7a80f6428e38a24cf4516c5b0db18227f16
1 /*
2 * Copyright 2006, Haiku Inc. All rights reserved.
3 * Distributed under the terms of the MIT License.
5 * Authors:
6 * Michael Lotz <mmlr@mlotz.ch>
7 */
8 #ifndef EHCI_H
9 #define EHCI_H
11 #include "usb_private.h"
12 #include "ehci_hardware.h"
15 struct pci_info;
16 struct pci_module_info;
17 struct pci_x86_module_info;
19 class EHCIRootHub;
22 typedef struct transfer_data {
23 Transfer * transfer;
24 ehci_qh * queue_head;
25 ehci_qtd * data_descriptor;
26 bool incoming;
27 bool canceled;
28 transfer_data * link;
29 } transfer_data;
32 // This structure is used to create a list of
33 // descriptors per isochronous transfer
34 typedef struct isochronous_transfer_data {
35 Transfer * transfer;
36 // The next field is used to keep track
37 // of every isochronous descriptor as they are NOT
38 // linked to each other in a queue like in every other
39 // transfer type
40 ehci_itd ** descriptors;
41 uint16 last_to_process;
42 bool incoming;
43 bool is_active;
44 isochronous_transfer_data * link;
46 size_t buffer_size;
47 void * buffer_log;
48 addr_t buffer_phy;
49 } isochronous_transfer_data;
52 class EHCI : public BusManager {
53 public:
54 EHCI(pci_info *info, Stack *stack);
55 ~EHCI();
57 status_t Start();
59 virtual status_t StartDebugTransfer(Transfer *transfer);
60 virtual status_t CheckDebugTransfer(Transfer *transfer);
61 void LinkAsyncDebugQueueHead(ehci_qh *queueHead);
62 void LinkPeriodicDebugQueueHead(
63 ehci_qh *queueHead, Pipe *pipe);
64 virtual void CancelDebugTransfer(Transfer *transfer);
65 void CleanupDebugTransfer(Transfer *transfer);
67 virtual status_t SubmitTransfer(Transfer *transfer);
68 status_t SubmitIsochronous(Transfer *transfer);
70 virtual status_t CancelQueuedTransfers(Pipe *pipe, bool force);
71 status_t CancelQueuedIsochronousTransfers(Pipe *pipe, bool force);
73 virtual status_t NotifyPipeChange(Pipe *pipe,
74 usb_change change);
76 static status_t AddTo(Stack *stack);
78 // Port operations for root hub
79 uint8 PortCount() { return fPortCount; };
80 status_t GetPortStatus(uint8 index, usb_port_status *status);
81 status_t SetPortFeature(uint8 index, uint16 feature);
82 status_t ClearPortFeature(uint8 index, uint16 feature);
84 status_t ResetPort(uint8 index);
85 status_t SuspendPort(uint8 index);
87 virtual const char * TypeName() const { return "ehci"; };
89 private:
90 // Controller resets
91 status_t ControllerReset();
92 status_t LightReset();
94 // Interrupt functions
95 static int32 InterruptHandler(void *data);
96 int32 Interrupt();
97 static int32 InterruptPollThread(void *data);
99 // Transfer management
100 status_t AddPendingTransfer(Transfer *transfer,
101 ehci_qh *queueHead,
102 ehci_qtd *dataDescriptor,
103 bool directionIn);
104 status_t AddPendingIsochronousTransfer(
105 Transfer *transfer,
106 ehci_itd **isoRequest, uint32 lastIndex,
107 bool directionIn, addr_t bufferPhy,
108 void *bufferLog, size_t bufferSize);
109 status_t CancelAllPendingTransfers();
112 static int32 FinishThread(void *data);
113 void FinishTransfers();
114 static int32 CleanupThread(void *data);
115 void Cleanup();
117 // Isochronous transfer functions
118 static int32 FinishIsochronousThread(void *data);
119 void FinishIsochronousTransfers();
120 isochronous_transfer_data * FindIsochronousTransfer(ehci_itd *itd);
121 void LinkITDescriptors(ehci_itd *itd,
122 ehci_itd **last);
123 void LinkSITDescriptors(ehci_sitd *sitd,
124 ehci_sitd **last);
125 void UnlinkITDescriptors(ehci_itd *itd,
126 ehci_itd **last);
127 void UnlinkSITDescriptors(ehci_sitd *sitd,
128 ehci_sitd **last);
130 // Queue Head functions
131 ehci_qh * CreateQueueHead();
132 status_t InitQueueHead(ehci_qh *queueHead,
133 Pipe *pipe);
134 void FreeQueueHead(ehci_qh *queueHead);
136 status_t LinkQueueHead(ehci_qh *queueHead);
137 status_t LinkInterruptQueueHead(ehci_qh *queueHead,
138 Pipe *pipe);
139 status_t UnlinkQueueHead(ehci_qh *queueHead,
140 ehci_qh **freeList);
142 // Queue functions
143 status_t FillQueueWithRequest(Transfer *transfer,
144 ehci_qh *queueHead,
145 ehci_qtd **dataDescriptor,
146 bool *directionIn);
147 status_t FillQueueWithData(Transfer *transfer,
148 ehci_qh *queueHead,
149 ehci_qtd **dataDescriptor,
150 bool *directionIn);
152 bool LockIsochronous();
153 void UnlockIsochronous();
155 // Descriptor functions
156 ehci_qtd * CreateDescriptor(
157 size_t bufferSizeToAllocate,
158 uint8 pid);
159 status_t CreateDescriptorChain(Pipe *pipe,
160 ehci_qtd **firstDescriptor,
161 ehci_qtd **lastDescriptor,
162 ehci_qtd *strayDescriptor,
163 size_t bufferSizeToAllocate,
164 uint8 pid);
165 ehci_itd* CreateItdDescriptor();
166 ehci_sitd* CreateSitdDescriptor();
168 void FreeDescriptor(ehci_qtd *descriptor);
169 void FreeDescriptorChain(ehci_qtd *topDescriptor);
170 void FreeDescriptor(ehci_itd *descriptor);
171 void FreeDescriptor(ehci_sitd *descriptor);
172 void FreeIsochronousData(
173 isochronous_transfer_data *data);
175 void LinkDescriptors(ehci_qtd *first,
176 ehci_qtd *last, ehci_qtd *alt);
178 size_t WriteDescriptorChain(
179 ehci_qtd *topDescriptor,
180 iovec *vector, size_t vectorCount);
181 size_t ReadDescriptorChain(ehci_qtd *topDescriptor,
182 iovec *vector, size_t vectorCount,
183 bool *nextDataToggle);
184 size_t ReadActualLength(ehci_qtd *topDescriptor,
185 bool *nextDataToggle);
186 size_t WriteIsochronousDescriptorChain(
187 isochronous_transfer_data *transfer,
188 uint32 packetCount,
189 iovec *vector);
190 size_t ReadIsochronousDescriptorChain(
191 isochronous_transfer_data *transfer);
193 // Operational register functions
194 inline void WriteOpReg(uint32 reg, uint32 value);
195 inline uint32 ReadOpReg(uint32 reg);
197 // Capability register functions
198 inline uint8 ReadCapReg8(uint32 reg);
199 inline uint16 ReadCapReg16(uint32 reg);
200 inline uint32 ReadCapReg32(uint32 reg);
202 static pci_module_info * sPCIModule;
203 static pci_x86_module_info * sPCIx86Module;
205 uint8 * fCapabilityRegisters;
206 uint8 * fOperationalRegisters;
207 area_id fRegisterArea;
208 pci_info * fPCIInfo;
209 Stack * fStack;
210 uint32 fEnabledInterrupts;
211 uint32 fThreshold;
213 // Periodic transfer framelist and interrupt entries
214 area_id fPeriodicFrameListArea;
215 uint32 * fPeriodicFrameList;
216 interrupt_entry * fInterruptEntries;
217 ehci_itd ** fItdEntries;
218 ehci_sitd ** fSitdEntries;
220 // Async transfer queue management
221 ehci_qh * fAsyncQueueHead;
222 sem_id fAsyncAdvanceSem;
224 // Maintain a linked list of transfers
225 transfer_data * fFirstTransfer;
226 transfer_data * fLastTransfer;
227 sem_id fFinishTransfersSem;
228 thread_id fFinishThread;
229 Pipe * fProcessingPipe;
231 ehci_qh * fFreeListHead;
232 sem_id fCleanupSem;
233 thread_id fCleanupThread;
234 bool fStopThreads;
235 int32 fNextStartingFrame;
237 // fFrameBandwidth[n] holds the available bandwidth
238 // of the nth frame in microseconds
239 uint16 * fFrameBandwidth;
241 // Maintain a linked list of isochronous transfers
242 isochronous_transfer_data * fFirstIsochronousTransfer;
243 isochronous_transfer_data * fLastIsochronousTransfer;
244 sem_id fFinishIsochronousTransfersSem;
245 thread_id fFinishIsochronousThread;
246 mutex fIsochronousLock;
248 // Root Hub
249 EHCIRootHub * fRootHub;
250 uint8 fRootHubAddress;
252 // Port management
253 uint8 fPortCount;
254 uint16 fPortResetChange;
255 uint16 fPortSuspendChange;
257 // Interrupt polling
258 thread_id fInterruptPollThread;
259 uint8 fIRQ;
260 bool fUseMSI;
264 class EHCIRootHub : public Hub {
265 public:
266 EHCIRootHub(Object *rootObject,
267 int8 deviceAddress);
269 static status_t ProcessTransfer(EHCI *ehci,
270 Transfer *transfer);
274 #endif // !EHCI_H