12 #define DEVICEINTIALIZED 0x01
13 #define DEVICESTARTED 0x02
14 #define DEVICEBUSY 0x04
15 #define DEVICESTOPPED 0x08
18 #define MAX_USB_DEVICES 127
19 #define EHCI_MAX_SIZE_TRANSFER 0x100000
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
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 */
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 )
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
61 /* QUEUE ELEMENT TRANSFER DESCRIPTOR, Token defines and structs */
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
69 /* Split Transaction States
70 OR with QUEUE_TRANSFER_DESCRIPTOR Token.SplitTransactionState */
71 #define DO_START_SPLIT 0x00
72 #define DO_COMPLETE_SPLIT 0x01
74 /* Ping States, OR with QUEUE_TRANSFER_DESCRIPTOR Token. */
75 #define PING_STATE_DO_OUT 0x00
76 #define PING_STATE_DO_PING 0x01
78 #define C_HUB_LOCAL_POWER 0
79 #define C_HUB_OVER_CURRENT 1
80 #define PORT_CONNECTION 0
82 #define PORT_SUSPEND 2
83 #define PORT_OVER_CURRENT 3
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
94 #define PORT_INDICATOR 22
95 #define USB_PORT_STATUS_CHANGE 0x4000
97 /* QUEUE ELEMENT TRANSFER DESCRIPTOR TOKEN */
98 typedef struct _QETD_TOKEN_BITS
101 ULONG SplitTransactionState
:1;
102 ULONG MissedMicroFrame
:1;
103 ULONG TransactionError
:1;
104 ULONG BabbelDetected
:1;
105 ULONG DataBufferError
:1;
109 ULONG ErrorCounter
:2;
111 ULONG InterruptOnComplete
:1;
112 ULONG TotalBytesToTransfer
:15;
114 } QETD_TOKEN_BITS
, *PQETD_TOKEN_BITS
;
117 /* QUEUE ELEMENT TRANSFER DESCRIPTOR */
118 typedef struct _QUEUE_TRANSFER_DESCRIPTOR
121 ULONG AlternateNextPointer
;
124 QETD_TOKEN_BITS Bits
;
127 ULONG BufferPointer
[5];
128 } QUEUE_TRANSFER_DESCRIPTOR
, *PQUEUE_TRANSFER_DESCRIPTOR
;
130 /* EndPointSpeeds of END_POINT_CAPABILITIES */
131 #define QH_ENDPOINT_FULLSPEED 0x00
132 #define QH_ENDPOINT_LOWSPEED 0x01
133 #define QH_ENDPOINT_HIGHSPEED 0x02
135 typedef struct _END_POINT_CAPABILITIES1
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
;
148 typedef struct _END_POINT_CAPABILITIES2
150 ULONG InterruptScheduleMask
:8;
151 ULONG SplitCompletionMask
:8;
155 ULONG NumberOfTransactionPerFrame
:2;
156 } END_POINT_CAPABILITIES2
, *PEND_POINT_CAPABILITIES2
;
159 /* QUEUE HEAD defines and structs */
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
168 typedef struct _QUEUE_HEAD
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 */
177 /* TERMINATE_POINTER valid, bits 1:4 is NAK_COUNTER */
178 ULONG AlternateNextPointer
;
179 /* Only DataToggle, InterruptOnComplete, ErrorCounter, PingState valid */
182 QETD_TOKEN_BITS Bits
;
185 ULONG BufferPointer
[5];
186 } QUEUE_HEAD
, *PQUEUE_HEAD
;
188 typedef struct _EHCI_SETUP_FORMAT
195 } EHCI_SETUP_FORMAT
, *PEHCI_SETUP_FORMAT
;
197 typedef struct _STRING_DESCRIPTOR
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
;
204 typedef struct _USB_DEVICE
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
;
216 /* USBCMD register 32 bits */
217 typedef struct _EHCI_USBCMD_CONTENT
221 ULONG FrameListSize
: 2;
222 ULONG PeriodicEnable
: 1;
223 ULONG AsyncEnable
: 1;
225 ULONG LightReset
: 1;
226 ULONG AsyncParkCount
: 2;
228 ULONG AsyncParkEnable
: 1;
230 ULONG IntThreshold
: 8;
233 } EHCI_USBCMD_CONTENT
, *PEHCI_USBCMD_CONTENT
;
235 typedef struct _EHCI_USBSTS_CONTENT
237 ULONG USBInterrupt
:1;
238 ULONG ErrorInterrupt
:1;
239 ULONG DetectChangeInterrupt
:1;
240 ULONG FrameListRolloverInterrupt
:1;
241 ULONG HostSystemErrorInterrupt
:1;
242 ULONG AsyncAdvanceInterrupt
:1;
246 ULONG PeriodicScheduleStatus
:1;
247 ULONG AsynchronousScheduleStatus
:1;
248 } EHCI_USBSTS_CONTEXT
, *PEHCI_USBSTS_CONTEXT
;
250 typedef struct _EHCI_USBPORTSC_CONTENT
252 ULONG CurrentConnectStatus
:1;
253 ULONG ConnectStatusChange
:1;
255 ULONG PortEnableChanged
:1;
256 ULONG OverCurrentActive
:1;
257 ULONG OverCurrentChange
:1;
258 ULONG ForcePortResume
:1;
265 } EHCI_USBPORTSC_CONTENT
, *PEHCI_USBPORTSC_CONTENT
;
267 typedef struct _EHCI_HCS_CONTENT
270 ULONG PortPowerControl
: 1;
272 ULONG PortRouteRules
: 1;
273 ULONG PortPerCHC
: 4;
275 ULONG PortIndicator
: 1;
277 ULONG DbgPortNum
: 4;
280 } EHCI_HCS_CONTENT
, *PEHCI_HCS_CONTENT
;
282 typedef struct _EHCI_HCC_CONTENT
284 ULONG CurAddrBits
: 1;
285 ULONG VarFrameList
: 1;
288 ULONG IsoSchedThreshold
: 4;
289 ULONG EECPCapable
: 8;
290 ULONG Reserved2
: 16;
292 } EHCI_HCC_CONTENT
, *PEHCI_HCC_CONTENT
;
294 typedef struct _EHCI_CAPS
{
300 EHCI_HCS_CONTENT HCSParams
;
305 } EHCI_CAPS
, *PEHCI_CAPS
;
307 typedef struct _COMMON_DEVICE_EXTENSION
310 PDRIVER_OBJECT DriverObject
;
311 PDEVICE_OBJECT DeviceObject
;
312 } COMMON_DEVICE_EXTENSION
, *PCOMMON_DEVICE_EXTENSION
;
314 typedef struct _EHCIPORTS
320 } EHCIPORTS
, *PEHCIPORTS
;
322 typedef struct _FDO_DEVICE_EXTENSION
324 COMMON_DEVICE_EXTENSION Common
;
325 PDRIVER_OBJECT DriverObject
;
326 PDEVICE_OBJECT DeviceObject
;
327 PDEVICE_OBJECT LowerDevice
;
331 PVOID RootHubDeviceHandle
;
332 PDMA_ADAPTER pDmaAdapter
;
337 KINTERRUPT_MODE Mode
;
339 PKINTERRUPT EhciInterrupt
;
351 BUS_INTERFACE_STANDARD BusInterface
;
358 PULONG ResourceMemory
;
361 PULONG PeriodicFramList
;
362 PULONG AsyncListQueueHeadPtr
;
363 PHYSICAL_ADDRESS PeriodicFramListPhysAddr
;
364 PHYSICAL_ADDRESS AsyncListQueueHeadPtrPhysAddr
;
366 BOOLEAN AsyncComplete
;
370 } FDO_DEVICE_EXTENSION
, *PFDO_DEVICE_EXTENSION
;
372 typedef struct _PDO_DEVICE_EXTENSION
374 COMMON_DEVICE_EXTENSION Common
;
375 PDEVICE_OBJECT DeviceObject
;
376 PDEVICE_OBJECT ControllerFdo
;
377 PUSB_DEVICE UsbDevices
[127];
379 KSPIN_LOCK IrpQueueLock
;
382 ULONG ChildDeviceCount
;
383 BOOLEAN HaltUrbHandling
;
384 PVOID CallbackContext
;
385 PRH_INIT_CALLBACK CallbackRoutine
;
388 } PDO_DEVICE_EXTENSION
, *PPDO_DEVICE_EXTENSION
;
390 typedef struct _WORKITEM_DATA
392 PIO_WORKITEM IoWorkItem
;
393 PPDO_DEVICE_EXTENSION PdoDeviceExtension
;
394 PDEVICE_OBJECT PortDeviceObject
;
395 } WORKITEM_DATA
, *PWORKITEM_DATA
;
399 UrbWorkerThread(PVOID Context
);
402 GetBusInterface(PDEVICE_OBJECT pcifido
, PBUS_INTERFACE_STANDARD busInterface
);
405 ForwardAndWaitCompletionRoutine(PDEVICE_OBJECT DeviceObject
, PIRP Irp
, PKEVENT Event
);
408 ForwardAndWait(PDEVICE_OBJECT DeviceObject
, PIRP Irp
);
411 ForwardIrpAndForget(PDEVICE_OBJECT DeviceObject
,PIRP Irp
);
414 FdoDispatchPnp(IN PDEVICE_OBJECT DeviceObject
, IN PIRP Irp
);
417 PdoDispatchPnp(IN PDEVICE_OBJECT DeviceObject
, IN PIRP Irp
);
420 AddDevice(PDRIVER_OBJECT DriverObject
, PDEVICE_OBJECT Pdo
);
423 DuplicateUnicodeString(ULONG Flags
, PCUNICODE_STRING SourceString
, PUNICODE_STRING DestinationString
);
426 GetSymbolicName(PDEVICE_OBJECT DeviceObject
);
429 GetPhysicalDeviceObjectName(PDEVICE_OBJECT DeviceObject
);
432 PdoDispatchInternalDeviceControl(PDEVICE_OBJECT DeviceObject
, PIRP Irp
);
435 GetDeviceDescriptor(PFDO_DEVICE_EXTENSION DeviceExtension
, UCHAR Index
, PUSB_DEVICE_DESCRIPTOR OutBuffer
, BOOLEAN Hub
);
438 GetDeviceStringDescriptor(PFDO_DEVICE_EXTENSION DeviceExtension
, UCHAR Index
);
441 QueueURBRequest(PPDO_DEVICE_EXTENSION DeviceExtension
, PIRP Irp
);
444 CompletePendingURBRequest(PPDO_DEVICE_EXTENSION DeviceExtension
);
447 URBRequestCancel (PDEVICE_OBJECT DeviceObject
, PIRP Irp
);
450 DeviceArrivalWorkItem(PDEVICE_OBJECT DeviceObject
, PVOID Context
);