Sync with trunk head.
[reactos.git] / drivers / usb / usbehci / usbehci.h
1 #pragma once
2
3 #include <ntifs.h>
4 #include <ntddk.h>
5 #include <stdio.h>
6 #define NDEBUG
7 #include <debug.h>
8 #include "usbiffn.h"
9 #include <usbioctl.h>
10 #include <usb.h>
11
12 #define DEVICEINTIALIZED 0x01
13 #define DEVICESTARTED 0x02
14 #define DEVICEBUSY 0x04
15 #define DEVICESTOPPED 0x08
16
17
18 #define MAX_USB_DEVICES 127
19 #define EHCI_MAX_SIZE_TRANSFER 0x100000
20
21 /* USB Command Register */
22 #define EHCI_USBCMD 0x00
23 #define EHCI_USBSTS 0x04
24 #define EHCI_USBINTR 0x08
25 #define EHCI_FRINDEX 0x0C
26 #define EHCI_CTRLDSSEGMENT 0x10
27 #define EHCI_PERIODICLISTBASE 0x14
28 #define EHCI_ASYNCLISTBASE 0x18
29 #define EHCI_CONFIGFLAG 0x40
30 #define EHCI_PORTSC 0x44
31
32 /* USB Interrupt Register Flags 32 Bits */
33 #define EHCI_USBINTR_INTE 0x01
34 #define EHCI_USBINTR_ERR 0x02
35 #define EHCI_USBINTR_PC 0x04
36 #define EHCI_USBINTR_FLROVR 0x08
37 #define EHCI_USBINTR_HSERR 0x10
38 #define EHCI_USBINTR_ASYNC 0x20
39 /* Bits 6:31 Reserved */
40
41 /* Status Register Flags 32 Bits */
42 #define EHCI_STS_INT 0x01
43 #define EHCI_STS_ERR 0x02
44 #define EHCI_STS_PCD 0x04
45 #define EHCI_STS_FLR 0x08
46 #define EHCI_STS_FATAL 0x10
47 #define EHCI_STS_IAA 0x20
48 /* Bits 11:6 Reserved */
49 #define EHCI_STS_HALT 0x1000
50 #define EHCI_STS_RECL 0x2000
51 #define EHCI_STS_PSS 0x4000
52 #define EHCI_STS_ASS 0x8000
53 #define EHCI_ERROR_INT ( EHCI_STS_FATAL | EHCI_STS_ERR )
54
55
56 /* Last bit in QUEUE ELEMENT TRANSFER DESCRIPTOR Next Pointer */
57 /* Used for Queue Element Transfer Descriptor Pointers
58 and Queue Head Horizontal Link Pointers */
59 #define TERMINATE_POINTER 0x01
60
61 /* QUEUE ELEMENT TRANSFER DESCRIPTOR, Token defines and structs */
62
63 /* PIDCodes for QETD_TOKEN
64 OR with QUEUE_TRANSFER_DESCRIPTOR Token.PIDCode*/
65 #define PID_CODE_OUT_TOKEN 0x00
66 #define PID_CODE_IN_TOKEN 0x01
67 #define PID_CODE_SETUP_TOKEN 0x02
68
69 /* Split Transaction States
70 OR with QUEUE_TRANSFER_DESCRIPTOR Token.SplitTransactionState */
71 #define DO_START_SPLIT 0x00
72 #define DO_COMPLETE_SPLIT 0x01
73
74 /* Ping States, OR with QUEUE_TRANSFER_DESCRIPTOR Token. */
75 #define PING_STATE_DO_OUT 0x00
76 #define PING_STATE_DO_PING 0x01
77
78 /* QUEUE ELEMENT TRANSFER DESCRIPTOR TOKEN */
79 typedef struct _QETD_TOKEN_BITS
80 {
81 ULONG PingState:1;
82 ULONG SplitTransactionState:1;
83 ULONG MissedMicroFrame:1;
84 ULONG TransactionError:1;
85 ULONG BabbelDetected:1;
86 ULONG DataBufferError:1;
87 ULONG Halted:1;
88 ULONG Active:1;
89 ULONG PIDCode:2;
90 ULONG ErrorCounter:2;
91 ULONG CurrentPage:3;
92 ULONG InterruptOnComplete:1;
93 ULONG TotalBytesToTransfer:15;
94 ULONG DataToggle:1;
95 } QETD_TOKEN_BITS, *PQETD_TOKEN_BITS;
96
97
98 /* QUEUE ELEMENT TRANSFER DESCRIPTOR */
99 typedef struct _QUEUE_TRANSFER_DESCRIPTOR
100 {
101 ULONG NextPointer;
102 ULONG AlternateNextPointer;
103 union
104 {
105 QETD_TOKEN_BITS Bits;
106 ULONG DWord;
107 } Token;
108 ULONG BufferPointer[5];
109 } QUEUE_TRANSFER_DESCRIPTOR, *PQUEUE_TRANSFER_DESCRIPTOR;
110
111 /* EndPointSpeeds of END_POINT_CAPABILITIES */
112 #define QH_ENDPOINT_FULLSPEED 0x00
113 #define QH_ENDPOINT_LOWSPEED 0x01
114 #define QH_ENDPOINT_HIGHSPEED 0x02
115
116 typedef struct _END_POINT_CAPABILITIES1
117 {
118 ULONG DeviceAddress:7;
119 ULONG InactiveOnNextTransaction:1;
120 ULONG EndPointNumber:4;
121 ULONG EndPointSpeed:2;
122 ULONG QEDTDataToggleControl:1;
123 ULONG HeadOfReclamation:1;
124 ULONG MaximumPacketLength:11;
125 ULONG ControlEndPointFlag:1;
126 ULONG NakCountReload:4;
127 } END_POINT_CAPABILITIES1, *PEND_POINT_CAPABILITIES1;
128
129 typedef struct _END_POINT_CAPABILITIES2
130 {
131 ULONG InterruptScheduleMask:8;
132 ULONG SplitCompletionMask:8;
133 ULONG HubAddr:6;
134 ULONG PortNumber:6;
135 /* Multi */
136 ULONG NumberOfTransactionPerFrame:2;
137 } END_POINT_CAPABILITIES2, *PEND_POINT_CAPABILITIES2;
138
139
140 /* QUEUE HEAD defines and structs */
141
142 /* QUEUE HEAD Select Types, OR with QUEUE_HEAD HorizontalLinkPointer */
143 #define QH_TYPE_IDT 0x00
144 #define QH_TYPE_QH 0x02
145 #define QH_TYPE_SITD 0x04
146 #define QH_TYPE_FSTN 0x06
147
148 /* QUEUE HEAD */
149 typedef struct _QUEUE_HEAD
150 {
151 ULONG HorizontalLinkPointer;
152 END_POINT_CAPABILITIES1 EndPointCapabilities1;
153 END_POINT_CAPABILITIES2 EndPointCapabilities2;
154 /* TERMINATE_POINTER not valid for this member */
155 ULONG CurrentLinkPointer;
156 /* TERMINATE_POINTER valid */
157 ULONG QETDPointer;
158 /* TERMINATE_POINTER valid, bits 1:4 is NAK_COUNTER */
159 ULONG AlternateNextPointer;
160 /* Only DataToggle, InterruptOnComplete, ErrorCounter, PingState valid */
161 union
162 {
163 QETD_TOKEN_BITS Bits;
164 ULONG DWord;
165 } Token;
166 ULONG BufferPointer[5];
167 } QUEUE_HEAD, *PQUEUE_HEAD;
168
169 typedef struct _EHCI_SETUP_FORMAT
170 {
171 UCHAR bmRequestType;
172 UCHAR bRequest;
173 USHORT wValue;
174 USHORT wIndex;
175 USHORT wLength;
176 } EHCI_SETUP_FORMAT, *PEHCI_SETUP_FORMAT;
177
178 typedef struct _STRING_DESCRIPTOR
179 {
180 UCHAR bLength; /* Size of this descriptor in bytes */
181 UCHAR bDescriptorType; /* STRING Descriptor Type */
182 UCHAR bString[0]; /* UNICODE encoded string */
183 } STRING_DESCRIPTOR, *PSTRING_DESCRIPTOR;
184
185 typedef struct _USB_DEVICE
186 {
187 UCHAR Address;
188 ULONG Port;
189 PVOID ParentDevice;
190 BOOLEAN IsHub;
191 USB_DEVICE_DESCRIPTOR DeviceDescriptor;
192 USB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor;
193 USB_INTERFACE_DESCRIPTOR InterfaceDescriptor;
194 USB_ENDPOINT_DESCRIPTOR EndPointDescriptor;
195 } USB_DEVICE, *PUSB_DEVICE;
196
197 /* USBCMD register 32 bits */
198 typedef struct _EHCI_USBCMD_CONTENT
199 {
200 ULONG Run : 1;
201 ULONG HCReset : 1;
202 ULONG FrameListSize : 2;
203 ULONG PeriodicEnable : 1;
204 ULONG AsyncEnable : 1;
205 ULONG DoorBell : 1;
206 ULONG LightReset : 1;
207 ULONG AsyncParkCount : 2;
208 ULONG Reserved : 1;
209 ULONG AsyncParkEnable : 1;
210 ULONG Reserved1 : 4;
211 ULONG IntThreshold : 8;
212 ULONG Reserved2 : 8;
213
214 } EHCI_USBCMD_CONTENT, *PEHCI_USBCMD_CONTENT;
215
216 typedef struct _EHCI_USBSTS_CONTENT
217 {
218 ULONG USBInterrupt:1;
219 ULONG ErrorInterrupt:1;
220 ULONG DetectChangeInterrupt:1;
221 ULONG FrameListRolloverInterrupt:1;
222 ULONG HostSystemErrorInterrupt:1;
223 ULONG AsyncAdvanceInterrupt:1;
224 ULONG Reserved:6;
225 ULONG HCHalted:1;
226 ULONG Reclamation:1;
227 ULONG PeriodicScheduleStatus:1;
228 ULONG AsynchronousScheduleStatus:1;
229 } EHCI_USBSTS_CONTEXT, *PEHCI_USBSTS_CONTEXT;
230
231 typedef struct _EHCI_USBPORTSC_CONTENT
232 {
233 ULONG CurrentConnectStatus:1;
234 ULONG ConnectStatusChange:1;
235 ULONG PortEnabled:1;
236 ULONG PortEnableChanged:1;
237 ULONG OverCurrentActive:1;
238 ULONG OverCurrentChange:1;
239 ULONG ForcePortResume:1;
240 ULONG Suspend:1;
241 ULONG PortReset:1;
242 ULONG Reserved:1;
243 ULONG LineStatus:2;
244 ULONG PortPower:1;
245 ULONG PortOwner:1;
246 } EHCI_USBPORTSC_CONTENT, *PEHCI_USBPORTSC_CONTENT;
247
248 typedef struct _EHCI_HCS_CONTENT
249 {
250 ULONG PortCount : 4;
251 ULONG PortPowerControl: 1;
252 ULONG Reserved : 2;
253 ULONG PortRouteRules : 1;
254 ULONG PortPerCHC : 4;
255 ULONG CHCCount : 4;
256 ULONG PortIndicator : 1;
257 ULONG Reserved2 : 3;
258 ULONG DbgPortNum : 4;
259 ULONG Reserved3 : 8;
260
261 } EHCI_HCS_CONTENT, *PEHCI_HCS_CONTENT;
262
263 typedef struct _EHCI_HCC_CONTENT
264 {
265 ULONG CurAddrBits : 1;
266 ULONG VarFrameList : 1;
267 ULONG ParkMode : 1;
268 ULONG Reserved : 1;
269 ULONG IsoSchedThreshold : 4;
270 ULONG EECPCapable : 8;
271 ULONG Reserved2 : 16;
272
273 } EHCI_HCC_CONTENT, *PEHCI_HCC_CONTENT;
274
275 typedef struct _EHCI_CAPS {
276 UCHAR Length;
277 UCHAR Reserved;
278 USHORT HCIVersion;
279 union
280 {
281 EHCI_HCS_CONTENT HCSParams;
282 ULONG HCSParamsLong;
283 };
284 ULONG HCCParams;
285 UCHAR PortRoute [8];
286 } EHCI_CAPS, *PEHCI_CAPS;
287
288 typedef struct _COMMON_DEVICE_EXTENSION
289 {
290 BOOLEAN IsFdo;
291 PDRIVER_OBJECT DriverObject;
292 PDEVICE_OBJECT DeviceObject;
293 } COMMON_DEVICE_EXTENSION, *PCOMMON_DEVICE_EXTENSION;
294
295 typedef struct _FDO_DEVICE_EXTENSION
296 {
297 COMMON_DEVICE_EXTENSION Common;
298 PDRIVER_OBJECT DriverObject;
299 PDEVICE_OBJECT DeviceObject;
300 PDEVICE_OBJECT LowerDevice;
301 PDEVICE_OBJECT Pdo;
302 ULONG DeviceState;
303
304 PVOID RootHubDeviceHandle;
305 PDMA_ADAPTER pDmaAdapter;
306
307 ULONG Vector;
308 KIRQL Irql;
309
310 KINTERRUPT_MODE Mode;
311 BOOLEAN IrqShared;
312 PKINTERRUPT EhciInterrupt;
313 KDPC DpcObject;
314 KAFFINITY Affinity;
315
316 ULONG MapRegisters;
317
318 ULONG BusNumber;
319 ULONG BusAddress;
320 ULONG PCIAddress;
321 USHORT VendorId;
322 USHORT DeviceId;
323
324 BUS_INTERFACE_STANDARD BusInterface;
325
326 EHCI_CAPS ECHICaps;
327
328 union
329 {
330 PULONG ResourcePort;
331 PULONG ResourceMemory;
332 };
333
334 PULONG PeriodicFramList;
335 PULONG AsyncListQueueHeadPtr;
336 PHYSICAL_ADDRESS PeriodicFramListPhysAddr;
337 PHYSICAL_ADDRESS AsyncListQueueHeadPtrPhysAddr;
338
339 BOOLEAN AsyncComplete;
340
341 PULONG ResourceBase;
342 ULONG Size;
343 } FDO_DEVICE_EXTENSION, *PFDO_DEVICE_EXTENSION;
344
345 typedef struct _PDO_DEVICE_EXTENSION
346 {
347 COMMON_DEVICE_EXTENSION Common;
348 PDEVICE_OBJECT DeviceObject;
349 PDEVICE_OBJECT ControllerFdo;
350 PUSB_DEVICE UsbDevices[127];
351 LIST_ENTRY IrpQueue;
352 KSPIN_LOCK IrpQueueLock;
353 PIRP CurrentIrp;
354 HANDLE ThreadHandle;
355 ULONG ChildDeviceCount;
356 BOOLEAN HaltUrbHandling;
357 PVOID CallbackContext;
358 PRH_INIT_CALLBACK CallbackRoutine;
359 } PDO_DEVICE_EXTENSION, *PPDO_DEVICE_EXTENSION;
360
361 typedef struct _WORKITEM_DATA
362 {
363 PIO_WORKITEM IoWorkItem;
364 PPDO_DEVICE_EXTENSION PdoDeviceExtension;
365 PDEVICE_OBJECT PortDeviceObject;
366 } WORKITEM_DATA, *PWORKITEM_DATA;
367
368
369 VOID NTAPI
370 UrbWorkerThread(PVOID Context);
371
372 NTSTATUS NTAPI
373 GetBusInterface(PDEVICE_OBJECT pcifido, PBUS_INTERFACE_STANDARD busInterface);
374
375 NTSTATUS NTAPI
376 ForwardAndWaitCompletionRoutine(PDEVICE_OBJECT DeviceObject, PIRP Irp, PKEVENT Event);
377
378 NTSTATUS NTAPI
379 ForwardAndWait(PDEVICE_OBJECT DeviceObject, PIRP Irp);
380
381 NTSTATUS NTAPI
382 ForwardIrpAndForget(PDEVICE_OBJECT DeviceObject,PIRP Irp);
383
384 NTSTATUS NTAPI
385 FdoDispatchPnp(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp);
386
387 NTSTATUS NTAPI
388 PdoDispatchPnp(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp);
389
390 NTSTATUS NTAPI
391 AddDevice(PDRIVER_OBJECT DriverObject, PDEVICE_OBJECT Pdo);
392
393 NTSTATUS
394 DuplicateUnicodeString(ULONG Flags, PCUNICODE_STRING SourceString, PUNICODE_STRING DestinationString);
395
396 PWSTR
397 GetSymbolicName(PDEVICE_OBJECT DeviceObject);
398
399 PWSTR
400 GetPhysicalDeviceObjectName(PDEVICE_OBJECT DeviceObject);
401
402 NTSTATUS NTAPI
403 PdoDispatchInternalDeviceControl(PDEVICE_OBJECT DeviceObject, PIRP Irp);
404
405 BOOLEAN
406 GetDeviceDescriptor(PFDO_DEVICE_EXTENSION DeviceExtension, UCHAR Index, PUSB_DEVICE_DESCRIPTOR OutBuffer, BOOLEAN Hub);
407
408 BOOLEAN
409 GetDeviceStringDescriptor(PFDO_DEVICE_EXTENSION DeviceExtension, UCHAR Index);
410
411 VOID
412 QueueURBRequest(PPDO_DEVICE_EXTENSION DeviceExtension, PIRP Irp);
413
414 VOID
415 CompletePendingURBRequest(PPDO_DEVICE_EXTENSION DeviceExtension);
416
417 VOID
418 URBRequestCancel (PDEVICE_OBJECT DeviceObject, PIRP Irp);
419
420 VOID NTAPI
421 DeviceArrivalWorkItem(PDEVICE_OBJECT DeviceObject, PVOID Context);