vfs: check userland buffers before reading them.
[haiku.git] / src / add-ons / kernel / busses / usb / uhci.h
blobd46d4809fb79b14be2c2ca66aedee7dc7be8b9dc
1 /*
2 * Copyright 2004-2011, Haiku Inc. All rights reserved.
3 * Distributed under the terms of the MIT License.
5 * Authors:
6 * Michael Lotz <mmlr@mlotz.ch>
7 * Niels S. Reedijk
8 * Salvatore Benedetto <salvatore.benedetto@gmail.com>
9 */
10 #ifndef UHCI_H
11 #define UHCI_H
13 #include "usb_private.h"
14 #include "uhci_hardware.h"
15 #include <lock.h>
17 #define UHCI_INTERRUPT_QUEUE 0
18 #define UHCI_LOW_SPEED_CONTROL_QUEUE 1
19 #define UHCI_FULL_SPEED_CONTROL_QUEUE 2
20 #define UHCI_BULK_QUEUE 3
21 #define UHCI_BANDWIDTH_RECLAMATION_QUEUE 4
22 #define UHCI_DEBUG_QUEUE 4
24 struct pci_info;
25 struct pci_module_info;
26 struct pci_x86_module_info;
28 class UHCIRootHub;
31 class Queue {
32 public:
33 Queue(Stack *stack);
34 ~Queue();
36 bool Lock();
37 void Unlock();
39 status_t InitCheck();
41 status_t LinkTo(Queue *other);
42 status_t TerminateByStrayDescriptor();
44 status_t AppendTransfer(uhci_qh *transfer,
45 bool lock = true);
46 status_t RemoveTransfer(uhci_qh *transfer,
47 bool lock = true);
49 uint32 PhysicalAddress();
51 void PrintToStream();
53 usb_id USBID() { return 0; };
54 const char * TypeName() { return "uhci"; };
56 private:
57 status_t fStatus;
58 Stack * fStack;
59 uhci_qh * fQueueHead;
60 uhci_td * fStrayDescriptor;
61 uhci_qh * fQueueTop;
62 mutex fLock;
66 typedef struct transfer_data {
67 Transfer * transfer;
68 Queue * queue;
69 uhci_qh * transfer_queue;
70 uhci_td * first_descriptor;
71 uhci_td * data_descriptor;
72 bool incoming;
73 bool canceled;
74 uint16 free_after_frame;
75 transfer_data * link;
76 } transfer_data;
79 // This structure is used to create a list of
80 // descriptors per isochronous transfer
81 typedef struct isochronous_transfer_data {
82 Transfer * transfer;
83 // The next field is used to keep track
84 // of every isochronous descriptor as they are NOT
85 // linked to each other in a queue like in every other
86 // transfer type
87 uhci_td ** descriptors;
88 uint16 last_to_process;
89 bool incoming;
90 bool is_active;
91 isochronous_transfer_data * link;
92 } isochronous_transfer_data;
95 class UHCI : public BusManager {
96 public:
97 UHCI(pci_info *info, Stack *stack);
98 ~UHCI();
100 status_t Start();
101 virtual status_t SubmitTransfer(Transfer *transfer);
103 virtual status_t StartDebugTransfer(Transfer *transfer);
104 virtual status_t CheckDebugTransfer(Transfer *transfer);
105 virtual void CancelDebugTransfer(Transfer *transfer);
107 virtual status_t CancelQueuedTransfers(Pipe *pipe, bool force);
108 status_t CancelQueuedIsochronousTransfers(Pipe *pipe, bool force);
109 status_t SubmitRequest(Transfer *transfer);
110 status_t SubmitIsochronous(Transfer *transfer);
112 static status_t AddTo(Stack *stack);
114 // Port operations
115 status_t GetPortStatus(uint8 index, usb_port_status *status);
116 status_t SetPortFeature(uint8 index, uint16 feature);
117 status_t ClearPortFeature(uint8 index, uint16 feature);
119 status_t ResetPort(uint8 index);
121 virtual const char * TypeName() const { return "uhci"; };
123 private:
124 // Controller resets
125 void GlobalReset();
126 status_t ControllerReset();
128 // Interrupt functions
129 static int32 InterruptHandler(void *data);
130 int32 Interrupt();
132 // Transfer functions
133 status_t AddPendingTransfer(Transfer *transfer,
134 Queue *queue,
135 uhci_qh *transferQueue,
136 uhci_td *firstDescriptor,
137 uhci_td *dataDescriptor,
138 bool directionIn);
139 status_t AddPendingIsochronousTransfer(
140 Transfer *transfer,
141 uhci_td **isoRequest,
142 bool directionIn);
144 static int32 FinishThread(void *data);
145 void FinishTransfers();
147 void AddToFreeList(transfer_data *transfer);
148 static int32 CleanupThread(void *data);
149 void Cleanup();
151 status_t CreateFilledTransfer(Transfer *transfer,
152 uhci_td **_firstDescriptor,
153 uhci_qh **_transferQueue);
155 // Isochronous transfer functions
156 static int32 FinishIsochronousThread(void *data);
157 void FinishIsochronousTransfers();
158 isochronous_transfer_data * FindIsochronousTransfer(uhci_td *descriptor);
160 status_t LinkIsochronousDescriptor(
161 uhci_td *descriptor,
162 uint16 frame);
163 uhci_td * UnlinkIsochronousDescriptor(uint16 frame);
165 // Transfer queue functions
166 uhci_qh * CreateTransferQueue(uhci_td *descriptor);
167 void FreeTransferQueue(uhci_qh *queueHead);
169 bool LockIsochronous();
170 void UnlockIsochronous();
172 // Descriptor functions
173 uhci_td * CreateDescriptor(Pipe *pipe,
174 uint8 direction,
175 size_t bufferSizeToAllocate);
176 status_t CreateDescriptorChain(Pipe *pipe,
177 uhci_td **firstDescriptor,
178 uhci_td **lastDescriptor,
179 uint8 direction,
180 size_t bufferSizeToAllocate);
182 void FreeDescriptor(uhci_td *descriptor);
183 void FreeDescriptorChain(uhci_td *topDescriptor);
185 void LinkDescriptors(uhci_td *first,
186 uhci_td *second);
188 size_t WriteDescriptorChain(uhci_td *topDescriptor,
189 iovec *vector, size_t vectorCount);
190 size_t ReadDescriptorChain(uhci_td *topDescriptor,
191 iovec *vector, size_t vectorCount,
192 uint8 *lastDataToggle);
193 size_t ReadActualLength(uhci_td *topDescriptor,
194 uint8 *lastDataToggle);
195 void WriteIsochronousDescriptorChain(
196 uhci_td **isoRequest,
197 uint32 packetCount,
198 iovec *vector);
199 void ReadIsochronousDescriptorChain(
200 isochronous_transfer_data *transfer,
201 iovec *vector);
203 // Register functions
204 inline void WriteReg8(uint32 reg, uint8 value);
205 inline void WriteReg16(uint32 reg, uint16 value);
206 inline void WriteReg32(uint32 reg, uint32 value);
207 inline uint8 ReadReg8(uint32 reg);
208 inline uint16 ReadReg16(uint32 reg);
209 inline uint32 ReadReg32(uint32 reg);
211 static pci_module_info * sPCIModule;
212 static pci_x86_module_info * sPCIx86Module;
214 uint32 fRegisterBase;
215 pci_info * fPCIInfo;
216 Stack * fStack;
217 uint32 fEnabledInterrupts;
219 // Frame list memory
220 area_id fFrameArea;
221 uint32 * fFrameList;
223 // fFrameBandwidth[n] holds the available bandwidth
224 // of the nth frame in microseconds
225 uint16 * fFrameBandwidth;
227 // fFirstIsochronousTransfer[n] and fLastIsochronousDescriptor[n]
228 // keeps track of the first and last isochronous transfer descriptor
229 // in the nth frame
230 uhci_td ** fFirstIsochronousDescriptor;
231 uhci_td ** fLastIsochronousDescriptor;
233 // Queues
234 int32 fQueueCount;
235 Queue ** fQueues;
237 // Maintain a linked list of transfers
238 transfer_data * fFirstTransfer;
239 transfer_data * fLastTransfer;
240 sem_id fFinishTransfersSem;
241 thread_id fFinishThread;
242 bool fStopThreads;
243 Pipe * fProcessingPipe;
245 transfer_data * fFreeList;
246 thread_id fCleanupThread;
247 sem_id fCleanupSem;
248 int32 fCleanupCount;
250 // Maintain a linked list of isochronous transfers
251 isochronous_transfer_data * fFirstIsochronousTransfer;
252 isochronous_transfer_data * fLastIsochronousTransfer;
253 sem_id fFinishIsochronousTransfersSem;
254 thread_id fFinishIsochronousThread;
255 mutex fIsochronousLock;
257 // Root hub
258 UHCIRootHub * fRootHub;
259 uint8 fRootHubAddress;
260 uint8 fPortResetChange;
262 uint8 fIRQ;
263 bool fUseMSI;
267 class UHCIRootHub : public Hub {
268 public:
269 UHCIRootHub(Object *rootObject,
270 int8 deviceAddress);
272 static status_t ProcessTransfer(UHCI *uhci,
273 Transfer *transfer);
277 #endif