Sync with trunk head (part 1 or 2)
[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 #define C_HUB_LOCAL_POWER 0
79 #define C_HUB_OVER_CURRENT 1
80 #define PORT_CONNECTION 0
81 #define PORT_ENABLE 1
82 #define PORT_SUSPEND 2
83 #define PORT_OVER_CURRENT 3
84 #define PORT_RESET 4
85 #define PORT_POWER 8
86 #define PORT_LOW_SPEED 9
87 #define PORT_HIGH_SPEED 9
88 #define C_PORT_CONNECTION 16
89 #define C_PORT_ENABLE 17
90 #define C_PORT_SUSPEND 18
91 #define C_PORT_OVER_CURRENT 19
92 #define C_PORT_RESET 20
93 #define PORT_TEST 21
94 #define PORT_INDICATOR 22
95 #define USB_PORT_STATUS_CHANGE 0x4000
96
97 /* QUEUE ELEMENT TRANSFER DESCRIPTOR TOKEN */
98 typedef struct _QETD_TOKEN_BITS
99 {
100 ULONG PingState:1;
101 ULONG SplitTransactionState:1;
102 ULONG MissedMicroFrame:1;
103 ULONG TransactionError:1;
104 ULONG BabbelDetected:1;
105 ULONG DataBufferError:1;
106 ULONG Halted:1;
107 ULONG Active:1;
108 ULONG PIDCode:2;
109 ULONG ErrorCounter:2;
110 ULONG CurrentPage:3;
111 ULONG InterruptOnComplete:1;
112 ULONG TotalBytesToTransfer:15;
113 ULONG DataToggle:1;
114 } QETD_TOKEN_BITS, *PQETD_TOKEN_BITS;
115
116
117 /* QUEUE ELEMENT TRANSFER DESCRIPTOR */
118 typedef struct _QUEUE_TRANSFER_DESCRIPTOR
119 {
120 ULONG NextPointer;
121 ULONG AlternateNextPointer;
122 union
123 {
124 QETD_TOKEN_BITS Bits;
125 ULONG DWord;
126 } Token;
127 ULONG BufferPointer[5];
128 } QUEUE_TRANSFER_DESCRIPTOR, *PQUEUE_TRANSFER_DESCRIPTOR;
129
130 /* EndPointSpeeds of END_POINT_CAPABILITIES */
131 #define QH_ENDPOINT_FULLSPEED 0x00
132 #define QH_ENDPOINT_LOWSPEED 0x01
133 #define QH_ENDPOINT_HIGHSPEED 0x02
134
135 typedef struct _END_POINT_CAPABILITIES1
136 {
137 ULONG DeviceAddress:7;
138 ULONG InactiveOnNextTransaction:1;
139 ULONG EndPointNumber:4;
140 ULONG EndPointSpeed:2;
141 ULONG QEDTDataToggleControl:1;
142 ULONG HeadOfReclamation:1;
143 ULONG MaximumPacketLength:11;
144 ULONG ControlEndPointFlag:1;
145 ULONG NakCountReload:4;
146 } END_POINT_CAPABILITIES1, *PEND_POINT_CAPABILITIES1;
147
148 typedef struct _END_POINT_CAPABILITIES2
149 {
150 ULONG InterruptScheduleMask:8;
151 ULONG SplitCompletionMask:8;
152 ULONG HubAddr:6;
153 ULONG PortNumber:6;
154 /* Multi */
155 ULONG NumberOfTransactionPerFrame:2;
156 } END_POINT_CAPABILITIES2, *PEND_POINT_CAPABILITIES2;
157
158
159 /* QUEUE HEAD defines and structs */
160
161 /* QUEUE HEAD Select Types, OR with QUEUE_HEAD HorizontalLinkPointer */
162 #define QH_TYPE_IDT 0x00
163 #define QH_TYPE_QH 0x02
164 #define QH_TYPE_SITD 0x04
165 #define QH_TYPE_FSTN 0x06
166
167 /* QUEUE HEAD */
168 typedef struct _QUEUE_HEAD
169 {
170 ULONG HorizontalLinkPointer;
171 END_POINT_CAPABILITIES1 EndPointCapabilities1;
172 END_POINT_CAPABILITIES2 EndPointCapabilities2;
173 /* TERMINATE_POINTER not valid for this member */
174 ULONG CurrentLinkPointer;
175 /* TERMINATE_POINTER valid */
176 ULONG QETDPointer;
177 /* TERMINATE_POINTER valid, bits 1:4 is NAK_COUNTER */
178 ULONG AlternateNextPointer;
179 /* Only DataToggle, InterruptOnComplete, ErrorCounter, PingState valid */
180 union
181 {
182 QETD_TOKEN_BITS Bits;
183 ULONG DWord;
184 } Token;
185 ULONG BufferPointer[5];
186 } QUEUE_HEAD, *PQUEUE_HEAD;
187
188 typedef struct _EHCI_SETUP_FORMAT
189 {
190 UCHAR bmRequestType;
191 UCHAR bRequest;
192 USHORT wValue;
193 USHORT wIndex;
194 USHORT wLength;
195 } EHCI_SETUP_FORMAT, *PEHCI_SETUP_FORMAT;
196
197 typedef struct _STRING_DESCRIPTOR
198 {
199 UCHAR bLength; /* Size of this descriptor in bytes */
200 UCHAR bDescriptorType; /* STRING Descriptor Type */
201 UCHAR bString[0]; /* UNICODE encoded string */
202 } STRING_DESCRIPTOR, *PSTRING_DESCRIPTOR;
203
204 typedef struct _USB_DEVICE
205 {
206 UCHAR Address;
207 ULONG Port;
208 PVOID ParentDevice;
209 BOOLEAN IsHub;
210 USB_DEVICE_DESCRIPTOR DeviceDescriptor;
211 USB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor;
212 USB_INTERFACE_DESCRIPTOR InterfaceDescriptor;
213 USB_ENDPOINT_DESCRIPTOR EndPointDescriptor;
214 } USB_DEVICE, *PUSB_DEVICE;
215
216 /* USBCMD register 32 bits */
217 typedef struct _EHCI_USBCMD_CONTENT
218 {
219 ULONG Run : 1;
220 ULONG HCReset : 1;
221 ULONG FrameListSize : 2;
222 ULONG PeriodicEnable : 1;
223 ULONG AsyncEnable : 1;
224 ULONG DoorBell : 1;
225 ULONG LightReset : 1;
226 ULONG AsyncParkCount : 2;
227 ULONG Reserved : 1;
228 ULONG AsyncParkEnable : 1;
229 ULONG Reserved1 : 4;
230 ULONG IntThreshold : 8;
231 ULONG Reserved2 : 8;
232
233 } EHCI_USBCMD_CONTENT, *PEHCI_USBCMD_CONTENT;
234
235 typedef struct _EHCI_USBSTS_CONTENT
236 {
237 ULONG USBInterrupt:1;
238 ULONG ErrorInterrupt:1;
239 ULONG DetectChangeInterrupt:1;
240 ULONG FrameListRolloverInterrupt:1;
241 ULONG HostSystemErrorInterrupt:1;
242 ULONG AsyncAdvanceInterrupt:1;
243 ULONG Reserved:6;
244 ULONG HCHalted:1;
245 ULONG Reclamation:1;
246 ULONG PeriodicScheduleStatus:1;
247 ULONG AsynchronousScheduleStatus:1;
248 } EHCI_USBSTS_CONTEXT, *PEHCI_USBSTS_CONTEXT;
249
250 typedef struct _EHCI_USBPORTSC_CONTENT
251 {
252 ULONG CurrentConnectStatus:1;
253 ULONG ConnectStatusChange:1;
254 ULONG PortEnabled:1;
255 ULONG PortEnableChanged:1;
256 ULONG OverCurrentActive:1;
257 ULONG OverCurrentChange:1;
258 ULONG ForcePortResume:1;
259 ULONG Suspend:1;
260 ULONG PortReset:1;
261 ULONG Reserved:1;
262 ULONG LineStatus:2;
263 ULONG PortPower:1;
264 ULONG PortOwner:1;
265 } EHCI_USBPORTSC_CONTENT, *PEHCI_USBPORTSC_CONTENT;
266
267 typedef struct _EHCI_HCS_CONTENT
268 {
269 ULONG PortCount : 4;
270 ULONG PortPowerControl: 1;
271 ULONG Reserved : 2;
272 ULONG PortRouteRules : 1;
273 ULONG PortPerCHC : 4;
274 ULONG CHCCount : 4;
275 ULONG PortIndicator : 1;
276 ULONG Reserved2 : 3;
277 ULONG DbgPortNum : 4;
278 ULONG Reserved3 : 8;
279
280 } EHCI_HCS_CONTENT, *PEHCI_HCS_CONTENT;
281
282 typedef struct _EHCI_HCC_CONTENT
283 {
284 ULONG CurAddrBits : 1;
285 ULONG VarFrameList : 1;
286 ULONG ParkMode : 1;
287 ULONG Reserved : 1;
288 ULONG IsoSchedThreshold : 4;
289 ULONG EECPCapable : 8;
290 ULONG Reserved2 : 16;
291
292 } EHCI_HCC_CONTENT, *PEHCI_HCC_CONTENT;
293
294 typedef struct _EHCI_CAPS {
295 UCHAR Length;
296 UCHAR Reserved;
297 USHORT HCIVersion;
298 union
299 {
300 EHCI_HCS_CONTENT HCSParams;
301 ULONG HCSParamsLong;
302 };
303 ULONG HCCParams;
304 UCHAR PortRoute [8];
305 } EHCI_CAPS, *PEHCI_CAPS;
306
307 typedef struct _COMMON_DEVICE_EXTENSION
308 {
309 BOOLEAN IsFdo;
310 PDRIVER_OBJECT DriverObject;
311 PDEVICE_OBJECT DeviceObject;
312 } COMMON_DEVICE_EXTENSION, *PCOMMON_DEVICE_EXTENSION;
313
314 typedef struct _EHCIPORTS
315 {
316 ULONG PortNumber;
317 ULONG PortType;
318 USHORT PortStatus;
319 USHORT PortChange;
320 } EHCIPORTS, *PEHCIPORTS;
321
322 typedef struct _FDO_DEVICE_EXTENSION
323 {
324 COMMON_DEVICE_EXTENSION Common;
325 PDRIVER_OBJECT DriverObject;
326 PDEVICE_OBJECT DeviceObject;
327 PDEVICE_OBJECT LowerDevice;
328 PDEVICE_OBJECT Pdo;
329 ULONG DeviceState;
330
331 PVOID RootHubDeviceHandle;
332 PDMA_ADAPTER pDmaAdapter;
333
334 ULONG Vector;
335 KIRQL Irql;
336
337 KINTERRUPT_MODE Mode;
338 BOOLEAN IrqShared;
339 PKINTERRUPT EhciInterrupt;
340 KDPC DpcObject;
341 KAFFINITY Affinity;
342
343 ULONG MapRegisters;
344
345 ULONG BusNumber;
346 ULONG BusAddress;
347 ULONG PCIAddress;
348 USHORT VendorId;
349 USHORT DeviceId;
350
351 BUS_INTERFACE_STANDARD BusInterface;
352
353 EHCI_CAPS ECHICaps;
354
355 union
356 {
357 PULONG ResourcePort;
358 PULONG ResourceMemory;
359 };
360
361 PULONG PeriodicFramList;
362 PULONG AsyncListQueueHeadPtr;
363 PHYSICAL_ADDRESS PeriodicFramListPhysAddr;
364 PHYSICAL_ADDRESS AsyncListQueueHeadPtrPhysAddr;
365
366 BOOLEAN AsyncComplete;
367
368 PULONG ResourceBase;
369 ULONG Size;
370 } FDO_DEVICE_EXTENSION, *PFDO_DEVICE_EXTENSION;
371
372 typedef struct _PDO_DEVICE_EXTENSION
373 {
374 COMMON_DEVICE_EXTENSION Common;
375 PDEVICE_OBJECT DeviceObject;
376 PDEVICE_OBJECT ControllerFdo;
377 PUSB_DEVICE UsbDevices[127];
378 LIST_ENTRY IrpQueue;
379 KSPIN_LOCK IrpQueueLock;
380 PIRP CurrentIrp;
381 HANDLE ThreadHandle;
382 ULONG ChildDeviceCount;
383 BOOLEAN HaltUrbHandling;
384 PVOID CallbackContext;
385 PRH_INIT_CALLBACK CallbackRoutine;
386 ULONG NumberOfPorts;
387 EHCIPORTS Ports[32];
388 } PDO_DEVICE_EXTENSION, *PPDO_DEVICE_EXTENSION;
389
390 typedef struct _WORKITEM_DATA
391 {
392 PIO_WORKITEM IoWorkItem;
393 PPDO_DEVICE_EXTENSION PdoDeviceExtension;
394 PDEVICE_OBJECT PortDeviceObject;
395 } WORKITEM_DATA, *PWORKITEM_DATA;
396
397
398 VOID NTAPI
399 UrbWorkerThread(PVOID Context);
400
401 NTSTATUS NTAPI
402 GetBusInterface(PDEVICE_OBJECT pcifido, PBUS_INTERFACE_STANDARD busInterface);
403
404 NTSTATUS NTAPI
405 ForwardAndWaitCompletionRoutine(PDEVICE_OBJECT DeviceObject, PIRP Irp, PKEVENT Event);
406
407 NTSTATUS NTAPI
408 ForwardAndWait(PDEVICE_OBJECT DeviceObject, PIRP Irp);
409
410 NTSTATUS NTAPI
411 ForwardIrpAndForget(PDEVICE_OBJECT DeviceObject,PIRP Irp);
412
413 NTSTATUS NTAPI
414 FdoDispatchPnp(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp);
415
416 NTSTATUS NTAPI
417 PdoDispatchPnp(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp);
418
419 NTSTATUS NTAPI
420 AddDevice(PDRIVER_OBJECT DriverObject, PDEVICE_OBJECT Pdo);
421
422 NTSTATUS
423 DuplicateUnicodeString(ULONG Flags, PCUNICODE_STRING SourceString, PUNICODE_STRING DestinationString);
424
425 PWSTR
426 GetSymbolicName(PDEVICE_OBJECT DeviceObject);
427
428 PWSTR
429 GetPhysicalDeviceObjectName(PDEVICE_OBJECT DeviceObject);
430
431 NTSTATUS NTAPI
432 PdoDispatchInternalDeviceControl(PDEVICE_OBJECT DeviceObject, PIRP Irp);
433
434 BOOLEAN
435 GetDeviceDescriptor(PFDO_DEVICE_EXTENSION DeviceExtension, UCHAR Index, PUSB_DEVICE_DESCRIPTOR OutBuffer, BOOLEAN Hub);
436
437 BOOLEAN
438 GetDeviceStringDescriptor(PFDO_DEVICE_EXTENSION DeviceExtension, UCHAR Index);
439
440 VOID
441 QueueURBRequest(PPDO_DEVICE_EXTENSION DeviceExtension, PIRP Irp);
442
443 VOID
444 CompletePendingURBRequest(PPDO_DEVICE_EXTENSION DeviceExtension);
445
446 VOID
447 URBRequestCancel (PDEVICE_OBJECT DeviceObject, PIRP Irp);
448
449 VOID NTAPI
450 DeviceArrivalWorkItem(PDEVICE_OBJECT DeviceObject, PVOID Context);