12 #define USB_POOL_TAG (ULONG)'UsbR'
14 #define DEVICEINTIALIZED 0x01
15 #define DEVICESTARTED 0x02
16 #define DEVICEBUSY 0x04
17 #define DEVICESTOPPED 0x08
20 #define MAX_USB_DEVICES 127
21 #define EHCI_MAX_SIZE_TRANSFER 0x100000
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
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 */
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 )
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
63 /* QUEUE ELEMENT TRANSFER DESCRIPTOR, Token defines and structs */
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
71 /* Split Transaction States
72 OR with QUEUE_TRANSFER_DESCRIPTOR Token.SplitTransactionState */
73 #define DO_START_SPLIT 0x00
74 #define DO_COMPLETE_SPLIT 0x01
76 /* Ping States, OR with QUEUE_TRANSFER_DESCRIPTOR Token. */
77 #define PING_STATE_DO_OUT 0x00
78 #define PING_STATE_DO_PING 0x01
80 #define C_HUB_LOCAL_POWER 0
81 #define C_HUB_OVER_CURRENT 1
82 #define PORT_CONNECTION 0
84 #define PORT_SUSPEND 2
85 #define PORT_OVER_CURRENT 3
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
96 #define PORT_INDICATOR 22
97 #define USB_PORT_STATUS_CHANGE 0x4000
99 /* QUEUE ELEMENT TRANSFER DESCRIPTOR TOKEN */
100 typedef struct _QETD_TOKEN_BITS
103 ULONG SplitTransactionState
:1;
104 ULONG MissedMicroFrame
:1;
105 ULONG TransactionError
:1;
106 ULONG BabbelDetected
:1;
107 ULONG DataBufferError
:1;
111 ULONG ErrorCounter
:2;
113 ULONG InterruptOnComplete
:1;
114 ULONG TotalBytesToTransfer
:15;
116 } QETD_TOKEN_BITS
, *PQETD_TOKEN_BITS
;
119 /* QUEUE ELEMENT TRANSFER DESCRIPTOR */
120 typedef struct _QUEUE_TRANSFER_DESCRIPTOR
123 ULONG AlternateNextPointer
;
126 QETD_TOKEN_BITS Bits
;
129 ULONG BufferPointer
[5];
130 } QUEUE_TRANSFER_DESCRIPTOR
, *PQUEUE_TRANSFER_DESCRIPTOR
;
132 /* EndPointSpeeds of END_POINT_CAPABILITIES */
133 #define QH_ENDPOINT_FULLSPEED 0x00
134 #define QH_ENDPOINT_LOWSPEED 0x01
135 #define QH_ENDPOINT_HIGHSPEED 0x02
137 typedef struct _END_POINT_CAPABILITIES1
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
;
150 typedef struct _END_POINT_CAPABILITIES2
152 ULONG InterruptScheduleMask
:8;
153 ULONG SplitCompletionMask
:8;
157 ULONG NumberOfTransactionPerFrame
:2;
158 } END_POINT_CAPABILITIES2
, *PEND_POINT_CAPABILITIES2
;
161 /* QUEUE HEAD defines and structs */
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
170 typedef struct _QUEUE_HEAD
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 */
179 /* TERMINATE_POINTER valid, bits 1:4 is NAK_COUNTER */
180 ULONG AlternateNextPointer
;
181 /* Only DataToggle, InterruptOnComplete, ErrorCounter, PingState valid */
184 QETD_TOKEN_BITS Bits
;
187 ULONG BufferPointer
[5];
188 } QUEUE_HEAD
, *PQUEUE_HEAD
;
190 typedef struct _EHCI_SETUP_FORMAT
197 } EHCI_SETUP_FORMAT
, *PEHCI_SETUP_FORMAT
;
199 typedef struct _STRING_DESCRIPTOR
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
;
206 typedef struct _USB_ENDPOINT
210 struct _USB_INTERFACE
*Interface
;
211 USB_ENDPOINT_DESCRIPTOR EndPointDescriptor
;
212 } USB_ENDPOINT
, *PUSB_ENDPOINT
;
214 typedef struct _USB_INTERFACE
216 struct _USB_CONFIGURATION
*Config
;
217 USB_INTERFACE_DESCRIPTOR InterfaceDescriptor
;
218 USB_ENDPOINT
*EndPoints
[];
219 } USB_INTERFACE
, *PUSB_INTERFACE
;
221 typedef struct _USB_CONFIGURATION
223 struct _USB_DEVICE
*Device
;
224 USB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor
;
225 USB_INTERFACE
*Interfaces
[];
226 } USB_CONFIGURATION
, *PUSB_CONFIGURATION
;
228 typedef struct _USB_DEVICE
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
;
241 } USB_DEVICE
, *PUSB_DEVICE
;
243 /* USBCMD register 32 bits */
244 typedef struct _EHCI_USBCMD_CONTENT
248 ULONG FrameListSize
: 2;
249 ULONG PeriodicEnable
: 1;
250 ULONG AsyncEnable
: 1;
252 ULONG LightReset
: 1;
253 ULONG AsyncParkCount
: 2;
255 ULONG AsyncParkEnable
: 1;
257 ULONG IntThreshold
: 8;
260 } EHCI_USBCMD_CONTENT
, *PEHCI_USBCMD_CONTENT
;
262 typedef struct _EHCI_USBSTS_CONTENT
264 ULONG USBInterrupt
:1;
265 ULONG ErrorInterrupt
:1;
266 ULONG DetectChangeInterrupt
:1;
267 ULONG FrameListRolloverInterrupt
:1;
268 ULONG HostSystemErrorInterrupt
:1;
269 ULONG AsyncAdvanceInterrupt
:1;
273 ULONG PeriodicScheduleStatus
:1;
274 ULONG AsynchronousScheduleStatus
:1;
275 } EHCI_USBSTS_CONTEXT
, *PEHCI_USBSTS_CONTEXT
;
277 typedef struct _EHCI_USBPORTSC_CONTENT
279 ULONG CurrentConnectStatus
:1;
280 ULONG ConnectStatusChange
:1;
282 ULONG PortEnableChanged
:1;
283 ULONG OverCurrentActive
:1;
284 ULONG OverCurrentChange
:1;
285 ULONG ForcePortResume
:1;
292 } EHCI_USBPORTSC_CONTENT
, *PEHCI_USBPORTSC_CONTENT
;
294 typedef struct _EHCI_HCS_CONTENT
297 ULONG PortPowerControl
: 1;
299 ULONG PortRouteRules
: 1;
300 ULONG PortPerCHC
: 4;
302 ULONG PortIndicator
: 1;
304 ULONG DbgPortNum
: 4;
307 } EHCI_HCS_CONTENT
, *PEHCI_HCS_CONTENT
;
309 typedef struct _EHCI_HCC_CONTENT
311 ULONG CurAddrBits
: 1;
312 ULONG VarFrameList
: 1;
315 ULONG IsoSchedThreshold
: 4;
316 ULONG EECPCapable
: 8;
317 ULONG Reserved2
: 16;
319 } EHCI_HCC_CONTENT
, *PEHCI_HCC_CONTENT
;
321 typedef struct _EHCI_CAPS
{
327 EHCI_HCS_CONTENT HCSParams
;
332 } EHCI_CAPS
, *PEHCI_CAPS
;
334 typedef struct _COMMON_DEVICE_EXTENSION
337 PDRIVER_OBJECT DriverObject
;
338 PDEVICE_OBJECT DeviceObject
;
339 } COMMON_DEVICE_EXTENSION
, *PCOMMON_DEVICE_EXTENSION
;
341 typedef struct _EHCIPORTS
347 } EHCIPORTS
, *PEHCIPORTS
;
349 typedef struct _FDO_DEVICE_EXTENSION
351 COMMON_DEVICE_EXTENSION Common
;
352 PDRIVER_OBJECT DriverObject
;
353 PDEVICE_OBJECT DeviceObject
;
354 PDEVICE_OBJECT LowerDevice
;
358 PVOID RootHubDeviceHandle
;
359 PDMA_ADAPTER pDmaAdapter
;
364 KINTERRUPT_MODE Mode
;
366 PKINTERRUPT EhciInterrupt
;
378 BUS_INTERFACE_STANDARD BusInterface
;
385 PULONG ResourceMemory
;
388 PULONG PeriodicFramList
;
389 PULONG AsyncListQueueHeadPtr
;
390 PHYSICAL_ADDRESS PeriodicFramListPhysAddr
;
391 PHYSICAL_ADDRESS AsyncListQueueHeadPtrPhysAddr
;
393 BOOLEAN AsyncComplete
;
397 } FDO_DEVICE_EXTENSION
, *PFDO_DEVICE_EXTENSION
;
399 typedef struct _PDO_DEVICE_EXTENSION
401 COMMON_DEVICE_EXTENSION Common
;
402 PDEVICE_OBJECT DeviceObject
;
403 PDEVICE_OBJECT ControllerFdo
;
404 PUSB_DEVICE UsbDevices
[127];
406 KSPIN_LOCK IrpQueueLock
;
409 ULONG ChildDeviceCount
;
411 PVOID CallbackContext
;
412 RH_INIT_CALLBACK
*CallbackRoutine
;
413 USB_IDLE_CALLBACK IdleCallback
;
418 KEVENT QueueDrainedEvent
;
420 } PDO_DEVICE_EXTENSION
, *PPDO_DEVICE_EXTENSION
;
422 typedef struct _WORKITEM_DATA
424 PIO_WORKITEM IoWorkItem
;
425 PPDO_DEVICE_EXTENSION PdoDeviceExtension
;
426 PDEVICE_OBJECT PortDeviceObject
;
427 } WORKITEM_DATA
, *PWORKITEM_DATA
;
431 UrbWorkerThread(PVOID Context
);
434 GetBusInterface(PDEVICE_OBJECT pcifido
, PBUS_INTERFACE_STANDARD busInterface
);
437 ForwardAndWaitCompletionRoutine(PDEVICE_OBJECT DeviceObject
, PIRP Irp
, PKEVENT Event
);
440 ForwardAndWait(PDEVICE_OBJECT DeviceObject
, PIRP Irp
);
443 ForwardIrpAndForget(PDEVICE_OBJECT DeviceObject
,PIRP Irp
);
446 FdoDispatchPnp(IN PDEVICE_OBJECT DeviceObject
, IN PIRP Irp
);
449 PdoDispatchPnp(IN PDEVICE_OBJECT DeviceObject
, IN PIRP Irp
);
452 AddDevice(PDRIVER_OBJECT DriverObject
, PDEVICE_OBJECT Pdo
);
455 DuplicateUnicodeString(ULONG Flags
, PCUNICODE_STRING SourceString
, PUNICODE_STRING DestinationString
);
458 GetSymbolicName(PDEVICE_OBJECT DeviceObject
);
461 GetPhysicalDeviceObjectName(PDEVICE_OBJECT DeviceObject
);
464 PdoDispatchInternalDeviceControl(PDEVICE_OBJECT DeviceObject
, PIRP Irp
);
467 ExecuteControlRequest(PFDO_DEVICE_EXTENSION DeviceExtension
, PUSB_DEFAULT_PIPE_SETUP_PACKET SetupPacket
, UCHAR Address
, ULONG Port
, PVOID Buffer
, ULONG BufferLength
);
470 QueueURBRequest(PPDO_DEVICE_EXTENSION DeviceExtension
, PIRP Irp
);
473 CompletePendingURBRequest(PPDO_DEVICE_EXTENSION DeviceExtension
);
476 URBRequestCancel (PDEVICE_OBJECT DeviceObject
, PIRP Irp
);
479 DeviceArrivalWorkItem(PDEVICE_OBJECT DeviceObject
, PVOID Context
);