2 * PROJECT: ReactOS USB Hub Driver
3 * LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
4 * PURPOSE: USBHub main driver functions
5 * COPYRIGHT: Copyright 2017 Vadim Galyant <vgal@rambler.ru>
13 #define NDEBUG_USBHUB_SCE
14 #define NDEBUG_USBHUB_PNP
19 PWSTR GenericUSBDeviceString
= NULL
;
23 USBH_Wait(IN ULONG Milliseconds
)
25 LARGE_INTEGER Interval
;
27 DPRINT("USBH_Wait: Milliseconds - %x\n", Milliseconds
);
28 Interval
.QuadPart
= -10000LL * Milliseconds
- ((ULONGLONG
)KeQueryTimeIncrement() - 1);
29 return KeDelayExecutionThread(KernelMode
, FALSE
, &Interval
);
34 USBH_GetConfigValue(IN PWSTR ValueName
,
39 IN PVOID EntryContext
)
41 NTSTATUS Status
= STATUS_SUCCESS
;
43 DPRINT("USBHUB_GetConfigValue: ... \n");
45 if (ValueType
== REG_BINARY
)
47 *(PUCHAR
)EntryContext
= *(PUCHAR
)ValueData
;
49 else if (ValueType
== REG_DWORD
)
51 *(PULONG
)EntryContext
= *(PULONG
)ValueData
;
55 Status
= STATUS_INVALID_PARAMETER
;
63 USBH_CompleteIrp(IN PIRP Irp
,
64 IN NTSTATUS CompleteStatus
)
66 if (CompleteStatus
!= STATUS_SUCCESS
)
68 DPRINT1("USBH_CompleteIrp: Irp - %p, CompleteStatus - %X\n",
73 Irp
->IoStatus
.Status
= CompleteStatus
;
74 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
79 USBH_PassIrp(IN PDEVICE_OBJECT DeviceObject
,
82 DPRINT_PNP("USBH_PassIrp: DeviceObject - %p, Irp - %p\n",
86 IoSkipCurrentIrpStackLocation(Irp
);
87 return IoCallDriver(DeviceObject
, Irp
);
92 USBH_SyncIrpComplete(IN PDEVICE_OBJECT DeviceObject
,
96 PUSBHUB_URB_TIMEOUT_CONTEXT HubTimeoutContext
;
98 BOOLEAN TimerCancelled
;
100 DPRINT("USBH_SyncIrpComplete: ... \n");
102 HubTimeoutContext
= Context
;
104 KeAcquireSpinLock(&HubTimeoutContext
->UrbTimeoutSpinLock
, &OldIrql
);
105 HubTimeoutContext
->IsNormalCompleted
= TRUE
;
106 TimerCancelled
= KeCancelTimer(&HubTimeoutContext
->UrbTimeoutTimer
);
107 KeReleaseSpinLock(&HubTimeoutContext
->UrbTimeoutSpinLock
, OldIrql
);
111 KeSetEvent(&HubTimeoutContext
->UrbTimeoutEvent
,
116 return STATUS_SUCCESS
;
121 IsBitSet(IN PUCHAR BitMapAddress
,
126 IsSet
= (BitMapAddress
[Bit
/ 8] & (1 << (Bit
& 7))) != 0;
127 DPRINT("IsBitSet: Bit - %lX, IsSet - %x\n", Bit
, IsSet
);
131 PUSBHUB_PORT_PDO_EXTENSION
133 PdoExt(IN PDEVICE_OBJECT DeviceObject
)
137 DPRINT("PdoExt: DeviceObject - %p\n", DeviceObject
);
141 PdoExtension
= DeviceObject
->DeviceExtension
;
148 return (PUSBHUB_PORT_PDO_EXTENSION
)PdoExtension
;
153 USBH_WriteFailReasonID(IN PDEVICE_OBJECT DeviceObject
,
158 UNICODE_STRING ValueName
= RTL_CONSTANT_STRING(L
"FailReasonID");
160 DPRINT("USBH_WriteFailReason: ID - %x\n", FailReason
);
162 Status
= IoOpenDeviceRegistryKey(DeviceObject
,
163 PLUGPLAY_REGKEY_DEVICE
,
167 if (NT_SUCCESS(Status
))
169 ZwSetValueKey(KeyHandle
,
184 USBH_UrbTimeoutDPC(IN PKDPC Dpc
,
185 IN PVOID DeferredContext
,
186 IN PVOID SystemArgument1
,
187 IN PVOID SystemArgument2
)
189 PUSBHUB_URB_TIMEOUT_CONTEXT HubTimeoutContext
;
193 DPRINT("USBH_TimeoutDPC ... \n");
195 HubTimeoutContext
= DeferredContext
;
197 KeAcquireSpinLock(&HubTimeoutContext
->UrbTimeoutSpinLock
, &OldIrql
);
198 IsCompleted
= HubTimeoutContext
->IsNormalCompleted
;
199 KeReleaseSpinLock(&HubTimeoutContext
->UrbTimeoutSpinLock
, OldIrql
);
203 IoCancelIrp(HubTimeoutContext
->Irp
);
206 KeSetEvent(&HubTimeoutContext
->UrbTimeoutEvent
,
213 USBH_SetPdoRegistryParameter(IN PDEVICE_OBJECT DeviceObject
,
218 IN ULONG DevInstKeyType
)
221 UNICODE_STRING ValueNameString
;
224 DPRINT("USBH_SetPdoRegistryParameter ... \n");
226 RtlInitUnicodeString(&ValueNameString
, ValueName
);
228 Status
= IoOpenDeviceRegistryKey(DeviceObject
,
233 if (NT_SUCCESS(Status
))
235 ZwSetValueKey(KeyHandle
,
250 USBH_SyncSubmitUrb(IN PDEVICE_OBJECT DeviceObject
,
254 IO_STATUS_BLOCK IoStatusBlock
;
256 PIO_STACK_LOCATION IoStack
;
257 PUSBHUB_URB_TIMEOUT_CONTEXT HubTimeoutContext
;
258 BOOLEAN IsWaitTimeout
= FALSE
;
259 LARGE_INTEGER DueTime
;
262 DPRINT("USBH_SyncSubmitUrb: ... \n");
264 Urb
->UrbHeader
.UsbdDeviceHandle
= NULL
;
266 KeInitializeEvent(&Event
, NotificationEvent
, FALSE
);
268 Irp
= IoBuildDeviceIoControlRequest(IOCTL_INTERNAL_USB_SUBMIT_URB
,
280 return STATUS_INSUFFICIENT_RESOURCES
;
283 IoStack
= IoGetNextIrpStackLocation(Irp
);
284 IoStack
->Parameters
.Others
.Argument1
= Urb
;
286 HubTimeoutContext
= ExAllocatePoolWithTag(NonPagedPool
,
287 sizeof(USBHUB_URB_TIMEOUT_CONTEXT
),
290 if (HubTimeoutContext
)
292 RtlZeroMemory(HubTimeoutContext
, sizeof(USBHUB_URB_TIMEOUT_CONTEXT
));
294 HubTimeoutContext
->Irp
= Irp
;
295 HubTimeoutContext
->IsNormalCompleted
= FALSE
;
297 KeInitializeEvent(&HubTimeoutContext
->UrbTimeoutEvent
,
301 KeInitializeSpinLock(&HubTimeoutContext
->UrbTimeoutSpinLock
);
302 KeInitializeTimer(&HubTimeoutContext
->UrbTimeoutTimer
);
304 KeInitializeDpc(&HubTimeoutContext
->UrbTimeoutDPC
,
308 DueTime
.QuadPart
= -5000 * 10000; // Timeout 5 sec.
310 KeSetTimer(&HubTimeoutContext
->UrbTimeoutTimer
,
312 &HubTimeoutContext
->UrbTimeoutDPC
);
314 IoSetCompletionRoutine(Irp
,
315 USBH_SyncIrpComplete
,
321 IsWaitTimeout
= TRUE
;
324 Status
= IoCallDriver(DeviceObject
, Irp
);
326 if (Status
== STATUS_PENDING
)
328 KeWaitForSingleObject(&Event
,
336 IoStatusBlock
.Status
= Status
;
341 KeWaitForSingleObject(&HubTimeoutContext
->UrbTimeoutEvent
,
347 ExFreePoolWithTag(HubTimeoutContext
, USB_HUB_TAG
);
350 return IoStatusBlock
.Status
;
355 USBH_FdoSyncSubmitUrb(IN PDEVICE_OBJECT FdoDevice
,
358 PUSBHUB_FDO_EXTENSION HubExtension
;
360 DPRINT("USBH_FdoSyncSubmitUrb: FdoDevice - %p, Urb - %p\n",
364 HubExtension
= FdoDevice
->DeviceExtension
;
365 return USBH_SyncSubmitUrb(HubExtension
->LowerDevice
, Urb
);
370 USBH_Transact(IN PUSBHUB_FDO_EXTENSION HubExtension
,
371 IN PVOID TransferBuffer
,
373 IN BOOLEAN IsDeviceToHost
,
375 IN BM_REQUEST_TYPE RequestType
,
377 IN USHORT RequestValue
,
378 IN USHORT RequestIndex
)
380 struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST
* Urb
;
386 DPRINT("USBH_Transact: ... \n");
390 Length
= ALIGN_DOWN_BY(BufferLen
+ sizeof(ULONG
), sizeof(ULONG
));
392 Buffer
= ExAllocatePoolWithTag(NonPagedPool
, Length
, USB_HUB_TAG
);
396 return STATUS_INSUFFICIENT_RESOURCES
;
399 RtlZeroMemory(Buffer
, Length
);
402 Urb
= ExAllocatePoolWithTag(NonPagedPool
,
403 sizeof(struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST
),
410 ExFreePoolWithTag(Buffer
, USB_HUB_TAG
);
413 return STATUS_INSUFFICIENT_RESOURCES
;
416 RtlZeroMemory(Urb
, sizeof(struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST
));
422 RtlZeroMemory(TransferBuffer
, BufferLen
);
425 TransferFlags
= USBD_TRANSFER_DIRECTION_IN
| USBD_SHORT_TRANSFER_OK
;
431 RtlCopyMemory(Buffer
, TransferBuffer
, BufferLen
);
434 TransferFlags
= USBD_TRANSFER_DIRECTION_OUT
;
437 Urb
->Hdr
.Length
= sizeof(struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST
);
438 Urb
->Hdr
.Function
= Function
;
439 Urb
->Hdr
.UsbdDeviceHandle
= NULL
;
441 Urb
->TransferFlags
= TransferFlags
;
442 Urb
->TransferBuffer
= BufferLen
!= 0 ? Buffer
: NULL
;
443 Urb
->TransferBufferLength
= BufferLen
;
444 Urb
->TransferBufferMDL
= NULL
;
447 Urb
->RequestTypeReservedBits
= RequestType
.B
;
448 Urb
->Request
= Request
;
449 Urb
->Value
= RequestValue
;
450 Urb
->Index
= RequestIndex
;
452 Status
= USBH_FdoSyncSubmitUrb(HubExtension
->Common
.SelfDevice
, (PURB
)Urb
);
454 if (IsDeviceToHost
&& BufferLen
)
456 RtlCopyMemory(TransferBuffer
, Buffer
, BufferLen
);
461 ExFreePoolWithTag(Buffer
, USB_HUB_TAG
);
464 ExFreePoolWithTag(Urb
, USB_HUB_TAG
);
471 USBH_SyncResetPort(IN PUSBHUB_FDO_EXTENSION HubExtension
,
474 USB_PORT_STATUS_AND_CHANGE PortStatus
;
476 LARGE_INTEGER Timeout
;
477 ULONG ResetRetry
= 0;
480 DPRINT("USBH_SyncResetPort: Port - %x\n", Port
);
482 InterlockedIncrement(&HubExtension
->PendingRequestCount
);
484 KeWaitForSingleObject(&HubExtension
->HubPortSemaphore
,
490 Status
= USBH_SyncGetPortStatus(HubExtension
,
493 sizeof(USB_PORT_STATUS_AND_CHANGE
));
495 if (NT_SUCCESS(Status
) &&
496 (PortStatus
.PortStatus
.Usb20PortStatus
.CurrentConnectStatus
== 0))
498 Status
= STATUS_UNSUCCESSFUL
;
502 HubExtension
->HubFlags
|= USBHUB_FDO_FLAG_RESET_PORT_LOCK
;
506 BM_REQUEST_TYPE RequestType
;
508 KeInitializeEvent(&Event
, NotificationEvent
, FALSE
);
510 InterlockedExchangePointer((PVOID
)&HubExtension
->pResetPortEvent
,
514 RequestType
.Recipient
= BMREQUEST_TO_DEVICE
;
515 RequestType
.Type
= BMREQUEST_CLASS
;
516 RequestType
.Dir
= BMREQUEST_HOST_TO_DEVICE
;
518 Status
= USBH_Transact(HubExtension
,
521 BMREQUEST_HOST_TO_DEVICE
,
522 URB_FUNCTION_CLASS_OTHER
,
524 USB_REQUEST_SET_FEATURE
,
525 USBHUB_FEATURE_PORT_RESET
,
528 Timeout
.QuadPart
= -5000 * 10000;
530 if (!NT_SUCCESS(Status
))
532 InterlockedExchangePointer((PVOID
)&HubExtension
->pResetPortEvent
,
536 HubExtension
->HubFlags
&= ~USBHUB_FDO_FLAG_RESET_PORT_LOCK
;
541 Status
= KeWaitForSingleObject(&Event
,
547 if (Status
!= STATUS_TIMEOUT
)
552 Status
= USBH_SyncGetPortStatus(HubExtension
,
555 sizeof(USB_PORT_STATUS_AND_CHANGE
));
557 if (!NT_SUCCESS(Status
) ||
558 (PortStatus
.PortStatus
.Usb20PortStatus
.CurrentConnectStatus
== 0) ||
559 ResetRetry
>= USBHUB_RESET_PORT_MAX_RETRY
)
561 InterlockedExchangePointer((PVOID
)&HubExtension
->pResetPortEvent
,
565 HubExtension
->HubFlags
&= ~USBHUB_FDO_FLAG_RESET_PORT_LOCK
;
567 Status
= STATUS_DEVICE_DATA_ERROR
;
574 Status
= USBH_SyncGetPortStatus(HubExtension
,
577 sizeof(USB_PORT_STATUS_AND_CHANGE
));
579 if ((PortStatus
.PortStatus
.Usb20PortStatus
.CurrentConnectStatus
== 0) &&
580 NT_SUCCESS(Status
) &&
581 HubExtension
->HubFlags
& USBHUB_FDO_FLAG_USB20_HUB
)
583 Status
= STATUS_DEVICE_DATA_ERROR
;
587 HubExtension
->HubFlags
&= ~USBHUB_FDO_FLAG_RESET_PORT_LOCK
;
591 KeReleaseSemaphore(&HubExtension
->HubPortSemaphore
,
592 LOW_REALTIME_PRIORITY
,
596 if (!InterlockedDecrement(&HubExtension
->PendingRequestCount
))
598 KeSetEvent(&HubExtension
->PendingRequestEvent
,
608 USBH_GetDeviceType(IN PUSBHUB_FDO_EXTENSION HubExtension
,
609 IN PUSB_DEVICE_HANDLE DeviceHandle
,
610 OUT USB_DEVICE_TYPE
* OutDeviceType
)
612 PUSB_BUSIFFN_GET_DEVICE_INFORMATION QueryDeviceInformation
;
613 PUSB_DEVICE_INFORMATION_0 DeviceInfo
;
614 SIZE_T DeviceInformationBufferLength
;
615 USB_DEVICE_TYPE DeviceType
= Usb11Device
;
619 DPRINT("USBH_GetDeviceType: ... \n");
621 QueryDeviceInformation
= HubExtension
->BusInterface
.QueryDeviceInformation
;
623 if (!QueryDeviceInformation
)
625 DPRINT1("USBH_GetDeviceType: no QueryDeviceInformation()\n");
626 return STATUS_NOT_IMPLEMENTED
;
629 DeviceInformationBufferLength
= sizeof(USB_DEVICE_INFORMATION_0
);
633 DeviceInfo
= ExAllocatePoolWithTag(PagedPool
,
634 DeviceInformationBufferLength
,
639 DPRINT1("USBH_GetDeviceType: ExAllocatePoolWithTag() failed\n");
640 Status
= STATUS_INSUFFICIENT_RESOURCES
;
644 RtlZeroMemory(DeviceInfo
, DeviceInformationBufferLength
);
646 DeviceInfo
->InformationLevel
= 0;
648 Status
= QueryDeviceInformation(HubExtension
->BusInterface
.BusContext
,
651 DeviceInformationBufferLength
,
654 if (Status
!= STATUS_BUFFER_TOO_SMALL
)
656 if (NT_SUCCESS(Status
))
658 DeviceType
= DeviceInfo
->DeviceType
;
661 ExFreePoolWithTag(DeviceInfo
, USB_HUB_TAG
);
665 DeviceInformationBufferLength
= DeviceInfo
->ActualLength
;
666 ExFreePoolWithTag(DeviceInfo
, USB_HUB_TAG
);
671 *OutDeviceType
= DeviceType
;
672 DPRINT("USBH_GetDeviceType: DeviceType - %x\n", DeviceType
);
680 USBHUB_GetExtendedHubInfo(IN PUSBHUB_FDO_EXTENSION HubExtension
,
681 IN PUSB_EXTHUB_INFORMATION_0 HubInfoBuffer
)
683 PUSB_BUSIFFN_GET_EXTENDED_HUB_INFO GetExtendedHubInformation
;
686 DPRINT("USBHUB_GetExtendedHubInfo: ... \n");
688 GetExtendedHubInformation
= HubExtension
->BusInterface
.GetExtendedHubInformation
;
690 return GetExtendedHubInformation(HubExtension
->BusInterface
.BusContext
,
691 HubExtension
->LowerPDO
,
693 sizeof(USB_EXTHUB_INFORMATION_0
),
697 PUSBHUB_FDO_EXTENSION
699 USBH_GetRootHubExtension(IN PUSBHUB_FDO_EXTENSION HubExtension
)
701 PDEVICE_OBJECT Device
;
702 PUSBHUB_FDO_EXTENSION RootHubExtension
;
704 DPRINT("USBH_GetRootHubExtension: HubExtension - %p\n", HubExtension
);
706 RootHubExtension
= HubExtension
;
708 if (HubExtension
->LowerPDO
!= HubExtension
->RootHubPdo
)
710 Device
= HubExtension
->RootHubPdo
;
714 Device
= Device
->AttachedDevice
;
716 while (Device
->DriverObject
!= HubExtension
->Common
.SelfDevice
->DriverObject
);
718 RootHubExtension
= Device
->DeviceExtension
;
721 DPRINT("USBH_GetRootHubExtension: RootHubExtension - %p\n", RootHubExtension
);
723 return RootHubExtension
;
728 USBH_SyncGetRootHubPdo(IN PDEVICE_OBJECT DeviceObject
,
729 IN OUT PDEVICE_OBJECT
* OutPdo1
,
730 IN OUT PDEVICE_OBJECT
* OutPdo2
)
733 IO_STATUS_BLOCK IoStatusBlock
;
735 PIO_STACK_LOCATION IoStack
;
738 DPRINT("USBH_SyncGetRootHubPdo: ... \n");
740 KeInitializeEvent(&Event
, NotificationEvent
, FALSE
);
742 Irp
= IoBuildDeviceIoControlRequest(IOCTL_INTERNAL_USB_GET_ROOTHUB_PDO
,
754 return STATUS_INSUFFICIENT_RESOURCES
;
757 IoStack
= IoGetNextIrpStackLocation(Irp
);
758 IoStack
->Parameters
.Others
.Argument1
= OutPdo1
;
759 IoStack
->Parameters
.Others
.Argument2
= OutPdo2
;
761 Status
= IoCallDriver(DeviceObject
, Irp
);
763 if (Status
== STATUS_PENDING
)
765 KeWaitForSingleObject(&Event
,
773 IoStatusBlock
.Status
= Status
;
776 return IoStatusBlock
.Status
;
781 USBH_SyncGetHubCount(IN PDEVICE_OBJECT DeviceObject
,
782 IN OUT PULONG OutHubCount
)
785 IO_STATUS_BLOCK IoStatusBlock
;
787 PIO_STACK_LOCATION IoStack
;
790 DPRINT("USBH_SyncGetHubCount: *OutHubCount - %x\n", *OutHubCount
);
792 KeInitializeEvent(&Event
, NotificationEvent
, FALSE
);
794 Irp
= IoBuildDeviceIoControlRequest(IOCTL_INTERNAL_USB_GET_HUB_COUNT
,
806 return STATUS_INSUFFICIENT_RESOURCES
;
809 IoStack
= IoGetNextIrpStackLocation(Irp
);
810 IoStack
->Parameters
.Others
.Argument1
= OutHubCount
;
812 Status
= IoCallDriver(DeviceObject
, Irp
);
814 if (Status
== STATUS_PENDING
)
816 KeWaitForSingleObject(&Event
,
824 IoStatusBlock
.Status
= Status
;
827 return IoStatusBlock
.Status
;
832 USBH_SyncGetDeviceHandle(IN PDEVICE_OBJECT DeviceObject
)
836 IO_STATUS_BLOCK IoStatusBlock
;
837 PUSB_DEVICE_HANDLE DeviceHandle
= NULL
;
838 PIO_STACK_LOCATION IoStack
;
840 DPRINT("USBH_SyncGetDeviceHandle: ... \n");
842 KeInitializeEvent(&Event
, NotificationEvent
, FALSE
);
844 Irp
= IoBuildDeviceIoControlRequest(IOCTL_INTERNAL_USB_GET_DEVICE_HANDLE
,
856 DPRINT1("USBH_SyncGetDeviceHandle: Irp - NULL!\n");
860 IoStack
= IoGetNextIrpStackLocation(Irp
);
861 IoStack
->Parameters
.Others
.Argument1
= &DeviceHandle
;
863 if (IoCallDriver(DeviceObject
, Irp
) == STATUS_PENDING
)
865 KeWaitForSingleObject(&Event
,
877 USBH_GetDeviceDescriptor(IN PDEVICE_OBJECT DeviceObject
,
878 IN PUSB_DEVICE_DESCRIPTOR HubDeviceDescriptor
)
880 struct _URB_CONTROL_DESCRIPTOR_REQUEST
* Urb
;
883 DPRINT("USBH_GetDeviceDescriptor: ... \n");
885 Urb
= ExAllocatePoolWithTag(NonPagedPool
,
886 sizeof(struct _URB_CONTROL_DESCRIPTOR_REQUEST
),
891 DPRINT1("USBH_SyncGetDeviceHandle: Urb - NULL!\n");
892 return STATUS_INSUFFICIENT_RESOURCES
;
895 RtlZeroMemory(Urb
, sizeof(struct _URB_CONTROL_DESCRIPTOR_REQUEST
));
897 Urb
->Hdr
.Function
= URB_FUNCTION_GET_DESCRIPTOR_FROM_DEVICE
;
898 Urb
->Hdr
.Length
= sizeof(struct _URB_CONTROL_DESCRIPTOR_REQUEST
);
900 Urb
->TransferBufferLength
= sizeof(USB_DEVICE_DESCRIPTOR
);
901 Urb
->TransferBuffer
= HubDeviceDescriptor
;
902 Urb
->DescriptorType
= USB_DEVICE_DESCRIPTOR_TYPE
;
904 Status
= USBH_FdoSyncSubmitUrb(DeviceObject
, (PURB
)Urb
);
906 ExFreePoolWithTag(Urb
, USB_HUB_TAG
);
913 USBH_SyncGetDeviceConfigurationDescriptor(IN PDEVICE_OBJECT DeviceObject
,
914 IN PUSB_CONFIGURATION_DESCRIPTOR ConfigDescriptor
,
915 IN ULONG NumberOfBytes
,
918 PCOMMON_DEVICE_EXTENSION DeviceExtension
;
919 struct _URB_CONTROL_DESCRIPTOR_REQUEST
* Urb
;
922 DPRINT("USBH_SyncGetDeviceConfigurationDescriptor: ... \n");
924 DeviceExtension
= DeviceObject
->DeviceExtension
;
931 Urb
= ExAllocatePoolWithTag(NonPagedPool
,
932 sizeof(struct _URB_CONTROL_DESCRIPTOR_REQUEST
),
937 return STATUS_INSUFFICIENT_RESOURCES
;
940 RtlZeroMemory(Urb
, sizeof(struct _URB_CONTROL_DESCRIPTOR_REQUEST
));
942 Urb
->Hdr
.Function
= URB_FUNCTION_GET_DESCRIPTOR_FROM_DEVICE
;
943 Urb
->Hdr
.Length
= sizeof(struct _URB_CONTROL_DESCRIPTOR_REQUEST
);
945 Urb
->TransferBufferLength
= NumberOfBytes
;
946 Urb
->TransferBuffer
= ConfigDescriptor
;
947 Urb
->DescriptorType
= USB_CONFIGURATION_DESCRIPTOR_TYPE
;
949 if (DeviceExtension
->ExtensionType
== USBH_EXTENSION_TYPE_HUB
||
950 DeviceExtension
->ExtensionType
== USBH_EXTENSION_TYPE_PARENT
)
952 Status
= USBH_FdoSyncSubmitUrb(DeviceObject
, (PURB
)Urb
);
956 Status
= USBH_SyncSubmitUrb(DeviceObject
, (PURB
)Urb
);
961 *OutLength
= Urb
->TransferBufferLength
;
966 ExFreePoolWithTag(Urb
, USB_HUB_TAG
);
974 USBH_GetConfigurationDescriptor(IN PDEVICE_OBJECT DeviceObject
,
975 IN PUSB_CONFIGURATION_DESCRIPTOR
* OutDescriptor
)
977 PUSB_CONFIGURATION_DESCRIPTOR ConfigDescriptor
;
979 SIZE_T DescriptorLen
;
982 DPRINT("USBH_GetConfigurationDescriptor: ... \n");
984 DescriptorLen
= MAXUCHAR
;
988 ConfigDescriptor
= ExAllocatePoolWithTag(NonPagedPool
,
992 if (!ConfigDescriptor
)
994 Status
= STATUS_INSUFFICIENT_RESOURCES
;
998 Status
= USBH_SyncGetDeviceConfigurationDescriptor(DeviceObject
,
1003 if (ReturnedLen
< sizeof(USB_CONFIGURATION_DESCRIPTOR
))
1005 Status
= STATUS_DEVICE_DATA_ERROR
;
1008 if (!NT_SUCCESS(Status
))
1013 *OutDescriptor
= ConfigDescriptor
;
1015 if (ConfigDescriptor
->wTotalLength
<= DescriptorLen
)
1020 DescriptorLen
= ConfigDescriptor
->wTotalLength
;
1022 ExFreePool(ConfigDescriptor
);
1023 *OutDescriptor
= NULL
;
1026 if (NT_SUCCESS(Status
))
1028 if (ReturnedLen
< ConfigDescriptor
->wTotalLength
)
1030 Status
= STATUS_DEVICE_DATA_ERROR
;
1035 if (ConfigDescriptor
)
1037 ExFreePool(ConfigDescriptor
);
1040 *OutDescriptor
= NULL
;
1048 USBH_SyncGetHubDescriptor(IN PUSBHUB_FDO_EXTENSION HubExtension
)
1050 PUSB_EXTHUB_INFORMATION_0 ExtendedHubInfo
;
1052 PUSBHUB_PORT_DATA PortData
;
1053 USHORT RequestValue
;
1054 ULONG NumberOfBytes
;
1056 PUSB_HUB_DESCRIPTOR HubDescriptor
= NULL
;
1060 DPRINT("USBH_SyncGetHubDescriptor: ... \n");
1062 ExtendedHubInfo
= ExAllocatePoolWithTag(NonPagedPool
,
1063 sizeof(USB_EXTHUB_INFORMATION_0
),
1066 if (!ExtendedHubInfo
)
1068 Status
= STATUS_INSUFFICIENT_RESOURCES
;
1072 RtlZeroMemory(ExtendedHubInfo
, sizeof(USB_EXTHUB_INFORMATION_0
));
1074 Status
= USBHUB_GetExtendedHubInfo(HubExtension
, ExtendedHubInfo
);
1076 if (!NT_SUCCESS(Status
))
1078 ExFreePoolWithTag(ExtendedHubInfo
, USB_HUB_TAG
);
1079 ExtendedHubInfo
= NULL
;
1082 NumberOfBytes
= sizeof(USB_HUB_DESCRIPTOR
);
1084 HubDescriptor
= ExAllocatePoolWithTag(NonPagedPool
,
1090 Status
= STATUS_INSUFFICIENT_RESOURCES
;
1094 RtlZeroMemory(HubDescriptor
, NumberOfBytes
);
1103 BM_REQUEST_TYPE RequestType
;
1106 RequestType
.Recipient
= BMREQUEST_TO_DEVICE
;
1107 RequestType
.Type
= BMREQUEST_STANDARD
;
1108 RequestType
.Dir
= BMREQUEST_DEVICE_TO_HOST
;
1110 Status
= USBH_Transact(HubExtension
,
1113 BMREQUEST_DEVICE_TO_HOST
,
1114 URB_FUNCTION_CLASS_DEVICE
,
1116 USB_REQUEST_GET_DESCRIPTOR
,
1120 if (NT_SUCCESS(Status
))
1125 RequestValue
= 0x2900; // Hub DescriptorType - 0x29
1130 if (HubDescriptor
->bDescriptorLength
<= NumberOfBytes
)
1135 NumberOfBytes
= HubDescriptor
->bDescriptorLength
;
1136 ExFreePoolWithTag(HubDescriptor
, USB_HUB_TAG
);
1140 Status
= STATUS_DEVICE_DATA_ERROR
;
1141 HubDescriptor
= NULL
;
1145 HubDescriptor
= ExAllocatePoolWithTag(NonPagedPool
,
1151 Status
= STATUS_INSUFFICIENT_RESOURCES
;
1155 RtlZeroMemory(HubDescriptor
, NumberOfBytes
);
1158 NumberPorts
= HubDescriptor
->bNumberOfPorts
;
1160 if (HubExtension
->PortData
)
1162 PortData
= HubExtension
->PortData
;
1164 for (ix
= 0; ix
< NumberPorts
; ix
++)
1166 PortData
[ix
].PortStatus
.AsUlong32
= 0;
1168 if (ExtendedHubInfo
)
1170 PortData
[ix
].PortAttributes
= ExtendedHubInfo
->Port
[ix
].PortAttributes
;
1174 PortData
[ix
].PortAttributes
= 0;
1177 PortData
[ix
].ConnectionStatus
= NoDeviceConnected
;
1179 if (PortData
[ix
].DeviceObject
!= NULL
)
1181 PortData
[ix
].ConnectionStatus
= DeviceConnected
;
1189 if (HubDescriptor
->bNumberOfPorts
)
1191 PortData
= ExAllocatePoolWithTag(NonPagedPool
,
1192 NumberPorts
* sizeof(USBHUB_PORT_DATA
),
1198 Status
= STATUS_INSUFFICIENT_RESOURCES
;
1202 RtlZeroMemory(PortData
, NumberPorts
* sizeof(USBHUB_PORT_DATA
));
1204 for (ix
= 0; ix
< NumberPorts
; ix
++)
1206 PortData
[ix
].ConnectionStatus
= NoDeviceConnected
;
1208 if (ExtendedHubInfo
)
1210 PortData
[ix
].PortAttributes
= ExtendedHubInfo
->Port
[ix
].PortAttributes
;
1215 if (!NT_SUCCESS(Status
))
1220 HubExtension
->HubDescriptor
= HubDescriptor
;
1222 HubExtension
->PortData
= PortData
;
1224 if (ExtendedHubInfo
)
1226 ExFreePoolWithTag(ExtendedHubInfo
, USB_HUB_TAG
);
1235 ExFreePoolWithTag(HubDescriptor
, USB_HUB_TAG
);
1238 if (ExtendedHubInfo
)
1240 ExFreePoolWithTag(ExtendedHubInfo
, USB_HUB_TAG
);
1248 USBH_SyncGetStringDescriptor(IN PDEVICE_OBJECT DeviceObject
,
1250 IN USHORT LanguageId
,
1251 IN PUSB_STRING_DESCRIPTOR Descriptor
,
1252 IN ULONG NumberOfBytes
,
1253 IN PULONG OutLength
,
1254 IN BOOLEAN IsValidateLength
)
1256 struct _URB_CONTROL_DESCRIPTOR_REQUEST
* Urb
;
1257 ULONG TransferedLength
;
1260 DPRINT("USBH_SyncGetStringDescriptor: Index - %x, LanguageId - %x\n",
1264 Urb
= ExAllocatePoolWithTag(NonPagedPool
,
1265 sizeof(struct _URB_CONTROL_DESCRIPTOR_REQUEST
),
1270 return STATUS_INSUFFICIENT_RESOURCES
;
1273 RtlZeroMemory(Urb
, sizeof(struct _URB_CONTROL_DESCRIPTOR_REQUEST
));
1275 Urb
->Hdr
.Function
= URB_FUNCTION_GET_DESCRIPTOR_FROM_DEVICE
;
1276 Urb
->Hdr
.Length
= sizeof(struct _URB_CONTROL_DESCRIPTOR_REQUEST
);
1278 Urb
->TransferBuffer
= Descriptor
;
1279 Urb
->TransferBufferLength
= NumberOfBytes
;
1282 Urb
->DescriptorType
= USB_STRING_DESCRIPTOR_TYPE
;
1283 Urb
->LanguageId
= LanguageId
;
1285 Status
= USBH_SyncSubmitUrb(DeviceObject
, (PURB
)Urb
);
1287 if (!NT_SUCCESS(Status
))
1289 ExFreePoolWithTag(Urb
, USB_HUB_TAG
);
1293 TransferedLength
= Urb
->TransferBufferLength
;
1295 if (TransferedLength
> NumberOfBytes
)
1297 Status
= STATUS_DEVICE_DATA_ERROR
;
1300 if (!NT_SUCCESS(Status
))
1302 ExFreePoolWithTag(Urb
, USB_HUB_TAG
);
1308 *OutLength
= TransferedLength
;
1311 if (IsValidateLength
&& TransferedLength
!= Descriptor
->bLength
)
1313 Status
= STATUS_DEVICE_DATA_ERROR
;
1316 ExFreePoolWithTag(Urb
, USB_HUB_TAG
);
1323 USBH_SyncGetStatus(IN PDEVICE_OBJECT DeviceObject
,
1324 IN PUSHORT OutStatus
,
1326 IN USHORT RequestIndex
)
1328 struct _URB_CONTROL_GET_STATUS_REQUEST
* Urb
;
1332 DPRINT("USBH_SyncGetStatus: ... \n");
1334 Urb
= ExAllocatePoolWithTag(NonPagedPool
,
1335 sizeof(struct _URB_CONTROL_GET_STATUS_REQUEST
),
1340 return STATUS_INSUFFICIENT_RESOURCES
;
1343 RtlZeroMemory(Urb
, sizeof(struct _URB_CONTROL_GET_STATUS_REQUEST
));
1345 Urb
->Hdr
.Length
= sizeof(struct _URB_CONTROL_GET_STATUS_REQUEST
);
1346 Urb
->Hdr
.Function
= Function
;
1348 Urb
->TransferBuffer
= &UsbStatus
;
1349 Urb
->TransferBufferLength
= sizeof(UsbStatus
);
1350 Urb
->Index
= RequestIndex
;
1352 NtStatus
= USBH_FdoSyncSubmitUrb(DeviceObject
, (PURB
)Urb
);
1354 *OutStatus
= UsbStatus
;
1356 ExFreePoolWithTag(Urb
, USB_HUB_TAG
);
1363 USBH_SyncGetPortStatus(IN PUSBHUB_FDO_EXTENSION HubExtension
,
1365 IN PUSB_PORT_STATUS_AND_CHANGE PortStatus
,
1368 BM_REQUEST_TYPE RequestType
;
1370 DPRINT("USBH_SyncGetPortStatus: Port - %x\n", Port
);
1373 RequestType
.Recipient
= BMREQUEST_TO_OTHER
;
1374 RequestType
.Type
= BMREQUEST_CLASS
;
1375 RequestType
.Dir
= BMREQUEST_DEVICE_TO_HOST
;
1377 return USBH_Transact(HubExtension
,
1380 BMREQUEST_DEVICE_TO_HOST
,
1381 URB_FUNCTION_CLASS_OTHER
,
1383 USB_REQUEST_GET_STATUS
,
1391 USBH_SyncClearPortStatus(IN PUSBHUB_FDO_EXTENSION HubExtension
,
1393 IN USHORT RequestValue
)
1395 BM_REQUEST_TYPE RequestType
;
1397 DPRINT("USBH_SyncClearPortStatus: Port - %x, RequestValue - %x\n",
1402 RequestType
.Recipient
= BMREQUEST_TO_DEVICE
;
1403 RequestType
.Type
= BMREQUEST_CLASS
;
1404 RequestType
.Dir
= BMREQUEST_HOST_TO_DEVICE
;
1406 return USBH_Transact(HubExtension
,
1409 BMREQUEST_HOST_TO_DEVICE
,
1410 URB_FUNCTION_CLASS_OTHER
,
1412 USB_REQUEST_CLEAR_FEATURE
,
1419 USBH_SyncPowerOnPort(IN PUSBHUB_FDO_EXTENSION HubExtension
,
1423 PUSBHUB_PORT_DATA PortData
;
1424 PUSB_HUB_DESCRIPTOR HubDescriptor
;
1425 NTSTATUS Status
= STATUS_SUCCESS
;
1426 BM_REQUEST_TYPE RequestType
;
1427 PUSB_PORT_STATUS_AND_CHANGE PortStatus
;
1429 DPRINT("USBH_SyncPowerOnPort: Port - %x, IsWait - %x\n", Port
, IsWait
);
1432 PortData
= &HubExtension
->PortData
[Port
- 1];
1433 PortStatus
= &PortData
->PortStatus
;
1435 if (PortStatus
->PortStatus
.Usb20PortStatus
.CurrentConnectStatus
== 1)
1441 RequestType
.Recipient
= BMREQUEST_TO_DEVICE
;
1442 RequestType
.Type
= BMREQUEST_CLASS
;
1443 RequestType
.Dir
= BMREQUEST_HOST_TO_DEVICE
;
1445 Status
= USBH_Transact(HubExtension
,
1448 BMREQUEST_HOST_TO_DEVICE
,
1449 URB_FUNCTION_CLASS_OTHER
,
1451 USB_REQUEST_SET_FEATURE
,
1452 USBHUB_FEATURE_PORT_POWER
,
1455 if (NT_SUCCESS(Status
))
1459 HubDescriptor
= HubExtension
->HubDescriptor
;
1460 USBH_Wait(2 * HubDescriptor
->bPowerOnToPowerGood
);
1463 PortStatus
->PortStatus
.Usb20PortStatus
.CurrentConnectStatus
= 1;
1471 USBH_SyncPowerOnPorts(IN PUSBHUB_FDO_EXTENSION HubExtension
)
1473 PUSB_HUB_DESCRIPTOR HubDescriptor
;
1474 NTSTATUS Status
= STATUS_UNSUCCESSFUL
;
1476 UCHAR NumberOfPorts
;
1478 DPRINT("USBH_SyncPowerOnPorts: ... \n");
1480 HubDescriptor
= HubExtension
->HubDescriptor
;
1481 NumberOfPorts
= HubDescriptor
->bNumberOfPorts
;
1483 for (Port
= 1; Port
<= NumberOfPorts
; ++Port
)
1485 Status
= USBH_SyncPowerOnPort(HubExtension
, Port
, 0);
1487 if (!NT_SUCCESS(Status
))
1489 DPRINT1("USBH_SyncPowerOnPorts: USBH_SyncPowerOnPort() failed - %lX\n",
1495 USBH_Wait(2 * HubDescriptor
->bPowerOnToPowerGood
);
1502 USBH_SyncDisablePort(IN PUSBHUB_FDO_EXTENSION HubExtension
,
1505 PUSBHUB_PORT_DATA PortData
;
1507 BM_REQUEST_TYPE RequestType
;
1509 DPRINT("USBH_SyncDisablePort ... \n");
1511 PortData
= &HubExtension
->PortData
[Port
- 1];
1514 RequestType
.Recipient
= BMREQUEST_TO_DEVICE
;
1515 RequestType
.Type
= BMREQUEST_CLASS
;
1516 RequestType
.Dir
= BMREQUEST_HOST_TO_DEVICE
;
1518 Status
= USBH_Transact(HubExtension
,
1521 BMREQUEST_HOST_TO_DEVICE
,
1522 URB_FUNCTION_CLASS_OTHER
,
1524 USB_REQUEST_CLEAR_FEATURE
,
1525 USBHUB_FEATURE_PORT_ENABLE
,
1528 if (NT_SUCCESS(Status
))
1530 PortData
->PortStatus
.PortStatus
.Usb20PortStatus
.PortEnabledDisabled
= 0;
1538 USBH_HubIsBusPowered(IN PDEVICE_OBJECT DeviceObject
,
1539 IN PUSB_CONFIGURATION_DESCRIPTOR HubConfigDescriptor
)
1545 DPRINT("USBH_HubIsBusPowered: ... \n");
1547 Status
= USBH_SyncGetStatus(DeviceObject
,
1549 URB_FUNCTION_GET_STATUS_FROM_DEVICE
,
1552 if (!NT_SUCCESS(Status
))
1554 Result
= (HubConfigDescriptor
->bmAttributes
& USB_CONFIG_POWERED_MASK
)
1555 == USB_CONFIG_BUS_POWERED
;
1559 Result
= (UsbStatus
& USB_GETSTATUS_SELF_POWERED
) == 0;
1567 USBH_ChangeIndicationAckChangeComplete(IN PDEVICE_OBJECT DeviceObject
,
1571 PUSBHUB_FDO_EXTENSION HubExtension
;
1575 HubExtension
= Context
;
1577 DPRINT_SCE("USBH_ChangeIndicationAckChangeComplete: ... \n");
1579 ASSERT(HubExtension
->Port
> 0);
1580 Port
= HubExtension
->Port
- 1;
1582 HubExtension
->PortData
[Port
].PortStatus
= HubExtension
->PortStatus
;
1584 Event
= InterlockedExchangePointer((PVOID
)&HubExtension
->pResetPortEvent
,
1589 KeSetEvent(Event
, EVENT_INCREMENT
, FALSE
);
1592 USBH_SubmitStatusChangeTransfer(HubExtension
);
1594 if (!InterlockedDecrement(&HubExtension
->ResetRequestCount
))
1596 KeSetEvent(&HubExtension
->ResetEvent
,
1601 return STATUS_MORE_PROCESSING_REQUIRED
;
1606 USBH_ChangeIndicationAckChange(IN PUSBHUB_FDO_EXTENSION HubExtension
,
1608 IN
struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST
* Urb
,
1610 IN USHORT RequestValue
)
1612 PIO_STACK_LOCATION IoStack
;
1613 BM_REQUEST_TYPE RequestType
;
1615 DPRINT_SCE("USBH_ChangeIndicationAckChange: ... \n");
1617 Urb
->Hdr
.Length
= sizeof(struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST
);
1618 Urb
->Hdr
.Function
= URB_FUNCTION_CLASS_OTHER
;
1619 Urb
->Hdr
.UsbdDeviceHandle
= NULL
;
1621 Urb
->TransferFlags
= USBD_SHORT_TRANSFER_OK
;
1622 Urb
->TransferBufferLength
= 0;
1623 Urb
->TransferBuffer
= NULL
;
1624 Urb
->TransferBufferMDL
= NULL
;
1625 Urb
->UrbLink
= NULL
;
1628 RequestType
.Recipient
= BMREQUEST_TO_OTHER
;
1629 RequestType
.Type
= BMREQUEST_CLASS
;
1630 RequestType
.Dir
= BMREQUEST_HOST_TO_DEVICE
;
1632 Urb
->RequestTypeReservedBits
= RequestType
.B
;
1633 Urb
->Request
= USB_REQUEST_CLEAR_FEATURE
;
1635 Urb
->Value
= RequestValue
;
1637 IoInitializeIrp(Irp
,
1638 IoSizeOfIrp(HubExtension
->LowerDevice
->StackSize
),
1639 HubExtension
->LowerDevice
->StackSize
);
1641 IoStack
= IoGetNextIrpStackLocation(Irp
);
1643 IoStack
->MajorFunction
= IRP_MJ_INTERNAL_DEVICE_CONTROL
;
1644 IoStack
->Parameters
.Others
.Argument1
= Urb
;
1645 IoStack
->Parameters
.DeviceIoControl
.IoControlCode
= IOCTL_INTERNAL_USB_SUBMIT_URB
;
1647 IoSetCompletionRoutine(Irp
,
1648 USBH_ChangeIndicationAckChangeComplete
,
1654 return IoCallDriver(HubExtension
->LowerDevice
, Irp
);
1659 USBH_ChangeIndicationProcessChange(IN PDEVICE_OBJECT DeviceObject
,
1663 PUSBHUB_FDO_EXTENSION HubExtension
;
1664 PUSBHUB_IO_WORK_ITEM WorkItem
;
1665 USHORT RequestValue
;
1667 HubExtension
= Context
;
1669 DPRINT_SCE("USBH_ChangeIndicationProcessChange: PortStatus - %lX\n",
1670 HubExtension
->PortStatus
.AsUlong32
);
1672 if ((NT_SUCCESS(Irp
->IoStatus
.Status
) ||
1673 USBD_SUCCESS(HubExtension
->SCEWorkerUrb
.Hdr
.Status
)) &&
1674 (HubExtension
->PortStatus
.PortChange
.Usb20PortChange
.ResetChange
||
1675 HubExtension
->PortStatus
.PortChange
.Usb20PortChange
.PortEnableDisableChange
))
1677 if (!InterlockedDecrement(&HubExtension
->PendingRequestCount
))
1679 KeSetEvent(&HubExtension
->PendingRequestEvent
,
1684 USBH_FreeWorkItem(HubExtension
->WorkItemToQueue
);
1686 HubExtension
->WorkItemToQueue
= NULL
;
1688 if (HubExtension
->PortStatus
.PortChange
.Usb20PortChange
.ResetChange
)
1690 RequestValue
= USBHUB_FEATURE_C_PORT_RESET
;
1694 RequestValue
= USBHUB_FEATURE_C_PORT_ENABLE
;
1697 USBH_ChangeIndicationAckChange(HubExtension
,
1698 HubExtension
->ResetPortIrp
,
1699 &HubExtension
->SCEWorkerUrb
,
1705 ASSERT(HubExtension
->WorkItemToQueue
!= NULL
);
1707 WorkItem
= HubExtension
->WorkItemToQueue
;
1708 HubExtension
->WorkItemToQueue
= NULL
;
1710 USBH_QueueWorkItem(HubExtension
, WorkItem
);
1713 return STATUS_MORE_PROCESSING_REQUIRED
;
1718 USBH_ChangeIndicationQueryChange(IN PUSBHUB_FDO_EXTENSION HubExtension
,
1720 IN
struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST
* Urb
,
1723 PUSBHUB_IO_WORK_ITEM WorkItem
;
1725 PIO_STACK_LOCATION IoStack
;
1726 BM_REQUEST_TYPE RequestType
;
1728 DPRINT_SCE("USBH_ChangeIndicationQueryChange: Port - %x\n", Port
);
1730 InterlockedIncrement(&HubExtension
->PendingRequestCount
);
1734 ASSERT(HubExtension
->WorkItemToQueue
!= NULL
);
1736 WorkItem
= HubExtension
->WorkItemToQueue
;
1737 HubExtension
->WorkItemToQueue
= NULL
;
1739 USBH_QueueWorkItem(HubExtension
, WorkItem
);
1741 return STATUS_SUCCESS
;
1744 Urb
->Hdr
.Length
= sizeof(struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST
);
1745 Urb
->Hdr
.UsbdDeviceHandle
= NULL
;
1746 Urb
->Hdr
.Function
= URB_FUNCTION_CLASS_OTHER
;
1748 Urb
->TransferFlags
= USBD_SHORT_TRANSFER_OK
| USBD_TRANSFER_DIRECTION_IN
;
1749 Urb
->TransferBuffer
= &HubExtension
->PortStatus
;
1750 Urb
->TransferBufferLength
= sizeof(HubExtension
->PortStatus
);
1751 Urb
->TransferBufferMDL
= NULL
;
1752 Urb
->UrbLink
= NULL
;
1755 RequestType
.Recipient
= BMREQUEST_TO_OTHER
;
1756 RequestType
.Type
= BMREQUEST_CLASS
;
1757 RequestType
.Dir
= BMREQUEST_DEVICE_TO_HOST
;
1759 Urb
->RequestTypeReservedBits
= RequestType
.B
;
1760 Urb
->Request
= USB_REQUEST_GET_STATUS
;
1764 HubExtension
->Port
= Port
;
1766 IoInitializeIrp(Irp
,
1767 IoSizeOfIrp(HubExtension
->LowerDevice
->StackSize
),
1768 HubExtension
->LowerDevice
->StackSize
);
1770 IoStack
= IoGetNextIrpStackLocation(Irp
);
1772 IoStack
->MajorFunction
= IRP_MJ_INTERNAL_DEVICE_CONTROL
;
1773 IoStack
->Parameters
.Others
.Argument1
= Urb
;
1774 IoStack
->Parameters
.DeviceIoControl
.IoControlCode
= IOCTL_INTERNAL_USB_SUBMIT_URB
;
1776 IoSetCompletionRoutine(Irp
,
1777 USBH_ChangeIndicationProcessChange
,
1783 Status
= IoCallDriver(HubExtension
->LowerDevice
, Irp
);
1790 USBH_ProcessPortStateChange(IN PUSBHUB_FDO_EXTENSION HubExtension
,
1792 IN PUSB_PORT_STATUS_AND_CHANGE PortStatus
)
1794 PUSBHUB_PORT_DATA PortData
;
1795 USB_20_PORT_CHANGE PortStatusChange
;
1796 PDEVICE_OBJECT PortDevice
;
1797 PUSBHUB_PORT_PDO_EXTENSION PortExtension
;
1800 USHORT RequestValue
;
1803 DPRINT_SCE("USBH_ProcessPortStateChange ... \n");
1806 PortData
= &HubExtension
->PortData
[Port
- 1];
1808 PortStatusChange
= PortStatus
->PortChange
.Usb20PortChange
;
1810 if (PortStatusChange
.ConnectStatusChange
)
1812 PortData
->PortStatus
= *PortStatus
;
1814 USBH_SyncClearPortStatus(HubExtension
,
1816 USBHUB_FEATURE_C_PORT_CONNECTION
);
1818 PortData
= &HubExtension
->PortData
[Port
- 1];
1820 PortDevice
= PortData
->DeviceObject
;
1824 IoInvalidateDeviceRelations(HubExtension
->LowerPDO
, BusRelations
);
1828 PortExtension
= PortDevice
->DeviceExtension
;
1830 if (PortExtension
->PortPdoFlags
& USBHUB_PDO_FLAG_OVERCURRENT_PORT
)
1835 KeAcquireSpinLock(&HubExtension
->RelationsWorkerSpinLock
, &Irql
);
1837 if (PortExtension
->PortPdoFlags
& USBHUB_PDO_FLAG_POWER_D3
)
1839 KeReleaseSpinLock(&HubExtension
->RelationsWorkerSpinLock
, Irql
);
1840 IoInvalidateDeviceRelations(HubExtension
->LowerPDO
, BusRelations
);
1844 PortData
->DeviceObject
= NULL
;
1845 PortData
->ConnectionStatus
= NoDeviceConnected
;
1847 HubExtension
->HubFlags
|= USBHUB_FDO_FLAG_STATE_CHANGING
;
1849 InsertTailList(&HubExtension
->PdoList
, &PortExtension
->PortLink
);
1851 KeReleaseSpinLock(&HubExtension
->RelationsWorkerSpinLock
, Irql
);
1853 SerialNumber
= InterlockedExchangePointer((PVOID
)&PortExtension
->SerialNumber
,
1858 ExFreePoolWithTag(SerialNumber
, USB_HUB_TAG
);
1861 DeviceHandle
= InterlockedExchangePointer(&PortExtension
->DeviceHandle
,
1866 USBD_RemoveDeviceEx(HubExtension
, DeviceHandle
, 0);
1867 USBH_SyncDisablePort(HubExtension
, Port
);
1870 IoInvalidateDeviceRelations(HubExtension
->LowerPDO
, BusRelations
);
1872 else if (PortStatusChange
.PortEnableDisableChange
)
1874 RequestValue
= USBHUB_FEATURE_C_PORT_ENABLE
;
1875 PortData
->PortStatus
= *PortStatus
;
1876 USBH_SyncClearPortStatus(HubExtension
, Port
, RequestValue
);
1879 else if (PortStatusChange
.SuspendChange
)
1881 DPRINT1("USBH_ProcessPortStateChange: SuspendChange UNIMPLEMENTED. FIXME\n");
1884 else if (PortStatusChange
.OverCurrentIndicatorChange
)
1886 DPRINT1("USBH_ProcessPortStateChange: OverCurrentIndicatorChange UNIMPLEMENTED. FIXME\n");
1889 else if (PortStatusChange
.ResetChange
)
1891 RequestValue
= USBHUB_FEATURE_C_PORT_RESET
;
1892 PortData
->PortStatus
= *PortStatus
;
1893 USBH_SyncClearPortStatus(HubExtension
, Port
, RequestValue
);
1899 USBH_GetPortStatus(IN PUSBHUB_FDO_EXTENSION HubExtension
,
1900 IN PULONG PortStatus
)
1903 PIO_STACK_LOCATION IoStack
;
1906 IO_STATUS_BLOCK IoStatusBlock
;
1908 DPRINT("USBH_GetPortStatus ... \n");
1912 KeInitializeEvent(&Event
, NotificationEvent
, FALSE
);
1914 Irp
= IoBuildDeviceIoControlRequest(IOCTL_INTERNAL_USB_GET_PORT_STATUS
,
1915 HubExtension
->LowerDevice
,
1926 return STATUS_INSUFFICIENT_RESOURCES
;
1929 IoStack
= IoGetNextIrpStackLocation(Irp
);
1930 IoStack
->Parameters
.Others
.Argument1
= PortStatus
;
1932 Status
= IoCallDriver(HubExtension
->LowerDevice
, Irp
);
1934 if (Status
== STATUS_PENDING
)
1936 KeWaitForSingleObject(&Event
,
1944 IoStatusBlock
.Status
= Status
;
1947 return IoStatusBlock
.Status
;
1952 USBH_EnableParentPort(IN PUSBHUB_FDO_EXTENSION HubExtension
)
1957 IO_STATUS_BLOCK IoStatusBlock
;
1959 DPRINT("USBH_EnableParentPort ... \n");
1961 KeInitializeEvent(&Event
, NotificationEvent
, FALSE
);
1963 Irp
= IoBuildDeviceIoControlRequest(IOCTL_INTERNAL_USB_ENABLE_PORT
,
1964 HubExtension
->LowerDevice
,
1975 return STATUS_INSUFFICIENT_RESOURCES
;
1978 Status
= IoCallDriver(HubExtension
->LowerDevice
, Irp
);
1980 if (Status
== STATUS_PENDING
)
1982 KeWaitForSingleObject(&Event
,
1990 IoStatusBlock
.Status
= Status
;
1993 return IoStatusBlock
.Status
;
1998 USBH_ResetInterruptPipe(IN PUSBHUB_FDO_EXTENSION HubExtension
)
2000 struct _URB_PIPE_REQUEST
* Urb
;
2003 DPRINT("USBH_ResetInterruptPipe ... \n");
2005 Urb
= ExAllocatePoolWithTag(NonPagedPool
,
2006 sizeof(struct _URB_PIPE_REQUEST
),
2011 RtlZeroMemory(Urb
, sizeof(struct _URB_PIPE_REQUEST
));
2013 Urb
->Hdr
.Length
= sizeof(struct _URB_PIPE_REQUEST
);
2014 Urb
->Hdr
.Function
= URB_FUNCTION_SYNC_RESET_PIPE_AND_CLEAR_STALL
;
2015 Urb
->PipeHandle
= HubExtension
->PipeInfo
.PipeHandle
;
2017 Status
= USBH_FdoSyncSubmitUrb(HubExtension
->Common
.SelfDevice
,
2020 ExFreePoolWithTag(Urb
, USB_HUB_TAG
);
2024 Status
= STATUS_INSUFFICIENT_RESOURCES
;
2027 if (NT_SUCCESS(Status
))
2029 HubExtension
->RequestErrors
= 0;
2037 USBH_ResetHub(IN PUSBHUB_FDO_EXTENSION HubExtension
)
2040 ULONG PortStatusFlags
= 0;
2042 DPRINT("USBH_ResetHub: ... \n");
2044 Status
= USBH_GetPortStatus(HubExtension
, &PortStatusFlags
);
2046 if (!NT_SUCCESS(Status
))
2051 if (!(PortStatusFlags
& USBD_PORT_ENABLED
))
2053 if (PortStatusFlags
& USBD_PORT_CONNECTED
)
2055 USBH_EnableParentPort(HubExtension
);
2059 Status
= USBH_ResetInterruptPipe(HubExtension
);
2066 USBH_ChangeIndicationWorker(IN PUSBHUB_FDO_EXTENSION HubExtension
,
2069 PUSBHUB_FDO_EXTENSION LowerHubExtension
;
2070 PUSBHUB_PORT_PDO_EXTENSION LowerPortExtension
;
2071 PUSBHUB_STATUS_CHANGE_CONTEXT WorkItem
;
2072 USB_PORT_STATUS_AND_CHANGE PortStatus
;
2076 DPRINT_SCE("USBH_ChangeIndicationWorker ... \n");
2080 KeWaitForSingleObject(&HubExtension
->HubSemaphore
,
2086 if (HubExtension
->HubFlags
& USBHUB_FDO_FLAG_DEVICE_STOPPING
)
2088 KeSetEvent(&HubExtension
->StatusChangeEvent
,
2095 if (!HubExtension
->RequestErrors
)
2100 DPRINT_SCE("USBH_ChangeIndicationWorker: RequestErrors - %x\n",
2101 HubExtension
->RequestErrors
);
2103 if (HubExtension
->LowerPDO
== HubExtension
->RootHubPdo
)
2108 LowerPortExtension
= HubExtension
->LowerPDO
->DeviceExtension
;
2110 if (LowerPortExtension
->PortPdoFlags
& USBHUB_PDO_FLAG_POWER_D1_OR_D2
)
2115 LowerHubExtension
= LowerPortExtension
->HubExtension
;
2117 if (!LowerHubExtension
)
2122 Status
= USBH_SyncGetPortStatus(LowerHubExtension
,
2123 LowerPortExtension
->PortNumber
,
2125 sizeof(USB_PORT_STATUS_AND_CHANGE
));
2127 if (!NT_SUCCESS(Status
) ||
2128 !PortStatus
.PortStatus
.Usb20PortStatus
.CurrentConnectStatus
)
2130 HubExtension
->HubFlags
|= USBHUB_FDO_FLAG_DEVICE_REMOVED
;
2132 KeSetEvent(&HubExtension
->StatusChangeEvent
,
2139 if (!(HubExtension
->HubFlags
& USBHUB_FDO_FLAG_ESD_RECOVERING
))
2141 HubExtension
->HubFlags
|= USBHUB_FDO_FLAG_ESD_RECOVERING
;
2143 DPRINT1("USBH_ChangeIndicationWorker: USBHUB_FDO_FLAG_ESD_RECOVERING FIXME\n");
2151 if (WorkItem
->IsRequestErrors
)
2153 USBH_ResetHub(HubExtension
);
2158 Port
< HubExtension
->HubDescriptor
->bNumberOfPorts
;
2161 if (IsBitSet((PUCHAR
)(WorkItem
+ 1), Port
))
2169 Status
= USBH_SyncGetPortStatus(HubExtension
,
2172 sizeof(USB_PORT_STATUS_AND_CHANGE
));
2176 DPRINT1("USBH_ChangeIndicationWorker: USBH_SyncGetHubStatus() UNIMPLEMENTED. FIXME\n");
2178 Status
= STATUS_ASSERTION_FAILURE
;
2181 if (NT_SUCCESS(Status
))
2185 USBH_ProcessPortStateChange(HubExtension
,
2191 DPRINT1("USBH_ChangeIndicationWorker: USBH_ProcessHubStateChange() UNIMPLEMENTED. FIXME\n");
2197 HubExtension
->RequestErrors
++;
2199 if (HubExtension
->RequestErrors
> USBHUB_MAX_REQUEST_ERRORS
)
2201 HubExtension
->HubFlags
|= USBHUB_FDO_FLAG_DEVICE_FAILED
;
2207 USBH_SubmitStatusChangeTransfer(HubExtension
);
2211 KeReleaseSemaphore(&HubExtension
->HubSemaphore
,
2212 LOW_REALTIME_PRIORITY
,
2216 if (!InterlockedDecrement(&HubExtension
->PendingRequestCount
))
2218 KeSetEvent(&HubExtension
->PendingRequestEvent
,
2223 if (!InterlockedDecrement((PLONG
)&HubExtension
->ResetRequestCount
))
2225 KeSetEvent(&HubExtension
->ResetEvent
,
2229 if (HubExtension
->HubFlags
& USBHUB_FDO_FLAG_DEFER_CHECK_IDLE
)
2231 USBH_CheckHubIdle(HubExtension
);
2238 USBH_ChangeIndication(IN PDEVICE_OBJECT DeviceObject
,
2242 PUSBHUB_FDO_EXTENSION HubExtension
;
2243 USBD_STATUS UrbStatus
;
2244 BOOLEAN IsErrors
= FALSE
;
2245 PUSBHUB_IO_WORK_ITEM HubWorkItem
;
2246 PUSBHUB_STATUS_CHANGE_CONTEXT HubWorkItemBuffer
;
2253 HubExtension
= Context
;
2254 UrbStatus
= HubExtension
->SCEWorkerUrb
.Hdr
.Status
;
2256 DPRINT_SCE("USBH_ChangeIndication: IrpStatus - %x, UrbStatus - %x, HubFlags - %lX\n",
2257 Irp
->IoStatus
.Status
,
2259 HubExtension
->HubFlags
);
2261 if (NT_ERROR(Irp
->IoStatus
.Status
) || USBD_ERROR(UrbStatus
) ||
2262 (HubExtension
->HubFlags
& USBHUB_FDO_FLAG_DEVICE_FAILED
) ||
2263 (HubExtension
->HubFlags
& USBHUB_FDO_FLAG_DEVICE_STOPPING
))
2265 HubExtension
->RequestErrors
++;
2269 KeSetEvent(&HubExtension
->StatusChangeEvent
,
2273 if (HubExtension
->HubFlags
& USBHUB_FDO_FLAG_DEVICE_STOPPING
||
2274 HubExtension
->HubFlags
& USBHUB_FDO_FLAG_DEVICE_FAILED
||
2275 HubExtension
->RequestErrors
> USBHUB_MAX_REQUEST_ERRORS
||
2276 Irp
->IoStatus
.Status
== STATUS_DELETE_PENDING
)
2278 DPRINT_SCE("USBH_ChangeIndication: HubExtension->RequestErrors - %x\n",
2279 HubExtension
->RequestErrors
);
2281 return STATUS_MORE_PROCESSING_REQUIRED
;
2284 DPRINT_SCE("USBH_ChangeIndication: HubExtension->RequestErrors - %x\n",
2285 HubExtension
->RequestErrors
);
2289 HubExtension
->RequestErrors
= 0;
2292 BufferLength
= sizeof(USBHUB_STATUS_CHANGE_CONTEXT
) +
2293 HubExtension
->SCEBitmapLength
;
2295 Status
= USBH_AllocateWorkItem(HubExtension
,
2297 USBH_ChangeIndicationWorker
,
2299 (PVOID
*)&HubWorkItemBuffer
,
2302 if (!NT_SUCCESS(Status
))
2304 return STATUS_MORE_PROCESSING_REQUIRED
;
2307 RtlZeroMemory(HubWorkItemBuffer
, BufferLength
);
2309 HubWorkItemBuffer
->IsRequestErrors
= FALSE
;
2313 HubWorkItemBuffer
->IsRequestErrors
= TRUE
;
2316 if (InterlockedIncrement(&HubExtension
->ResetRequestCount
) == 1)
2318 KeResetEvent(&HubExtension
->ResetEvent
);
2321 HubWorkItemBuffer
->HubExtension
= HubExtension
;
2323 HubExtension
->WorkItemToQueue
= HubWorkItem
;
2325 Bitmap
= HubWorkItemBuffer
+ 1;
2327 RtlCopyMemory(Bitmap
,
2328 HubExtension
->SCEBitmap
,
2329 HubExtension
->SCEBitmapLength
);
2331 NumPorts
= HubExtension
->HubDescriptor
->bNumberOfPorts
;
2333 for (Port
= 0; Port
<= NumPorts
; ++Port
)
2335 if (IsBitSet(Bitmap
, Port
))
2341 if (Port
> NumPorts
)
2346 Status
= USBH_ChangeIndicationQueryChange(HubExtension
,
2347 HubExtension
->ResetPortIrp
,
2348 &HubExtension
->SCEWorkerUrb
,
2351 if (NT_ERROR(Status
))
2353 HubExtension
->HubFlags
|= USBHUB_FDO_FLAG_DEVICE_FAILED
;
2356 return STATUS_MORE_PROCESSING_REQUIRED
;
2361 USBH_SubmitStatusChangeTransfer(IN PUSBHUB_FDO_EXTENSION HubExtension
)
2365 struct _URB_BULK_OR_INTERRUPT_TRANSFER
* Urb
;
2366 PIO_STACK_LOCATION IoStack
;
2368 DPRINT_SCE("USBH_SubmitStatusChangeTransfer: HubExtension - %p, SCEIrp - %p\n",
2370 HubExtension
->SCEIrp
);
2372 if (HubExtension
->HubFlags
& USBHUB_FDO_FLAG_NOT_D0_STATE
)
2374 DPRINT_SCE("USBH_SubmitStatusChangeTransfer: USBHUB_FDO_FLAG_NOT_D0_STATE\n");
2375 DPRINT_SCE("USBH_SubmitStatusChangeTransfer: HubFlags - %lX\n",
2376 HubExtension
->HubFlags
);
2378 return STATUS_INVALID_DEVICE_STATE
;
2381 Irp
= HubExtension
->SCEIrp
;
2385 return STATUS_INVALID_DEVICE_STATE
;
2388 Urb
= (struct _URB_BULK_OR_INTERRUPT_TRANSFER
*)&HubExtension
->SCEWorkerUrb
;
2390 Urb
->Hdr
.Length
= sizeof(struct _URB_BULK_OR_INTERRUPT_TRANSFER
);
2391 Urb
->Hdr
.Function
= URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER
;
2392 Urb
->Hdr
.UsbdDeviceHandle
= NULL
;
2394 Urb
->PipeHandle
= HubExtension
->PipeInfo
.PipeHandle
;
2395 Urb
->TransferFlags
= USBD_SHORT_TRANSFER_OK
;
2396 Urb
->TransferBuffer
= HubExtension
->SCEBitmap
;
2397 Urb
->TransferBufferLength
= HubExtension
->SCEBitmapLength
;
2398 Urb
->TransferBufferMDL
= NULL
;
2399 Urb
->UrbLink
= NULL
;
2401 IoInitializeIrp(Irp
,
2402 IoSizeOfIrp(HubExtension
->LowerDevice
->StackSize
),
2403 HubExtension
->LowerDevice
->StackSize
);
2405 IoStack
= IoGetNextIrpStackLocation(Irp
);
2407 IoStack
->MajorFunction
= IRP_MJ_INTERNAL_DEVICE_CONTROL
;
2408 IoStack
->Parameters
.Others
.Argument1
= &HubExtension
->SCEWorkerUrb
;
2409 IoStack
->Parameters
.DeviceIoControl
.IoControlCode
= IOCTL_INTERNAL_USB_SUBMIT_URB
;
2411 IoSetCompletionRoutine(Irp
,
2412 USBH_ChangeIndication
,
2418 KeResetEvent(&HubExtension
->StatusChangeEvent
);
2420 Status
= IoCallDriver(HubExtension
->LowerDevice
, Irp
);
2427 USBD_CreateDeviceEx(IN PUSBHUB_FDO_EXTENSION HubExtension
,
2428 IN PUSB_DEVICE_HANDLE
* OutDeviceHandle
,
2429 IN USB_PORT_STATUS UsbPortStatus
,
2432 PUSB_DEVICE_HANDLE HubDeviceHandle
;
2433 PUSB_BUSIFFN_CREATE_USB_DEVICE CreateUsbDevice
;
2435 DPRINT("USBD_CreateDeviceEx: Port - %x, UsbPortStatus - 0x%04X\n",
2437 UsbPortStatus
.AsUshort16
);
2439 CreateUsbDevice
= HubExtension
->BusInterface
.CreateUsbDevice
;
2441 if (!CreateUsbDevice
)
2443 return STATUS_NOT_IMPLEMENTED
;
2446 HubDeviceHandle
= USBH_SyncGetDeviceHandle(HubExtension
->LowerDevice
);
2448 return CreateUsbDevice(HubExtension
->BusInterface
.BusContext
,
2451 UsbPortStatus
.AsUshort16
,
2457 USBD_RemoveDeviceEx(IN PUSBHUB_FDO_EXTENSION HubExtension
,
2458 IN PUSB_DEVICE_HANDLE DeviceHandle
,
2461 PUSB_BUSIFFN_REMOVE_USB_DEVICE RemoveUsbDevice
;
2463 DPRINT("USBD_RemoveDeviceEx: DeviceHandle - %p, Flags - %X\n",
2467 RemoveUsbDevice
= HubExtension
->BusInterface
.RemoveUsbDevice
;
2469 if (!RemoveUsbDevice
)
2471 return STATUS_NOT_IMPLEMENTED
;
2474 return RemoveUsbDevice(HubExtension
->BusInterface
.BusContext
,
2481 USBD_InitializeDeviceEx(IN PUSBHUB_FDO_EXTENSION HubExtension
,
2482 IN PUSB_DEVICE_HANDLE DeviceHandle
,
2483 IN PUCHAR DeviceDescriptorBuffer
,
2484 IN ULONG DeviceDescriptorBufferLength
,
2485 IN PUCHAR ConfigDescriptorBuffer
,
2486 IN ULONG ConfigDescriptorBufferLength
)
2489 PUSB_BUSIFFN_INITIALIZE_USB_DEVICE InitializeUsbDevice
;
2490 PUSB_BUSIFFN_GET_USB_DESCRIPTORS GetUsbDescriptors
;
2492 DPRINT("USBD_InitializeDeviceEx: ... \n");
2494 InitializeUsbDevice
= HubExtension
->BusInterface
.InitializeUsbDevice
;
2495 GetUsbDescriptors
= HubExtension
->BusInterface
.GetUsbDescriptors
;
2497 if (!InitializeUsbDevice
|| !GetUsbDescriptors
)
2499 return STATUS_NOT_IMPLEMENTED
;
2502 Status
= InitializeUsbDevice(HubExtension
->BusInterface
.BusContext
,
2505 if (!NT_SUCCESS(Status
))
2510 return GetUsbDescriptors(HubExtension
->BusInterface
.BusContext
,
2512 DeviceDescriptorBuffer
,
2513 &DeviceDescriptorBufferLength
,
2514 ConfigDescriptorBuffer
,
2515 &ConfigDescriptorBufferLength
);
2520 USBHUB_SetDeviceHandleData(IN PUSBHUB_FDO_EXTENSION HubExtension
,
2521 IN PDEVICE_OBJECT UsbDevicePdo
,
2522 IN PVOID DeviceHandle
)
2524 PUSB_BUSIFFN_SET_DEVHANDLE_DATA SetDeviceHandleData
;
2526 DPRINT("USBHUB_SetDeviceHandleData ... \n");
2528 SetDeviceHandleData
= HubExtension
->BusInterface
.SetDeviceHandleData
;
2530 if (!SetDeviceHandleData
)
2535 SetDeviceHandleData(HubExtension
->BusInterface
.BusContext
,
2542 USBHUB_FlushAllTransfers(IN PUSBHUB_FDO_EXTENSION HubExtension
)
2544 PUSB_BUSIFFN_FLUSH_TRANSFERS FlushTransfers
;
2546 DPRINT("USBHUB_FlushAllTransfers ... \n");
2548 FlushTransfers
= HubExtension
->BusInterface
.FlushTransfers
;
2552 FlushTransfers(HubExtension
->BusInterface
.BusContext
, NULL
);
2558 USBD_GetDeviceInformationEx(IN PUSBHUB_PORT_PDO_EXTENSION PortExtension
,
2559 IN PUSBHUB_FDO_EXTENSION HubExtension
,
2560 IN PUSB_NODE_CONNECTION_INFORMATION_EX Info
,
2562 IN PUSB_DEVICE_HANDLE DeviceHandle
)
2564 PUSB_BUSIFFN_GET_DEVICE_INFORMATION QueryDeviceInformation
;
2565 PUSB_DEVICE_INFORMATION_0 DeviceInfo
;
2566 SIZE_T DeviceInfoLength
;
2567 PUSB_NODE_CONNECTION_INFORMATION_EX NodeInfo
;
2568 SIZE_T NodeInfoLength
;
2573 DPRINT("USBD_GetDeviceInformationEx ... \n");
2575 QueryDeviceInformation
= HubExtension
->BusInterface
.QueryDeviceInformation
;
2577 if (!QueryDeviceInformation
)
2579 Status
= STATUS_NOT_IMPLEMENTED
;
2583 DeviceInfoLength
= sizeof(USB_DEVICE_INFORMATION_0
);
2587 DeviceInfo
= ExAllocatePoolWithTag(PagedPool
,
2593 return STATUS_INSUFFICIENT_RESOURCES
;
2596 RtlZeroMemory(DeviceInfo
, DeviceInfoLength
);
2598 DeviceInfo
->InformationLevel
= 0;
2600 Status
= QueryDeviceInformation(HubExtension
->BusInterface
.BusContext
,
2606 if (Status
!= STATUS_BUFFER_TOO_SMALL
)
2611 DeviceInfoLength
= DeviceInfo
->ActualLength
;
2613 ExFreePoolWithTag(DeviceInfo
, USB_HUB_TAG
);
2619 if (NT_SUCCESS(Status
))
2621 NodeInfoLength
= (sizeof(USB_NODE_CONNECTION_INFORMATION_EX
) - sizeof(USB_PIPE_INFO
)) +
2622 DeviceInfo
->NumberOfOpenPipes
* sizeof(USB_PIPE_INFO
);
2624 NodeInfo
= ExAllocatePoolWithTag(PagedPool
, NodeInfoLength
, USB_HUB_TAG
);
2628 ExFreePoolWithTag(DeviceInfo
, USB_HUB_TAG
);
2629 return STATUS_INSUFFICIENT_RESOURCES
;
2632 RtlZeroMemory(NodeInfo
, NodeInfoLength
);
2634 NodeInfo
->ConnectionIndex
= Info
->ConnectionIndex
;
2636 RtlCopyMemory(&NodeInfo
->DeviceDescriptor
,
2637 &DeviceInfo
->DeviceDescriptor
,
2638 sizeof(USB_DEVICE_DESCRIPTOR
));
2640 NodeInfo
->CurrentConfigurationValue
= DeviceInfo
->CurrentConfigurationValue
;
2641 NodeInfo
->Speed
= DeviceInfo
->DeviceSpeed
;
2642 NodeInfo
->DeviceIsHub
= PortExtension
->PortPdoFlags
& USBHUB_PDO_FLAG_HUB_DEVICE
;
2643 NodeInfo
->DeviceAddress
= DeviceInfo
->DeviceAddress
;
2644 NodeInfo
->NumberOfOpenPipes
= DeviceInfo
->NumberOfOpenPipes
;
2645 NodeInfo
->ConnectionStatus
= Info
->ConnectionStatus
;
2647 for (PipeNumber
= 0;
2648 PipeNumber
< DeviceInfo
->NumberOfOpenPipes
;
2651 RtlCopyMemory(&NodeInfo
->PipeList
[PipeNumber
],
2652 &DeviceInfo
->PipeList
[PipeNumber
],
2653 sizeof(USB_PIPE_INFO
));
2657 ExFreePoolWithTag(DeviceInfo
, USB_HUB_TAG
);
2661 if (NodeInfoLength
<= Length
)
2663 Length
= NodeInfoLength
;
2667 Status
= STATUS_BUFFER_TOO_SMALL
;
2670 RtlCopyMemory(Info
, NodeInfo
, Length
);
2672 ExFreePoolWithTag(NodeInfo
, USB_HUB_TAG
);
2680 USBD_RestoreDeviceEx(IN PUSBHUB_FDO_EXTENSION HubExtension
,
2681 IN OUT PUSB_DEVICE_HANDLE OldDeviceHandle
,
2682 IN OUT PUSB_DEVICE_HANDLE NewDeviceHandle
)
2684 PUSB_BUSIFFN_RESTORE_DEVICE RestoreUsbDevice
;
2687 DPRINT("USBD_RestoreDeviceEx: HubExtension - %p, OldDeviceHandle - %p, NewDeviceHandle - %p\n",
2692 RestoreUsbDevice
= HubExtension
->BusInterface
.RestoreUsbDevice
;
2694 if (RestoreUsbDevice
)
2696 Status
= RestoreUsbDevice(HubExtension
->BusInterface
.BusContext
,
2702 Status
= STATUS_NOT_IMPLEMENTED
;
2710 USBH_AllocateWorkItem(PUSBHUB_FDO_EXTENSION HubExtension
,
2711 PUSBHUB_IO_WORK_ITEM
* OutHubIoWorkItem
,
2712 PUSBHUB_WORKER_ROUTINE WorkerRoutine
,
2713 SIZE_T BufferLength
,
2714 PVOID
* OutHubWorkItemBuffer
,
2715 WORK_QUEUE_TYPE Type
)
2717 PUSBHUB_IO_WORK_ITEM HubIoWorkItem
;
2718 PIO_WORKITEM WorkItem
;
2719 PVOID WorkItemBuffer
;
2721 DPRINT("USBH_AllocateWorkItem: ... \n");
2723 if (!(HubExtension
->HubFlags
& USBHUB_FDO_FLAG_WITEM_INIT
))
2725 return STATUS_INVALID_PARAMETER
;
2728 HubIoWorkItem
= ExAllocatePoolWithTag(NonPagedPool
,
2729 sizeof(USBHUB_IO_WORK_ITEM
),
2734 return STATUS_INSUFFICIENT_RESOURCES
;
2737 RtlZeroMemory(HubIoWorkItem
, sizeof(USBHUB_IO_WORK_ITEM
));
2739 WorkItem
= IoAllocateWorkItem(HubExtension
->Common
.SelfDevice
);
2741 HubIoWorkItem
->HubWorkItem
= WorkItem
;
2745 ExFreePoolWithTag(HubIoWorkItem
, USB_HUB_TAG
);
2746 return STATUS_INSUFFICIENT_RESOURCES
;
2749 if (BufferLength
&& OutHubWorkItemBuffer
)
2751 WorkItemBuffer
= ExAllocatePoolWithTag(NonPagedPool
,
2755 HubIoWorkItem
->HubWorkItemBuffer
= WorkItemBuffer
;
2757 if (!WorkItemBuffer
)
2759 IoFreeWorkItem(HubIoWorkItem
->HubWorkItem
);
2760 ExFreePoolWithTag(HubIoWorkItem
, USB_HUB_TAG
);
2762 return STATUS_INSUFFICIENT_RESOURCES
;
2765 RtlZeroMemory(WorkItemBuffer
, BufferLength
);
2769 HubIoWorkItem
->HubWorkItemBuffer
= NULL
;
2772 HubIoWorkItem
->HubWorkItemType
= Type
;
2773 HubIoWorkItem
->HubExtension
= HubExtension
;
2774 HubIoWorkItem
->HubWorkerRoutine
= WorkerRoutine
;
2776 if (OutHubIoWorkItem
)
2778 *OutHubIoWorkItem
= HubIoWorkItem
;
2781 if (OutHubWorkItemBuffer
)
2783 *OutHubWorkItemBuffer
= HubIoWorkItem
->HubWorkItemBuffer
;
2786 return STATUS_SUCCESS
;
2791 USBH_Worker(IN PDEVICE_OBJECT DeviceObject
,
2794 PUSBHUB_IO_WORK_ITEM HubIoWorkItem
;
2795 PUSBHUB_FDO_EXTENSION HubExtension
;
2797 PIO_WORKITEM WorkItem
;
2799 DPRINT("USBH_Worker: HubIoWorkItem - %p\n", Context
);
2801 HubIoWorkItem
= Context
;
2803 InterlockedDecrement(&HubIoWorkItem
->HubWorkerQueued
);
2805 HubExtension
= HubIoWorkItem
->HubExtension
;
2806 WorkItem
= HubIoWorkItem
->HubWorkItem
;
2808 HubIoWorkItem
->HubWorkerRoutine(HubIoWorkItem
->HubExtension
,
2809 HubIoWorkItem
->HubWorkItemBuffer
);
2811 KeAcquireSpinLock(&HubExtension
->WorkItemSpinLock
, &OldIrql
);
2812 RemoveEntryList(&HubIoWorkItem
->HubWorkItemLink
);
2813 KeReleaseSpinLock(&HubExtension
->WorkItemSpinLock
, OldIrql
);
2815 if (HubIoWorkItem
->HubWorkItemBuffer
)
2817 ExFreePoolWithTag(HubIoWorkItem
->HubWorkItemBuffer
, USB_HUB_TAG
);
2820 ExFreePoolWithTag(HubIoWorkItem
, USB_HUB_TAG
);
2822 if (!InterlockedDecrement(&HubExtension
->PendingRequestCount
))
2824 KeSetEvent(&HubExtension
->PendingRequestEvent
,
2829 IoFreeWorkItem(WorkItem
);
2831 DPRINT("USBH_Worker: HubIoWorkItem %p complete\n", Context
);
2836 USBH_QueueWorkItem(IN PUSBHUB_FDO_EXTENSION HubExtension
,
2837 IN PUSBHUB_IO_WORK_ITEM HubIoWorkItem
)
2839 DPRINT("USBH_QueueWorkItem: ... \n");
2841 InterlockedIncrement(&HubExtension
->PendingRequestCount
);
2842 InterlockedIncrement(&HubIoWorkItem
->HubWorkerQueued
);
2844 ExInterlockedInsertTailList(&HubExtension
->WorkItemList
,
2845 &HubIoWorkItem
->HubWorkItemLink
,
2846 &HubExtension
->WorkItemSpinLock
);
2848 IoQueueWorkItem(HubIoWorkItem
->HubWorkItem
,
2850 HubIoWorkItem
->HubWorkItemType
,
2856 USBH_FreeWorkItem(IN PUSBHUB_IO_WORK_ITEM HubIoWorkItem
)
2858 PIO_WORKITEM WorkItem
;
2860 DPRINT("USBH_FreeWorkItem: ... \n");
2862 WorkItem
= HubIoWorkItem
->HubWorkItem
;
2864 if (HubIoWorkItem
->HubWorkItemBuffer
)
2866 ExFreePoolWithTag(HubIoWorkItem
->HubWorkItemBuffer
, USB_HUB_TAG
);
2869 ExFreePoolWithTag(HubIoWorkItem
, USB_HUB_TAG
);
2871 IoFreeWorkItem(WorkItem
);
2876 USBHUB_RootHubCallBack(IN PVOID Context
)
2878 PUSBHUB_FDO_EXTENSION HubExtension
;
2880 DPRINT("USBHUB_RootHubCallBack: ... \n");
2882 HubExtension
= Context
;
2884 if (HubExtension
->SCEIrp
)
2886 HubExtension
->HubFlags
|= (USBHUB_FDO_FLAG_DO_ENUMERATION
|
2887 USBHUB_FDO_FLAG_NOT_ENUMERATED
);
2889 USBH_SubmitStatusChangeTransfer(HubExtension
);
2891 IoInvalidateDeviceRelations(HubExtension
->LowerPDO
, BusRelations
);
2895 HubExtension
->HubFlags
|= USBHUB_FDO_FLAG_DO_ENUMERATION
;
2898 KeSetEvent(&HubExtension
->RootHubNotificationEvent
,
2905 USBD_RegisterRootHubCallBack(IN PUSBHUB_FDO_EXTENSION HubExtension
)
2907 PUSB_BUSIFFN_ROOTHUB_INIT_NOTIFY RootHubInitNotification
;
2909 DPRINT("USBD_RegisterRootHubCallBack: ... \n");
2911 RootHubInitNotification
= HubExtension
->BusInterface
.RootHubInitNotification
;
2913 if (!RootHubInitNotification
)
2915 return STATUS_NOT_IMPLEMENTED
;
2918 KeResetEvent(&HubExtension
->RootHubNotificationEvent
);
2920 return RootHubInitNotification(HubExtension
->BusInterface
.BusContext
,
2922 USBHUB_RootHubCallBack
);
2927 USBD_UnRegisterRootHubCallBack(IN PUSBHUB_FDO_EXTENSION HubExtension
)
2929 PUSB_BUSIFFN_ROOTHUB_INIT_NOTIFY RootHubInitNotification
;
2932 DPRINT("USBD_UnRegisterRootHubCallBack ... \n");
2934 RootHubInitNotification
= HubExtension
->BusInterface
.RootHubInitNotification
;
2936 if (!RootHubInitNotification
)
2938 return STATUS_NOT_IMPLEMENTED
;
2941 Status
= RootHubInitNotification(HubExtension
->BusInterface
.BusContext
,
2945 if (!NT_SUCCESS(Status
))
2947 KeWaitForSingleObject(&HubExtension
->RootHubNotificationEvent
,
2959 USBH_HubSetDWakeCompletion(IN PDEVICE_OBJECT DeviceObject
,
2960 IN UCHAR MinorFunction
,
2961 IN POWER_STATE PowerState
,
2963 IN PIO_STATUS_BLOCK IoStatus
)
2965 DPRINT("USBH_HubSetDWakeCompletion: ... \n");
2966 KeSetEvent((PRKEVENT
)Context
, IO_NO_INCREMENT
, FALSE
);
2971 USBH_HubQueuePortIdleIrps(IN PUSBHUB_FDO_EXTENSION HubExtension
,
2972 IN PLIST_ENTRY IdleList
)
2974 PDEVICE_OBJECT PortDevice
;
2975 PUSBHUB_PORT_PDO_EXTENSION PortExtension
;
2982 DPRINT("USBH_HubQueuePortIdleIrps ... \n");
2984 InitializeListHead(IdleList
);
2986 IoAcquireCancelSpinLock(&Irql
);
2988 NumPorts
= HubExtension
->HubDescriptor
->bNumberOfPorts
;
2990 for (Port
= 0; Port
< NumPorts
; ++Port
)
2992 PortDevice
= HubExtension
->PortData
[Port
].DeviceObject
;
2996 PortExtension
= PortDevice
->DeviceExtension
;
2998 IdleIrp
= PortExtension
->IdleNotificationIrp
;
2999 PortExtension
->IdleNotificationIrp
= NULL
;
3001 if (IdleIrp
&& IoSetCancelRoutine(IdleIrp
, NULL
))
3003 DPRINT1("USBH_HubQueuePortIdleIrps: IdleIrp != NULL. FIXME\n");
3009 if (HubExtension
->HubFlags
& USBHUB_FDO_FLAG_WAIT_IDLE_REQUEST
)
3011 HubIdleIrp
= HubExtension
->PendingIdleIrp
;
3012 HubExtension
->PendingIdleIrp
= NULL
;
3019 IoReleaseCancelSpinLock(Irql
);
3023 USBH_HubCancelIdleIrp(HubExtension
, HubIdleIrp
);
3029 USBH_HubCompleteQueuedPortIdleIrps(IN PUSBHUB_FDO_EXTENSION HubExtension
,
3030 IN PLIST_ENTRY IdleList
,
3031 IN NTSTATUS NtStatus
)
3033 DPRINT("USBH_HubCompleteQueuedPortIdleIrps ... \n");
3035 while (!IsListEmpty(IdleList
))
3037 DPRINT1("USBH_HubCompleteQueuedPortIdleIrps: IdleList not Empty. FIXME\n");
3044 USBH_FlushPortPwrList(IN PUSBHUB_FDO_EXTENSION HubExtension
)
3046 PDEVICE_OBJECT PortDevice
;
3047 PUSBHUB_PORT_PDO_EXTENSION PortExtension
;
3051 DPRINT("USBH_FlushPortPwrList ... \n");
3053 InterlockedIncrement((PLONG
)&HubExtension
->PendingRequestCount
);
3055 KeWaitForSingleObject(&HubExtension
->ResetDeviceSemaphore
,
3061 for (Port
= 0; Port
< HubExtension
->HubDescriptor
->bNumberOfPorts
; ++Port
)
3063 PortDevice
= HubExtension
->PortData
[Port
].DeviceObject
;
3070 PortExtension
= PortDevice
->DeviceExtension
;
3072 InterlockedExchange((PLONG
)&PortExtension
->StateBehindD2
, 0);
3076 Entry
= ExInterlockedRemoveHeadList(&PortExtension
->PortPowerList
,
3077 &PortExtension
->PortPowerListSpinLock
);
3084 DPRINT1("USBH_FlushPortPwrList: PortPowerList FIXME\n");
3089 KeReleaseSemaphore(&HubExtension
->ResetDeviceSemaphore
,
3090 LOW_REALTIME_PRIORITY
,
3094 if (!InterlockedDecrement((PLONG
)&HubExtension
->PendingRequestCount
))
3096 KeSetEvent(&HubExtension
->PendingRequestEvent
,
3104 USBH_HubCompletePortIdleIrps(IN PUSBHUB_FDO_EXTENSION HubExtension
,
3105 IN NTSTATUS NtStatus
)
3107 LIST_ENTRY IdleList
;
3109 DPRINT("USBH_HubCompletePortIdleIrps ... \n");
3111 if (HubExtension
->HubFlags
& USBHUB_FDO_FLAG_DEVICE_STARTED
)
3113 USBH_HubQueuePortIdleIrps(HubExtension
, &IdleList
);
3115 USBH_HubCompleteQueuedPortIdleIrps(HubExtension
,
3119 USBH_FlushPortPwrList(HubExtension
);
3125 USBH_HubCancelIdleIrp(IN PUSBHUB_FDO_EXTENSION HubExtension
,
3128 DPRINT("USBH_HubCancelIdleIrp ... \n");
3130 IoCancelIrp(IdleIrp
);
3132 if (InterlockedExchange(&HubExtension
->IdleRequestLock
, 1))
3140 USBH_CheckIdleAbort(IN PUSBHUB_FDO_EXTENSION HubExtension
,
3142 IN BOOLEAN IsExtCheck
)
3144 PDEVICE_OBJECT PdoDevice
;
3145 PUSBHUB_PORT_PDO_EXTENSION PortExtension
;
3146 PUSBHUB_PORT_DATA PortData
;
3148 BOOLEAN Result
= FALSE
;
3150 DPRINT("USBH_CheckIdleAbort: ... \n");
3152 InterlockedIncrement(&HubExtension
->PendingRequestCount
);
3156 KeWaitForSingleObject(&HubExtension
->ResetDeviceSemaphore
,
3163 PortData
= HubExtension
->PortData
;
3165 for (Port
= 0; Port
< HubExtension
->HubDescriptor
->bNumberOfPorts
; Port
++)
3167 PdoDevice
= PortData
[Port
].DeviceObject
;
3171 PortExtension
= PdoDevice
->DeviceExtension
;
3173 if (PortExtension
->PoRequestCounter
)
3181 if (IsExtCheck
== TRUE
)
3183 PortData
= HubExtension
->PortData
;
3186 Port
< HubExtension
->HubDescriptor
->bNumberOfPorts
;
3189 PdoDevice
= PortData
[Port
].DeviceObject
;
3193 PortExtension
= PdoDevice
->DeviceExtension
;
3194 InterlockedExchange(&PortExtension
->StateBehindD2
, 0);
3203 KeReleaseSemaphore(&HubExtension
->ResetDeviceSemaphore
,
3204 LOW_REALTIME_PRIORITY
,
3209 if (!InterlockedDecrement(&HubExtension
->PendingRequestCount
))
3211 KeSetEvent(&HubExtension
->PendingRequestEvent
,
3221 USBH_FdoWaitWakeIrpCompletion(IN PDEVICE_OBJECT DeviceObject
,
3222 IN UCHAR MinorFunction
,
3223 IN POWER_STATE PowerState
,
3225 IN PIO_STATUS_BLOCK IoStatus
)
3227 DPRINT("USBH_FdoWaitWakeIrpCompletion ... \n");
3232 USBH_FdoSubmitWaitWakeIrp(IN PUSBHUB_FDO_EXTENSION HubExtension
)
3234 POWER_STATE PowerState
;
3239 DPRINT("USBH_FdoSubmitWaitWakeIrp: ... \n");
3241 PowerState
.SystemState
= HubExtension
->SystemWake
;
3242 HubExtension
->HubFlags
|= USBHUB_FDO_FLAG_PENDING_WAKE_IRP
;
3244 InterlockedIncrement(&HubExtension
->PendingRequestCount
);
3245 InterlockedExchange(&HubExtension
->FdoWaitWakeLock
, 0);
3247 Status
= PoRequestPowerIrp(HubExtension
->LowerPDO
,
3250 USBH_FdoWaitWakeIrpCompletion
,
3254 IoAcquireCancelSpinLock(&Irql
);
3256 if (Status
== STATUS_PENDING
)
3258 if (HubExtension
->HubFlags
& USBHUB_FDO_FLAG_PENDING_WAKE_IRP
)
3260 HubExtension
->PendingWakeIrp
= Irp
;
3261 DPRINT("USBH_FdoSubmitWaitWakeIrp: PendingWakeIrp - %p\n",
3262 HubExtension
->PendingWakeIrp
);
3267 HubExtension
->HubFlags
&= ~USBHUB_FDO_FLAG_PENDING_WAKE_IRP
;
3269 if (!InterlockedDecrement(&HubExtension
->PendingRequestCount
))
3271 KeSetEvent(&HubExtension
->PendingRequestEvent
,
3277 IoReleaseCancelSpinLock(Irql
);
3284 USBH_FdoIdleNotificationCallback(IN PVOID Context
)
3286 PUSBHUB_FDO_EXTENSION HubExtension
;
3287 PUSBHUB_PORT_DATA PortData
;
3288 PDEVICE_OBJECT PortDevice
;
3289 PUSBHUB_PORT_PDO_EXTENSION PortExtension
;
3292 POWER_STATE PowerState
;
3295 PIO_STACK_LOCATION IoStack
;
3296 PUSB_IDLE_CALLBACK_INFO CallbackInfo
;
3301 HubExtension
= Context
;
3303 DPRINT("USBH_FdoIdleNotificationCallback: HubExtension - %p, HubFlags - %lX\n",
3305 HubExtension
->HubFlags
);
3307 if (HubExtension
->HubFlags
& (USBHUB_FDO_FLAG_ENUM_POST_RECOVER
|
3308 USBHUB_FDO_FLAG_WAKEUP_START
|
3309 USBHUB_FDO_FLAG_DEVICE_REMOVED
|
3310 USBHUB_FDO_FLAG_STATE_CHANGING
|
3311 USBHUB_FDO_FLAG_ESD_RECOVERING
|
3312 USBHUB_FDO_FLAG_DEVICE_FAILED
|
3313 USBHUB_FDO_FLAG_DEVICE_STOPPING
))
3319 HubExtension
->HubFlags
|= USBHUB_FDO_FLAG_GOING_IDLE
;
3321 if (!(HubExtension
->HubFlags
& USBHUB_FDO_FLAG_PENDING_WAKE_IRP
))
3323 Status
= USBH_FdoSubmitWaitWakeIrp(HubExtension
);
3325 if (Status
!= STATUS_PENDING
)
3327 DPRINT("Status != STATUS_PENDING. DbgBreakPoint()\n");
3329 HubExtension
->HubFlags
&= ~USBHUB_FDO_FLAG_GOING_IDLE
;
3334 InterlockedIncrement(&HubExtension
->PendingRequestCount
);
3336 KeWaitForSingleObject(&HubExtension
->ResetDeviceSemaphore
,
3342 PortData
= HubExtension
->PortData
;
3346 Port
< HubExtension
->HubDescriptor
->bNumberOfPorts
;
3349 PortDevice
= PortData
[Port
].DeviceObject
;
3353 PortExtension
= PortDevice
->DeviceExtension
;
3355 IdleIrp
= PortExtension
->IdleNotificationIrp
;
3363 IoStack
= IoGetCurrentIrpStackLocation(IdleIrp
);
3365 CallbackInfo
= IoStack
->Parameters
.DeviceIoControl
.Type3InputBuffer
;
3373 if (!CallbackInfo
->IdleCallback
)
3379 if (PortExtension
->PendingSystemPoRequest
)
3385 if (InterlockedCompareExchange(&PortExtension
->StateBehindD2
,
3393 DPRINT("USBH_FdoIdleNotificationCallback: IdleContext - %p\n",
3394 CallbackInfo
->IdleContext
);
3396 CallbackInfo
->IdleCallback(CallbackInfo
->IdleContext
);
3398 if (PortExtension
->CurrentPowerState
.DeviceState
== PowerDeviceD0
)
3406 if (!(HubExtension
->HubFlags
& USBHUB_FDO_FLAG_DEVICE_STOPPING
) &&
3407 (USBH_CheckIdleAbort(HubExtension
, FALSE
, FALSE
) == TRUE
))
3414 KeReleaseSemaphore(&HubExtension
->ResetDeviceSemaphore
,
3415 LOW_REALTIME_PRIORITY
,
3419 if (!InterlockedDecrement(&HubExtension
->PendingRequestCount
))
3421 KeSetEvent(&HubExtension
->PendingRequestEvent
,
3427 (HubExtension
->HubFlags
& USBHUB_FDO_FLAG_DEVICE_SUSPENDED
))
3429 DPRINT1("USBH_FdoIdleNotificationCallback: HubFlags - %lX\n",
3430 HubExtension
->HubFlags
);
3432 HubExtension
->HubFlags
&= ~(USBHUB_FDO_FLAG_DEVICE_SUSPENDED
|
3433 USBHUB_FDO_FLAG_GOING_IDLE
);
3435 /* Aborting Idle for Hub */
3436 IoAcquireCancelSpinLock(&OldIrql
);
3438 if (HubExtension
->PendingIdleIrp
)
3440 Irp
= HubExtension
->PendingIdleIrp
;
3441 HubExtension
->PendingIdleIrp
= NULL
;
3444 IoReleaseCancelSpinLock(OldIrql
);
3448 USBH_HubCancelIdleIrp(HubExtension
, Irp
);
3452 USBH_HubCompletePortIdleIrps(HubExtension
, STATUS_CANCELLED
);
3456 PowerState
.DeviceState
= HubExtension
->DeviceWake
;
3458 KeWaitForSingleObject(&HubExtension
->IdleSemaphore
,
3464 HubExtension
->HubFlags
&= ~USBHUB_FDO_FLAG_GOING_IDLE
;
3465 HubExtension
->HubFlags
|= USBHUB_FDO_FLAG_DO_SUSPENSE
;
3467 KeInitializeEvent(&Event
, NotificationEvent
, FALSE
);
3469 DPRINT("USBH_FdoIdleNotificationCallback: LowerPdo - %p\n",
3470 HubExtension
->LowerPDO
);
3472 DPRINT("USBH_FdoIdleNotificationCallback: PowerState.DeviceState - %x\n",
3473 PowerState
.DeviceState
);
3475 Status
= PoRequestPowerIrp(HubExtension
->LowerPDO
,
3478 USBH_HubSetDWakeCompletion
,
3482 if (Status
== STATUS_PENDING
)
3484 KeWaitForSingleObject(&Event
,
3495 USBH_CompletePortIdleIrpsWorker(IN PUSBHUB_FDO_EXTENSION HubExtension
,
3498 PUSBHUB_IDLE_PORT_CONTEXT IdlePortContext
;
3501 BOOLEAN IsFlush
= FALSE
;
3503 DPRINT("USBH_CompletePortIdleIrpsWorker ... \n");
3505 IdlePortContext
= Context
;
3506 NtStatus
= IdlePortContext
->Status
;
3508 USBH_HubCompleteQueuedPortIdleIrps(HubExtension
,
3509 &IdlePortContext
->PwrList
,
3512 DPRINT1("USBH_CompletePortIdleIrpsWorker: USBH_RegQueryFlushPortPowerIrpsFlag() UNIMPLEMENTED. FIXME\n");
3513 Status
= STATUS_NOT_IMPLEMENTED
;// USBH_RegQueryFlushPortPowerIrpsFlag(&IsFlush);
3515 if (NT_SUCCESS(Status
))
3519 USBH_FlushPortPwrList(HubExtension
);
3526 USBH_IdleCompletePowerHubWorker(IN PUSBHUB_FDO_EXTENSION HubExtension
,
3529 PUSBHUB_IDLE_HUB_CONTEXT HubWorkItemBuffer
;
3531 DPRINT("USBH_IdleCompletePowerHubWorker ... \n");
3534 HubExtension
->CurrentPowerState
.DeviceState
!= PowerDeviceD0
&&
3535 HubExtension
->HubFlags
& USBHUB_FDO_FLAG_DEVICE_STARTED
)
3537 USBH_HubSetD0(HubExtension
);
3540 HubWorkItemBuffer
= Context
;
3542 USBH_HubCompletePortIdleIrps(HubExtension
, HubWorkItemBuffer
->Status
);
3548 USBH_FdoIdleNotificationRequestComplete(IN PDEVICE_OBJECT DeviceObject
,
3552 PUSBHUB_FDO_EXTENSION HubExtension
;
3557 PUSBHUB_IO_WORK_ITEM HubIoWorkItem
;
3559 IoAcquireCancelSpinLock(&Irql
);
3561 HubExtension
= Context
;
3562 HubExtension
->HubFlags
&= ~USBHUB_FDO_FLAG_WAIT_IDLE_REQUEST
;
3564 IdleIrp
= InterlockedExchangePointer((PVOID
)&HubExtension
->PendingIdleIrp
,
3567 DPRINT("USBH_FdoIdleNotificationRequestComplete: IdleIrp - %p\n", IdleIrp
);
3569 if (!InterlockedDecrement(&HubExtension
->PendingRequestCount
))
3571 KeSetEvent(&HubExtension
->PendingRequestEvent
, EVENT_INCREMENT
, FALSE
);
3574 IoReleaseCancelSpinLock(Irql
);
3576 NtStatus
= Irp
->IoStatus
.Status
;
3578 DPRINT("USBH_FdoIdleNotificationRequestComplete: NtStatus - %lX\n",
3581 if (!NT_SUCCESS(NtStatus
) &&
3582 NtStatus
!= STATUS_POWER_STATE_INVALID
&&
3583 !(HubExtension
->HubFlags
& USBHUB_FDO_FLAG_DEVICE_REMOVED
) &&
3584 !(HubExtension
->HubFlags
& USBHUB_FDO_FLAG_DEVICE_STOPPED
))
3586 DPRINT("USBH_FdoIdleNotificationRequestComplete: DeviceState - %x\n",
3587 HubExtension
->CurrentPowerState
.DeviceState
);
3589 if (HubExtension
->CurrentPowerState
.DeviceState
== PowerDeviceD0
)
3591 PUSBHUB_IDLE_PORT_CONTEXT HubWorkItemBuffer
;
3593 Status
= USBH_AllocateWorkItem(HubExtension
,
3595 USBH_CompletePortIdleIrpsWorker
,
3596 sizeof(USBHUB_IDLE_PORT_CONTEXT
),
3597 (PVOID
*)&HubWorkItemBuffer
,
3600 if (NT_SUCCESS(Status
))
3602 HubWorkItemBuffer
->Status
= NtStatus
;
3604 USBH_HubQueuePortIdleIrps(HubExtension
,
3605 &HubWorkItemBuffer
->PwrList
);
3607 USBH_QueueWorkItem(HubExtension
, HubIoWorkItem
);
3612 PUSBHUB_IDLE_HUB_CONTEXT HubWorkItemBuffer
;
3614 Status
= USBH_AllocateWorkItem(HubExtension
,
3616 USBH_IdleCompletePowerHubWorker
,
3617 sizeof(USBHUB_IDLE_HUB_CONTEXT
),
3618 (PVOID
*)&HubWorkItemBuffer
,
3621 if (NT_SUCCESS(Status
))
3623 HubWorkItemBuffer
->Status
= NtStatus
;
3624 USBH_QueueWorkItem(HubExtension
, HubIoWorkItem
);
3630 InterlockedExchange((PLONG
)&HubExtension
->IdleRequestLock
, 1))
3632 DPRINT("USBH_FdoIdleNotificationRequestComplete: Irp - %p\n", Irp
);
3636 return STATUS_MORE_PROCESSING_REQUIRED
;
3641 USBH_FdoSubmitIdleRequestIrp(IN PUSBHUB_FDO_EXTENSION HubExtension
)
3645 PDEVICE_OBJECT LowerPDO
;
3647 PIO_STACK_LOCATION IoStack
;
3650 DPRINT("USBH_FdoSubmitIdleRequestIrp: HubExtension - %p, PendingIdleIrp - %p\n",
3652 HubExtension
->PendingIdleIrp
);
3654 if (HubExtension
->PendingIdleIrp
)
3656 Status
= STATUS_DEVICE_BUSY
;
3657 KeSetEvent(&HubExtension
->IdleEvent
, EVENT_INCREMENT
, FALSE
);
3661 HubFlags
= HubExtension
->HubFlags
;
3663 if (HubFlags
& USBHUB_FDO_FLAG_DEVICE_STOPPING
||
3664 HubFlags
& USBHUB_FDO_FLAG_DEVICE_REMOVED
)
3666 HubExtension
->HubFlags
= HubFlags
& ~USBHUB_FDO_FLAG_WAIT_IDLE_REQUEST
;
3667 KeSetEvent(&HubExtension
->IdleEvent
, EVENT_INCREMENT
, FALSE
);
3668 return STATUS_DEVICE_REMOVED
;
3671 LowerPDO
= HubExtension
->LowerPDO
;
3673 HubExtension
->IdleCallbackInfo
.IdleCallback
= USBH_FdoIdleNotificationCallback
;
3674 HubExtension
->IdleCallbackInfo
.IdleContext
= HubExtension
;
3676 Irp
= IoAllocateIrp(LowerPDO
->StackSize
, FALSE
);
3680 HubExtension
->HubFlags
&= ~USBHUB_FDO_FLAG_WAIT_IDLE_REQUEST
;
3681 Status
= STATUS_INSUFFICIENT_RESOURCES
;
3683 KeSetEvent(&HubExtension
->IdleEvent
, EVENT_INCREMENT
, FALSE
);
3687 IoStack
= IoGetNextIrpStackLocation(Irp
);
3689 IoStack
->MajorFunction
= IRP_MJ_INTERNAL_DEVICE_CONTROL
;
3691 IoStack
->Parameters
.DeviceIoControl
.InputBufferLength
= sizeof(USB_IDLE_CALLBACK_INFO
);
3692 IoStack
->Parameters
.DeviceIoControl
.IoControlCode
= IOCTL_INTERNAL_USB_SUBMIT_IDLE_NOTIFICATION
;
3693 IoStack
->Parameters
.DeviceIoControl
.Type3InputBuffer
= &HubExtension
->IdleCallbackInfo
;
3695 IoSetCompletionRoutine(Irp
,
3696 USBH_FdoIdleNotificationRequestComplete
,
3702 InterlockedIncrement(&HubExtension
->PendingRequestCount
);
3703 InterlockedExchange(&HubExtension
->IdleRequestLock
, 0);
3705 HubExtension
->HubFlags
&= ~(USBHUB_FDO_FLAG_DEVICE_SUSPENDED
|
3706 USBHUB_FDO_FLAG_GOING_IDLE
);
3708 Status
= IoCallDriver(HubExtension
->LowerPDO
, Irp
);
3710 IoAcquireCancelSpinLock(&Irql
);
3712 if (Status
== STATUS_PENDING
&&
3713 HubExtension
->HubFlags
& USBHUB_FDO_FLAG_WAIT_IDLE_REQUEST
)
3715 HubExtension
->PendingIdleIrp
= Irp
;
3718 IoReleaseCancelSpinLock(Irql
);
3720 KeSetEvent(&HubExtension
->IdleEvent
, EVENT_INCREMENT
, FALSE
);
3727 USBH_CheckHubIdle(IN PUSBHUB_FDO_EXTENSION HubExtension
)
3729 PDEVICE_OBJECT PdoDevice
;
3730 PUSBHUB_PORT_PDO_EXTENSION PortExtension
;
3731 PUSBHUB_PORT_DATA PortData
;
3735 BOOLEAN IsHubIdle
= FALSE
;
3736 BOOLEAN IsAllPortsIdle
;
3737 BOOLEAN IsHubCheck
= TRUE
;
3739 DPRINT("USBH_CheckHubIdle: FIXME !!! HubExtension - %p\n", HubExtension
);
3741 return; //HACK: delete it line after fixing Power Manager!!!
3743 KeAcquireSpinLock(&HubExtension
->CheckIdleSpinLock
, &Irql
);
3745 if (HubExtension
->HubFlags
& USBHUB_FDO_FLAG_CHECK_IDLE_LOCK
)
3747 KeReleaseSpinLock(&HubExtension
->CheckIdleSpinLock
, Irql
);
3751 HubExtension
->HubFlags
|= USBHUB_FDO_FLAG_CHECK_IDLE_LOCK
;
3752 KeReleaseSpinLock(&HubExtension
->CheckIdleSpinLock
, Irql
);
3754 if (USBH_GetRootHubExtension(HubExtension
)->SystemPowerState
.SystemState
!= PowerSystemWorking
)
3756 KeAcquireSpinLock(&HubExtension
->CheckIdleSpinLock
, &Irql
);
3757 HubExtension
->HubFlags
&= ~USBHUB_FDO_FLAG_CHECK_IDLE_LOCK
;
3758 KeReleaseSpinLock(&HubExtension
->CheckIdleSpinLock
, Irql
);
3762 HubFlags
= HubExtension
->HubFlags
;
3763 DPRINT("USBH_CheckHubIdle: HubFlags - %lX\n", HubFlags
);
3765 if (!(HubFlags
& USBHUB_FDO_FLAG_DEVICE_STARTED
) ||
3766 !(HubFlags
& USBHUB_FDO_FLAG_DO_ENUMERATION
))
3771 if (HubFlags
& USBHUB_FDO_FLAG_NOT_ENUMERATED
||
3772 HubFlags
& USBHUB_FDO_FLAG_ENUM_POST_RECOVER
||
3773 HubFlags
& USBHUB_FDO_FLAG_DEVICE_FAILED
||
3774 HubFlags
& USBHUB_FDO_FLAG_DEVICE_STOPPING
||
3775 HubFlags
& USBHUB_FDO_FLAG_DEVICE_REMOVED
||
3776 HubFlags
& USBHUB_FDO_FLAG_STATE_CHANGING
||
3777 HubFlags
& USBHUB_FDO_FLAG_WAKEUP_START
||
3778 HubFlags
& USBHUB_FDO_FLAG_ESD_RECOVERING
)
3783 if (HubExtension
->ResetRequestCount
)
3785 HubExtension
->HubFlags
|= USBHUB_FDO_FLAG_DEFER_CHECK_IDLE
;
3789 HubExtension
->HubFlags
&= ~USBHUB_FDO_FLAG_DEFER_CHECK_IDLE
;
3791 InterlockedIncrement(&HubExtension
->PendingRequestCount
);
3793 KeWaitForSingleObject(&HubExtension
->ResetDeviceSemaphore
,
3799 IoAcquireCancelSpinLock(&Irql
);
3801 IsAllPortsIdle
= TRUE
;
3803 PortData
= HubExtension
->PortData
;
3806 Port
< HubExtension
->HubDescriptor
->bNumberOfPorts
;
3809 PdoDevice
= PortData
[Port
].DeviceObject
;
3813 PortExtension
= PdoDevice
->DeviceExtension
;
3815 if (!PortExtension
->IdleNotificationIrp
)
3817 DPRINT("USBH_CheckHubIdle: PortExtension - %p\n",
3820 IsAllPortsIdle
= FALSE
;
3829 !(HubExtension
->HubFlags
& USBHUB_FDO_FLAG_WAIT_IDLE_REQUEST
))
3831 KeResetEvent(&HubExtension
->IdleEvent
);
3832 HubExtension
->HubFlags
|= USBHUB_FDO_FLAG_WAIT_IDLE_REQUEST
;
3836 IoReleaseCancelSpinLock(Irql
);
3838 KeReleaseSemaphore(&HubExtension
->ResetDeviceSemaphore
,
3839 LOW_REALTIME_PRIORITY
,
3843 if (!InterlockedDecrement(&HubExtension
->PendingRequestCount
))
3845 KeSetEvent(&HubExtension
->PendingRequestEvent
,
3850 DPRINT("USBH_CheckHubIdle: IsAllPortsIdle - %x, IsHubIdle - %x\n",
3854 if (IsAllPortsIdle
&& IsHubIdle
)
3856 USBH_FdoSubmitIdleRequestIrp(HubExtension
);
3860 KeAcquireSpinLock(&HubExtension
->CheckIdleSpinLock
, &Irql
);
3861 HubExtension
->HubFlags
&= ~USBHUB_FDO_FLAG_CHECK_IDLE_LOCK
;
3862 KeReleaseSpinLock(&HubExtension
->CheckIdleSpinLock
, Irql
);
3867 USBH_CheckIdleWorker(IN PUSBHUB_FDO_EXTENSION HubExtension
,
3870 DPRINT("USBH_CheckIdleWorker: ... \n");
3871 USBH_CheckHubIdle(HubExtension
);
3876 USBH_CheckIdleDeferred(IN PUSBHUB_FDO_EXTENSION HubExtension
)
3878 PUSBHUB_IO_WORK_ITEM HubIoWorkItem
;
3881 DPRINT("USBH_CheckIdleDeferred: HubExtension - %p\n", HubExtension
);
3883 Status
= USBH_AllocateWorkItem(HubExtension
,
3885 USBH_CheckIdleWorker
,
3890 DPRINT("USBH_CheckIdleDeferred: HubIoWorkItem - %p\n", HubIoWorkItem
);
3892 if (NT_SUCCESS(Status
))
3894 USBH_QueueWorkItem(HubExtension
, HubIoWorkItem
);
3900 USBH_PdoSetCapabilities(IN PUSBHUB_PORT_PDO_EXTENSION PortExtension
)
3902 PUSBHUB_FDO_EXTENSION HubExtension
;
3904 SYSTEM_POWER_STATE SystemPowerState
;
3905 PDEVICE_POWER_STATE pDeviceState
;
3907 DPRINT("USBH_PdoSetCapabilities ... \n");
3909 HubExtension
= PortExtension
->HubExtension
;
3911 PortExtension
->Capabilities
.Size
= 64;
3912 PortExtension
->Capabilities
.Version
= 1;
3914 PortExtension
->Capabilities
.Removable
= 1;
3915 PortExtension
->Capabilities
.Address
= PortExtension
->PortNumber
;
3917 if (PortExtension
->SerialNumber
)
3919 PortExtension
->Capabilities
.UniqueID
= 1;
3923 PortExtension
->Capabilities
.UniqueID
= 0;
3926 PortExtension
->Capabilities
.RawDeviceOK
= 0;
3928 RtlCopyMemory(PortExtension
->Capabilities
.DeviceState
,
3929 HubExtension
->DeviceState
,
3930 (PowerSystemMaximum
+ 2) * sizeof(POWER_STATE
));
3932 PortExtension
->Capabilities
.DeviceState
[1] = PowerDeviceD0
;
3934 if (PortExtension
->PortPdoFlags
& USBHUB_PDO_FLAG_REMOTE_WAKEUP
)
3936 PortExtension
->Capabilities
.DeviceWake
= PowerDeviceD2
;
3938 PortExtension
->Capabilities
.DeviceD1
= 1;
3939 PortExtension
->Capabilities
.DeviceD2
= 1;
3941 PortExtension
->Capabilities
.WakeFromD0
= 1;
3942 PortExtension
->Capabilities
.WakeFromD1
= 1;
3943 PortExtension
->Capabilities
.WakeFromD2
= 1;
3945 pDeviceState
= &PortExtension
->Capabilities
.DeviceState
[2];
3947 for (State
= 2; State
<= 5; State
++)
3949 SystemPowerState
= State
;
3951 if (PortExtension
->Capabilities
.SystemWake
< SystemPowerState
)
3953 *pDeviceState
= PowerDeviceD3
;
3957 *pDeviceState
= PowerDeviceD2
;
3965 PortExtension
->Capabilities
.DeviceWake
= PowerDeviceD0
;
3966 PortExtension
->Capabilities
.DeviceState
[2] = PowerDeviceD3
;
3967 PortExtension
->Capabilities
.DeviceState
[3] = PowerDeviceD3
;
3968 PortExtension
->Capabilities
.DeviceState
[4] = PowerDeviceD3
;
3969 PortExtension
->Capabilities
.DeviceState
[5] = PowerDeviceD3
;
3975 USBH_ProcessDeviceInformation(IN PUSBHUB_PORT_PDO_EXTENSION PortExtension
)
3977 PUSB_INTERFACE_DESCRIPTOR Pid
;
3978 PUSB_CONFIGURATION_DESCRIPTOR ConfigDescriptor
;
3981 DPRINT("USBH_ProcessDeviceInformation ... \n");
3983 ConfigDescriptor
= NULL
;
3985 RtlZeroMemory(&PortExtension
->InterfaceDescriptor
,
3986 sizeof(PortExtension
->InterfaceDescriptor
));
3988 PortExtension
->PortPdoFlags
&= ~USBHUB_PDO_FLAG_HUB_DEVICE
;
3990 Status
= USBH_GetConfigurationDescriptor(PortExtension
->Common
.SelfDevice
,
3993 if (!NT_SUCCESS(Status
))
3995 if (ConfigDescriptor
)
3997 ExFreePool(ConfigDescriptor
);
4003 PortExtension
->PortPdoFlags
&= ~USBHUB_PDO_FLAG_REMOTE_WAKEUP
;
4005 if (ConfigDescriptor
->bmAttributes
& 0x20)
4007 /* device configuration supports remote wakeup */
4008 PortExtension
->PortPdoFlags
|= USBHUB_PDO_FLAG_REMOTE_WAKEUP
;
4011 USBHUB_DumpingDeviceDescriptor(&PortExtension
->DeviceDescriptor
);
4012 USBHUB_DumpingConfiguration(ConfigDescriptor
);
4014 DPRINT_PNP("USBH_ProcessDeviceInformation: Class - %x, SubClass - %x, Protocol - %x\n",
4015 PortExtension
->DeviceDescriptor
.bDeviceClass
,
4016 PortExtension
->DeviceDescriptor
.bDeviceSubClass
,
4017 PortExtension
->DeviceDescriptor
.bDeviceProtocol
);
4019 DPRINT_PNP("USBH_ProcessDeviceInformation: bNumConfigurations - %x, bNumInterfaces - %x\n",
4020 PortExtension
->DeviceDescriptor
.bNumConfigurations
,
4021 ConfigDescriptor
->bNumInterfaces
);
4024 /* Enumeration of USB Composite Devices (msdn):
4025 1) The device class field of the device descriptor (bDeviceClass) must contain a value of zero,
4026 or the class (bDeviceClass), subclass (bDeviceSubClass), and protocol (bDeviceProtocol)
4027 fields of the device descriptor must have the values 0xEF, 0x02 and 0x01 respectively,
4028 as explained in USB Interface Association Descriptor.
4029 2) The device must have multiple interfaces
4030 3) The device must have a single configuration.
4033 if (((PortExtension
->DeviceDescriptor
.bDeviceClass
== USB_DEVICE_CLASS_RESERVED
) ||
4034 (PortExtension
->DeviceDescriptor
.bDeviceClass
== USB_DEVICE_CLASS_MISCELLANEOUS
&&
4035 PortExtension
->DeviceDescriptor
.bDeviceSubClass
== 0x02 &&
4036 PortExtension
->DeviceDescriptor
.bDeviceProtocol
== 0x01)) &&
4037 (ConfigDescriptor
->bNumInterfaces
> 1) &&
4038 (PortExtension
->DeviceDescriptor
.bNumConfigurations
< 2))
4040 DPRINT("USBH_ProcessDeviceInformation: Multi-Interface configuration\n");
4042 PortExtension
->PortPdoFlags
|= USBHUB_PDO_FLAG_MULTI_INTERFACE
;
4044 if (ConfigDescriptor
)
4046 ExFreePool(ConfigDescriptor
);
4052 Pid
= USBD_ParseConfigurationDescriptorEx(ConfigDescriptor
,
4061 RtlCopyMemory(&PortExtension
->InterfaceDescriptor
,
4063 sizeof(PortExtension
->InterfaceDescriptor
));
4065 if (Pid
->bInterfaceClass
== USB_DEVICE_CLASS_HUB
)
4067 PortExtension
->PortPdoFlags
|= (USBHUB_PDO_FLAG_HUB_DEVICE
|
4068 USBHUB_PDO_FLAG_REMOTE_WAKEUP
);
4073 Status
= STATUS_UNSUCCESSFUL
;
4076 if (ConfigDescriptor
)
4078 ExFreePool(ConfigDescriptor
);
4086 USBH_CheckDeviceIDUnique(IN PUSBHUB_FDO_EXTENSION HubExtension
,
4088 IN USHORT idProduct
,
4089 IN PVOID SerialNumber
,
4090 IN USHORT SN_DescriptorLength
)
4092 PDEVICE_OBJECT PortDevice
;
4093 PUSBHUB_PORT_PDO_EXTENSION PortExtension
;
4097 DPRINT("USBH_CheckDeviceIDUnique: idVendor - 0x%04X, idProduct - 0x%04X\n",
4101 if (!HubExtension
->HubDescriptor
->bNumberOfPorts
)
4106 for (Port
= 0; Port
< HubExtension
->HubDescriptor
->bNumberOfPorts
; Port
++)
4108 PortDevice
= HubExtension
->PortData
[Port
].DeviceObject
;
4112 PortExtension
= PortDevice
->DeviceExtension
;
4114 if (PortExtension
->DeviceDescriptor
.idVendor
== idVendor
&&
4115 PortExtension
->DeviceDescriptor
.idProduct
== idProduct
&&
4116 PortExtension
->SN_DescriptorLength
== SN_DescriptorLength
)
4118 if (PortExtension
->SerialNumber
)
4120 NumberBytes
= RtlCompareMemory(PortExtension
->SerialNumber
,
4122 SN_DescriptorLength
);
4124 if (NumberBytes
== SN_DescriptorLength
)
4138 USBH_ValidateSerialNumberString(IN PUSHORT SerialNumberString
)
4143 DPRINT("USBH_ValidateSerialNumberString: ... \n");
4145 for (ix
= 0; SerialNumberString
[ix
] != UNICODE_NULL
; ix
++)
4147 Symbol
= SerialNumberString
[ix
];
4149 if (Symbol
< 0x20 || Symbol
> 0x7F || Symbol
== 0x2C) // ','
4161 USBH_CheckDeviceLanguage(IN PDEVICE_OBJECT DeviceObject
,
4162 IN USHORT LanguageId
)
4164 PUSB_STRING_DESCRIPTOR Descriptor
;
4171 DPRINT("USBH_CheckDeviceLanguage: LanguageId - 0x%04X\n", LanguageId
);
4173 Descriptor
= ExAllocatePoolWithTag(NonPagedPool
,
4174 MAXIMUM_USB_STRING_LENGTH
,
4179 return STATUS_INSUFFICIENT_RESOURCES
;
4182 RtlZeroMemory(Descriptor
, MAXIMUM_USB_STRING_LENGTH
);
4184 Status
= USBH_SyncGetStringDescriptor(DeviceObject
,
4188 MAXIMUM_USB_STRING_LENGTH
,
4192 if (!NT_SUCCESS(Status
) ||
4193 Length
< sizeof(USB_COMMON_DESCRIPTOR
))
4198 NumSymbols
= (Length
-
4199 FIELD_OFFSET(USB_STRING_DESCRIPTOR
, bString
)) / sizeof(WCHAR
);
4201 pSymbol
= Descriptor
->bString
;
4203 for (ix
= 1; ix
< NumSymbols
; ix
++)
4205 if (*pSymbol
== (WCHAR
)LanguageId
)
4207 Status
= STATUS_SUCCESS
;
4214 Status
= STATUS_NOT_SUPPORTED
;
4217 ExFreePoolWithTag(Descriptor
, USB_HUB_TAG
);
4223 USBH_GetSerialNumberString(IN PDEVICE_OBJECT DeviceObject
,
4224 IN LPWSTR
* OutSerialNumber
,
4225 IN PUSHORT OutDescriptorLength
,
4226 IN USHORT LanguageId
,
4229 PUSB_STRING_DESCRIPTOR Descriptor
;
4231 LPWSTR SerialNumberBuffer
= NULL
;
4235 DPRINT("USBH_GetSerialNumberString: ... \n");
4237 *OutSerialNumber
= NULL
;
4238 *OutDescriptorLength
= 0;
4240 Descriptor
= ExAllocatePoolWithTag(NonPagedPool
,
4241 MAXIMUM_USB_STRING_LENGTH
,
4246 return STATUS_INSUFFICIENT_RESOURCES
;
4249 RtlZeroMemory(Descriptor
, MAXIMUM_USB_STRING_LENGTH
);
4251 Status
= USBH_CheckDeviceLanguage(DeviceObject
, LanguageId
);
4253 if (!NT_SUCCESS(Status
))
4258 Status
= USBH_SyncGetStringDescriptor(DeviceObject
,
4262 MAXIMUM_USB_STRING_LENGTH
,
4266 if (!NT_SUCCESS(Status
) ||
4267 Descriptor
->bLength
<= sizeof(USB_COMMON_DESCRIPTOR
))
4269 Status
= STATUS_INSUFFICIENT_RESOURCES
;
4273 StringLength
= Descriptor
->bLength
-
4274 FIELD_OFFSET(USB_STRING_DESCRIPTOR
, bString
);
4276 Length
= StringLength
+ sizeof(UNICODE_NULL
);
4278 SerialNumberBuffer
= ExAllocatePoolWithTag(PagedPool
, Length
, USB_HUB_TAG
);
4280 if (!SerialNumberBuffer
)
4285 RtlZeroMemory(SerialNumberBuffer
, Length
);
4286 RtlCopyMemory(SerialNumberBuffer
, Descriptor
->bString
, StringLength
);
4288 *OutSerialNumber
= SerialNumberBuffer
;
4289 *OutDescriptorLength
= Length
;
4292 ExFreePoolWithTag(Descriptor
, USB_HUB_TAG
);
4298 USBH_CreateDevice(IN PUSBHUB_FDO_EXTENSION HubExtension
,
4300 IN USB_PORT_STATUS UsbPortStatus
,
4303 ULONG PdoNumber
= 0;
4304 WCHAR CharDeviceName
[64];
4305 UNICODE_STRING DeviceName
;
4306 PDEVICE_OBJECT DeviceObject
= NULL
;
4307 PUSBHUB_PORT_PDO_EXTENSION PortExtension
;
4308 PUSB_DEVICE_HANDLE DeviceHandle
;
4309 LPWSTR SerialNumberBuffer
;
4312 BOOLEAN IgnoringHwSerial
= FALSE
;
4314 UNICODE_STRING DestinationString
;
4316 DPRINT("USBH_CreateDevice: Port - %x, UsbPortStatus - %lX\n",
4318 UsbPortStatus
.AsUshort16
);
4322 RtlStringCbPrintfW(CharDeviceName
,
4323 sizeof(CharDeviceName
),
4324 L
"\\Device\\USBPDO-%d",
4327 RtlInitUnicodeString(&DeviceName
, CharDeviceName
);
4329 Status
= IoCreateDevice(HubExtension
->Common
.SelfDevice
->DriverObject
,
4330 sizeof(USBHUB_PORT_PDO_EXTENSION
),
4339 while (Status
== STATUS_OBJECT_NAME_COLLISION
);
4341 if (!NT_SUCCESS(Status
))
4344 HubExtension
->PortData
[Port
-1].DeviceObject
= DeviceObject
;
4348 DeviceObject
->StackSize
= HubExtension
->RootHubPdo2
->StackSize
;
4350 PortExtension
= DeviceObject
->DeviceExtension
;
4352 DPRINT("USBH_CreateDevice: PortDevice - %p, <%wZ>\n", DeviceObject
, &DeviceName
);
4353 DPRINT("USBH_CreateDevice: PortExtension - %p\n", PortExtension
);
4355 RtlZeroMemory(PortExtension
, sizeof(USBHUB_PORT_PDO_EXTENSION
));
4357 PortExtension
->Common
.ExtensionType
= USBH_EXTENSION_TYPE_PORT
;
4358 PortExtension
->Common
.SelfDevice
= DeviceObject
;
4360 PortExtension
->HubExtension
= HubExtension
;
4361 PortExtension
->RootHubExtension
= HubExtension
;
4363 PortExtension
->PortNumber
= Port
;
4364 PortExtension
->CurrentPowerState
.DeviceState
= PowerDeviceD0
;
4365 PortExtension
->IgnoringHwSerial
= FALSE
;
4367 KeInitializeSpinLock(&PortExtension
->PortTimeoutSpinLock
);
4369 InitializeListHead(&PortExtension
->PortPowerList
);
4370 KeInitializeSpinLock(&PortExtension
->PortPowerListSpinLock
);
4372 PortExtension
->PoRequestCounter
= 0;
4373 PortExtension
->PendingSystemPoRequest
= 0;
4374 PortExtension
->PendingDevicePoRequest
= 0;
4375 PortExtension
->StateBehindD2
= 0;
4377 SerialNumberBuffer
= NULL
;
4379 IsHsDevice
= UsbPortStatus
.Usb20PortStatus
.HighSpeedDeviceAttached
;
4380 IsLsDevice
= UsbPortStatus
.Usb20PortStatus
.LowSpeedDeviceAttached
;
4382 if (IsLsDevice
== 0)
4386 PortExtension
->PortPdoFlags
= USBHUB_PDO_FLAG_PORT_HIGH_SPEED
;
4391 PortExtension
->PortPdoFlags
= USBHUB_PDO_FLAG_PORT_LOW_SPEED
;
4394 /* Initialize PortExtension->InstanceID */
4395 RtlInitUnicodeString(&DestinationString
, (PCWSTR
)&PortExtension
->InstanceID
);
4396 DestinationString
.MaximumLength
= 4 * sizeof(WCHAR
);
4397 Status
= RtlIntegerToUnicodeString(Port
, 10, &DestinationString
);
4399 DeviceObject
->Flags
|= DO_POWER_PAGABLE
;
4400 DeviceObject
->Flags
&= ~DO_DEVICE_INITIALIZING
;
4402 if (!NT_SUCCESS(Status
))
4404 DPRINT1("USBH_CreateDevice: IoCreateDevice() failed - %lX\n", Status
);
4408 Status
= USBD_CreateDeviceEx(HubExtension
,
4409 &PortExtension
->DeviceHandle
,
4413 if (!NT_SUCCESS(Status
))
4415 DPRINT1("USBH_CreateDevice: USBD_CreateDeviceEx() failed - %lX\n", Status
);
4419 Status
= USBH_SyncResetPort(HubExtension
, Port
);
4421 if (!NT_SUCCESS(Status
))
4423 DPRINT1("USBH_CreateDevice: USBH_SyncResetPort() failed - %lX\n", Status
);
4432 Status
= USBD_InitializeDeviceEx(HubExtension
,
4433 PortExtension
->DeviceHandle
,
4434 (PUCHAR
)&PortExtension
->DeviceDescriptor
,
4435 sizeof(USB_DEVICE_DESCRIPTOR
),
4436 (PUCHAR
)&PortExtension
->ConfigDescriptor
,
4437 sizeof(USB_CONFIGURATION_DESCRIPTOR
));
4439 if (!NT_SUCCESS(Status
))
4441 DPRINT1("USBH_CreateDevice: USBD_InitializeDeviceEx() failed - %lX\n", Status
);
4442 PortExtension
->DeviceHandle
= NULL
;
4446 DPRINT1("USBH_RegQueryDeviceIgnoreHWSerNumFlag UNIMPLEMENTED. FIXME\n");
4447 //Status = USBH_RegQueryDeviceIgnoreHWSerNumFlag(PortExtension->DeviceDescriptor.idVendor,
4448 // PortExtension->DeviceDescriptor.idProduct,
4449 // &IgnoringHwSerial);
4451 if (TRUE
)//Status == STATUS_OBJECT_NAME_NOT_FOUND)
4453 IgnoringHwSerial
= FALSE
;
4456 if (IgnoringHwSerial
)
4458 PortExtension
->IgnoringHwSerial
= TRUE
;
4461 if (PortExtension
->DeviceDescriptor
.iSerialNumber
&&
4462 !PortExtension
->IgnoringHwSerial
)
4464 InterlockedExchangePointer((PVOID
)&PortExtension
->SerialNumber
, NULL
);
4466 USBH_GetSerialNumberString(PortExtension
->Common
.SelfDevice
,
4467 &SerialNumberBuffer
,
4468 &PortExtension
->SN_DescriptorLength
,
4469 MAKELANGID(LANG_ENGLISH
, SUBLANG_ENGLISH_US
),
4470 PortExtension
->DeviceDescriptor
.iSerialNumber
);
4472 if (SerialNumberBuffer
)
4474 if (!USBH_ValidateSerialNumberString((PUSHORT
)SerialNumberBuffer
))
4476 ExFreePoolWithTag(SerialNumberBuffer
, USB_HUB_TAG
);
4477 SerialNumberBuffer
= NULL
;
4480 if (SerialNumberBuffer
&&
4481 !USBH_CheckDeviceIDUnique(HubExtension
,
4482 PortExtension
->DeviceDescriptor
.idVendor
,
4483 PortExtension
->DeviceDescriptor
.idProduct
,
4485 PortExtension
->SN_DescriptorLength
))
4487 ExFreePoolWithTag(SerialNumberBuffer
, USB_HUB_TAG
);
4488 SerialNumberBuffer
= NULL
;
4492 InterlockedExchangePointer((PVOID
)&PortExtension
->SerialNumber
,
4493 SerialNumberBuffer
);
4496 Status
= USBH_ProcessDeviceInformation(PortExtension
);
4498 USBH_PdoSetCapabilities(PortExtension
);
4500 if (NT_SUCCESS(Status
))
4507 PortExtension
->PortPdoFlags
|= USBHUB_PDO_FLAG_INIT_PORT_FAILED
;
4509 DeviceHandle
= InterlockedExchangePointer(&PortExtension
->DeviceHandle
,
4514 USBD_RemoveDeviceEx(HubExtension
, DeviceHandle
, 0);
4517 SerialNumberBuffer
= InterlockedExchangePointer((PVOID
)&PortExtension
->SerialNumber
,
4520 if (SerialNumberBuffer
)
4522 ExFreePoolWithTag(SerialNumberBuffer
, USB_HUB_TAG
);
4528 HubExtension
->PortData
[Port
-1].DeviceObject
= DeviceObject
;
4534 USBH_ResetDevice(IN PUSBHUB_FDO_EXTENSION HubExtension
,
4536 IN BOOLEAN IsKeepDeviceData
,
4540 PUSBHUB_PORT_DATA PortData
;
4541 PDEVICE_OBJECT PortDevice
;
4542 PUSBHUB_PORT_PDO_EXTENSION PortExtension
;
4543 PVOID NewDeviceHandle
;
4545 PVOID OldDeviceHandle
;
4546 PUSB_DEVICE_HANDLE
* DeviceHandle
;
4547 USB_PORT_STATUS_AND_CHANGE PortStatus
;
4549 DPRINT("USBH_ResetDevice: HubExtension - %p, Port - %x, IsKeepDeviceData - %x, IsWait - %x\n",
4555 Status
= USBH_SyncGetPortStatus(HubExtension
,
4558 sizeof(USB_PORT_STATUS_AND_CHANGE
));
4560 if (!NT_SUCCESS(Status
) ||
4561 !(PortStatus
.PortStatus
.Usb20PortStatus
.CurrentConnectStatus
))
4563 return STATUS_UNSUCCESSFUL
;
4566 InterlockedIncrement(&HubExtension
->PendingRequestCount
);
4568 KeWaitForSingleObject(&HubExtension
->ResetDeviceSemaphore
,
4575 PortData
= &HubExtension
->PortData
[Port
-1];
4577 PortDevice
= PortData
->DeviceObject
;
4581 Status
= STATUS_INVALID_PARAMETER
;
4583 KeReleaseSemaphore(&HubExtension
->ResetDeviceSemaphore
,
4584 LOW_REALTIME_PRIORITY
,
4588 if (!InterlockedDecrement(&HubExtension
->PendingRequestCount
))
4590 KeSetEvent(&HubExtension
->PendingRequestEvent
,
4598 PortExtension
= PortDevice
->DeviceExtension
;
4599 DeviceHandle
= &PortExtension
->DeviceHandle
;
4601 OldDeviceHandle
= InterlockedExchangePointer(&PortExtension
->DeviceHandle
,
4604 if (OldDeviceHandle
)
4606 if (!(PortExtension
->PortPdoFlags
& USBHUB_PDO_FLAG_REMOVING_PORT_PDO
))
4608 Status
= USBD_RemoveDeviceEx(HubExtension
,
4612 PortExtension
->PortPdoFlags
|= USBHUB_PDO_FLAG_REMOVING_PORT_PDO
;
4617 OldDeviceHandle
= NULL
;
4620 if (!NT_SUCCESS(Status
))
4625 Status
= USBH_SyncResetPort(HubExtension
, Port
);
4627 if (!NT_SUCCESS(Status
))
4632 Status
= USBH_SyncGetPortStatus(HubExtension
,
4635 sizeof(USB_PORT_STATUS_AND_CHANGE
));
4637 if (!NT_SUCCESS(Status
))
4642 Status
= USBD_CreateDeviceEx(HubExtension
,
4644 PortStatus
.PortStatus
,
4647 if (!NT_SUCCESS(Status
))
4652 Status
= USBH_SyncResetPort(HubExtension
, Port
);
4659 if (!NT_SUCCESS(Status
))
4664 Status
= USBD_InitializeDeviceEx(HubExtension
,
4666 &PortExtension
->DeviceDescriptor
.bLength
,
4667 sizeof(PortExtension
->DeviceDescriptor
),
4668 &PortExtension
->ConfigDescriptor
.bLength
,
4669 sizeof(PortExtension
->ConfigDescriptor
));
4671 if (NT_SUCCESS(Status
))
4673 if (IsKeepDeviceData
)
4675 Status
= USBD_RestoreDeviceEx(HubExtension
,
4679 if (!NT_SUCCESS(Status
))
4681 Handle
= InterlockedExchangePointer(DeviceHandle
, NULL
);
4683 USBD_RemoveDeviceEx(HubExtension
, Handle
, 0);
4684 USBH_SyncDisablePort(HubExtension
, Port
);
4686 Status
= STATUS_NO_SUCH_DEVICE
;
4691 PortExtension
->PortPdoFlags
&= ~USBHUB_PDO_FLAG_REMOVING_PORT_PDO
;
4697 *DeviceHandle
= NULL
;
4701 NewDeviceHandle
= InterlockedExchangePointer(DeviceHandle
,
4704 if (NewDeviceHandle
)
4706 Status
= USBD_RemoveDeviceEx(HubExtension
, NewDeviceHandle
, 0);
4711 KeReleaseSemaphore(&HubExtension
->ResetDeviceSemaphore
,
4712 LOW_REALTIME_PRIORITY
,
4716 if (!InterlockedDecrement(&HubExtension
->PendingRequestCount
))
4718 KeSetEvent(&HubExtension
->PendingRequestEvent
,
4728 USBH_PdoDispatch(IN PUSBHUB_PORT_PDO_EXTENSION PortExtension
,
4731 PIO_STACK_LOCATION IoStack
;
4732 UCHAR MajorFunction
;
4733 BOOLEAN ShouldCompleteIrp
;
4737 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
4738 MajorFunction
= IoStack
->MajorFunction
;
4740 switch (MajorFunction
)
4744 DPRINT("USBH_PdoDispatch: IRP_MJ_CREATE / IRP_MJ_CLOSE (%d)\n",
4746 Status
= STATUS_SUCCESS
;
4747 USBH_CompleteIrp(Irp
, Status
);
4750 case IRP_MJ_DEVICE_CONTROL
:
4751 ControlCode
= IoStack
->Parameters
.DeviceIoControl
.IoControlCode
;
4752 DPRINT("USBH_PdoDispatch: IRP_MJ_DEVICE_CONTROL ControlCode - %x\n",
4755 if (ControlCode
== IOCTL_STORAGE_GET_MEDIA_SERIAL_NUMBER
)
4757 Status
= STATUS_NOT_SUPPORTED
;
4758 USBH_CompleteIrp(Irp
, Status
);
4762 if (ControlCode
== IOCTL_KS_PROPERTY
)
4764 DPRINT1("USBH_PdoDispatch: IOCTL_KS_PROPERTY FIXME\n");
4766 Status
= STATUS_NOT_SUPPORTED
;
4767 USBH_CompleteIrp(Irp
, Status
);
4771 Status
= Irp
->IoStatus
.Status
;
4772 USBH_CompleteIrp(Irp
, Status
);
4775 case IRP_MJ_INTERNAL_DEVICE_CONTROL
:
4776 Status
= USBH_PdoInternalControl(PortExtension
, Irp
);
4780 Status
= USBH_PdoPnP(PortExtension
,
4782 IoStack
->MinorFunction
,
4783 &ShouldCompleteIrp
);
4785 if (ShouldCompleteIrp
)
4787 USBH_CompleteIrp(Irp
, Status
);
4793 Status
= USBH_PdoPower(PortExtension
, Irp
, IoStack
->MinorFunction
);
4796 case IRP_MJ_SYSTEM_CONTROL
:
4797 DPRINT1("USBH_PdoDispatch: USBH_SystemControl() UNIMPLEMENTED. FIXME\n");
4798 Status
= STATUS_NOT_SUPPORTED
;//USBH_PortSystemControl(PortExtension, Irp);
4802 DPRINT("USBH_PdoDispatch: Unhandled MajorFunction - %d\n", MajorFunction
);
4803 Status
= Irp
->IoStatus
.Status
;
4804 USBH_CompleteIrp(Irp
, Status
);
4813 USBH_FdoDispatch(IN PUSBHUB_FDO_EXTENSION HubExtension
,
4816 PIO_STACK_LOCATION IoStack
;
4817 UCHAR MajorFunction
;
4820 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
4822 DPRINT("USBH_FdoDispatch: HubExtension - %p, Irp - %p, MajorFunction - %X\n",
4825 IoStack
->MajorFunction
);
4827 MajorFunction
= IoStack
->MajorFunction
;
4829 switch (MajorFunction
)
4833 Status
= STATUS_SUCCESS
;
4834 USBH_CompleteIrp(Irp
, Status
);
4837 case IRP_MJ_DEVICE_CONTROL
:
4838 Status
= USBH_DeviceControl(HubExtension
, Irp
);
4842 Status
= USBH_FdoPnP(HubExtension
, Irp
, IoStack
->MinorFunction
);
4846 Status
= USBH_FdoPower(HubExtension
, Irp
, IoStack
->MinorFunction
);
4849 case IRP_MJ_SYSTEM_CONTROL
:
4850 DPRINT1("USBH_FdoDispatch: USBH_SystemControl() UNIMPLEMENTED. FIXME\n");
4853 case IRP_MJ_INTERNAL_DEVICE_CONTROL
:
4855 Status
= USBH_PassIrp(HubExtension
->LowerDevice
, Irp
);
4864 USBH_AddDevice(IN PDRIVER_OBJECT DriverObject
,
4865 IN PDEVICE_OBJECT LowerPDO
)
4867 PDEVICE_OBJECT DeviceObject
;
4869 PUSBHUB_FDO_EXTENSION HubExtension
;
4870 PDEVICE_OBJECT LowerDevice
;
4872 DPRINT("USBH_AddDevice: DriverObject - %p, LowerPDO - %p\n",
4876 DeviceObject
= NULL
;
4878 Status
= IoCreateDevice(DriverObject
,
4879 sizeof(USBHUB_FDO_EXTENSION
),
4882 FILE_AUTOGENERATED_DEVICE_NAME
,
4886 if (!NT_SUCCESS(Status
))
4888 DPRINT1("USBH_AddDevice: IoCreateDevice() fail\n");
4892 IoDeleteDevice(DeviceObject
);
4898 DPRINT("USBH_AddDevice: DeviceObject - %p\n", DeviceObject
);
4900 HubExtension
= DeviceObject
->DeviceExtension
;
4901 RtlZeroMemory(HubExtension
, sizeof(USBHUB_FDO_EXTENSION
));
4903 HubExtension
->Common
.ExtensionType
= USBH_EXTENSION_TYPE_HUB
;
4905 LowerDevice
= IoAttachDeviceToDeviceStack(DeviceObject
, LowerPDO
);
4909 DPRINT1("USBH_AddDevice: IoAttachDeviceToDeviceStack() fail\n");
4913 IoDeleteDevice(DeviceObject
);
4916 return STATUS_UNSUCCESSFUL
;
4919 DPRINT("USBH_AddDevice: LowerDevice - %p\n", LowerDevice
);
4921 HubExtension
->Common
.SelfDevice
= DeviceObject
;
4923 HubExtension
->LowerPDO
= LowerPDO
;
4924 HubExtension
->LowerDevice
= LowerDevice
;
4926 KeInitializeSemaphore(&HubExtension
->IdleSemaphore
, 1, 1);
4928 DeviceObject
->Flags
|= DO_POWER_PAGABLE
;
4929 DeviceObject
->Flags
&= ~DO_DEVICE_INITIALIZING
;
4931 DPRINT("USBH_AddDevice: call IoWMIRegistrationControl() UNIMPLEMENTED. FIXME\n");
4938 USBH_DriverUnload(IN PDRIVER_OBJECT DriverObject
)
4940 DPRINT("USBH_DriverUnload: UNIMPLEMENTED\n");
4942 if (GenericUSBDeviceString
)
4944 ExFreePool(GenericUSBDeviceString
);
4945 GenericUSBDeviceString
= NULL
;
4951 USBH_HubDispatch(IN PDEVICE_OBJECT DeviceObject
,
4954 PCOMMON_DEVICE_EXTENSION DeviceExtension
;
4955 ULONG ExtensionType
;
4959 DeviceExtension
= DeviceObject
->DeviceExtension
;
4960 ExtensionType
= DeviceExtension
->ExtensionType
;
4962 if (ExtensionType
== USBH_EXTENSION_TYPE_HUB
)
4964 DPRINT("USBH_HubDispatch: DeviceObject - %p, Irp - %p\n",
4968 Status
= USBH_FdoDispatch((PUSBHUB_FDO_EXTENSION
)DeviceExtension
, Irp
);
4970 else if (ExtensionType
== USBH_EXTENSION_TYPE_PORT
)
4972 PIO_STACK_LOCATION IoStack
= IoGetCurrentIrpStackLocation(Irp
);
4973 UCHAR MajorFunction
= IoStack
->MajorFunction
;
4974 BOOLEAN IsDprint
= TRUE
;
4976 if (MajorFunction
== IRP_MJ_INTERNAL_DEVICE_CONTROL
)
4978 ULONG ControlCode
= IoStack
->Parameters
.DeviceIoControl
.IoControlCode
;
4980 if (ControlCode
== IOCTL_INTERNAL_USB_SUBMIT_URB
)
4988 DPRINT("USBH_HubDispatch: DeviceObject - %p, Irp - %p\n",
4993 Status
= USBH_PdoDispatch((PUSBHUB_PORT_PDO_EXTENSION
)DeviceExtension
, Irp
);
4997 DPRINT1("USBH_HubDispatch: Unknown ExtensionType - %x\n", ExtensionType
);
4999 Status
= STATUS_ASSERTION_FAILURE
;
5007 USBH_RegQueryGenericUSBDeviceString(PVOID USBDeviceString
)
5009 RTL_QUERY_REGISTRY_TABLE QueryTable
[2];
5011 DPRINT("USBH_RegQueryGenericUSBDeviceString ... \n");
5013 RtlZeroMemory(QueryTable
, sizeof(QueryTable
));
5015 QueryTable
[0].QueryRoutine
= USBH_GetConfigValue
;
5016 QueryTable
[0].Flags
= RTL_QUERY_REGISTRY_REQUIRED
;
5017 QueryTable
[0].Name
= L
"GenericUSBDeviceString";
5018 QueryTable
[0].EntryContext
= USBDeviceString
;
5019 QueryTable
[0].DefaultType
= REG_NONE
;
5020 QueryTable
[0].DefaultData
= 0;
5021 QueryTable
[0].DefaultLength
= 0;
5023 return RtlQueryRegistryValues(RTL_REGISTRY_CONTROL
,
5032 DriverEntry(IN PDRIVER_OBJECT DriverObject
,
5033 IN PUNICODE_STRING RegistryPath
)
5035 DPRINT("USBHUB: DriverEntry - %wZ\n", RegistryPath
);
5037 DriverObject
->DriverExtension
->AddDevice
= USBH_AddDevice
;
5038 DriverObject
->DriverUnload
= USBH_DriverUnload
;
5040 DriverObject
->MajorFunction
[IRP_MJ_CREATE
] = USBH_HubDispatch
;
5041 DriverObject
->MajorFunction
[IRP_MJ_CLOSE
] = USBH_HubDispatch
;
5043 DriverObject
->MajorFunction
[IRP_MJ_DEVICE_CONTROL
] = USBH_HubDispatch
;
5044 DriverObject
->MajorFunction
[IRP_MJ_INTERNAL_DEVICE_CONTROL
] = USBH_HubDispatch
;
5046 DriverObject
->MajorFunction
[IRP_MJ_PNP
] = USBH_HubDispatch
;
5047 DriverObject
->MajorFunction
[IRP_MJ_POWER
] = USBH_HubDispatch
;
5048 DriverObject
->MajorFunction
[IRP_MJ_SYSTEM_CONTROL
] = USBH_HubDispatch
;
5050 USBH_RegQueryGenericUSBDeviceString(&GenericUSBDeviceString
);
5052 return STATUS_SUCCESS
;