2 * PROJECT: ReactOS USB Hub Driver
3 * LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
4 * PURPOSE: USBHub declarations
5 * COPYRIGHT: Copyright 2017 Vadim Galyant <vgal@rambler.ru>
17 #include <ntstrsafe.h>
24 #include <drivers/usbport/usbmport.h>
26 #define USB_HUB_TAG 'BUHU'
28 #define USBH_EXTENSION_TYPE_HUB 0x01
29 #define USBH_EXTENSION_TYPE_PORT 0x02
30 #define USBH_EXTENSION_TYPE_PARENT 0x04
31 #define USBH_EXTENSION_TYPE_FUNCTION 0x08
33 #define USBHUB_FDO_FLAG_DEVICE_STARTED (1 << 0)
34 #define USBHUB_FDO_FLAG_DEVICE_STOPPING (1 << 2)
35 #define USBHUB_FDO_FLAG_DEVICE_FAILED (1 << 3)
36 #define USBHUB_FDO_FLAG_REMOTE_WAKEUP (1 << 4)
37 #define USBHUB_FDO_FLAG_DEVICE_STOPPED (1 << 5)
38 #define USBHUB_FDO_FLAG_HUB_BUSY (1 << 6)
39 #define USBHUB_FDO_FLAG_PENDING_WAKE_IRP (1 << 7)
40 #define USBHUB_FDO_FLAG_RESET_PORT_LOCK (1 << 8)
41 #define USBHUB_FDO_FLAG_ESD_RECOVERING (1 << 9)
42 #define USBHUB_FDO_FLAG_SET_D0_STATE (1 << 10)
43 #define USBHUB_FDO_FLAG_NOT_D0_STATE (1 << 11)
44 #define USBHUB_FDO_FLAG_WAIT_IDLE_REQUEST (1 << 12)
45 #define USBHUB_FDO_FLAG_STATE_CHANGING (1 << 13)
46 #define USBHUB_FDO_FLAG_DEVICE_REMOVED (1 << 14)
47 #define USBHUB_FDO_FLAG_USB20_HUB (1 << 15)
48 #define USBHUB_FDO_FLAG_DEFER_CHECK_IDLE (1 << 16)
49 #define USBHUB_FDO_FLAG_WAKEUP_START (1 << 17)
50 #define USBHUB_FDO_FLAG_MULTIPLE_TTS (1 << 18) // High-speed Operating Hub with Multiple TTs
51 #define USBHUB_FDO_FLAG_ENUM_POST_RECOVER (1 << 19)
52 #define USBHUB_FDO_FLAG_DO_ENUMERATION (1 << 20)
53 #define USBHUB_FDO_FLAG_CHECK_IDLE_LOCK (1 << 21)
54 #define USBHUB_FDO_FLAG_HIBERNATE_STATE (1 << 22)
55 #define USBHUB_FDO_FLAG_NOT_ENUMERATED (1 << 23)
56 #define USBHUB_FDO_FLAG_DO_SUSPENSE (1 << 24)
57 #define USBHUB_FDO_FLAG_GOING_IDLE (1 << 25)
58 #define USBHUB_FDO_FLAG_DEVICE_SUSPENDED (1 << 26)
59 #define USBHUB_FDO_FLAG_WITEM_INIT (1 << 27)
61 #define USBHUB_PDO_FLAG_HUB_DEVICE (1 << 0)
62 #define USBHUB_PDO_FLAG_MULTI_INTERFACE (1 << 1)
63 #define USBHUB_PDO_FLAG_INIT_PORT_FAILED (1 << 2)
64 #define USBHUB_PDO_FLAG_PORT_LOW_SPEED (1 << 3)
65 #define USBHUB_PDO_FLAG_REMOTE_WAKEUP (1 << 4)
66 #define USBHUB_PDO_FLAG_WAIT_WAKE (1 << 5)
67 #define USBHUB_PDO_FLAG_NOT_CONNECTED (1 << 6)
68 #define USBHUB_PDO_FLAG_DELETE_PENDING (1 << 7)
69 #define USBHUB_PDO_FLAG_POWER_D3 (1 << 8)
70 #define USBHUB_PDO_FLAG_DEVICE_STARTED (1 << 9)
71 #define USBHUB_PDO_FLAG_HS_USB1_DUALMODE (1 << 10)
72 #define USBHUB_PDO_FLAG_REG_DEV_INTERFACE (1 << 11) // SymbolicLink
73 #define USBHUB_PDO_FLAG_PORT_RESTORE_FAIL (1 << 12)
74 #define USBHUB_PDO_FLAG_POWER_D1_OR_D2 (1 << 13)
75 #define USBHUB_PDO_FLAG_OVERCURRENT_PORT (1 << 14)
76 #define USBHUB_PDO_FLAG_REMOVING_PORT_PDO (1 << 15)
77 #define USBHUB_PDO_FLAG_INSUFFICIENT_PWR (1 << 16)
78 #define USBHUB_PDO_FLAG_ALLOC_BNDW_FAILED (1 << 18)
79 #define USBHUB_PDO_FLAG_PORT_RESSETING (1 << 19)
80 #define USBHUB_PDO_FLAG_IDLE_NOTIFICATION (1 << 22)
81 #define USBHUB_PDO_FLAG_PORT_HIGH_SPEED (1 << 23)
82 #define USBHUB_PDO_FLAG_ENUMERATED (1 << 26)
84 #define USBHUB_ENUM_FLAG_DEVICE_PRESENT 0x01
85 #define USBHUB_ENUM_FLAG_GHOST_DEVICE 0x02
87 /* Hub Class Feature Selectors */
88 #define USBHUB_FEATURE_C_HUB_LOCAL_POWER 0
89 #define USBHUB_FEATURE_C_HUB_OVER_CURRENT 1
91 #define USBHUB_FEATURE_PORT_CONNECTION 0
92 #define USBHUB_FEATURE_PORT_ENABLE 1
93 #define USBHUB_FEATURE_PORT_SUSPEND 2
94 #define USBHUB_FEATURE_PORT_OVER_CURRENT 3
95 #define USBHUB_FEATURE_PORT_RESET 4
96 #define USBHUB_FEATURE_PORT_POWER 8
97 #define USBHUB_FEATURE_PORT_LOW_SPEED 9
98 #define USBHUB_FEATURE_C_PORT_CONNECTION 16
99 #define USBHUB_FEATURE_C_PORT_ENABLE 17
100 #define USBHUB_FEATURE_C_PORT_SUSPEND 18
101 #define USBHUB_FEATURE_C_PORT_OVER_CURRENT 19
102 #define USBHUB_FEATURE_C_PORT_RESET 20
103 #define USBHUB_FEATURE_PORT_TEST 21
104 #define USBHUB_FEATURE_PORT_INDICATOR 22
106 #define USBHUB_MAX_CASCADE_LEVELS 6
107 #define USBHUB_RESET_PORT_MAX_RETRY 3
108 #define USBHUB_MAX_REQUEST_ERRORS 3
111 #define USBHUB_FAIL_NO_FAIL 5
112 #define USBHUB_FAIL_NESTED_TOO_DEEPLY 6
113 #define USBHUB_FAIL_OVERCURRENT 7
115 extern PWSTR GenericUSBDeviceString
;
117 typedef struct _USBHUB_PORT_DATA
{
118 USB_PORT_STATUS_AND_CHANGE PortStatus
;
119 PDEVICE_OBJECT DeviceObject
;
120 USB_CONNECTION_STATUS ConnectionStatus
;
121 ULONG PortAttributes
;
122 } USBHUB_PORT_DATA
, *PUSBHUB_PORT_DATA
;
124 typedef struct _USBHUB_FDO_EXTENSION
*PUSBHUB_FDO_EXTENSION
;
127 (NTAPI
* PUSBHUB_WORKER_ROUTINE
)(
128 IN PUSBHUB_FDO_EXTENSION HubExtension
,
131 typedef struct _USBHUB_IO_WORK_ITEM
{
133 LIST_ENTRY HubWorkItemLink
;
134 LONG HubWorkerQueued
;
135 PIO_WORKITEM HubWorkItem
;
136 WORK_QUEUE_TYPE HubWorkItemType
;
137 PUSBHUB_FDO_EXTENSION HubExtension
;
138 PUSBHUB_WORKER_ROUTINE HubWorkerRoutine
;
139 PVOID HubWorkItemBuffer
;
140 } USBHUB_IO_WORK_ITEM
, *PUSBHUB_IO_WORK_ITEM
;
142 typedef struct _COMMON_DEVICE_EXTENSION
{
144 PDEVICE_OBJECT SelfDevice
;
145 } COMMON_DEVICE_EXTENSION
, *PCOMMON_DEVICE_EXTENSION
;
147 typedef struct _USBHUB_FDO_EXTENSION
{
148 COMMON_DEVICE_EXTENSION Common
;
149 PDEVICE_OBJECT LowerPDO
;
150 PDEVICE_OBJECT LowerDevice
;
151 PDEVICE_OBJECT RootHubPdo
;
152 PDEVICE_OBJECT RootHubPdo2
;
153 KEVENT LowerDeviceEvent
;
155 USB_BUS_INTERFACE_HUB_V5 BusInterface
;
156 USB_BUS_INTERFACE_USBDI_V2 BusInterfaceUSBDI
;
157 DEVICE_POWER_STATE DeviceState
[POWER_SYSTEM_MAXIMUM
];
158 SYSTEM_POWER_STATE SystemWake
;
159 DEVICE_POWER_STATE DeviceWake
;
160 POWER_STATE CurrentPowerState
;
161 POWER_STATE SystemPowerState
;
162 ULONG MaxPowerPerPort
;
163 USB_DEVICE_DESCRIPTOR HubDeviceDescriptor
;
165 PUSB_CONFIGURATION_DESCRIPTOR HubConfigDescriptor
;
166 PUSB_HUB_DESCRIPTOR HubDescriptor
;
167 PUSBHUB_PORT_DATA PortData
;
168 USBD_CONFIGURATION_HANDLE ConfigHandle
;
169 USBD_PIPE_INFORMATION PipeInfo
;
172 PVOID SCEBitmap
; // 11.12.4 Hub and Port Status Change Bitmap (USB 2.0 Specification)
173 ULONG SCEBitmapLength
;
174 KEVENT RootHubNotificationEvent
;
175 struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST SCEWorkerUrb
;
176 KEVENT StatusChangeEvent
;
177 KSEMAPHORE IdleSemaphore
;
178 KSPIN_LOCK RelationsWorkerSpinLock
;
180 LONG PendingRequestCount
;
181 KEVENT PendingRequestEvent
;
182 KSEMAPHORE ResetDeviceSemaphore
;
183 PRKEVENT pResetPortEvent
;
184 KSEMAPHORE HubPortSemaphore
;
185 LONG ResetRequestCount
;
189 LONG FdoWaitWakeLock
;
190 LIST_ENTRY WorkItemList
;
191 KSPIN_LOCK WorkItemSpinLock
;
192 KSPIN_LOCK CheckIdleSpinLock
;
194 LONG IdleRequestLock
;
196 KSEMAPHORE HubSemaphore
;
197 PUSBHUB_IO_WORK_ITEM WorkItemToQueue
;
198 USB_IDLE_CALLBACK_INFO IdleCallbackInfo
;
199 USB_PORT_STATUS_AND_CHANGE PortStatus
;
201 } USBHUB_FDO_EXTENSION
, *PUSBHUB_FDO_EXTENSION
;
203 typedef struct _USBHUB_PORT_PDO_EXTENSION
{
204 COMMON_DEVICE_EXTENSION Common
;
207 UNICODE_STRING SymbolicLinkName
;
209 PUSBHUB_FDO_EXTENSION HubExtension
;
210 PUSBHUB_FDO_EXTENSION RootHubExtension
;
211 PUSB_DEVICE_HANDLE DeviceHandle
;
213 USHORT SN_DescriptorLength
;
214 BOOL IgnoringHwSerial
;
215 LPWSTR SerialNumber
; // serial number string
216 USB_DEVICE_DESCRIPTOR DeviceDescriptor
;
217 USB_DEVICE_DESCRIPTOR OldDeviceDescriptor
;
218 USB_CONFIGURATION_DESCRIPTOR ConfigDescriptor
;
219 USB_INTERFACE_DESCRIPTOR InterfaceDescriptor
;
221 PIRP IdleNotificationIrp
;
222 POWER_STATE CurrentPowerState
;
223 DEVICE_CAPABILITIES Capabilities
;
225 PVOID BndwTimeoutContext
;
226 KSPIN_LOCK PortTimeoutSpinLock
;
228 LONG PoRequestCounter
;
229 LONG PendingSystemPoRequest
;
230 LONG PendingDevicePoRequest
;
233 LIST_ENTRY PortPowerList
;
234 KSPIN_LOCK PortPowerListSpinLock
;
235 } USBHUB_PORT_PDO_EXTENSION
, *PUSBHUB_PORT_PDO_EXTENSION
;
237 typedef struct _USBHUB_URB_TIMEOUT_CONTEXT
{
239 KEVENT UrbTimeoutEvent
;
241 KTIMER UrbTimeoutTimer
;
242 KSPIN_LOCK UrbTimeoutSpinLock
;
243 BOOL IsNormalCompleted
;
244 } USBHUB_URB_TIMEOUT_CONTEXT
, *PUSBHUB_URB_TIMEOUT_CONTEXT
;
246 typedef struct _USBHUB_STATUS_CHANGE_CONTEXT
{
248 BOOL IsRequestErrors
;
249 PUSBHUB_FDO_EXTENSION HubExtension
;
250 } USBHUB_STATUS_CHANGE_CONTEXT
, *PUSBHUB_STATUS_CHANGE_CONTEXT
;
252 typedef struct _USBHUB_IDLE_HUB_CONTEXT
{
255 } USBHUB_IDLE_HUB_CONTEXT
, *PUSBHUB_IDLE_HUB_CONTEXT
;
257 typedef struct _USBHUB_IDLE_PORT_CONTEXT
{
261 } USBHUB_IDLE_PORT_CONTEXT
, *PUSBHUB_IDLE_PORT_CONTEXT
;
263 typedef struct _USBHUB_IDLE_PORT_CANCEL_CONTEXT
{
266 } USBHUB_IDLE_PORT_CANCEL_CONTEXT
, *PUSBHUB_IDLE_PORT_CANCEL_CONTEXT
;
268 typedef struct _USBHUB_RESET_PORT_CONTEXT
{
270 PUSBHUB_PORT_PDO_EXTENSION PortExtension
;
272 } USBHUB_RESET_PORT_CONTEXT
, *PUSBHUB_RESET_PORT_CONTEXT
;
277 USBHUB_DumpingDeviceDescriptor(
278 IN PUSB_DEVICE_DESCRIPTOR DeviceDescriptor
);
282 USBHUB_DumpingConfiguration(
283 IN PUSB_CONFIGURATION_DESCRIPTOR ConfigDescriptor
);
294 IN PUSBHUB_FDO_EXTENSION HubExtension
,
299 USBH_PdoInternalControl(
300 IN PUSBHUB_PORT_PDO_EXTENSION PortExtension
,
306 USBH_PdoRemoveDevice(
307 IN PUSBHUB_PORT_PDO_EXTENSION PortExtension
,
308 IN PUSBHUB_FDO_EXTENSION HubExtension
);
313 IN PUSBHUB_FDO_EXTENSION HubExtension
,
320 IN PUSBHUB_PORT_PDO_EXTENSION PortExtension
,
323 OUT BOOLEAN
* IsCompleteIrp
);
328 USBH_CompletePowerIrp(
329 IN PUSBHUB_FDO_EXTENSION HubExtension
,
331 IN NTSTATUS NtStatus
);
336 IN PUSBHUB_FDO_EXTENSION HubExtension
);
341 IN PUSBHUB_FDO_EXTENSION HubExtension
,
348 IN PUSBHUB_PORT_PDO_EXTENSION PortExtension
,
354 USBH_HubCompletePortWakeIrps(
355 IN PUSBHUB_FDO_EXTENSION HubExtension
,
356 IN NTSTATUS NtStatus
);
360 USBH_HubCancelWakeIrp(
361 IN PUSBHUB_FDO_EXTENSION HubExtension
,
366 USBH_IdleCancelPowerHubWorker(
367 IN PUSBHUB_FDO_EXTENSION HubExtension
,
374 IN ULONG Milliseconds
);
380 IN NTSTATUS CompleteStatus
);
385 IN PDEVICE_OBJECT DeviceObject
,
388 PUSBHUB_PORT_PDO_EXTENSION
391 IN PDEVICE_OBJECT DeviceObject
);
395 USBH_WriteFailReasonID(
396 IN PDEVICE_OBJECT DeviceObject
,
401 USBH_SetPdoRegistryParameter(
402 IN PDEVICE_OBJECT DeviceObject
,
403 IN PCWSTR SourceString
,
407 IN ULONG DevInstKeyType
);
412 IN PDEVICE_OBJECT DeviceObject
,
417 USBH_FdoSyncSubmitUrb(
418 IN PDEVICE_OBJECT FdoDevice
,
424 IN PUSBHUB_FDO_EXTENSION HubExtension
,
430 IN PUSBHUB_FDO_EXTENSION HubExtension
,
431 IN PUSB_DEVICE_HANDLE DeviceHandle
,
432 OUT USB_DEVICE_TYPE
* OutDeviceType
);
434 PUSBHUB_FDO_EXTENSION
436 USBH_GetRootHubExtension(
437 IN PUSBHUB_FDO_EXTENSION HubExtension
);
441 USBH_SyncGetRootHubPdo(
442 IN PDEVICE_OBJECT DeviceObject
,
443 IN OUT PDEVICE_OBJECT
* OutPdo1
,
444 IN OUT PDEVICE_OBJECT
* OutPdo2
);
448 USBH_SyncGetHubCount(
449 IN PDEVICE_OBJECT DeviceObject
,
450 IN OUT PULONG OutHubCount
);
454 USBH_SyncGetDeviceHandle(
455 IN PDEVICE_OBJECT DeviceObject
);
459 USBH_GetDeviceDescriptor(
460 IN PDEVICE_OBJECT DeviceObject
,
461 IN PUSB_DEVICE_DESCRIPTOR HubDeviceDescriptor
);
465 USBH_GetConfigurationDescriptor(
466 IN PDEVICE_OBJECT DeviceObject
,
467 IN PUSB_CONFIGURATION_DESCRIPTOR
* pConfigurationDescriptor
);
471 USBH_SyncGetHubDescriptor(
472 IN PUSBHUB_FDO_EXTENSION HubExtension
);
476 USBH_SyncGetStringDescriptor(
477 IN PDEVICE_OBJECT DeviceObject
,
479 IN USHORT LanguageId
,
480 IN PUSB_STRING_DESCRIPTOR Descriptor
,
481 IN ULONG NumberOfBytes
,
483 IN BOOLEAN IsValidateLength
);
487 USBH_SyncGetPortStatus(
488 IN PUSBHUB_FDO_EXTENSION HubExtension
,
490 IN PUSB_PORT_STATUS_AND_CHANGE PortStatus
,
495 USBH_SyncClearPortStatus(
496 IN PUSBHUB_FDO_EXTENSION HubExtension
,
498 IN USHORT RequestValue
);
502 USBH_SyncPowerOnPorts(
503 IN PUSBHUB_FDO_EXTENSION HubExtension
);
507 USBH_SyncDisablePort(
508 IN PUSBHUB_FDO_EXTENSION HubExtension
,
513 USBH_HubIsBusPowered(
514 IN PDEVICE_OBJECT DeviceObject
,
515 IN PUSB_CONFIGURATION_DESCRIPTOR HubConfigDescriptor
);
519 USBH_SubmitStatusChangeTransfer(
520 IN PUSBHUB_FDO_EXTENSION HubExtension
);
525 IN PUSBHUB_FDO_EXTENSION HubExtension
,
526 IN PUSB_DEVICE_HANDLE
* OutDeviceHandle
,
527 IN USB_PORT_STATUS UsbPortStatus
,
533 IN PUSBHUB_FDO_EXTENSION HubExtension
,
534 IN PUSB_DEVICE_HANDLE DeviceHandle
,
539 USBD_InitializeDeviceEx(
540 IN PUSBHUB_FDO_EXTENSION HubExtension
,
541 IN PUSB_DEVICE_HANDLE DeviceHandle
,
542 IN PUCHAR DeviceDescriptorBuffer
,
543 IN ULONG DeviceDescriptorBufferLength
,
544 IN PUCHAR ConfigDescriptorBuffer
,
545 IN ULONG ConfigDescriptorBufferLength
);
549 USBHUB_SetDeviceHandleData(
550 IN PUSBHUB_FDO_EXTENSION HubExtension
,
551 IN PDEVICE_OBJECT UsbDevicePdo
,
552 IN PVOID DeviceHandle
);
556 USBHUB_FlushAllTransfers(
557 IN PUSBHUB_FDO_EXTENSION HubExtension
);
561 USBD_GetDeviceInformationEx(
562 IN PUSBHUB_PORT_PDO_EXTENSION PortExtension
,
563 IN PUSBHUB_FDO_EXTENSION HubExtension
,
564 IN PUSB_NODE_CONNECTION_INFORMATION_EX Info
,
566 IN PUSB_DEVICE_HANDLE DeviceHandle
);
570 USBD_RestoreDeviceEx(
571 IN PUSBHUB_FDO_EXTENSION HubExtension
,
572 IN OUT PUSB_DEVICE_HANDLE OldDeviceHandle
,
573 IN OUT PUSB_DEVICE_HANDLE NewDeviceHandle
);
577 USBH_AllocateWorkItem(
578 IN PUSBHUB_FDO_EXTENSION HubExtension
,
579 OUT PUSBHUB_IO_WORK_ITEM
* OutHubIoWorkItem
,
580 IN PUSBHUB_WORKER_ROUTINE WorkerRoutine
,
581 IN SIZE_T BufferLength
,
582 OUT PVOID
* OutHubWorkItemBuffer
,
583 IN WORK_QUEUE_TYPE Type
);
588 IN PUSBHUB_FDO_EXTENSION HubExtension
,
589 IN PUSBHUB_IO_WORK_ITEM HubIoWorkItem
);
594 IN PUSBHUB_IO_WORK_ITEM HubIoWorkItem
);
598 USBD_RegisterRootHubCallBack(
599 IN PUSBHUB_FDO_EXTENSION HubExtension
);
603 USBD_UnRegisterRootHubCallBack(
604 IN PUSBHUB_FDO_EXTENSION HubExtension
);
608 USBH_HubCancelIdleIrp(
609 IN PUSBHUB_FDO_EXTENSION HubExtension
,
615 IN PUSBHUB_FDO_EXTENSION HubExtension
,
617 IN BOOLEAN IsExtCheck
);
622 IN PUSBHUB_FDO_EXTENSION HubExtension
);
626 USBH_CheckIdleDeferred(
627 IN PUSBHUB_FDO_EXTENSION HubExtension
);
631 USBH_CheckDeviceLanguage(
632 IN PDEVICE_OBJECT DeviceObject
,
633 IN USHORT LanguageId
);
638 IN PUSBHUB_FDO_EXTENSION HubExtension
,
640 IN USB_PORT_STATUS UsbPortStatus
,
646 IN PUSBHUB_FDO_EXTENSION HubExtension
,
648 IN BOOLEAN IsKeepDeviceData
,
654 IN PDRIVER_OBJECT DriverObject
,
655 IN PUNICODE_STRING RegistryPath
);
657 #endif /* _USBHUB_H_ */