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