6 #define NDEBUG_USBHUB_SCE
7 #define NDEBUG_USBHUB_PNP
12 PWSTR GenericUSBDeviceString
= NULL
;
16 USBH_Wait(IN ULONG Milliseconds
)
18 LARGE_INTEGER Interval
;
20 DPRINT("USBH_Wait: Milliseconds - %x\n", Milliseconds
);
21 Interval
.QuadPart
= -10000 * Milliseconds
+ (KeQueryTimeIncrement() - 1);
22 return KeDelayExecutionThread(KernelMode
, FALSE
, &Interval
);
27 USBH_GetConfigValue(IN PWSTR ValueName
,
32 IN PVOID EntryContext
)
34 NTSTATUS Status
= STATUS_SUCCESS
;
36 DPRINT("USBHUB_GetConfigValue: ... \n");
38 if (ValueType
== REG_BINARY
)
40 *(PUCHAR
)EntryContext
= *(PUCHAR
)ValueData
;
42 else if (ValueType
== REG_DWORD
)
44 *(PULONG
)EntryContext
= *(PULONG
)ValueData
;
48 Status
= STATUS_INVALID_PARAMETER
;
56 USBH_CompleteIrp(IN PIRP Irp
,
57 IN NTSTATUS CompleteStatus
)
59 if (CompleteStatus
!= STATUS_SUCCESS
)
61 DPRINT1("USBH_CompleteIrp: Irp - %p, CompleteStatus - %X\n",
66 Irp
->IoStatus
.Status
= CompleteStatus
;
67 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
72 USBH_PassIrp(IN PDEVICE_OBJECT DeviceObject
,
75 DPRINT_PNP("USBH_PassIrp: DeviceObject - %p, Irp - %p\n",
79 IoSkipCurrentIrpStackLocation(Irp
);
80 return IoCallDriver(DeviceObject
, Irp
);
85 USBH_SyncIrpComplete(IN PDEVICE_OBJECT DeviceObject
,
89 PUSBHUB_URB_TIMEOUT_CONTEXT HubTimeoutContext
;
91 BOOLEAN TimerCancelled
;
93 DPRINT("USBH_SyncIrpComplete: ... \n");
95 HubTimeoutContext
= Context
;
97 KeAcquireSpinLock(&HubTimeoutContext
->UrbTimeoutSpinLock
, &OldIrql
);
98 HubTimeoutContext
->IsNormalCompleted
= TRUE
;
99 TimerCancelled
= KeCancelTimer(&HubTimeoutContext
->UrbTimeoutTimer
);
100 KeReleaseSpinLock(&HubTimeoutContext
->UrbTimeoutSpinLock
, OldIrql
);
104 KeSetEvent(&HubTimeoutContext
->UrbTimeoutEvent
,
109 return STATUS_SUCCESS
;
114 IsBitSet(IN PUCHAR BitMapAddress
,
119 IsSet
= (BitMapAddress
[Bit
/ 8] & (1 << (Bit
& 7))) != 0;
120 DPRINT("IsBitSet: Bit - %lX, IsSet - %x\n", Bit
, IsSet
);
124 PUSBHUB_PORT_PDO_EXTENSION
126 PdoExt(IN PDEVICE_OBJECT DeviceObject
)
130 DPRINT("PdoExt: DeviceObject - %p\n", DeviceObject
);
134 PdoExtension
= DeviceObject
->DeviceExtension
;
141 return (PUSBHUB_PORT_PDO_EXTENSION
)PdoExtension
;
146 USBH_WriteFailReasonID(IN PDEVICE_OBJECT DeviceObject
,
151 UNICODE_STRING ValueName
= RTL_CONSTANT_STRING(L
"FailReasonID");
153 DPRINT("USBH_WriteFailReason: ID - %x\n", FailReason
);
155 Status
= IoOpenDeviceRegistryKey(DeviceObject
,
156 PLUGPLAY_REGKEY_DEVICE
,
160 if (NT_SUCCESS(Status
))
162 ZwSetValueKey(KeyHandle
,
177 USBH_UrbTimeoutDPC(IN PKDPC Dpc
,
178 IN PVOID DeferredContext
,
179 IN PVOID SystemArgument1
,
180 IN PVOID SystemArgument2
)
182 PUSBHUB_URB_TIMEOUT_CONTEXT HubTimeoutContext
;
186 DPRINT("USBH_TimeoutDPC ... \n");
188 HubTimeoutContext
= DeferredContext
;
190 KeAcquireSpinLock(&HubTimeoutContext
->UrbTimeoutSpinLock
, &OldIrql
);
191 IsCompleted
= HubTimeoutContext
->IsNormalCompleted
;
192 KeReleaseSpinLock(&HubTimeoutContext
->UrbTimeoutSpinLock
, OldIrql
);
196 IoCancelIrp(HubTimeoutContext
->Irp
);
199 KeSetEvent(&HubTimeoutContext
->UrbTimeoutEvent
,
206 USBH_SetPdoRegistryParameter(IN PDEVICE_OBJECT DeviceObject
,
211 IN ULONG DevInstKeyType
)
214 UNICODE_STRING ValueNameString
;
217 DPRINT("USBH_SetPdoRegistryParameter ... \n");
219 RtlInitUnicodeString(&ValueNameString
, ValueName
);
221 Status
= IoOpenDeviceRegistryKey(DeviceObject
,
226 if (NT_SUCCESS(Status
))
228 ZwSetValueKey(KeyHandle
,
243 USBH_SyncSubmitUrb(IN PDEVICE_OBJECT DeviceObject
,
247 IO_STATUS_BLOCK IoStatusBlock
;
249 PIO_STACK_LOCATION IoStack
;
250 PUSBHUB_URB_TIMEOUT_CONTEXT HubTimeoutContext
;
251 BOOLEAN IsWaitTimeout
= FALSE
;
252 LARGE_INTEGER DueTime
;
255 DPRINT("USBH_SyncSubmitUrb: ... \n");
257 Urb
->UrbHeader
.UsbdDeviceHandle
= NULL
;
259 KeInitializeEvent(&Event
, NotificationEvent
, FALSE
);
261 Irp
= IoBuildDeviceIoControlRequest(IOCTL_INTERNAL_USB_SUBMIT_URB
,
273 return STATUS_INSUFFICIENT_RESOURCES
;
276 IoStack
= IoGetNextIrpStackLocation(Irp
);
277 IoStack
->Parameters
.Others
.Argument1
= Urb
;
279 HubTimeoutContext
= ExAllocatePoolWithTag(NonPagedPool
,
280 sizeof(USBHUB_URB_TIMEOUT_CONTEXT
),
283 if (HubTimeoutContext
)
285 RtlZeroMemory(HubTimeoutContext
, sizeof(USBHUB_URB_TIMEOUT_CONTEXT
));
287 HubTimeoutContext
->Irp
= Irp
;
288 HubTimeoutContext
->IsNormalCompleted
= FALSE
;
290 KeInitializeEvent(&HubTimeoutContext
->UrbTimeoutEvent
,
294 KeInitializeSpinLock(&HubTimeoutContext
->UrbTimeoutSpinLock
);
295 KeInitializeTimer(&HubTimeoutContext
->UrbTimeoutTimer
);
297 KeInitializeDpc(&HubTimeoutContext
->UrbTimeoutDPC
,
301 DueTime
.QuadPart
= -5000 * 10000; // Timeout 5 sec.
303 KeSetTimer(&HubTimeoutContext
->UrbTimeoutTimer
,
305 &HubTimeoutContext
->UrbTimeoutDPC
);
307 IoSetCompletionRoutine(Irp
,
308 USBH_SyncIrpComplete
,
314 IsWaitTimeout
= TRUE
;
317 Status
= IoCallDriver(DeviceObject
, Irp
);
319 if (Status
== STATUS_PENDING
)
321 KeWaitForSingleObject(&Event
,
329 IoStatusBlock
.Status
= Status
;
334 KeWaitForSingleObject(&HubTimeoutContext
->UrbTimeoutEvent
,
340 ExFreePoolWithTag(HubTimeoutContext
, USB_HUB_TAG
);
343 return IoStatusBlock
.Status
;
348 USBH_FdoSyncSubmitUrb(IN PDEVICE_OBJECT FdoDevice
,
351 PUSBHUB_FDO_EXTENSION HubExtension
;
353 DPRINT("USBH_FdoSyncSubmitUrb: FdoDevice - %p, Urb - %p\n",
357 HubExtension
= FdoDevice
->DeviceExtension
;
358 return USBH_SyncSubmitUrb(HubExtension
->LowerDevice
, Urb
);
363 USBH_Transact(IN PUSBHUB_FDO_EXTENSION HubExtension
,
364 IN PVOID TransferBuffer
,
366 IN BOOLEAN IsDeviceToHost
,
368 IN BM_REQUEST_TYPE RequestType
,
370 IN USHORT RequestValue
,
371 IN USHORT RequestIndex
)
373 struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST
* Urb
;
379 DPRINT("USBH_Transact: ... \n");
383 Length
= ALIGN_DOWN_BY(BufferLen
+ sizeof(ULONG
), sizeof(ULONG
));
385 Buffer
= ExAllocatePoolWithTag(NonPagedPool
, Length
, USB_HUB_TAG
);
389 return STATUS_INSUFFICIENT_RESOURCES
;
392 RtlZeroMemory(Buffer
, Length
);
395 Urb
= ExAllocatePoolWithTag(NonPagedPool
,
396 sizeof(struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST
),
403 ExFreePoolWithTag(Buffer
, USB_HUB_TAG
);
406 return STATUS_INSUFFICIENT_RESOURCES
;
409 RtlZeroMemory(Urb
, sizeof(struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST
));
415 RtlZeroMemory(TransferBuffer
, BufferLen
);
418 TransferFlags
= USBD_TRANSFER_DIRECTION_IN
| USBD_SHORT_TRANSFER_OK
;
424 RtlCopyMemory(Buffer
, TransferBuffer
, BufferLen
);
427 TransferFlags
= USBD_TRANSFER_DIRECTION_OUT
;
430 Urb
->Hdr
.Length
= sizeof(struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST
);
431 Urb
->Hdr
.Function
= Function
;
432 Urb
->Hdr
.UsbdDeviceHandle
= NULL
;
434 Urb
->TransferFlags
= TransferFlags
;
435 Urb
->TransferBuffer
= BufferLen
!= 0 ? Buffer
: NULL
;
436 Urb
->TransferBufferLength
= BufferLen
;
437 Urb
->TransferBufferMDL
= NULL
;
440 Urb
->RequestTypeReservedBits
= RequestType
.B
;
441 Urb
->Request
= Request
;
442 Urb
->Value
= RequestValue
;
443 Urb
->Index
= RequestIndex
;
445 Status
= USBH_FdoSyncSubmitUrb(HubExtension
->Common
.SelfDevice
, (PURB
)Urb
);
447 if (IsDeviceToHost
&& BufferLen
)
449 RtlCopyMemory(TransferBuffer
, Buffer
, BufferLen
);
454 ExFreePoolWithTag(Buffer
, USB_HUB_TAG
);
457 ExFreePoolWithTag(Urb
, USB_HUB_TAG
);
464 USBH_SyncResetPort(IN PUSBHUB_FDO_EXTENSION HubExtension
,
467 USB_PORT_STATUS_AND_CHANGE PortStatus
;
469 LARGE_INTEGER Timeout
;
470 ULONG ResetRetry
= 0;
473 DPRINT("USBH_SyncResetPort: Port - %x\n", Port
);
475 InterlockedIncrement(&HubExtension
->PendingRequestCount
);
477 KeWaitForSingleObject(&HubExtension
->HubPortSemaphore
,
483 Status
= USBH_SyncGetPortStatus(HubExtension
,
486 sizeof(USB_PORT_STATUS_AND_CHANGE
));
488 if (NT_SUCCESS(Status
) &&
489 (PortStatus
.PortStatus
.Usb20PortStatus
.CurrentConnectStatus
== 0))
491 Status
= STATUS_UNSUCCESSFUL
;
495 HubExtension
->HubFlags
|= USBHUB_FDO_FLAG_RESET_PORT_LOCK
;
499 BM_REQUEST_TYPE RequestType
;
501 KeInitializeEvent(&Event
, NotificationEvent
, FALSE
);
503 InterlockedExchangePointer((PVOID
)&HubExtension
->pResetPortEvent
,
507 RequestType
.Recipient
= BMREQUEST_TO_DEVICE
;
508 RequestType
.Type
= BMREQUEST_CLASS
;
509 RequestType
.Dir
= BMREQUEST_HOST_TO_DEVICE
;
511 Status
= USBH_Transact(HubExtension
,
514 BMREQUEST_HOST_TO_DEVICE
,
515 URB_FUNCTION_CLASS_OTHER
,
517 USB_REQUEST_SET_FEATURE
,
518 USBHUB_FEATURE_PORT_RESET
,
521 Timeout
.QuadPart
= -5000 * 10000;
523 if (!NT_SUCCESS(Status
))
525 InterlockedExchangePointer((PVOID
)&HubExtension
->pResetPortEvent
,
529 HubExtension
->HubFlags
&= ~USBHUB_FDO_FLAG_RESET_PORT_LOCK
;
534 Status
= KeWaitForSingleObject(&Event
,
540 if (Status
!= STATUS_TIMEOUT
)
545 Status
= USBH_SyncGetPortStatus(HubExtension
,
548 sizeof(USB_PORT_STATUS_AND_CHANGE
));
550 if (!NT_SUCCESS(Status
) ||
551 (PortStatus
.PortStatus
.Usb20PortStatus
.CurrentConnectStatus
== 0) ||
552 ResetRetry
>= USBHUB_RESET_PORT_MAX_RETRY
)
554 InterlockedExchangePointer((PVOID
)&HubExtension
->pResetPortEvent
,
558 HubExtension
->HubFlags
&= ~USBHUB_FDO_FLAG_RESET_PORT_LOCK
;
560 Status
= STATUS_DEVICE_DATA_ERROR
;
567 Status
= USBH_SyncGetPortStatus(HubExtension
,
570 sizeof(USB_PORT_STATUS_AND_CHANGE
));
572 if ((PortStatus
.PortStatus
.Usb20PortStatus
.CurrentConnectStatus
== 0) &&
573 NT_SUCCESS(Status
) &&
574 HubExtension
->HubFlags
& USBHUB_FDO_FLAG_USB20_HUB
)
576 Status
= STATUS_DEVICE_DATA_ERROR
;
580 HubExtension
->HubFlags
&= ~USBHUB_FDO_FLAG_RESET_PORT_LOCK
;
584 KeReleaseSemaphore(&HubExtension
->HubPortSemaphore
,
585 LOW_REALTIME_PRIORITY
,
589 if (!InterlockedDecrement(&HubExtension
->PendingRequestCount
))
591 KeSetEvent(&HubExtension
->PendingRequestEvent
,
601 USBH_GetDeviceType(IN PUSBHUB_FDO_EXTENSION HubExtension
,
602 IN PUSB_DEVICE_HANDLE DeviceHandle
,
603 OUT USB_DEVICE_TYPE
* OutDeviceType
)
605 PUSB_BUSIFFN_GET_DEVICE_INFORMATION QueryDeviceInformation
;
606 PUSB_DEVICE_INFORMATION_0 DeviceInfo
;
607 SIZE_T DeviceInformationBufferLength
;
608 USB_DEVICE_TYPE DeviceType
= Usb11Device
;
612 DPRINT("USBH_GetDeviceType: ... \n");
614 QueryDeviceInformation
= HubExtension
->BusInterface
.QueryDeviceInformation
;
616 if (!QueryDeviceInformation
)
618 DPRINT1("USBH_GetDeviceType: no QueryDeviceInformation()\n");
619 return STATUS_NOT_IMPLEMENTED
;
622 DeviceInformationBufferLength
= sizeof(USB_DEVICE_INFORMATION_0
);
626 DeviceInfo
= ExAllocatePoolWithTag(PagedPool
,
627 DeviceInformationBufferLength
,
632 DPRINT1("USBH_GetDeviceType: ExAllocatePoolWithTag() failed\n");
633 Status
= STATUS_INSUFFICIENT_RESOURCES
;
637 RtlZeroMemory(DeviceInfo
, DeviceInformationBufferLength
);
639 DeviceInfo
->InformationLevel
= 0;
641 Status
= QueryDeviceInformation(HubExtension
->BusInterface
.BusContext
,
644 DeviceInformationBufferLength
,
647 if (Status
!= STATUS_BUFFER_TOO_SMALL
)
649 if (NT_SUCCESS(Status
))
651 DeviceType
= DeviceInfo
->DeviceType
;
654 ExFreePoolWithTag(DeviceInfo
, USB_HUB_TAG
);
658 DeviceInformationBufferLength
= DeviceInfo
->ActualLength
;
659 ExFreePoolWithTag(DeviceInfo
, USB_HUB_TAG
);
664 *OutDeviceType
= DeviceType
;
665 DPRINT("USBH_GetDeviceType: DeviceType - %x\n", DeviceType
);
673 USBHUB_GetExtendedHubInfo(IN PUSBHUB_FDO_EXTENSION HubExtension
,
674 IN PUSB_EXTHUB_INFORMATION_0 HubInfoBuffer
)
676 PUSB_BUSIFFN_GET_EXTENDED_HUB_INFO GetExtendedHubInformation
;
679 DPRINT("USBHUB_GetExtendedHubInfo: ... \n");
681 GetExtendedHubInformation
= HubExtension
->BusInterface
.GetExtendedHubInformation
;
683 return GetExtendedHubInformation(HubExtension
->BusInterface
.BusContext
,
684 HubExtension
->LowerPDO
,
686 sizeof(USB_EXTHUB_INFORMATION_0
),
690 PUSBHUB_FDO_EXTENSION
692 USBH_GetRootHubExtension(IN PUSBHUB_FDO_EXTENSION HubExtension
)
694 PDEVICE_OBJECT Device
;
695 PUSBHUB_FDO_EXTENSION RootHubExtension
;
697 DPRINT("USBH_GetRootHubExtension: HubExtension - %p\n", HubExtension
);
699 RootHubExtension
= HubExtension
;
701 if (HubExtension
->LowerPDO
!= HubExtension
->RootHubPdo
)
703 Device
= HubExtension
->RootHubPdo
;
707 Device
= Device
->AttachedDevice
;
709 while (Device
->DriverObject
!= HubExtension
->Common
.SelfDevice
->DriverObject
);
711 RootHubExtension
= Device
->DeviceExtension
;
714 DPRINT("USBH_GetRootHubExtension: RootHubExtension - %p\n", RootHubExtension
);
716 return RootHubExtension
;
721 USBH_SyncGetRootHubPdo(IN PDEVICE_OBJECT DeviceObject
,
722 IN OUT PDEVICE_OBJECT
* OutPdo1
,
723 IN OUT PDEVICE_OBJECT
* OutPdo2
)
726 IO_STATUS_BLOCK IoStatusBlock
;
728 PIO_STACK_LOCATION IoStack
;
731 DPRINT("USBH_SyncGetRootHubPdo: ... \n");
733 KeInitializeEvent(&Event
, NotificationEvent
, FALSE
);
735 Irp
= IoBuildDeviceIoControlRequest(IOCTL_INTERNAL_USB_GET_ROOTHUB_PDO
,
747 return STATUS_INSUFFICIENT_RESOURCES
;
750 IoStack
= IoGetNextIrpStackLocation(Irp
);
751 IoStack
->Parameters
.Others
.Argument1
= OutPdo1
;
752 IoStack
->Parameters
.Others
.Argument2
= OutPdo2
;
754 Status
= IoCallDriver(DeviceObject
, Irp
);
756 if (Status
== STATUS_PENDING
)
758 KeWaitForSingleObject(&Event
,
766 IoStatusBlock
.Status
= Status
;
769 return IoStatusBlock
.Status
;
774 USBH_SyncGetHubCount(IN PDEVICE_OBJECT DeviceObject
,
775 IN OUT PULONG OutHubCount
)
778 IO_STATUS_BLOCK IoStatusBlock
;
780 PIO_STACK_LOCATION IoStack
;
783 DPRINT("USBH_SyncGetHubCount: *OutHubCount - %x\n", *OutHubCount
);
785 KeInitializeEvent(&Event
, NotificationEvent
, FALSE
);
787 Irp
= IoBuildDeviceIoControlRequest(IOCTL_INTERNAL_USB_GET_HUB_COUNT
,
799 return STATUS_INSUFFICIENT_RESOURCES
;
802 IoStack
= IoGetNextIrpStackLocation(Irp
);
803 IoStack
->Parameters
.Others
.Argument1
= OutHubCount
;
805 Status
= IoCallDriver(DeviceObject
, Irp
);
807 if (Status
== STATUS_PENDING
)
809 KeWaitForSingleObject(&Event
,
817 IoStatusBlock
.Status
= Status
;
820 return IoStatusBlock
.Status
;
825 USBH_SyncGetDeviceHandle(IN PDEVICE_OBJECT DeviceObject
)
829 IO_STATUS_BLOCK IoStatusBlock
;
830 PUSB_DEVICE_HANDLE DeviceHandle
= NULL
;
831 PIO_STACK_LOCATION IoStack
;
833 DPRINT("USBH_SyncGetDeviceHandle: ... \n");
835 KeInitializeEvent(&Event
, NotificationEvent
, FALSE
);
837 Irp
= IoBuildDeviceIoControlRequest(IOCTL_INTERNAL_USB_GET_DEVICE_HANDLE
,
849 DPRINT1("USBH_SyncGetDeviceHandle: Irp - NULL!\n");
853 IoStack
= IoGetNextIrpStackLocation(Irp
);
854 IoStack
->Parameters
.Others
.Argument1
= &DeviceHandle
;
856 if (IoCallDriver(DeviceObject
, Irp
) == STATUS_PENDING
)
858 KeWaitForSingleObject(&Event
,
870 USBH_GetDeviceDescriptor(IN PDEVICE_OBJECT DeviceObject
,
871 IN PUSB_DEVICE_DESCRIPTOR HubDeviceDescriptor
)
873 struct _URB_CONTROL_DESCRIPTOR_REQUEST
* Urb
;
876 DPRINT("USBH_GetDeviceDescriptor: ... \n");
878 Urb
= ExAllocatePoolWithTag(NonPagedPool
,
879 sizeof(struct _URB_CONTROL_DESCRIPTOR_REQUEST
),
884 DPRINT1("USBH_SyncGetDeviceHandle: Urb - NULL!\n");
885 return STATUS_INSUFFICIENT_RESOURCES
;
888 RtlZeroMemory(Urb
, sizeof(struct _URB_CONTROL_DESCRIPTOR_REQUEST
));
890 Urb
->Hdr
.Function
= URB_FUNCTION_GET_DESCRIPTOR_FROM_DEVICE
;
891 Urb
->Hdr
.Length
= sizeof(struct _URB_CONTROL_DESCRIPTOR_REQUEST
);
893 Urb
->TransferBufferLength
= sizeof(USB_DEVICE_DESCRIPTOR
);
894 Urb
->TransferBuffer
= HubDeviceDescriptor
;
895 Urb
->DescriptorType
= USB_DEVICE_DESCRIPTOR_TYPE
;
897 Status
= USBH_FdoSyncSubmitUrb(DeviceObject
, (PURB
)Urb
);
899 ExFreePoolWithTag(Urb
, USB_HUB_TAG
);
906 USBH_SyncGetDeviceConfigurationDescriptor(IN PDEVICE_OBJECT DeviceObject
,
907 IN PUSB_CONFIGURATION_DESCRIPTOR ConfigDescriptor
,
908 IN ULONG NumberOfBytes
,
911 PCOMMON_DEVICE_EXTENSION DeviceExtension
;
912 struct _URB_CONTROL_DESCRIPTOR_REQUEST
* Urb
;
915 DPRINT("USBH_SyncGetDeviceConfigurationDescriptor: ... \n");
917 DeviceExtension
= DeviceObject
->DeviceExtension
;
924 Urb
= ExAllocatePoolWithTag(NonPagedPool
,
925 sizeof(struct _URB_CONTROL_DESCRIPTOR_REQUEST
),
930 return STATUS_INSUFFICIENT_RESOURCES
;
933 RtlZeroMemory(Urb
, sizeof(struct _URB_CONTROL_DESCRIPTOR_REQUEST
));
935 Urb
->Hdr
.Function
= URB_FUNCTION_GET_DESCRIPTOR_FROM_DEVICE
;
936 Urb
->Hdr
.Length
= sizeof(struct _URB_CONTROL_DESCRIPTOR_REQUEST
);
938 Urb
->TransferBufferLength
= NumberOfBytes
;
939 Urb
->TransferBuffer
= ConfigDescriptor
;
940 Urb
->DescriptorType
= USB_CONFIGURATION_DESCRIPTOR_TYPE
;
942 if (DeviceExtension
->ExtensionType
== USBH_EXTENSION_TYPE_HUB
||
943 DeviceExtension
->ExtensionType
== USBH_EXTENSION_TYPE_PARENT
)
945 Status
= USBH_FdoSyncSubmitUrb(DeviceObject
, (PURB
)Urb
);
949 Status
= USBH_SyncSubmitUrb(DeviceObject
, (PURB
)Urb
);
954 *OutLength
= Urb
->TransferBufferLength
;
959 ExFreePoolWithTag(Urb
, USB_HUB_TAG
);
967 USBH_GetConfigurationDescriptor(IN PDEVICE_OBJECT DeviceObject
,
968 IN PUSB_CONFIGURATION_DESCRIPTOR
* OutDescriptor
)
970 PUSB_CONFIGURATION_DESCRIPTOR ConfigDescriptor
;
972 SIZE_T DescriptorLen
;
975 DPRINT("USBH_GetConfigurationDescriptor: ... \n");
977 DescriptorLen
= MAXUCHAR
;
981 ConfigDescriptor
= ExAllocatePoolWithTag(NonPagedPool
,
985 if (!ConfigDescriptor
)
987 Status
= STATUS_INSUFFICIENT_RESOURCES
;
991 Status
= USBH_SyncGetDeviceConfigurationDescriptor(DeviceObject
,
996 if (ReturnedLen
< sizeof(USB_CONFIGURATION_DESCRIPTOR
))
998 Status
= STATUS_DEVICE_DATA_ERROR
;
1001 if (!NT_SUCCESS(Status
))
1006 *OutDescriptor
= ConfigDescriptor
;
1008 if (ConfigDescriptor
->wTotalLength
<= DescriptorLen
)
1013 DescriptorLen
= ConfigDescriptor
->wTotalLength
;
1015 ExFreePool(ConfigDescriptor
);
1016 *OutDescriptor
= NULL
;
1019 if (NT_SUCCESS(Status
))
1021 if (ReturnedLen
< ConfigDescriptor
->wTotalLength
)
1023 Status
= STATUS_DEVICE_DATA_ERROR
;
1028 if (ConfigDescriptor
)
1030 ExFreePool(ConfigDescriptor
);
1033 *OutDescriptor
= NULL
;
1041 USBH_SyncGetHubDescriptor(IN PUSBHUB_FDO_EXTENSION HubExtension
)
1043 PUSB_EXTHUB_INFORMATION_0 ExtendedHubInfo
;
1045 PUSBHUB_PORT_DATA PortData
;
1046 USHORT RequestValue
;
1047 ULONG NumberOfBytes
;
1049 PUSB_HUB_DESCRIPTOR HubDescriptor
= NULL
;
1053 DPRINT("USBH_SyncGetHubDescriptor: ... \n");
1055 ExtendedHubInfo
= ExAllocatePoolWithTag(NonPagedPool
,
1056 sizeof(USB_EXTHUB_INFORMATION_0
),
1059 if (!ExtendedHubInfo
)
1061 Status
= STATUS_INSUFFICIENT_RESOURCES
;
1065 RtlZeroMemory(ExtendedHubInfo
, sizeof(USB_EXTHUB_INFORMATION_0
));
1067 Status
= USBHUB_GetExtendedHubInfo(HubExtension
, ExtendedHubInfo
);
1069 if (!NT_SUCCESS(Status
))
1071 ExFreePoolWithTag(ExtendedHubInfo
, USB_HUB_TAG
);
1072 ExtendedHubInfo
= NULL
;
1075 NumberOfBytes
= sizeof(USB_HUB_DESCRIPTOR
);
1077 HubDescriptor
= ExAllocatePoolWithTag(NonPagedPool
,
1083 Status
= STATUS_INSUFFICIENT_RESOURCES
;
1087 RtlZeroMemory(HubDescriptor
, NumberOfBytes
);
1096 BM_REQUEST_TYPE RequestType
;
1099 RequestType
.Recipient
= BMREQUEST_TO_DEVICE
;
1100 RequestType
.Type
= BMREQUEST_STANDARD
;
1101 RequestType
.Dir
= BMREQUEST_DEVICE_TO_HOST
;
1103 Status
= USBH_Transact(HubExtension
,
1106 BMREQUEST_DEVICE_TO_HOST
,
1107 URB_FUNCTION_CLASS_DEVICE
,
1109 USB_REQUEST_GET_DESCRIPTOR
,
1113 if (NT_SUCCESS(Status
))
1118 RequestValue
= 0x2900; // Hub DescriptorType - 0x29
1123 if (HubDescriptor
->bDescriptorLength
<= NumberOfBytes
)
1128 NumberOfBytes
= HubDescriptor
->bDescriptorLength
;
1129 ExFreePoolWithTag(HubDescriptor
, USB_HUB_TAG
);
1133 Status
= STATUS_DEVICE_DATA_ERROR
;
1134 HubDescriptor
= NULL
;
1138 HubDescriptor
= ExAllocatePoolWithTag(NonPagedPool
,
1144 Status
= STATUS_INSUFFICIENT_RESOURCES
;
1148 RtlZeroMemory(HubDescriptor
, NumberOfBytes
);
1151 NumberPorts
= HubDescriptor
->bNumberOfPorts
;
1153 if (HubExtension
->PortData
)
1155 PortData
= HubExtension
->PortData
;
1157 for (ix
= 0; ix
< NumberPorts
; ix
++)
1159 PortData
[ix
].PortStatus
.AsUlong32
= 0;
1161 if (ExtendedHubInfo
)
1163 PortData
[ix
].PortAttributes
= ExtendedHubInfo
->Port
[ix
].PortAttributes
;
1167 PortData
[ix
].PortAttributes
= 0;
1170 PortData
[ix
].ConnectionStatus
= NoDeviceConnected
;
1172 if (PortData
[ix
].DeviceObject
!= NULL
)
1174 PortData
[ix
].ConnectionStatus
= DeviceConnected
;
1182 if (HubDescriptor
->bNumberOfPorts
)
1184 PortData
= ExAllocatePoolWithTag(NonPagedPool
,
1185 NumberPorts
* sizeof(USBHUB_PORT_DATA
),
1191 Status
= STATUS_INSUFFICIENT_RESOURCES
;
1195 RtlZeroMemory(PortData
, NumberPorts
* sizeof(USBHUB_PORT_DATA
));
1197 for (ix
= 0; ix
< NumberPorts
; ix
++)
1199 PortData
[ix
].ConnectionStatus
= NoDeviceConnected
;
1201 if (ExtendedHubInfo
)
1203 PortData
[ix
].PortAttributes
= ExtendedHubInfo
->Port
[ix
].PortAttributes
;
1208 if (!NT_SUCCESS(Status
))
1213 HubExtension
->HubDescriptor
= HubDescriptor
;
1215 HubExtension
->PortData
= PortData
;
1217 if (ExtendedHubInfo
)
1219 ExFreePoolWithTag(ExtendedHubInfo
, USB_HUB_TAG
);
1228 ExFreePoolWithTag(HubDescriptor
, USB_HUB_TAG
);
1231 if (ExtendedHubInfo
)
1233 ExFreePoolWithTag(ExtendedHubInfo
, USB_HUB_TAG
);
1241 USBH_SyncGetStringDescriptor(IN PDEVICE_OBJECT DeviceObject
,
1243 IN USHORT LanguageId
,
1244 IN PUSB_STRING_DESCRIPTOR Descriptor
,
1245 IN ULONG NumberOfBytes
,
1246 IN PULONG OutLength
,
1247 IN BOOLEAN IsValidateLength
)
1249 struct _URB_CONTROL_DESCRIPTOR_REQUEST
* Urb
;
1250 ULONG TransferedLength
;
1253 DPRINT("USBH_SyncGetStringDescriptor: Index - %x, LanguageId - %x\n",
1257 Urb
= ExAllocatePoolWithTag(NonPagedPool
,
1258 sizeof(struct _URB_CONTROL_DESCRIPTOR_REQUEST
),
1263 return STATUS_INSUFFICIENT_RESOURCES
;
1266 RtlZeroMemory(Urb
, sizeof(struct _URB_CONTROL_DESCRIPTOR_REQUEST
));
1268 Urb
->Hdr
.Function
= URB_FUNCTION_GET_DESCRIPTOR_FROM_DEVICE
;
1269 Urb
->Hdr
.Length
= sizeof(struct _URB_CONTROL_DESCRIPTOR_REQUEST
);
1271 Urb
->TransferBuffer
= Descriptor
;
1272 Urb
->TransferBufferLength
= NumberOfBytes
;
1275 Urb
->DescriptorType
= USB_STRING_DESCRIPTOR_TYPE
;
1276 Urb
->LanguageId
= LanguageId
;
1278 Status
= USBH_SyncSubmitUrb(DeviceObject
, (PURB
)Urb
);
1280 if (!NT_SUCCESS(Status
))
1282 ExFreePoolWithTag(Urb
, USB_HUB_TAG
);
1286 TransferedLength
= Urb
->TransferBufferLength
;
1288 if (TransferedLength
> NumberOfBytes
)
1290 Status
= STATUS_DEVICE_DATA_ERROR
;
1293 if (!NT_SUCCESS(Status
))
1295 ExFreePoolWithTag(Urb
, USB_HUB_TAG
);
1301 *OutLength
= TransferedLength
;
1304 if (IsValidateLength
&& TransferedLength
!= Descriptor
->bLength
)
1306 Status
= STATUS_DEVICE_DATA_ERROR
;
1309 ExFreePoolWithTag(Urb
, USB_HUB_TAG
);
1316 USBH_SyncGetStatus(IN PDEVICE_OBJECT DeviceObject
,
1317 IN PUSHORT OutStatus
,
1319 IN USHORT RequestIndex
)
1321 struct _URB_CONTROL_GET_STATUS_REQUEST
* Urb
;
1325 DPRINT("USBH_SyncGetStatus: ... \n");
1327 Urb
= ExAllocatePoolWithTag(NonPagedPool
,
1328 sizeof(struct _URB_CONTROL_GET_STATUS_REQUEST
),
1333 return STATUS_INSUFFICIENT_RESOURCES
;
1336 RtlZeroMemory(Urb
, sizeof(struct _URB_CONTROL_GET_STATUS_REQUEST
));
1338 Urb
->Hdr
.Length
= sizeof(struct _URB_CONTROL_GET_STATUS_REQUEST
);
1339 Urb
->Hdr
.Function
= Function
;
1341 Urb
->TransferBuffer
= &UsbStatus
;
1342 Urb
->TransferBufferLength
= sizeof(UsbStatus
);
1343 Urb
->Index
= RequestIndex
;
1345 NtStatus
= USBH_FdoSyncSubmitUrb(DeviceObject
, (PURB
)Urb
);
1347 *OutStatus
= UsbStatus
;
1349 ExFreePoolWithTag(Urb
, USB_HUB_TAG
);
1356 USBH_SyncGetPortStatus(IN PUSBHUB_FDO_EXTENSION HubExtension
,
1358 IN PUSB_PORT_STATUS_AND_CHANGE PortStatus
,
1361 BM_REQUEST_TYPE RequestType
;
1363 DPRINT("USBH_SyncGetPortStatus: Port - %x\n", Port
);
1366 RequestType
.Recipient
= BMREQUEST_TO_OTHER
;
1367 RequestType
.Type
= BMREQUEST_CLASS
;
1368 RequestType
.Dir
= BMREQUEST_DEVICE_TO_HOST
;
1370 return USBH_Transact(HubExtension
,
1373 BMREQUEST_DEVICE_TO_HOST
,
1374 URB_FUNCTION_CLASS_OTHER
,
1376 USB_REQUEST_GET_STATUS
,
1384 USBH_SyncClearPortStatus(IN PUSBHUB_FDO_EXTENSION HubExtension
,
1386 IN USHORT RequestValue
)
1388 BM_REQUEST_TYPE RequestType
;
1390 DPRINT("USBH_SyncClearPortStatus: Port - %x, RequestValue - %x\n",
1395 RequestType
.Recipient
= BMREQUEST_TO_DEVICE
;
1396 RequestType
.Type
= BMREQUEST_CLASS
;
1397 RequestType
.Dir
= BMREQUEST_HOST_TO_DEVICE
;
1399 return USBH_Transact(HubExtension
,
1402 BMREQUEST_HOST_TO_DEVICE
,
1403 URB_FUNCTION_CLASS_OTHER
,
1405 USB_REQUEST_CLEAR_FEATURE
,
1412 USBH_SyncPowerOnPort(IN PUSBHUB_FDO_EXTENSION HubExtension
,
1416 PUSBHUB_PORT_DATA PortData
;
1417 PUSB_HUB_DESCRIPTOR HubDescriptor
;
1418 NTSTATUS Status
= STATUS_SUCCESS
;
1419 BM_REQUEST_TYPE RequestType
;
1420 PUSB_PORT_STATUS_AND_CHANGE PortStatus
;
1422 DPRINT("USBH_SyncPowerOnPort: Port - %x, IsWait - %x\n", Port
, IsWait
);
1425 PortData
= &HubExtension
->PortData
[Port
- 1];
1426 PortStatus
= &PortData
->PortStatus
;
1428 if (PortStatus
->PortStatus
.Usb20PortStatus
.CurrentConnectStatus
== 1)
1434 RequestType
.Recipient
= BMREQUEST_TO_DEVICE
;
1435 RequestType
.Type
= BMREQUEST_CLASS
;
1436 RequestType
.Dir
= BMREQUEST_HOST_TO_DEVICE
;
1438 Status
= USBH_Transact(HubExtension
,
1441 BMREQUEST_HOST_TO_DEVICE
,
1442 URB_FUNCTION_CLASS_OTHER
,
1444 USB_REQUEST_SET_FEATURE
,
1445 USBHUB_FEATURE_PORT_POWER
,
1448 if (NT_SUCCESS(Status
))
1452 HubDescriptor
= HubExtension
->HubDescriptor
;
1453 USBH_Wait(2 * HubDescriptor
->bPowerOnToPowerGood
);
1456 PortStatus
->PortStatus
.Usb20PortStatus
.CurrentConnectStatus
= 1;
1464 USBH_SyncPowerOnPorts(IN PUSBHUB_FDO_EXTENSION HubExtension
)
1466 PUSB_HUB_DESCRIPTOR HubDescriptor
;
1467 NTSTATUS Status
= STATUS_UNSUCCESSFUL
;
1469 UCHAR NumberOfPorts
;
1471 DPRINT("USBH_SyncPowerOnPorts: ... \n");
1473 HubDescriptor
= HubExtension
->HubDescriptor
;
1474 NumberOfPorts
= HubDescriptor
->bNumberOfPorts
;
1476 for (Port
= 1; Port
<= NumberOfPorts
; ++Port
)
1478 Status
= USBH_SyncPowerOnPort(HubExtension
, Port
, 0);
1480 if (!NT_SUCCESS(Status
))
1482 DPRINT1("USBH_SyncPowerOnPorts: USBH_SyncPowerOnPort() failed - %lX\n",
1488 USBH_Wait(2 * HubDescriptor
->bPowerOnToPowerGood
);
1495 USBH_SyncDisablePort(IN PUSBHUB_FDO_EXTENSION HubExtension
,
1498 PUSBHUB_PORT_DATA PortData
;
1500 BM_REQUEST_TYPE RequestType
;
1502 DPRINT("USBH_SyncDisablePort ... \n");
1504 PortData
= &HubExtension
->PortData
[Port
- 1];
1507 RequestType
.Recipient
= BMREQUEST_TO_DEVICE
;
1508 RequestType
.Type
= BMREQUEST_CLASS
;
1509 RequestType
.Dir
= BMREQUEST_HOST_TO_DEVICE
;
1511 Status
= USBH_Transact(HubExtension
,
1514 BMREQUEST_HOST_TO_DEVICE
,
1515 URB_FUNCTION_CLASS_OTHER
,
1517 USB_REQUEST_CLEAR_FEATURE
,
1518 USBHUB_FEATURE_PORT_ENABLE
,
1521 if (NT_SUCCESS(Status
))
1523 PortData
->PortStatus
.PortStatus
.Usb20PortStatus
.PortEnabledDisabled
= 0;
1531 USBH_HubIsBusPowered(IN PDEVICE_OBJECT DeviceObject
,
1532 IN PUSB_CONFIGURATION_DESCRIPTOR HubConfigDescriptor
)
1538 DPRINT("USBH_HubIsBusPowered: ... \n");
1540 Status
= USBH_SyncGetStatus(DeviceObject
,
1542 URB_FUNCTION_GET_STATUS_FROM_DEVICE
,
1545 if (!NT_SUCCESS(Status
))
1547 Result
= (HubConfigDescriptor
->bmAttributes
& USB_CONFIG_POWERED_MASK
)
1548 == USB_CONFIG_BUS_POWERED
;
1552 Result
= (UsbStatus
& USB_GETSTATUS_SELF_POWERED
) == 0;
1560 USBH_ChangeIndicationAckChangeComplete(IN PDEVICE_OBJECT DeviceObject
,
1564 PUSBHUB_FDO_EXTENSION HubExtension
;
1568 HubExtension
= Context
;
1570 DPRINT_SCE("USBH_ChangeIndicationAckChangeComplete: ... \n");
1572 ASSERT(HubExtension
->Port
> 0);
1573 Port
= HubExtension
->Port
- 1;
1575 HubExtension
->PortData
[Port
].PortStatus
= HubExtension
->PortStatus
;
1577 Event
= InterlockedExchangePointer((PVOID
)&HubExtension
->pResetPortEvent
,
1582 KeSetEvent(Event
, EVENT_INCREMENT
, FALSE
);
1585 USBH_SubmitStatusChangeTransfer(HubExtension
);
1587 if (!InterlockedDecrement(&HubExtension
->ResetRequestCount
))
1589 KeSetEvent(&HubExtension
->ResetEvent
,
1594 return STATUS_MORE_PROCESSING_REQUIRED
;
1599 USBH_ChangeIndicationAckChange(IN PUSBHUB_FDO_EXTENSION HubExtension
,
1601 IN
struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST
* Urb
,
1603 IN USHORT RequestValue
)
1605 PIO_STACK_LOCATION IoStack
;
1606 BM_REQUEST_TYPE RequestType
;
1608 DPRINT_SCE("USBH_ChangeIndicationAckChange: ... \n");
1610 Urb
->Hdr
.Length
= sizeof(struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST
);
1611 Urb
->Hdr
.Function
= URB_FUNCTION_CLASS_OTHER
;
1612 Urb
->Hdr
.UsbdDeviceHandle
= NULL
;
1614 Urb
->TransferFlags
= USBD_SHORT_TRANSFER_OK
;
1615 Urb
->TransferBufferLength
= 0;
1616 Urb
->TransferBuffer
= NULL
;
1617 Urb
->TransferBufferMDL
= NULL
;
1618 Urb
->UrbLink
= NULL
;
1621 RequestType
.Recipient
= BMREQUEST_TO_OTHER
;
1622 RequestType
.Type
= BMREQUEST_CLASS
;
1623 RequestType
.Dir
= BMREQUEST_HOST_TO_DEVICE
;
1625 Urb
->RequestTypeReservedBits
= RequestType
.B
;
1626 Urb
->Request
= USB_REQUEST_CLEAR_FEATURE
;
1628 Urb
->Value
= RequestValue
;
1630 IoInitializeIrp(Irp
,
1631 IoSizeOfIrp(HubExtension
->LowerDevice
->StackSize
),
1632 HubExtension
->LowerDevice
->StackSize
);
1634 IoStack
= IoGetNextIrpStackLocation(Irp
);
1636 IoStack
->MajorFunction
= IRP_MJ_INTERNAL_DEVICE_CONTROL
;
1637 IoStack
->Parameters
.Others
.Argument1
= Urb
;
1638 IoStack
->Parameters
.DeviceIoControl
.IoControlCode
= IOCTL_INTERNAL_USB_SUBMIT_URB
;
1640 IoSetCompletionRoutine(Irp
,
1641 USBH_ChangeIndicationAckChangeComplete
,
1647 return IoCallDriver(HubExtension
->LowerDevice
, Irp
);
1652 USBH_ChangeIndicationProcessChange(IN PDEVICE_OBJECT DeviceObject
,
1656 PUSBHUB_FDO_EXTENSION HubExtension
;
1657 PUSBHUB_IO_WORK_ITEM WorkItem
;
1658 USHORT RequestValue
;
1660 HubExtension
= Context
;
1662 DPRINT_SCE("USBH_ChangeIndicationProcessChange: PortStatus - %lX\n",
1663 HubExtension
->PortStatus
.AsUlong32
);
1665 if ((NT_SUCCESS(Irp
->IoStatus
.Status
) ||
1666 USBD_SUCCESS(HubExtension
->SCEWorkerUrb
.Hdr
.Status
)) &&
1667 (HubExtension
->PortStatus
.PortChange
.Usb20PortChange
.ResetChange
||
1668 HubExtension
->PortStatus
.PortChange
.Usb20PortChange
.PortEnableDisableChange
))
1670 if (!InterlockedDecrement(&HubExtension
->PendingRequestCount
))
1672 KeSetEvent(&HubExtension
->PendingRequestEvent
,
1677 USBH_FreeWorkItem(HubExtension
->WorkItemToQueue
);
1679 HubExtension
->WorkItemToQueue
= NULL
;
1681 if (HubExtension
->PortStatus
.PortChange
.Usb20PortChange
.ResetChange
)
1683 RequestValue
= USBHUB_FEATURE_C_PORT_RESET
;
1687 RequestValue
= USBHUB_FEATURE_C_PORT_ENABLE
;
1690 USBH_ChangeIndicationAckChange(HubExtension
,
1691 HubExtension
->ResetPortIrp
,
1692 &HubExtension
->SCEWorkerUrb
,
1698 ASSERT(HubExtension
->WorkItemToQueue
!= NULL
);
1700 WorkItem
= HubExtension
->WorkItemToQueue
;
1701 HubExtension
->WorkItemToQueue
= NULL
;
1703 USBH_QueueWorkItem(HubExtension
, WorkItem
);
1706 return STATUS_MORE_PROCESSING_REQUIRED
;
1711 USBH_ChangeIndicationQueryChange(IN PUSBHUB_FDO_EXTENSION HubExtension
,
1713 IN
struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST
* Urb
,
1716 PUSBHUB_IO_WORK_ITEM WorkItem
;
1718 PIO_STACK_LOCATION IoStack
;
1719 BM_REQUEST_TYPE RequestType
;
1721 DPRINT_SCE("USBH_ChangeIndicationQueryChange: Port - %x\n", Port
);
1723 InterlockedIncrement(&HubExtension
->PendingRequestCount
);
1727 ASSERT(HubExtension
->WorkItemToQueue
!= NULL
);
1729 WorkItem
= HubExtension
->WorkItemToQueue
;
1730 HubExtension
->WorkItemToQueue
= NULL
;
1732 USBH_QueueWorkItem(HubExtension
, WorkItem
);
1734 return STATUS_SUCCESS
;
1737 Urb
->Hdr
.Length
= sizeof(struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST
);
1738 Urb
->Hdr
.UsbdDeviceHandle
= NULL
;
1739 Urb
->Hdr
.Function
= URB_FUNCTION_CLASS_OTHER
;
1741 Urb
->TransferFlags
= USBD_SHORT_TRANSFER_OK
| USBD_TRANSFER_DIRECTION_IN
;
1742 Urb
->TransferBuffer
= &HubExtension
->PortStatus
;
1743 Urb
->TransferBufferLength
= sizeof(HubExtension
->PortStatus
);
1744 Urb
->TransferBufferMDL
= NULL
;
1745 Urb
->UrbLink
= NULL
;
1748 RequestType
.Recipient
= BMREQUEST_TO_OTHER
;
1749 RequestType
.Type
= BMREQUEST_CLASS
;
1750 RequestType
.Dir
= BMREQUEST_DEVICE_TO_HOST
;
1752 Urb
->RequestTypeReservedBits
= RequestType
.B
;
1753 Urb
->Request
= USB_REQUEST_GET_STATUS
;
1757 HubExtension
->Port
= Port
;
1759 IoInitializeIrp(Irp
,
1760 IoSizeOfIrp(HubExtension
->LowerDevice
->StackSize
),
1761 HubExtension
->LowerDevice
->StackSize
);
1763 IoStack
= IoGetNextIrpStackLocation(Irp
);
1765 IoStack
->MajorFunction
= IRP_MJ_INTERNAL_DEVICE_CONTROL
;
1766 IoStack
->Parameters
.Others
.Argument1
= Urb
;
1767 IoStack
->Parameters
.DeviceIoControl
.IoControlCode
= IOCTL_INTERNAL_USB_SUBMIT_URB
;
1769 IoSetCompletionRoutine(Irp
,
1770 USBH_ChangeIndicationProcessChange
,
1776 Status
= IoCallDriver(HubExtension
->LowerDevice
, Irp
);
1783 USBH_ProcessPortStateChange(IN PUSBHUB_FDO_EXTENSION HubExtension
,
1785 IN PUSB_PORT_STATUS_AND_CHANGE PortStatus
)
1787 PUSBHUB_PORT_DATA PortData
;
1788 USB_20_PORT_CHANGE PortStatusChange
;
1789 PDEVICE_OBJECT PortDevice
;
1790 PUSBHUB_PORT_PDO_EXTENSION PortExtension
;
1793 USHORT RequestValue
;
1796 DPRINT_SCE("USBH_ProcessPortStateChange ... \n");
1799 PortData
= &HubExtension
->PortData
[Port
- 1];
1801 PortStatusChange
= PortStatus
->PortChange
.Usb20PortChange
;
1803 if (PortStatusChange
.ConnectStatusChange
)
1805 PortData
->PortStatus
= *PortStatus
;
1807 USBH_SyncClearPortStatus(HubExtension
,
1809 USBHUB_FEATURE_C_PORT_CONNECTION
);
1811 PortData
= &HubExtension
->PortData
[Port
- 1];
1813 PortDevice
= PortData
->DeviceObject
;
1817 IoInvalidateDeviceRelations(HubExtension
->LowerPDO
, BusRelations
);
1821 PortExtension
= PortDevice
->DeviceExtension
;
1823 if (PortExtension
->PortPdoFlags
& USBHUB_PDO_FLAG_OVERCURRENT_PORT
)
1828 KeAcquireSpinLock(&HubExtension
->RelationsWorkerSpinLock
, &Irql
);
1830 if (PortExtension
->PortPdoFlags
& USBHUB_PDO_FLAG_POWER_D3
)
1832 KeReleaseSpinLock(&HubExtension
->RelationsWorkerSpinLock
, Irql
);
1833 IoInvalidateDeviceRelations(HubExtension
->LowerPDO
, BusRelations
);
1837 PortData
->DeviceObject
= NULL
;
1838 PortData
->ConnectionStatus
= NoDeviceConnected
;
1840 HubExtension
->HubFlags
|= USBHUB_FDO_FLAG_STATE_CHANGING
;
1842 InsertTailList(&HubExtension
->PdoList
, &PortExtension
->PortLink
);
1844 KeReleaseSpinLock(&HubExtension
->RelationsWorkerSpinLock
, Irql
);
1846 SerialNumber
= InterlockedExchangePointer((PVOID
)&PortExtension
->SerialNumber
,
1851 ExFreePoolWithTag(SerialNumber
, USB_HUB_TAG
);
1854 DeviceHandle
= InterlockedExchangePointer(&PortExtension
->DeviceHandle
,
1859 USBD_RemoveDeviceEx(HubExtension
, DeviceHandle
, 0);
1860 USBH_SyncDisablePort(HubExtension
, Port
);
1863 IoInvalidateDeviceRelations(HubExtension
->LowerPDO
, BusRelations
);
1865 else if (PortStatusChange
.PortEnableDisableChange
)
1867 RequestValue
= USBHUB_FEATURE_C_PORT_ENABLE
;
1868 PortData
->PortStatus
= *PortStatus
;
1869 USBH_SyncClearPortStatus(HubExtension
, Port
, RequestValue
);
1872 else if (PortStatusChange
.SuspendChange
)
1874 DPRINT1("USBH_ProcessPortStateChange: SuspendChange UNIMPLEMENTED. FIXME\n");
1877 else if (PortStatusChange
.OverCurrentIndicatorChange
)
1879 DPRINT1("USBH_ProcessPortStateChange: OverCurrentIndicatorChange UNIMPLEMENTED. FIXME\n");
1882 else if (PortStatusChange
.ResetChange
)
1884 RequestValue
= USBHUB_FEATURE_C_PORT_RESET
;
1885 PortData
->PortStatus
= *PortStatus
;
1886 USBH_SyncClearPortStatus(HubExtension
, Port
, RequestValue
);
1892 USBH_GetPortStatus(IN PUSBHUB_FDO_EXTENSION HubExtension
,
1893 IN PULONG PortStatus
)
1896 PIO_STACK_LOCATION IoStack
;
1899 IO_STATUS_BLOCK IoStatusBlock
;
1901 DPRINT("USBH_GetPortStatus ... \n");
1905 KeInitializeEvent(&Event
, NotificationEvent
, FALSE
);
1907 Irp
= IoBuildDeviceIoControlRequest(IOCTL_INTERNAL_USB_GET_PORT_STATUS
,
1908 HubExtension
->LowerDevice
,
1919 return STATUS_INSUFFICIENT_RESOURCES
;
1922 IoStack
= IoGetNextIrpStackLocation(Irp
);
1923 IoStack
->Parameters
.Others
.Argument1
= PortStatus
;
1925 Status
= IoCallDriver(HubExtension
->LowerDevice
, Irp
);
1927 if (Status
== STATUS_PENDING
)
1929 KeWaitForSingleObject(&Event
,
1937 IoStatusBlock
.Status
= Status
;
1940 return IoStatusBlock
.Status
;
1945 USBH_EnableParentPort(IN PUSBHUB_FDO_EXTENSION HubExtension
)
1950 IO_STATUS_BLOCK IoStatusBlock
;
1952 DPRINT("USBH_EnableParentPort ... \n");
1954 KeInitializeEvent(&Event
, NotificationEvent
, FALSE
);
1956 Irp
= IoBuildDeviceIoControlRequest(IOCTL_INTERNAL_USB_ENABLE_PORT
,
1957 HubExtension
->LowerDevice
,
1968 return STATUS_INSUFFICIENT_RESOURCES
;
1971 Status
= IoCallDriver(HubExtension
->LowerDevice
, Irp
);
1973 if (Status
== STATUS_PENDING
)
1975 KeWaitForSingleObject(&Event
,
1983 IoStatusBlock
.Status
= Status
;
1986 return IoStatusBlock
.Status
;
1991 USBH_ResetInterruptPipe(IN PUSBHUB_FDO_EXTENSION HubExtension
)
1993 struct _URB_PIPE_REQUEST
* Urb
;
1996 DPRINT("USBH_ResetInterruptPipe ... \n");
1998 Urb
= ExAllocatePoolWithTag(NonPagedPool
,
1999 sizeof(struct _URB_PIPE_REQUEST
),
2004 RtlZeroMemory(Urb
, sizeof(struct _URB_PIPE_REQUEST
));
2006 Urb
->Hdr
.Length
= sizeof(struct _URB_PIPE_REQUEST
);
2007 Urb
->Hdr
.Function
= URB_FUNCTION_SYNC_RESET_PIPE_AND_CLEAR_STALL
;
2008 Urb
->PipeHandle
= HubExtension
->PipeInfo
.PipeHandle
;
2010 Status
= USBH_FdoSyncSubmitUrb(HubExtension
->Common
.SelfDevice
,
2013 ExFreePoolWithTag(Urb
, USB_HUB_TAG
);
2017 Status
= STATUS_INSUFFICIENT_RESOURCES
;
2020 if (NT_SUCCESS(Status
))
2022 HubExtension
->RequestErrors
= 0;
2030 USBH_ResetHub(IN PUSBHUB_FDO_EXTENSION HubExtension
)
2033 ULONG PortStatusFlags
= 0;
2035 DPRINT("USBH_ResetHub: ... \n");
2037 Status
= USBH_GetPortStatus(HubExtension
, &PortStatusFlags
);
2039 if (!NT_SUCCESS(Status
))
2044 if (!(PortStatusFlags
& USBD_PORT_ENABLED
))
2046 if (PortStatusFlags
& USBD_PORT_CONNECTED
)
2048 USBH_EnableParentPort(HubExtension
);
2052 Status
= USBH_ResetInterruptPipe(HubExtension
);
2059 USBH_ChangeIndicationWorker(IN PUSBHUB_FDO_EXTENSION HubExtension
,
2062 PUSBHUB_FDO_EXTENSION LowerHubExtension
;
2063 PUSBHUB_PORT_PDO_EXTENSION LowerPortExtension
;
2064 PUSBHUB_STATUS_CHANGE_CONTEXT WorkItem
;
2065 USB_PORT_STATUS_AND_CHANGE PortStatus
;
2069 DPRINT_SCE("USBH_ChangeIndicationWorker ... \n");
2073 KeWaitForSingleObject(&HubExtension
->HubSemaphore
,
2079 if (HubExtension
->HubFlags
& USBHUB_FDO_FLAG_DEVICE_STOPPING
)
2081 KeSetEvent(&HubExtension
->StatusChangeEvent
,
2088 if (!HubExtension
->RequestErrors
)
2093 DPRINT_SCE("USBH_ChangeIndicationWorker: RequestErrors - %x\n",
2094 HubExtension
->RequestErrors
);
2096 if (HubExtension
->LowerPDO
== HubExtension
->RootHubPdo
)
2101 LowerPortExtension
= HubExtension
->LowerPDO
->DeviceExtension
;
2103 if (LowerPortExtension
->PortPdoFlags
& USBHUB_PDO_FLAG_POWER_D1_OR_D2
)
2108 LowerHubExtension
= LowerPortExtension
->HubExtension
;
2110 if (!LowerHubExtension
)
2115 Status
= USBH_SyncGetPortStatus(LowerHubExtension
,
2116 LowerPortExtension
->PortNumber
,
2118 sizeof(USB_PORT_STATUS_AND_CHANGE
));
2120 if (!NT_SUCCESS(Status
) ||
2121 !PortStatus
.PortStatus
.Usb20PortStatus
.CurrentConnectStatus
)
2123 HubExtension
->HubFlags
|= USBHUB_FDO_FLAG_DEVICE_REMOVED
;
2125 KeSetEvent(&HubExtension
->StatusChangeEvent
,
2132 if (!(HubExtension
->HubFlags
& USBHUB_FDO_FLAG_ESD_RECOVERING
))
2134 HubExtension
->HubFlags
|= USBHUB_FDO_FLAG_ESD_RECOVERING
;
2136 DPRINT1("USBH_ChangeIndicationWorker: USBHUB_FDO_FLAG_ESD_RECOVERING FIXME\n");
2144 if (WorkItem
->IsRequestErrors
)
2146 USBH_ResetHub(HubExtension
);
2151 Port
< HubExtension
->HubDescriptor
->bNumberOfPorts
;
2154 if (IsBitSet((PUCHAR
)(WorkItem
+ 1), Port
))
2162 Status
= USBH_SyncGetPortStatus(HubExtension
,
2165 sizeof(USB_PORT_STATUS_AND_CHANGE
));
2169 DPRINT1("USBH_ChangeIndicationWorker: USBH_SyncGetHubStatus() UNIMPLEMENTED. FIXME\n");
2171 Status
= STATUS_ASSERTION_FAILURE
;
2174 if (NT_SUCCESS(Status
))
2178 USBH_ProcessPortStateChange(HubExtension
,
2184 DPRINT1("USBH_ChangeIndicationWorker: USBH_ProcessHubStateChange() UNIMPLEMENTED. FIXME\n");
2190 HubExtension
->RequestErrors
++;
2192 if (HubExtension
->RequestErrors
> USBHUB_MAX_REQUEST_ERRORS
)
2194 HubExtension
->HubFlags
|= USBHUB_FDO_FLAG_DEVICE_FAILED
;
2200 USBH_SubmitStatusChangeTransfer(HubExtension
);
2204 KeReleaseSemaphore(&HubExtension
->HubSemaphore
,
2205 LOW_REALTIME_PRIORITY
,
2209 if (!InterlockedDecrement(&HubExtension
->PendingRequestCount
))
2211 KeSetEvent(&HubExtension
->PendingRequestEvent
,
2216 if (!InterlockedDecrement((PLONG
)&HubExtension
->ResetRequestCount
))
2218 KeSetEvent(&HubExtension
->ResetEvent
,
2222 if (HubExtension
->HubFlags
& USBHUB_FDO_FLAG_DEFER_CHECK_IDLE
)
2224 USBH_CheckHubIdle(HubExtension
);
2231 USBH_ChangeIndication(IN PDEVICE_OBJECT DeviceObject
,
2235 PUSBHUB_FDO_EXTENSION HubExtension
;
2236 USBD_STATUS UrbStatus
;
2237 BOOLEAN IsErrors
= FALSE
;
2238 PUSBHUB_IO_WORK_ITEM HubWorkItem
;
2239 PUSBHUB_STATUS_CHANGE_CONTEXT HubWorkItemBuffer
;
2246 HubExtension
= Context
;
2247 UrbStatus
= HubExtension
->SCEWorkerUrb
.Hdr
.Status
;
2249 DPRINT_SCE("USBH_ChangeIndication: IrpStatus - %x, UrbStatus - %x, HubFlags - %lX\n",
2250 Irp
->IoStatus
.Status
,
2252 HubExtension
->HubFlags
);
2254 if (NT_ERROR(Irp
->IoStatus
.Status
) || USBD_ERROR(UrbStatus
) ||
2255 (HubExtension
->HubFlags
& USBHUB_FDO_FLAG_DEVICE_FAILED
) ||
2256 (HubExtension
->HubFlags
& USBHUB_FDO_FLAG_DEVICE_STOPPING
))
2258 HubExtension
->RequestErrors
++;
2262 KeSetEvent(&HubExtension
->StatusChangeEvent
,
2266 if (HubExtension
->HubFlags
& USBHUB_FDO_FLAG_DEVICE_STOPPING
||
2267 HubExtension
->HubFlags
& USBHUB_FDO_FLAG_DEVICE_FAILED
||
2268 HubExtension
->RequestErrors
> USBHUB_MAX_REQUEST_ERRORS
||
2269 Irp
->IoStatus
.Status
== STATUS_DELETE_PENDING
)
2271 DPRINT_SCE("USBH_ChangeIndication: HubExtension->RequestErrors - %x\n",
2272 HubExtension
->RequestErrors
);
2274 return STATUS_MORE_PROCESSING_REQUIRED
;
2277 DPRINT_SCE("USBH_ChangeIndication: HubExtension->RequestErrors - %x\n",
2278 HubExtension
->RequestErrors
);
2282 HubExtension
->RequestErrors
= 0;
2285 BufferLength
= sizeof(USBHUB_STATUS_CHANGE_CONTEXT
) +
2286 HubExtension
->SCEBitmapLength
;
2288 Status
= USBH_AllocateWorkItem(HubExtension
,
2290 USBH_ChangeIndicationWorker
,
2292 (PVOID
*)&HubWorkItemBuffer
,
2295 if (!NT_SUCCESS(Status
))
2297 return STATUS_MORE_PROCESSING_REQUIRED
;
2300 RtlZeroMemory(HubWorkItemBuffer
, BufferLength
);
2302 HubWorkItemBuffer
->IsRequestErrors
= FALSE
;
2306 HubWorkItemBuffer
->IsRequestErrors
= TRUE
;
2309 if (InterlockedIncrement(&HubExtension
->ResetRequestCount
) == 1)
2311 KeResetEvent(&HubExtension
->ResetEvent
);
2314 HubWorkItemBuffer
->HubExtension
= HubExtension
;
2316 HubExtension
->WorkItemToQueue
= HubWorkItem
;
2318 Bitmap
= HubWorkItemBuffer
+ 1;
2320 RtlCopyMemory(Bitmap
,
2321 HubExtension
->SCEBitmap
,
2322 HubExtension
->SCEBitmapLength
);
2324 NumPorts
= HubExtension
->HubDescriptor
->bNumberOfPorts
;
2326 for (Port
= 0; Port
<= NumPorts
; ++Port
)
2328 if (IsBitSet(Bitmap
, Port
))
2334 if (Port
> NumPorts
)
2339 Status
= USBH_ChangeIndicationQueryChange(HubExtension
,
2340 HubExtension
->ResetPortIrp
,
2341 &HubExtension
->SCEWorkerUrb
,
2344 if (NT_ERROR(Status
))
2346 HubExtension
->HubFlags
|= USBHUB_FDO_FLAG_DEVICE_FAILED
;
2349 return STATUS_MORE_PROCESSING_REQUIRED
;
2354 USBH_SubmitStatusChangeTransfer(IN PUSBHUB_FDO_EXTENSION HubExtension
)
2358 struct _URB_BULK_OR_INTERRUPT_TRANSFER
* Urb
;
2359 PIO_STACK_LOCATION IoStack
;
2361 DPRINT_SCE("USBH_SubmitStatusChangeTransfer: HubExtension - %p, SCEIrp - %p\n",
2363 HubExtension
->SCEIrp
);
2365 if (HubExtension
->HubFlags
& USBHUB_FDO_FLAG_NOT_D0_STATE
)
2367 DPRINT_SCE("USBH_SubmitStatusChangeTransfer: USBHUB_FDO_FLAG_NOT_D0_STATE\n");
2368 DPRINT_SCE("USBH_SubmitStatusChangeTransfer: HubFlags - %lX\n",
2369 HubExtension
->HubFlags
);
2371 return STATUS_INVALID_DEVICE_STATE
;
2374 Irp
= HubExtension
->SCEIrp
;
2378 return STATUS_INVALID_DEVICE_STATE
;
2381 Urb
= (struct _URB_BULK_OR_INTERRUPT_TRANSFER
*)&HubExtension
->SCEWorkerUrb
;
2383 Urb
->Hdr
.Length
= sizeof(struct _URB_BULK_OR_INTERRUPT_TRANSFER
);
2384 Urb
->Hdr
.Function
= URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER
;
2385 Urb
->Hdr
.UsbdDeviceHandle
= NULL
;
2387 Urb
->PipeHandle
= HubExtension
->PipeInfo
.PipeHandle
;
2388 Urb
->TransferFlags
= USBD_SHORT_TRANSFER_OK
;
2389 Urb
->TransferBuffer
= HubExtension
->SCEBitmap
;
2390 Urb
->TransferBufferLength
= HubExtension
->SCEBitmapLength
;
2391 Urb
->TransferBufferMDL
= NULL
;
2392 Urb
->UrbLink
= NULL
;
2394 IoInitializeIrp(Irp
,
2395 IoSizeOfIrp(HubExtension
->LowerDevice
->StackSize
),
2396 HubExtension
->LowerDevice
->StackSize
);
2398 IoStack
= IoGetNextIrpStackLocation(Irp
);
2400 IoStack
->MajorFunction
= IRP_MJ_INTERNAL_DEVICE_CONTROL
;
2401 IoStack
->Parameters
.Others
.Argument1
= &HubExtension
->SCEWorkerUrb
;
2402 IoStack
->Parameters
.DeviceIoControl
.IoControlCode
= IOCTL_INTERNAL_USB_SUBMIT_URB
;
2404 IoSetCompletionRoutine(Irp
,
2405 USBH_ChangeIndication
,
2411 KeResetEvent(&HubExtension
->StatusChangeEvent
);
2413 Status
= IoCallDriver(HubExtension
->LowerDevice
, Irp
);
2420 USBD_CreateDeviceEx(IN PUSBHUB_FDO_EXTENSION HubExtension
,
2421 IN PUSB_DEVICE_HANDLE
* OutDeviceHandle
,
2422 IN USB_PORT_STATUS UsbPortStatus
,
2425 PUSB_DEVICE_HANDLE HubDeviceHandle
;
2426 PUSB_BUSIFFN_CREATE_USB_DEVICE CreateUsbDevice
;
2428 DPRINT("USBD_CreateDeviceEx: Port - %x, UsbPortStatus - 0x%04X\n",
2430 UsbPortStatus
.AsUshort16
);
2432 CreateUsbDevice
= HubExtension
->BusInterface
.CreateUsbDevice
;
2434 if (!CreateUsbDevice
)
2436 return STATUS_NOT_IMPLEMENTED
;
2439 HubDeviceHandle
= USBH_SyncGetDeviceHandle(HubExtension
->LowerDevice
);
2441 return CreateUsbDevice(HubExtension
->BusInterface
.BusContext
,
2444 UsbPortStatus
.AsUshort16
,
2450 USBD_RemoveDeviceEx(IN PUSBHUB_FDO_EXTENSION HubExtension
,
2451 IN PUSB_DEVICE_HANDLE DeviceHandle
,
2454 PUSB_BUSIFFN_REMOVE_USB_DEVICE RemoveUsbDevice
;
2456 DPRINT("USBD_RemoveDeviceEx: DeviceHandle - %p, Flags - %X\n",
2460 RemoveUsbDevice
= HubExtension
->BusInterface
.RemoveUsbDevice
;
2462 if (!RemoveUsbDevice
)
2464 return STATUS_NOT_IMPLEMENTED
;
2467 return RemoveUsbDevice(HubExtension
->BusInterface
.BusContext
,
2474 USBD_InitializeDeviceEx(IN PUSBHUB_FDO_EXTENSION HubExtension
,
2475 IN PUSB_DEVICE_HANDLE DeviceHandle
,
2476 IN PUCHAR DeviceDescriptorBuffer
,
2477 IN ULONG DeviceDescriptorBufferLength
,
2478 IN PUCHAR ConfigDescriptorBuffer
,
2479 IN ULONG ConfigDescriptorBufferLength
)
2482 PUSB_BUSIFFN_INITIALIZE_USB_DEVICE InitializeUsbDevice
;
2483 PUSB_BUSIFFN_GET_USB_DESCRIPTORS GetUsbDescriptors
;
2485 DPRINT("USBD_InitializeDeviceEx: ... \n");
2487 InitializeUsbDevice
= HubExtension
->BusInterface
.InitializeUsbDevice
;
2488 GetUsbDescriptors
= HubExtension
->BusInterface
.GetUsbDescriptors
;
2490 if (!InitializeUsbDevice
|| !GetUsbDescriptors
)
2492 return STATUS_NOT_IMPLEMENTED
;
2495 Status
= InitializeUsbDevice(HubExtension
->BusInterface
.BusContext
,
2498 if (!NT_SUCCESS(Status
))
2503 return GetUsbDescriptors(HubExtension
->BusInterface
.BusContext
,
2505 DeviceDescriptorBuffer
,
2506 &DeviceDescriptorBufferLength
,
2507 ConfigDescriptorBuffer
,
2508 &ConfigDescriptorBufferLength
);
2513 USBHUB_SetDeviceHandleData(IN PUSBHUB_FDO_EXTENSION HubExtension
,
2514 IN PDEVICE_OBJECT UsbDevicePdo
,
2515 IN PVOID DeviceHandle
)
2517 PUSB_BUSIFFN_SET_DEVHANDLE_DATA SetDeviceHandleData
;
2519 DPRINT("USBHUB_SetDeviceHandleData ... \n");
2521 SetDeviceHandleData
= HubExtension
->BusInterface
.SetDeviceHandleData
;
2523 if (!SetDeviceHandleData
)
2528 SetDeviceHandleData(HubExtension
->BusInterface
.BusContext
,
2535 USBHUB_FlushAllTransfers(IN PUSBHUB_FDO_EXTENSION HubExtension
)
2537 PUSB_BUSIFFN_FLUSH_TRANSFERS FlushTransfers
;
2539 DPRINT("USBHUB_FlushAllTransfers ... \n");
2541 FlushTransfers
= HubExtension
->BusInterface
.FlushTransfers
;
2545 FlushTransfers(HubExtension
->BusInterface
.BusContext
, NULL
);
2551 USBD_GetDeviceInformationEx(IN PUSBHUB_PORT_PDO_EXTENSION PortExtension
,
2552 IN PUSBHUB_FDO_EXTENSION HubExtension
,
2553 IN PUSB_NODE_CONNECTION_INFORMATION_EX Info
,
2555 IN PUSB_DEVICE_HANDLE DeviceHandle
)
2557 PUSB_BUSIFFN_GET_DEVICE_INFORMATION QueryDeviceInformation
;
2558 PUSB_DEVICE_INFORMATION_0 DeviceInfo
;
2559 SIZE_T DeviceInfoLength
;
2560 PUSB_NODE_CONNECTION_INFORMATION_EX NodeInfo
;
2561 SIZE_T NodeInfoLength
;
2566 DPRINT("USBD_GetDeviceInformationEx ... \n");
2568 QueryDeviceInformation
= HubExtension
->BusInterface
.QueryDeviceInformation
;
2570 if (!QueryDeviceInformation
)
2572 Status
= STATUS_NOT_IMPLEMENTED
;
2576 DeviceInfoLength
= sizeof(USB_DEVICE_INFORMATION_0
);
2580 DeviceInfo
= ExAllocatePoolWithTag(PagedPool
,
2586 return STATUS_INSUFFICIENT_RESOURCES
;
2589 RtlZeroMemory(DeviceInfo
, DeviceInfoLength
);
2591 DeviceInfo
->InformationLevel
= 0;
2593 Status
= QueryDeviceInformation(HubExtension
->BusInterface
.BusContext
,
2599 if (Status
!= STATUS_BUFFER_TOO_SMALL
)
2604 DeviceInfoLength
= DeviceInfo
->ActualLength
;
2606 ExFreePoolWithTag(DeviceInfo
, USB_HUB_TAG
);
2612 if (NT_SUCCESS(Status
))
2614 NodeInfoLength
= (sizeof(USB_NODE_CONNECTION_INFORMATION_EX
) - sizeof(USB_PIPE_INFO
)) +
2615 DeviceInfo
->NumberOfOpenPipes
* sizeof(USB_PIPE_INFO
);
2617 NodeInfo
= ExAllocatePoolWithTag(PagedPool
, NodeInfoLength
, USB_HUB_TAG
);
2621 ExFreePoolWithTag(DeviceInfo
, USB_HUB_TAG
);
2622 return STATUS_INSUFFICIENT_RESOURCES
;
2625 RtlZeroMemory(NodeInfo
, NodeInfoLength
);
2627 NodeInfo
->ConnectionIndex
= Info
->ConnectionIndex
;
2629 RtlCopyMemory(&NodeInfo
->DeviceDescriptor
,
2630 &DeviceInfo
->DeviceDescriptor
,
2631 sizeof(USB_DEVICE_DESCRIPTOR
));
2633 NodeInfo
->CurrentConfigurationValue
= DeviceInfo
->CurrentConfigurationValue
;
2634 NodeInfo
->Speed
= DeviceInfo
->DeviceSpeed
;
2635 NodeInfo
->DeviceIsHub
= PortExtension
->PortPdoFlags
& USBHUB_PDO_FLAG_HUB_DEVICE
;
2636 NodeInfo
->DeviceAddress
= DeviceInfo
->DeviceAddress
;
2637 NodeInfo
->NumberOfOpenPipes
= DeviceInfo
->NumberOfOpenPipes
;
2638 NodeInfo
->ConnectionStatus
= Info
->ConnectionStatus
;
2640 for (PipeNumber
= 0;
2641 PipeNumber
< DeviceInfo
->NumberOfOpenPipes
;
2644 RtlCopyMemory(&NodeInfo
->PipeList
[PipeNumber
],
2645 &DeviceInfo
->PipeList
[PipeNumber
],
2646 sizeof(USB_PIPE_INFO
));
2650 ExFreePoolWithTag(DeviceInfo
, USB_HUB_TAG
);
2654 if (NodeInfoLength
<= Length
)
2656 Length
= NodeInfoLength
;
2660 Status
= STATUS_BUFFER_TOO_SMALL
;
2663 RtlCopyMemory(Info
, NodeInfo
, Length
);
2665 ExFreePoolWithTag(NodeInfo
, USB_HUB_TAG
);
2673 USBD_RestoreDeviceEx(IN PUSBHUB_FDO_EXTENSION HubExtension
,
2674 IN OUT PUSB_DEVICE_HANDLE OldDeviceHandle
,
2675 IN OUT PUSB_DEVICE_HANDLE NewDeviceHandle
)
2677 PUSB_BUSIFFN_RESTORE_DEVICE RestoreUsbDevice
;
2680 DPRINT("USBD_RestoreDeviceEx: HubExtension - %p, OldDeviceHandle - %p, NewDeviceHandle - %p\n",
2685 RestoreUsbDevice
= HubExtension
->BusInterface
.RestoreUsbDevice
;
2687 if (RestoreUsbDevice
)
2689 Status
= RestoreUsbDevice(HubExtension
->BusInterface
.BusContext
,
2695 Status
= STATUS_NOT_IMPLEMENTED
;
2703 USBH_AllocateWorkItem(PUSBHUB_FDO_EXTENSION HubExtension
,
2704 PUSBHUB_IO_WORK_ITEM
* OutHubIoWorkItem
,
2705 PUSBHUB_WORKER_ROUTINE WorkerRoutine
,
2706 SIZE_T BufferLength
,
2707 PVOID
* OutHubWorkItemBuffer
,
2708 WORK_QUEUE_TYPE Type
)
2710 PUSBHUB_IO_WORK_ITEM HubIoWorkItem
;
2711 PIO_WORKITEM WorkItem
;
2712 PVOID WorkItemBuffer
;
2714 DPRINT("USBH_AllocateWorkItem: ... \n");
2716 if (!(HubExtension
->HubFlags
& USBHUB_FDO_FLAG_WITEM_INIT
))
2718 return STATUS_INVALID_PARAMETER
;
2721 HubIoWorkItem
= ExAllocatePoolWithTag(NonPagedPool
,
2722 sizeof(USBHUB_IO_WORK_ITEM
),
2727 return STATUS_INSUFFICIENT_RESOURCES
;
2730 RtlZeroMemory(HubIoWorkItem
, sizeof(USBHUB_IO_WORK_ITEM
));
2732 WorkItem
= IoAllocateWorkItem(HubExtension
->Common
.SelfDevice
);
2734 HubIoWorkItem
->HubWorkItem
= WorkItem
;
2738 ExFreePoolWithTag(HubIoWorkItem
, USB_HUB_TAG
);
2739 return STATUS_INSUFFICIENT_RESOURCES
;
2742 if (BufferLength
&& OutHubWorkItemBuffer
)
2744 WorkItemBuffer
= ExAllocatePoolWithTag(NonPagedPool
,
2748 HubIoWorkItem
->HubWorkItemBuffer
= WorkItemBuffer
;
2750 if (!WorkItemBuffer
)
2752 IoFreeWorkItem(HubIoWorkItem
->HubWorkItem
);
2753 ExFreePoolWithTag(HubIoWorkItem
, USB_HUB_TAG
);
2755 return STATUS_INSUFFICIENT_RESOURCES
;
2758 RtlZeroMemory(WorkItemBuffer
, BufferLength
);
2762 HubIoWorkItem
->HubWorkItemBuffer
= NULL
;
2765 HubIoWorkItem
->HubWorkItemType
= Type
;
2766 HubIoWorkItem
->HubExtension
= HubExtension
;
2767 HubIoWorkItem
->HubWorkerRoutine
= WorkerRoutine
;
2769 if (OutHubIoWorkItem
)
2771 *OutHubIoWorkItem
= HubIoWorkItem
;
2774 if (OutHubWorkItemBuffer
)
2776 *OutHubWorkItemBuffer
= HubIoWorkItem
->HubWorkItemBuffer
;
2779 return STATUS_SUCCESS
;
2784 USBH_Worker(IN PDEVICE_OBJECT DeviceObject
,
2787 PUSBHUB_IO_WORK_ITEM HubIoWorkItem
;
2788 PUSBHUB_FDO_EXTENSION HubExtension
;
2790 PIO_WORKITEM WorkItem
;
2792 DPRINT("USBH_Worker: HubIoWorkItem - %p\n", Context
);
2794 HubIoWorkItem
= Context
;
2796 InterlockedDecrement(&HubIoWorkItem
->HubWorkerQueued
);
2798 HubExtension
= HubIoWorkItem
->HubExtension
;
2799 WorkItem
= HubIoWorkItem
->HubWorkItem
;
2801 HubIoWorkItem
->HubWorkerRoutine(HubIoWorkItem
->HubExtension
,
2802 HubIoWorkItem
->HubWorkItemBuffer
);
2804 KeAcquireSpinLock(&HubExtension
->WorkItemSpinLock
, &OldIrql
);
2805 RemoveEntryList(&HubIoWorkItem
->HubWorkItemLink
);
2806 KeReleaseSpinLock(&HubExtension
->WorkItemSpinLock
, OldIrql
);
2808 if (HubIoWorkItem
->HubWorkItemBuffer
)
2810 ExFreePoolWithTag(HubIoWorkItem
->HubWorkItemBuffer
, USB_HUB_TAG
);
2813 ExFreePoolWithTag(HubIoWorkItem
, USB_HUB_TAG
);
2815 if (!InterlockedDecrement(&HubExtension
->PendingRequestCount
))
2817 KeSetEvent(&HubExtension
->PendingRequestEvent
,
2822 IoFreeWorkItem(WorkItem
);
2824 DPRINT("USBH_Worker: HubIoWorkItem %p complete\n", Context
);
2829 USBH_QueueWorkItem(IN PUSBHUB_FDO_EXTENSION HubExtension
,
2830 IN PUSBHUB_IO_WORK_ITEM HubIoWorkItem
)
2832 DPRINT("USBH_QueueWorkItem: ... \n");
2834 InterlockedIncrement(&HubExtension
->PendingRequestCount
);
2835 InterlockedIncrement(&HubIoWorkItem
->HubWorkerQueued
);
2837 ExInterlockedInsertTailList(&HubExtension
->WorkItemList
,
2838 &HubIoWorkItem
->HubWorkItemLink
,
2839 &HubExtension
->WorkItemSpinLock
);
2841 IoQueueWorkItem(HubIoWorkItem
->HubWorkItem
,
2843 HubIoWorkItem
->HubWorkItemType
,
2849 USBH_FreeWorkItem(IN PUSBHUB_IO_WORK_ITEM HubIoWorkItem
)
2851 PIO_WORKITEM WorkItem
;
2853 DPRINT("USBH_FreeWorkItem: ... \n");
2855 WorkItem
= HubIoWorkItem
->HubWorkItem
;
2857 if (HubIoWorkItem
->HubWorkItemBuffer
)
2859 ExFreePoolWithTag(HubIoWorkItem
->HubWorkItemBuffer
, USB_HUB_TAG
);
2862 ExFreePoolWithTag(HubIoWorkItem
, USB_HUB_TAG
);
2864 IoFreeWorkItem(WorkItem
);
2869 USBHUB_RootHubCallBack(IN PVOID Context
)
2871 PUSBHUB_FDO_EXTENSION HubExtension
;
2873 DPRINT("USBHUB_RootHubCallBack: ... \n");
2875 HubExtension
= Context
;
2877 if (HubExtension
->SCEIrp
)
2879 HubExtension
->HubFlags
|= (USBHUB_FDO_FLAG_DO_ENUMERATION
|
2880 USBHUB_FDO_FLAG_NOT_ENUMERATED
);
2882 USBH_SubmitStatusChangeTransfer(HubExtension
);
2884 IoInvalidateDeviceRelations(HubExtension
->LowerPDO
, BusRelations
);
2888 HubExtension
->HubFlags
|= USBHUB_FDO_FLAG_DO_ENUMERATION
;
2891 KeSetEvent(&HubExtension
->RootHubNotificationEvent
,
2898 USBD_RegisterRootHubCallBack(IN PUSBHUB_FDO_EXTENSION HubExtension
)
2900 PUSB_BUSIFFN_ROOTHUB_INIT_NOTIFY RootHubInitNotification
;
2902 DPRINT("USBD_RegisterRootHubCallBack: ... \n");
2904 RootHubInitNotification
= HubExtension
->BusInterface
.RootHubInitNotification
;
2906 if (!RootHubInitNotification
)
2908 return STATUS_NOT_IMPLEMENTED
;
2911 KeResetEvent(&HubExtension
->RootHubNotificationEvent
);
2913 return RootHubInitNotification(HubExtension
->BusInterface
.BusContext
,
2915 USBHUB_RootHubCallBack
);
2920 USBD_UnRegisterRootHubCallBack(IN PUSBHUB_FDO_EXTENSION HubExtension
)
2922 PUSB_BUSIFFN_ROOTHUB_INIT_NOTIFY RootHubInitNotification
;
2925 DPRINT("USBD_UnRegisterRootHubCallBack ... \n");
2927 RootHubInitNotification
= HubExtension
->BusInterface
.RootHubInitNotification
;
2929 if (!RootHubInitNotification
)
2931 return STATUS_NOT_IMPLEMENTED
;
2934 Status
= RootHubInitNotification(HubExtension
->BusInterface
.BusContext
,
2938 if (!NT_SUCCESS(Status
))
2940 KeWaitForSingleObject(&HubExtension
->RootHubNotificationEvent
,
2952 USBH_HubSetDWakeCompletion(IN PDEVICE_OBJECT DeviceObject
,
2953 IN UCHAR MinorFunction
,
2954 IN POWER_STATE PowerState
,
2956 IN PIO_STATUS_BLOCK IoStatus
)
2958 DPRINT("USBH_HubSetDWakeCompletion: ... \n");
2959 KeSetEvent((PRKEVENT
)Context
, IO_NO_INCREMENT
, FALSE
);
2964 USBH_HubQueuePortIdleIrps(IN PUSBHUB_FDO_EXTENSION HubExtension
,
2965 IN PLIST_ENTRY IdleList
)
2967 PDEVICE_OBJECT PortDevice
;
2968 PUSBHUB_PORT_PDO_EXTENSION PortExtension
;
2975 DPRINT("USBH_HubQueuePortIdleIrps ... \n");
2977 InitializeListHead(IdleList
);
2979 IoAcquireCancelSpinLock(&Irql
);
2981 NumPorts
= HubExtension
->HubDescriptor
->bNumberOfPorts
;
2983 for (Port
= 0; Port
< NumPorts
; ++Port
)
2985 PortDevice
= HubExtension
->PortData
[Port
].DeviceObject
;
2989 PortExtension
= PortDevice
->DeviceExtension
;
2991 IdleIrp
= PortExtension
->IdleNotificationIrp
;
2992 PortExtension
->IdleNotificationIrp
= NULL
;
2994 if (IdleIrp
&& IoSetCancelRoutine(IdleIrp
, NULL
))
2996 DPRINT1("USBH_HubQueuePortIdleIrps: IdleIrp != NULL. FIXME\n");
3002 if (HubExtension
->HubFlags
& USBHUB_FDO_FLAG_WAIT_IDLE_REQUEST
)
3004 HubIdleIrp
= HubExtension
->PendingIdleIrp
;
3005 HubExtension
->PendingIdleIrp
= NULL
;
3012 IoReleaseCancelSpinLock(Irql
);
3016 USBH_HubCancelIdleIrp(HubExtension
, HubIdleIrp
);
3022 USBH_HubCompleteQueuedPortIdleIrps(IN PUSBHUB_FDO_EXTENSION HubExtension
,
3023 IN PLIST_ENTRY IdleList
,
3024 IN NTSTATUS NtStatus
)
3026 DPRINT("USBH_HubCompleteQueuedPortIdleIrps ... \n");
3028 while (!IsListEmpty(IdleList
))
3030 DPRINT1("USBH_HubCompleteQueuedPortIdleIrps: IdleList not Empty. FIXME\n");
3037 USBH_FlushPortPwrList(IN PUSBHUB_FDO_EXTENSION HubExtension
)
3039 PDEVICE_OBJECT PortDevice
;
3040 PUSBHUB_PORT_PDO_EXTENSION PortExtension
;
3044 DPRINT("USBH_FlushPortPwrList ... \n");
3046 InterlockedIncrement((PLONG
)&HubExtension
->PendingRequestCount
);
3048 KeWaitForSingleObject(&HubExtension
->ResetDeviceSemaphore
,
3054 for (Port
= 0; Port
< HubExtension
->HubDescriptor
->bNumberOfPorts
; ++Port
)
3056 PortDevice
= HubExtension
->PortData
[Port
].DeviceObject
;
3063 PortExtension
= PortDevice
->DeviceExtension
;
3065 InterlockedExchange((PLONG
)&PortExtension
->StateBehindD2
, 0);
3069 Entry
= ExInterlockedRemoveHeadList(&PortExtension
->PortPowerList
,
3070 &PortExtension
->PortPowerListSpinLock
);
3077 DPRINT1("USBH_FlushPortPwrList: PortPowerList FIXME\n");
3082 KeReleaseSemaphore(&HubExtension
->ResetDeviceSemaphore
,
3083 LOW_REALTIME_PRIORITY
,
3087 if (!InterlockedDecrement((PLONG
)&HubExtension
->PendingRequestCount
))
3089 KeSetEvent(&HubExtension
->PendingRequestEvent
,
3097 USBH_HubCompletePortIdleIrps(IN PUSBHUB_FDO_EXTENSION HubExtension
,
3098 IN NTSTATUS NtStatus
)
3100 LIST_ENTRY IdleList
;
3102 DPRINT("USBH_HubCompletePortIdleIrps ... \n");
3104 if (HubExtension
->HubFlags
& USBHUB_FDO_FLAG_DEVICE_STARTED
)
3106 USBH_HubQueuePortIdleIrps(HubExtension
, &IdleList
);
3108 USBH_HubCompleteQueuedPortIdleIrps(HubExtension
,
3112 USBH_FlushPortPwrList(HubExtension
);
3118 USBH_HubCancelIdleIrp(IN PUSBHUB_FDO_EXTENSION HubExtension
,
3121 DPRINT("USBH_HubCancelIdleIrp ... \n");
3123 IoCancelIrp(IdleIrp
);
3125 if (InterlockedExchange(&HubExtension
->IdleRequestLock
, 1))
3133 USBH_CheckIdleAbort(IN PUSBHUB_FDO_EXTENSION HubExtension
,
3135 IN BOOLEAN IsExtCheck
)
3137 PDEVICE_OBJECT PdoDevice
;
3138 PUSBHUB_PORT_PDO_EXTENSION PortExtension
;
3139 PUSBHUB_PORT_DATA PortData
;
3141 BOOLEAN Result
= FALSE
;
3143 DPRINT("USBH_CheckIdleAbort: ... \n");
3145 InterlockedIncrement(&HubExtension
->PendingRequestCount
);
3149 KeWaitForSingleObject(&HubExtension
->ResetDeviceSemaphore
,
3156 PortData
= HubExtension
->PortData
;
3158 for (Port
= 0; Port
< HubExtension
->HubDescriptor
->bNumberOfPorts
; Port
++)
3160 PdoDevice
= PortData
[Port
].DeviceObject
;
3164 PortExtension
= PdoDevice
->DeviceExtension
;
3166 if (PortExtension
->PoRequestCounter
)
3174 if (IsExtCheck
== TRUE
)
3176 PortData
= HubExtension
->PortData
;
3179 Port
< HubExtension
->HubDescriptor
->bNumberOfPorts
;
3182 PdoDevice
= PortData
[Port
].DeviceObject
;
3186 PortExtension
= PdoDevice
->DeviceExtension
;
3187 InterlockedExchange(&PortExtension
->StateBehindD2
, 0);
3196 KeReleaseSemaphore(&HubExtension
->ResetDeviceSemaphore
,
3197 LOW_REALTIME_PRIORITY
,
3202 if (!InterlockedDecrement(&HubExtension
->PendingRequestCount
))
3204 KeSetEvent(&HubExtension
->PendingRequestEvent
,
3214 USBH_FdoWaitWakeIrpCompletion(IN PDEVICE_OBJECT DeviceObject
,
3215 IN UCHAR MinorFunction
,
3216 IN POWER_STATE PowerState
,
3218 IN PIO_STATUS_BLOCK IoStatus
)
3220 DPRINT("USBH_FdoWaitWakeIrpCompletion ... \n");
3225 USBH_FdoSubmitWaitWakeIrp(IN PUSBHUB_FDO_EXTENSION HubExtension
)
3227 POWER_STATE PowerState
;
3232 DPRINT("USBH_FdoSubmitWaitWakeIrp: ... \n");
3234 PowerState
.SystemState
= HubExtension
->SystemWake
;
3235 HubExtension
->HubFlags
|= USBHUB_FDO_FLAG_PENDING_WAKE_IRP
;
3237 InterlockedIncrement(&HubExtension
->PendingRequestCount
);
3238 InterlockedExchange(&HubExtension
->FdoWaitWakeLock
, 0);
3240 Status
= PoRequestPowerIrp(HubExtension
->LowerPDO
,
3243 USBH_FdoWaitWakeIrpCompletion
,
3247 IoAcquireCancelSpinLock(&Irql
);
3249 if (Status
== STATUS_PENDING
)
3251 if (HubExtension
->HubFlags
& USBHUB_FDO_FLAG_PENDING_WAKE_IRP
)
3253 HubExtension
->PendingWakeIrp
= Irp
;
3254 DPRINT("USBH_FdoSubmitWaitWakeIrp: PendingWakeIrp - %p\n",
3255 HubExtension
->PendingWakeIrp
);
3260 HubExtension
->HubFlags
&= ~USBHUB_FDO_FLAG_PENDING_WAKE_IRP
;
3262 if (!InterlockedDecrement(&HubExtension
->PendingRequestCount
))
3264 KeSetEvent(&HubExtension
->PendingRequestEvent
,
3270 IoReleaseCancelSpinLock(Irql
);
3277 USBH_FdoIdleNotificationCallback(IN PVOID Context
)
3279 PUSBHUB_FDO_EXTENSION HubExtension
;
3280 PUSBHUB_PORT_DATA PortData
;
3281 PDEVICE_OBJECT PortDevice
;
3282 PUSBHUB_PORT_PDO_EXTENSION PortExtension
;
3285 POWER_STATE PowerState
;
3288 PIO_STACK_LOCATION IoStack
;
3289 PUSB_IDLE_CALLBACK_INFO CallbackInfo
;
3294 HubExtension
= Context
;
3296 DPRINT("USBH_FdoIdleNotificationCallback: HubExtension - %p, HubFlags - %lX\n",
3298 HubExtension
->HubFlags
);
3300 if (HubExtension
->HubFlags
& (USBHUB_FDO_FLAG_ENUM_POST_RECOVER
|
3301 USBHUB_FDO_FLAG_WAKEUP_START
|
3302 USBHUB_FDO_FLAG_DEVICE_REMOVED
|
3303 USBHUB_FDO_FLAG_STATE_CHANGING
|
3304 USBHUB_FDO_FLAG_ESD_RECOVERING
|
3305 USBHUB_FDO_FLAG_DEVICE_FAILED
|
3306 USBHUB_FDO_FLAG_DEVICE_STOPPING
))
3312 HubExtension
->HubFlags
|= USBHUB_FDO_FLAG_GOING_IDLE
;
3314 if (!(HubExtension
->HubFlags
& USBHUB_FDO_FLAG_PENDING_WAKE_IRP
))
3316 Status
= USBH_FdoSubmitWaitWakeIrp(HubExtension
);
3318 if (Status
!= STATUS_PENDING
)
3320 DPRINT("Status != STATUS_PENDING. DbgBreakPoint()\n");
3322 HubExtension
->HubFlags
&= ~USBHUB_FDO_FLAG_GOING_IDLE
;
3327 InterlockedIncrement(&HubExtension
->PendingRequestCount
);
3329 KeWaitForSingleObject(&HubExtension
->ResetDeviceSemaphore
,
3335 PortData
= HubExtension
->PortData
;
3339 Port
< HubExtension
->HubDescriptor
->bNumberOfPorts
;
3342 PortDevice
= PortData
[Port
].DeviceObject
;
3346 PortExtension
= PortDevice
->DeviceExtension
;
3348 IdleIrp
= PortExtension
->IdleNotificationIrp
;
3356 IoStack
= IoGetCurrentIrpStackLocation(IdleIrp
);
3358 CallbackInfo
= IoStack
->Parameters
.DeviceIoControl
.Type3InputBuffer
;
3366 if (!CallbackInfo
->IdleCallback
)
3372 if (PortExtension
->PendingSystemPoRequest
)
3378 if (InterlockedCompareExchange(&PortExtension
->StateBehindD2
,
3386 DPRINT("USBH_FdoIdleNotificationCallback: IdleContext - %p\n",
3387 CallbackInfo
->IdleContext
);
3389 CallbackInfo
->IdleCallback(CallbackInfo
->IdleContext
);
3391 if (PortExtension
->CurrentPowerState
.DeviceState
== PowerDeviceD0
)
3399 if (!(HubExtension
->HubFlags
& USBHUB_FDO_FLAG_DEVICE_STOPPING
) &&
3400 (USBH_CheckIdleAbort(HubExtension
, FALSE
, FALSE
) == TRUE
))
3407 KeReleaseSemaphore(&HubExtension
->ResetDeviceSemaphore
,
3408 LOW_REALTIME_PRIORITY
,
3412 if (!InterlockedDecrement(&HubExtension
->PendingRequestCount
))
3414 KeSetEvent(&HubExtension
->PendingRequestEvent
,
3420 (HubExtension
->HubFlags
& USBHUB_FDO_FLAG_DEVICE_SUSPENDED
))
3422 DPRINT1("USBH_FdoIdleNotificationCallback: HubFlags - %lX\n",
3423 HubExtension
->HubFlags
);
3425 HubExtension
->HubFlags
&= ~(USBHUB_FDO_FLAG_DEVICE_SUSPENDED
|
3426 USBHUB_FDO_FLAG_GOING_IDLE
);
3428 /* Aborting Idle for Hub */
3429 IoAcquireCancelSpinLock(&OldIrql
);
3431 if (HubExtension
->PendingIdleIrp
)
3433 Irp
= HubExtension
->PendingIdleIrp
;
3434 HubExtension
->PendingIdleIrp
= NULL
;
3437 IoReleaseCancelSpinLock(OldIrql
);
3441 USBH_HubCancelIdleIrp(HubExtension
, Irp
);
3445 USBH_HubCompletePortIdleIrps(HubExtension
, STATUS_CANCELLED
);
3449 PowerState
.DeviceState
= HubExtension
->DeviceWake
;
3451 KeWaitForSingleObject(&HubExtension
->IdleSemaphore
,
3457 HubExtension
->HubFlags
&= ~USBHUB_FDO_FLAG_GOING_IDLE
;
3458 HubExtension
->HubFlags
|= USBHUB_FDO_FLAG_DO_SUSPENSE
;
3460 KeInitializeEvent(&Event
, NotificationEvent
, FALSE
);
3462 DPRINT("USBH_FdoIdleNotificationCallback: LowerPdo - %p\n",
3463 HubExtension
->LowerPDO
);
3465 DPRINT("USBH_FdoIdleNotificationCallback: PowerState.DeviceState - %x\n",
3466 PowerState
.DeviceState
);
3468 Status
= PoRequestPowerIrp(HubExtension
->LowerPDO
,
3471 USBH_HubSetDWakeCompletion
,
3475 if (Status
== STATUS_PENDING
)
3477 KeWaitForSingleObject(&Event
,
3488 USBH_CompletePortIdleIrpsWorker(IN PUSBHUB_FDO_EXTENSION HubExtension
,
3491 PUSBHUB_IDLE_PORT_CONTEXT IdlePortContext
;
3494 BOOLEAN IsFlush
= FALSE
;
3496 DPRINT("USBH_CompletePortIdleIrpsWorker ... \n");
3498 IdlePortContext
= Context
;
3499 NtStatus
= IdlePortContext
->Status
;
3501 USBH_HubCompleteQueuedPortIdleIrps(HubExtension
,
3502 &IdlePortContext
->PwrList
,
3505 DPRINT1("USBH_CompletePortIdleIrpsWorker: USBH_RegQueryFlushPortPowerIrpsFlag() UNIMPLEMENTED. FIXME\n");
3506 Status
= STATUS_NOT_IMPLEMENTED
;// USBH_RegQueryFlushPortPowerIrpsFlag(&IsFlush);
3508 if (NT_SUCCESS(Status
))
3512 USBH_FlushPortPwrList(HubExtension
);
3519 USBH_IdleCompletePowerHubWorker(IN PUSBHUB_FDO_EXTENSION HubExtension
,
3522 PUSBHUB_IDLE_HUB_CONTEXT HubWorkItemBuffer
;
3524 DPRINT("USBH_IdleCompletePowerHubWorker ... \n");
3527 HubExtension
->CurrentPowerState
.DeviceState
!= PowerDeviceD0
&&
3528 HubExtension
->HubFlags
& USBHUB_FDO_FLAG_DEVICE_STARTED
)
3530 USBH_HubSetD0(HubExtension
);
3533 HubWorkItemBuffer
= Context
;
3535 USBH_HubCompletePortIdleIrps(HubExtension
, HubWorkItemBuffer
->Status
);
3541 USBH_FdoIdleNotificationRequestComplete(IN PDEVICE_OBJECT DeviceObject
,
3545 PUSBHUB_FDO_EXTENSION HubExtension
;
3550 PUSBHUB_IO_WORK_ITEM HubIoWorkItem
;
3552 IoAcquireCancelSpinLock(&Irql
);
3554 HubExtension
= Context
;
3555 HubExtension
->HubFlags
&= ~USBHUB_FDO_FLAG_WAIT_IDLE_REQUEST
;
3557 IdleIrp
= InterlockedExchangePointer((PVOID
)&HubExtension
->PendingIdleIrp
,
3560 DPRINT("USBH_FdoIdleNotificationRequestComplete: IdleIrp - %p\n", IdleIrp
);
3562 if (!InterlockedDecrement(&HubExtension
->PendingRequestCount
))
3564 KeSetEvent(&HubExtension
->PendingRequestEvent
, EVENT_INCREMENT
, FALSE
);
3567 IoReleaseCancelSpinLock(Irql
);
3569 NtStatus
= Irp
->IoStatus
.Status
;
3571 DPRINT("USBH_FdoIdleNotificationRequestComplete: NtStatus - %lX\n",
3574 if (!NT_SUCCESS(NtStatus
) &&
3575 NtStatus
!= STATUS_POWER_STATE_INVALID
&&
3576 !(HubExtension
->HubFlags
& USBHUB_FDO_FLAG_DEVICE_REMOVED
) &&
3577 !(HubExtension
->HubFlags
& USBHUB_FDO_FLAG_DEVICE_STOPPED
))
3579 DPRINT("USBH_FdoIdleNotificationRequestComplete: DeviceState - %x\n",
3580 HubExtension
->CurrentPowerState
.DeviceState
);
3582 if (HubExtension
->CurrentPowerState
.DeviceState
== PowerDeviceD0
)
3584 PUSBHUB_IDLE_PORT_CONTEXT HubWorkItemBuffer
;
3586 Status
= USBH_AllocateWorkItem(HubExtension
,
3588 USBH_CompletePortIdleIrpsWorker
,
3589 sizeof(USBHUB_IDLE_PORT_CONTEXT
),
3590 (PVOID
*)&HubWorkItemBuffer
,
3593 if (NT_SUCCESS(Status
))
3595 HubWorkItemBuffer
->Status
= NtStatus
;
3597 USBH_HubQueuePortIdleIrps(HubExtension
,
3598 &HubWorkItemBuffer
->PwrList
);
3600 USBH_QueueWorkItem(HubExtension
, HubIoWorkItem
);
3605 PUSBHUB_IDLE_HUB_CONTEXT HubWorkItemBuffer
;
3607 Status
= USBH_AllocateWorkItem(HubExtension
,
3609 USBH_IdleCompletePowerHubWorker
,
3610 sizeof(USBHUB_IDLE_HUB_CONTEXT
),
3611 (PVOID
*)&HubWorkItemBuffer
,
3614 if (NT_SUCCESS(Status
))
3616 HubWorkItemBuffer
->Status
= NtStatus
;
3617 USBH_QueueWorkItem(HubExtension
, HubIoWorkItem
);
3623 InterlockedExchange((PLONG
)&HubExtension
->IdleRequestLock
, 1))
3625 DPRINT("USBH_FdoIdleNotificationRequestComplete: Irp - %p\n", Irp
);
3629 return STATUS_MORE_PROCESSING_REQUIRED
;
3634 USBH_FdoSubmitIdleRequestIrp(IN PUSBHUB_FDO_EXTENSION HubExtension
)
3638 PDEVICE_OBJECT LowerPDO
;
3640 PIO_STACK_LOCATION IoStack
;
3643 DPRINT("USBH_FdoSubmitIdleRequestIrp: HubExtension - %p, PendingIdleIrp - %p\n",
3645 HubExtension
->PendingIdleIrp
);
3647 if (HubExtension
->PendingIdleIrp
)
3649 Status
= STATUS_DEVICE_BUSY
;
3650 KeSetEvent(&HubExtension
->IdleEvent
, EVENT_INCREMENT
, FALSE
);
3654 HubFlags
= HubExtension
->HubFlags
;
3656 if (HubFlags
& USBHUB_FDO_FLAG_DEVICE_STOPPING
||
3657 HubFlags
& USBHUB_FDO_FLAG_DEVICE_REMOVED
)
3659 HubExtension
->HubFlags
= HubFlags
& ~USBHUB_FDO_FLAG_WAIT_IDLE_REQUEST
;
3660 KeSetEvent(&HubExtension
->IdleEvent
, EVENT_INCREMENT
, FALSE
);
3661 return STATUS_DEVICE_REMOVED
;
3664 LowerPDO
= HubExtension
->LowerPDO
;
3666 HubExtension
->IdleCallbackInfo
.IdleCallback
= USBH_FdoIdleNotificationCallback
;
3667 HubExtension
->IdleCallbackInfo
.IdleContext
= HubExtension
;
3669 Irp
= IoAllocateIrp(LowerPDO
->StackSize
, FALSE
);
3673 HubExtension
->HubFlags
&= ~USBHUB_FDO_FLAG_WAIT_IDLE_REQUEST
;
3674 Status
= STATUS_INSUFFICIENT_RESOURCES
;
3676 KeSetEvent(&HubExtension
->IdleEvent
, EVENT_INCREMENT
, FALSE
);
3680 IoStack
= IoGetNextIrpStackLocation(Irp
);
3682 IoStack
->MajorFunction
= IRP_MJ_INTERNAL_DEVICE_CONTROL
;
3684 IoStack
->Parameters
.DeviceIoControl
.InputBufferLength
= sizeof(USB_IDLE_CALLBACK_INFO
);
3685 IoStack
->Parameters
.DeviceIoControl
.IoControlCode
= IOCTL_INTERNAL_USB_SUBMIT_IDLE_NOTIFICATION
;
3686 IoStack
->Parameters
.DeviceIoControl
.Type3InputBuffer
= &HubExtension
->IdleCallbackInfo
;
3688 IoSetCompletionRoutine(Irp
,
3689 USBH_FdoIdleNotificationRequestComplete
,
3695 InterlockedIncrement(&HubExtension
->PendingRequestCount
);
3696 InterlockedExchange(&HubExtension
->IdleRequestLock
, 0);
3698 HubExtension
->HubFlags
&= ~(USBHUB_FDO_FLAG_DEVICE_SUSPENDED
|
3699 USBHUB_FDO_FLAG_GOING_IDLE
);
3701 Status
= IoCallDriver(HubExtension
->LowerPDO
, Irp
);
3703 IoAcquireCancelSpinLock(&Irql
);
3705 if (Status
== STATUS_PENDING
&&
3706 HubExtension
->HubFlags
& USBHUB_FDO_FLAG_WAIT_IDLE_REQUEST
)
3708 HubExtension
->PendingIdleIrp
= Irp
;
3711 IoReleaseCancelSpinLock(Irql
);
3713 KeSetEvent(&HubExtension
->IdleEvent
, EVENT_INCREMENT
, FALSE
);
3720 USBH_CheckHubIdle(IN PUSBHUB_FDO_EXTENSION HubExtension
)
3722 PDEVICE_OBJECT PdoDevice
;
3723 PUSBHUB_PORT_PDO_EXTENSION PortExtension
;
3724 PUSBHUB_PORT_DATA PortData
;
3728 BOOLEAN IsHubIdle
= FALSE
;
3729 BOOLEAN IsAllPortsIdle
;
3730 BOOLEAN IsHubCheck
= TRUE
;
3732 DPRINT("USBH_CheckHubIdle: FIXME !!! HubExtension - %p\n", HubExtension
);
3734 return; //HACK: delete it line after fixing Power Manager!!!
3736 KeAcquireSpinLock(&HubExtension
->CheckIdleSpinLock
, &Irql
);
3738 if (HubExtension
->HubFlags
& USBHUB_FDO_FLAG_CHECK_IDLE_LOCK
)
3740 KeReleaseSpinLock(&HubExtension
->CheckIdleSpinLock
, Irql
);
3744 HubExtension
->HubFlags
|= USBHUB_FDO_FLAG_CHECK_IDLE_LOCK
;
3745 KeReleaseSpinLock(&HubExtension
->CheckIdleSpinLock
, Irql
);
3747 if (USBH_GetRootHubExtension(HubExtension
)->SystemPowerState
.SystemState
!= PowerSystemWorking
)
3749 KeAcquireSpinLock(&HubExtension
->CheckIdleSpinLock
, &Irql
);
3750 HubExtension
->HubFlags
&= ~USBHUB_FDO_FLAG_CHECK_IDLE_LOCK
;
3751 KeReleaseSpinLock(&HubExtension
->CheckIdleSpinLock
, Irql
);
3755 HubFlags
= HubExtension
->HubFlags
;
3756 DPRINT("USBH_CheckHubIdle: HubFlags - %lX\n", HubFlags
);
3758 if (!(HubFlags
& USBHUB_FDO_FLAG_DEVICE_STARTED
) ||
3759 !(HubFlags
& USBHUB_FDO_FLAG_DO_ENUMERATION
))
3764 if (HubFlags
& USBHUB_FDO_FLAG_NOT_ENUMERATED
||
3765 HubFlags
& USBHUB_FDO_FLAG_ENUM_POST_RECOVER
||
3766 HubFlags
& USBHUB_FDO_FLAG_DEVICE_FAILED
||
3767 HubFlags
& USBHUB_FDO_FLAG_DEVICE_STOPPING
||
3768 HubFlags
& USBHUB_FDO_FLAG_DEVICE_REMOVED
||
3769 HubFlags
& USBHUB_FDO_FLAG_STATE_CHANGING
||
3770 HubFlags
& USBHUB_FDO_FLAG_WAKEUP_START
||
3771 HubFlags
& USBHUB_FDO_FLAG_ESD_RECOVERING
)
3776 if (HubExtension
->ResetRequestCount
)
3778 HubExtension
->HubFlags
|= USBHUB_FDO_FLAG_DEFER_CHECK_IDLE
;
3782 HubExtension
->HubFlags
&= ~USBHUB_FDO_FLAG_DEFER_CHECK_IDLE
;
3784 InterlockedIncrement(&HubExtension
->PendingRequestCount
);
3786 KeWaitForSingleObject(&HubExtension
->ResetDeviceSemaphore
,
3792 IoAcquireCancelSpinLock(&Irql
);
3794 IsAllPortsIdle
= TRUE
;
3796 PortData
= HubExtension
->PortData
;
3799 Port
< HubExtension
->HubDescriptor
->bNumberOfPorts
;
3802 PdoDevice
= PortData
[Port
].DeviceObject
;
3806 PortExtension
= PdoDevice
->DeviceExtension
;
3808 if (!PortExtension
->IdleNotificationIrp
)
3810 DPRINT("USBH_CheckHubIdle: PortExtension - %p\n",
3813 IsAllPortsIdle
= FALSE
;
3822 !(HubExtension
->HubFlags
& USBHUB_FDO_FLAG_WAIT_IDLE_REQUEST
))
3824 KeResetEvent(&HubExtension
->IdleEvent
);
3825 HubExtension
->HubFlags
|= USBHUB_FDO_FLAG_WAIT_IDLE_REQUEST
;
3829 IoReleaseCancelSpinLock(Irql
);
3831 KeReleaseSemaphore(&HubExtension
->ResetDeviceSemaphore
,
3832 LOW_REALTIME_PRIORITY
,
3836 if (!InterlockedDecrement(&HubExtension
->PendingRequestCount
))
3838 KeSetEvent(&HubExtension
->PendingRequestEvent
,
3843 DPRINT("USBH_CheckHubIdle: IsAllPortsIdle - %x, IsHubIdle - %x\n",
3847 if (IsAllPortsIdle
&& IsHubIdle
)
3849 USBH_FdoSubmitIdleRequestIrp(HubExtension
);
3853 KeAcquireSpinLock(&HubExtension
->CheckIdleSpinLock
, &Irql
);
3854 HubExtension
->HubFlags
&= ~USBHUB_FDO_FLAG_CHECK_IDLE_LOCK
;
3855 KeReleaseSpinLock(&HubExtension
->CheckIdleSpinLock
, Irql
);
3860 USBH_CheckIdleWorker(IN PUSBHUB_FDO_EXTENSION HubExtension
,
3863 DPRINT("USBH_CheckIdleWorker: ... \n");
3864 USBH_CheckHubIdle(HubExtension
);
3869 USBH_CheckIdleDeferred(IN PUSBHUB_FDO_EXTENSION HubExtension
)
3871 PUSBHUB_IO_WORK_ITEM HubIoWorkItem
;
3874 DPRINT("USBH_CheckIdleDeferred: HubExtension - %p\n", HubExtension
);
3876 Status
= USBH_AllocateWorkItem(HubExtension
,
3878 USBH_CheckIdleWorker
,
3883 DPRINT("USBH_CheckIdleDeferred: HubIoWorkItem - %p\n", HubIoWorkItem
);
3885 if (NT_SUCCESS(Status
))
3887 USBH_QueueWorkItem(HubExtension
, HubIoWorkItem
);
3893 USBH_PdoSetCapabilities(IN PUSBHUB_PORT_PDO_EXTENSION PortExtension
)
3895 PUSBHUB_FDO_EXTENSION HubExtension
;
3897 SYSTEM_POWER_STATE SystemPowerState
;
3898 PDEVICE_POWER_STATE pDeviceState
;
3900 DPRINT("USBH_PdoSetCapabilities ... \n");
3902 HubExtension
= PortExtension
->HubExtension
;
3904 PortExtension
->Capabilities
.Size
= 64;
3905 PortExtension
->Capabilities
.Version
= 1;
3907 PortExtension
->Capabilities
.Removable
= 1;
3908 PortExtension
->Capabilities
.Address
= PortExtension
->PortNumber
;
3910 if (PortExtension
->SerialNumber
)
3912 PortExtension
->Capabilities
.UniqueID
= 1;
3916 PortExtension
->Capabilities
.UniqueID
= 0;
3919 PortExtension
->Capabilities
.RawDeviceOK
= 0;
3921 RtlCopyMemory(PortExtension
->Capabilities
.DeviceState
,
3922 HubExtension
->DeviceState
,
3923 (PowerSystemMaximum
+ 2) * sizeof(POWER_STATE
));
3925 PortExtension
->Capabilities
.DeviceState
[1] = PowerDeviceD0
;
3927 if (PortExtension
->PortPdoFlags
& USBHUB_PDO_FLAG_REMOTE_WAKEUP
)
3929 PortExtension
->Capabilities
.DeviceWake
= PowerDeviceD2
;
3931 PortExtension
->Capabilities
.DeviceD1
= 1;
3932 PortExtension
->Capabilities
.DeviceD2
= 1;
3934 PortExtension
->Capabilities
.WakeFromD0
= 1;
3935 PortExtension
->Capabilities
.WakeFromD1
= 1;
3936 PortExtension
->Capabilities
.WakeFromD2
= 1;
3938 pDeviceState
= &PortExtension
->Capabilities
.DeviceState
[2];
3940 for (State
= 2; State
<= 5; State
++)
3942 SystemPowerState
= State
;
3944 if (PortExtension
->Capabilities
.SystemWake
< SystemPowerState
)
3946 *pDeviceState
= PowerDeviceD3
;
3950 *pDeviceState
= PowerDeviceD2
;
3958 PortExtension
->Capabilities
.DeviceWake
= PowerDeviceD0
;
3959 PortExtension
->Capabilities
.DeviceState
[2] = PowerDeviceD3
;
3960 PortExtension
->Capabilities
.DeviceState
[3] = PowerDeviceD3
;
3961 PortExtension
->Capabilities
.DeviceState
[4] = PowerDeviceD3
;
3962 PortExtension
->Capabilities
.DeviceState
[5] = PowerDeviceD3
;
3968 USBH_ProcessDeviceInformation(IN PUSBHUB_PORT_PDO_EXTENSION PortExtension
)
3970 PUSB_INTERFACE_DESCRIPTOR Pid
;
3971 PUSB_CONFIGURATION_DESCRIPTOR ConfigDescriptor
;
3974 DPRINT("USBH_ProcessDeviceInformation ... \n");
3976 ConfigDescriptor
= NULL
;
3978 RtlZeroMemory(&PortExtension
->InterfaceDescriptor
,
3979 sizeof(PortExtension
->InterfaceDescriptor
));
3981 PortExtension
->PortPdoFlags
&= ~USBHUB_PDO_FLAG_HUB_DEVICE
;
3983 Status
= USBH_GetConfigurationDescriptor(PortExtension
->Common
.SelfDevice
,
3986 if (!NT_SUCCESS(Status
))
3988 if (ConfigDescriptor
)
3990 ExFreePool(ConfigDescriptor
);
3996 PortExtension
->PortPdoFlags
&= ~USBHUB_PDO_FLAG_REMOTE_WAKEUP
;
3998 if (ConfigDescriptor
->bmAttributes
& 0x20)
4000 /* device configuration supports remote wakeup */
4001 PortExtension
->PortPdoFlags
|= USBHUB_PDO_FLAG_REMOTE_WAKEUP
;
4004 USBHUB_DumpingDeviceDescriptor(&PortExtension
->DeviceDescriptor
);
4005 USBHUB_DumpingConfiguration(ConfigDescriptor
);
4007 DPRINT_PNP("USBH_ProcessDeviceInformation: Class - %x, SubClass - %x, Protocol - %x\n",
4008 PortExtension
->DeviceDescriptor
.bDeviceClass
,
4009 PortExtension
->DeviceDescriptor
.bDeviceSubClass
,
4010 PortExtension
->DeviceDescriptor
.bDeviceProtocol
);
4012 DPRINT_PNP("USBH_ProcessDeviceInformation: bNumConfigurations - %x, bNumInterfaces - %x\n",
4013 PortExtension
->DeviceDescriptor
.bNumConfigurations
,
4014 ConfigDescriptor
->bNumInterfaces
);
4017 /* Enumeration of USB Composite Devices (msdn):
4018 1) The device class field of the device descriptor (bDeviceClass) must contain a value of zero,
4019 or the class (bDeviceClass), subclass (bDeviceSubClass), and protocol (bDeviceProtocol)
4020 fields of the device descriptor must have the values 0xEF, 0x02 and 0x01 respectively,
4021 as explained in USB Interface Association Descriptor.
4022 2) The device must have multiple interfaces
4023 3) The device must have a single configuration.
4026 if (((PortExtension
->DeviceDescriptor
.bDeviceClass
== USB_DEVICE_CLASS_RESERVED
) ||
4027 (PortExtension
->DeviceDescriptor
.bDeviceClass
== USB_DEVICE_CLASS_MISCELLANEOUS
&&
4028 PortExtension
->DeviceDescriptor
.bDeviceSubClass
== 0x02 &&
4029 PortExtension
->DeviceDescriptor
.bDeviceProtocol
== 0x01)) &&
4030 (ConfigDescriptor
->bNumInterfaces
> 1) &&
4031 (PortExtension
->DeviceDescriptor
.bNumConfigurations
< 2))
4033 DPRINT("USBH_ProcessDeviceInformation: Multi-Interface configuration\n");
4035 PortExtension
->PortPdoFlags
|= USBHUB_PDO_FLAG_MULTI_INTERFACE
;
4037 if (ConfigDescriptor
)
4039 ExFreePool(ConfigDescriptor
);
4045 Pid
= USBD_ParseConfigurationDescriptorEx(ConfigDescriptor
,
4054 RtlCopyMemory(&PortExtension
->InterfaceDescriptor
,
4056 sizeof(PortExtension
->InterfaceDescriptor
));
4058 if (Pid
->bInterfaceClass
== USB_DEVICE_CLASS_HUB
)
4060 PortExtension
->PortPdoFlags
|= (USBHUB_PDO_FLAG_HUB_DEVICE
|
4061 USBHUB_PDO_FLAG_REMOTE_WAKEUP
);
4066 Status
= STATUS_UNSUCCESSFUL
;
4069 if (ConfigDescriptor
)
4071 ExFreePool(ConfigDescriptor
);
4079 USBH_CheckDeviceIDUnique(IN PUSBHUB_FDO_EXTENSION HubExtension
,
4081 IN USHORT idProduct
,
4082 IN PVOID SerialNumber
,
4083 IN USHORT SN_DescriptorLength
)
4085 PDEVICE_OBJECT PortDevice
;
4086 PUSBHUB_PORT_PDO_EXTENSION PortExtension
;
4090 DPRINT("USBH_CheckDeviceIDUnique: idVendor - 0x%04X, idProduct - 0x%04X\n",
4094 if (!HubExtension
->HubDescriptor
->bNumberOfPorts
)
4099 for (Port
= 0; Port
< HubExtension
->HubDescriptor
->bNumberOfPorts
; Port
++)
4101 PortDevice
= HubExtension
->PortData
[Port
].DeviceObject
;
4105 PortExtension
= PortDevice
->DeviceExtension
;
4107 if (PortExtension
->DeviceDescriptor
.idVendor
== idVendor
&&
4108 PortExtension
->DeviceDescriptor
.idProduct
== idProduct
&&
4109 PortExtension
->SN_DescriptorLength
== SN_DescriptorLength
)
4111 if (PortExtension
->SerialNumber
)
4113 NumberBytes
= RtlCompareMemory(PortExtension
->SerialNumber
,
4115 SN_DescriptorLength
);
4117 if (NumberBytes
== SN_DescriptorLength
)
4131 USBH_ValidateSerialNumberString(IN PUSHORT SerialNumberString
)
4136 DPRINT("USBH_ValidateSerialNumberString: ... \n");
4138 for (ix
= 0; SerialNumberString
[ix
] != UNICODE_NULL
; ix
++)
4140 Symbol
= SerialNumberString
[ix
];
4142 if (Symbol
< 0x20 || Symbol
> 0x7F || Symbol
== 0x2C) // ','
4154 USBH_CheckDeviceLanguage(IN PDEVICE_OBJECT DeviceObject
,
4155 IN USHORT LanguageId
)
4157 PUSB_STRING_DESCRIPTOR Descriptor
;
4164 DPRINT("USBH_CheckDeviceLanguage: LanguageId - 0x%04X\n", LanguageId
);
4166 Descriptor
= ExAllocatePoolWithTag(NonPagedPool
,
4167 MAXIMUM_USB_STRING_LENGTH
,
4172 return STATUS_INSUFFICIENT_RESOURCES
;
4175 RtlZeroMemory(Descriptor
, MAXIMUM_USB_STRING_LENGTH
);
4177 Status
= USBH_SyncGetStringDescriptor(DeviceObject
,
4181 MAXIMUM_USB_STRING_LENGTH
,
4185 if (!NT_SUCCESS(Status
) ||
4186 Length
< sizeof(USB_COMMON_DESCRIPTOR
))
4191 NumSymbols
= (Length
-
4192 FIELD_OFFSET(USB_STRING_DESCRIPTOR
, bString
)) / sizeof(WCHAR
);
4194 pSymbol
= Descriptor
->bString
;
4196 for (ix
= 1; ix
< NumSymbols
; ix
++)
4198 if (*pSymbol
== (WCHAR
)LanguageId
)
4200 Status
= STATUS_SUCCESS
;
4207 Status
= STATUS_NOT_SUPPORTED
;
4210 ExFreePoolWithTag(Descriptor
, USB_HUB_TAG
);
4216 USBH_GetSerialNumberString(IN PDEVICE_OBJECT DeviceObject
,
4217 IN LPWSTR
* OutSerialNumber
,
4218 IN PUSHORT OutDescriptorLength
,
4219 IN USHORT LanguageId
,
4222 PUSB_STRING_DESCRIPTOR Descriptor
;
4224 LPWSTR SerialNumberBuffer
= NULL
;
4228 DPRINT("USBH_GetSerialNumberString: ... \n");
4230 *OutSerialNumber
= NULL
;
4231 *OutDescriptorLength
= 0;
4233 Descriptor
= ExAllocatePoolWithTag(NonPagedPool
,
4234 MAXIMUM_USB_STRING_LENGTH
,
4239 return STATUS_INSUFFICIENT_RESOURCES
;
4242 RtlZeroMemory(Descriptor
, MAXIMUM_USB_STRING_LENGTH
);
4244 Status
= USBH_CheckDeviceLanguage(DeviceObject
, LanguageId
);
4246 if (!NT_SUCCESS(Status
))
4251 Status
= USBH_SyncGetStringDescriptor(DeviceObject
,
4255 MAXIMUM_USB_STRING_LENGTH
,
4259 if (!NT_SUCCESS(Status
) ||
4260 Descriptor
->bLength
<= sizeof(USB_COMMON_DESCRIPTOR
))
4262 Status
= STATUS_INSUFFICIENT_RESOURCES
;
4266 StringLength
= Descriptor
->bLength
-
4267 FIELD_OFFSET(USB_STRING_DESCRIPTOR
, bString
);
4269 Length
= StringLength
+ sizeof(UNICODE_NULL
);
4271 SerialNumberBuffer
= ExAllocatePoolWithTag(PagedPool
, Length
, USB_HUB_TAG
);
4273 if (!SerialNumberBuffer
)
4278 RtlZeroMemory(SerialNumberBuffer
, Length
);
4279 RtlCopyMemory(SerialNumberBuffer
, Descriptor
->bString
, StringLength
);
4281 *OutSerialNumber
= SerialNumberBuffer
;
4282 *OutDescriptorLength
= Length
;
4285 ExFreePoolWithTag(Descriptor
, USB_HUB_TAG
);
4291 USBH_CreateDevice(IN PUSBHUB_FDO_EXTENSION HubExtension
,
4293 IN USB_PORT_STATUS UsbPortStatus
,
4296 ULONG PdoNumber
= 0;
4297 WCHAR CharDeviceName
[64];
4298 UNICODE_STRING DeviceName
;
4299 PDEVICE_OBJECT DeviceObject
= NULL
;
4300 PUSBHUB_PORT_PDO_EXTENSION PortExtension
;
4301 PUSB_DEVICE_HANDLE DeviceHandle
;
4302 LPWSTR SerialNumberBuffer
;
4305 BOOLEAN IgnoringHwSerial
= FALSE
;
4307 UNICODE_STRING DestinationString
;
4309 DPRINT("USBH_CreateDevice: Port - %x, UsbPortStatus - %lX\n",
4311 UsbPortStatus
.AsUshort16
);
4315 RtlStringCbPrintfW(CharDeviceName
,
4316 sizeof(CharDeviceName
),
4317 L
"\\Device\\USBPDO-%d",
4320 RtlInitUnicodeString(&DeviceName
, CharDeviceName
);
4322 Status
= IoCreateDevice(HubExtension
->Common
.SelfDevice
->DriverObject
,
4323 sizeof(USBHUB_PORT_PDO_EXTENSION
),
4332 while (Status
== STATUS_OBJECT_NAME_COLLISION
);
4334 if (!NT_SUCCESS(Status
))
4337 HubExtension
->PortData
[Port
-1].DeviceObject
= DeviceObject
;
4341 DeviceObject
->StackSize
= HubExtension
->RootHubPdo2
->StackSize
;
4343 PortExtension
= DeviceObject
->DeviceExtension
;
4345 DPRINT("USBH_CreateDevice: PortDevice - %p, <%wZ>\n", DeviceObject
, &DeviceName
);
4346 DPRINT("USBH_CreateDevice: PortExtension - %p\n", PortExtension
);
4348 RtlZeroMemory(PortExtension
, sizeof(USBHUB_PORT_PDO_EXTENSION
));
4350 PortExtension
->Common
.ExtensionType
= USBH_EXTENSION_TYPE_PORT
;
4351 PortExtension
->Common
.SelfDevice
= DeviceObject
;
4353 PortExtension
->HubExtension
= HubExtension
;
4354 PortExtension
->RootHubExtension
= HubExtension
;
4356 PortExtension
->PortNumber
= Port
;
4357 PortExtension
->CurrentPowerState
.DeviceState
= PowerDeviceD0
;
4358 PortExtension
->IgnoringHwSerial
= FALSE
;
4360 KeInitializeSpinLock(&PortExtension
->PortTimeoutSpinLock
);
4362 InitializeListHead(&PortExtension
->PortPowerList
);
4363 KeInitializeSpinLock(&PortExtension
->PortPowerListSpinLock
);
4365 PortExtension
->PoRequestCounter
= 0;
4366 PortExtension
->PendingSystemPoRequest
= 0;
4367 PortExtension
->PendingDevicePoRequest
= 0;
4368 PortExtension
->StateBehindD2
= 0;
4370 SerialNumberBuffer
= NULL
;
4372 IsHsDevice
= UsbPortStatus
.Usb20PortStatus
.HighSpeedDeviceAttached
;
4373 IsLsDevice
= UsbPortStatus
.Usb20PortStatus
.LowSpeedDeviceAttached
;
4375 if (IsLsDevice
== 0)
4379 PortExtension
->PortPdoFlags
= USBHUB_PDO_FLAG_PORT_HIGH_SPEED
;
4384 PortExtension
->PortPdoFlags
= USBHUB_PDO_FLAG_PORT_LOW_SPEED
;
4387 /* Initialize PortExtension->InstanceID */
4388 RtlInitUnicodeString(&DestinationString
, (PCWSTR
)&PortExtension
->InstanceID
);
4389 DestinationString
.MaximumLength
= 4 * sizeof(WCHAR
);
4390 Status
= RtlIntegerToUnicodeString(Port
, 10, &DestinationString
);
4392 DeviceObject
->Flags
|= DO_POWER_PAGABLE
;
4393 DeviceObject
->Flags
&= ~DO_DEVICE_INITIALIZING
;
4395 if (!NT_SUCCESS(Status
))
4397 DPRINT1("USBH_CreateDevice: IoCreateDevice() failed - %lX\n", Status
);
4401 Status
= USBD_CreateDeviceEx(HubExtension
,
4402 &PortExtension
->DeviceHandle
,
4406 if (!NT_SUCCESS(Status
))
4408 DPRINT1("USBH_CreateDevice: USBD_CreateDeviceEx() failed - %lX\n", Status
);
4412 Status
= USBH_SyncResetPort(HubExtension
, Port
);
4414 if (!NT_SUCCESS(Status
))
4416 DPRINT1("USBH_CreateDevice: USBH_SyncResetPort() failed - %lX\n", Status
);
4425 Status
= USBD_InitializeDeviceEx(HubExtension
,
4426 PortExtension
->DeviceHandle
,
4427 (PUCHAR
)&PortExtension
->DeviceDescriptor
,
4428 sizeof(USB_DEVICE_DESCRIPTOR
),
4429 (PUCHAR
)&PortExtension
->ConfigDescriptor
,
4430 sizeof(USB_CONFIGURATION_DESCRIPTOR
));
4432 if (!NT_SUCCESS(Status
))
4434 DPRINT1("USBH_CreateDevice: USBD_InitializeDeviceEx() failed - %lX\n", Status
);
4435 PortExtension
->DeviceHandle
= NULL
;
4439 DPRINT1("USBH_RegQueryDeviceIgnoreHWSerNumFlag UNIMPLEMENTED. FIXME\n");
4440 //Status = USBH_RegQueryDeviceIgnoreHWSerNumFlag(PortExtension->DeviceDescriptor.idVendor,
4441 // PortExtension->DeviceDescriptor.idProduct,
4442 // &IgnoringHwSerial);
4444 if (TRUE
)//Status == STATUS_OBJECT_NAME_NOT_FOUND)
4446 IgnoringHwSerial
= FALSE
;
4449 if (IgnoringHwSerial
)
4451 PortExtension
->IgnoringHwSerial
= TRUE
;
4454 if (PortExtension
->DeviceDescriptor
.iSerialNumber
&&
4455 !PortExtension
->IgnoringHwSerial
)
4457 InterlockedExchangePointer((PVOID
)&PortExtension
->SerialNumber
, NULL
);
4459 USBH_GetSerialNumberString(PortExtension
->Common
.SelfDevice
,
4460 &SerialNumberBuffer
,
4461 &PortExtension
->SN_DescriptorLength
,
4462 MAKELANGID(LANG_ENGLISH
, SUBLANG_ENGLISH_US
),
4463 PortExtension
->DeviceDescriptor
.iSerialNumber
);
4465 if (SerialNumberBuffer
)
4467 if (!USBH_ValidateSerialNumberString((PUSHORT
)SerialNumberBuffer
))
4469 ExFreePoolWithTag(SerialNumberBuffer
, USB_HUB_TAG
);
4470 SerialNumberBuffer
= NULL
;
4473 if (SerialNumberBuffer
&&
4474 !USBH_CheckDeviceIDUnique(HubExtension
,
4475 PortExtension
->DeviceDescriptor
.idVendor
,
4476 PortExtension
->DeviceDescriptor
.idProduct
,
4478 PortExtension
->SN_DescriptorLength
))
4480 ExFreePoolWithTag(SerialNumberBuffer
, USB_HUB_TAG
);
4481 SerialNumberBuffer
= NULL
;
4485 InterlockedExchangePointer((PVOID
)&PortExtension
->SerialNumber
,
4486 SerialNumberBuffer
);
4489 Status
= USBH_ProcessDeviceInformation(PortExtension
);
4491 USBH_PdoSetCapabilities(PortExtension
);
4493 if (NT_SUCCESS(Status
))
4500 PortExtension
->PortPdoFlags
|= USBHUB_PDO_FLAG_INIT_PORT_FAILED
;
4502 DeviceHandle
= InterlockedExchangePointer(&PortExtension
->DeviceHandle
,
4507 USBD_RemoveDeviceEx(HubExtension
, DeviceHandle
, 0);
4510 SerialNumberBuffer
= InterlockedExchangePointer((PVOID
)&PortExtension
->SerialNumber
,
4513 if (SerialNumberBuffer
)
4515 ExFreePoolWithTag(SerialNumberBuffer
, USB_HUB_TAG
);
4521 HubExtension
->PortData
[Port
-1].DeviceObject
= DeviceObject
;
4527 USBH_ResetDevice(IN PUSBHUB_FDO_EXTENSION HubExtension
,
4529 IN BOOLEAN IsKeepDeviceData
,
4533 PUSBHUB_PORT_DATA PortData
;
4534 PDEVICE_OBJECT PortDevice
;
4535 PUSBHUB_PORT_PDO_EXTENSION PortExtension
;
4536 PVOID NewDeviceHandle
;
4538 PVOID OldDeviceHandle
;
4539 PUSB_DEVICE_HANDLE
* DeviceHandle
;
4540 USB_PORT_STATUS_AND_CHANGE PortStatus
;
4542 DPRINT("USBH_ResetDevice: HubExtension - %p, Port - %x, IsKeepDeviceData - %x, IsWait - %x\n",
4548 Status
= USBH_SyncGetPortStatus(HubExtension
,
4551 sizeof(USB_PORT_STATUS_AND_CHANGE
));
4553 if (!NT_SUCCESS(Status
) ||
4554 !(PortStatus
.PortStatus
.Usb20PortStatus
.CurrentConnectStatus
))
4556 return STATUS_UNSUCCESSFUL
;
4559 InterlockedIncrement(&HubExtension
->PendingRequestCount
);
4561 KeWaitForSingleObject(&HubExtension
->ResetDeviceSemaphore
,
4568 PortData
= &HubExtension
->PortData
[Port
-1];
4570 PortDevice
= PortData
->DeviceObject
;
4574 Status
= STATUS_INVALID_PARAMETER
;
4576 KeReleaseSemaphore(&HubExtension
->ResetDeviceSemaphore
,
4577 LOW_REALTIME_PRIORITY
,
4581 if (!InterlockedDecrement(&HubExtension
->PendingRequestCount
))
4583 KeSetEvent(&HubExtension
->PendingRequestEvent
,
4591 PortExtension
= PortDevice
->DeviceExtension
;
4592 DeviceHandle
= &PortExtension
->DeviceHandle
;
4594 OldDeviceHandle
= InterlockedExchangePointer(&PortExtension
->DeviceHandle
,
4597 if (OldDeviceHandle
)
4599 if (!(PortExtension
->PortPdoFlags
& USBHUB_PDO_FLAG_REMOVING_PORT_PDO
))
4601 Status
= USBD_RemoveDeviceEx(HubExtension
,
4605 PortExtension
->PortPdoFlags
|= USBHUB_PDO_FLAG_REMOVING_PORT_PDO
;
4610 OldDeviceHandle
= NULL
;
4613 if (!NT_SUCCESS(Status
))
4618 Status
= USBH_SyncResetPort(HubExtension
, Port
);
4620 if (!NT_SUCCESS(Status
))
4625 Status
= USBH_SyncGetPortStatus(HubExtension
,
4628 sizeof(USB_PORT_STATUS_AND_CHANGE
));
4630 if (!NT_SUCCESS(Status
))
4635 Status
= USBD_CreateDeviceEx(HubExtension
,
4637 PortStatus
.PortStatus
,
4640 if (!NT_SUCCESS(Status
))
4645 Status
= USBH_SyncResetPort(HubExtension
, Port
);
4652 if (!NT_SUCCESS(Status
))
4657 Status
= USBD_InitializeDeviceEx(HubExtension
,
4659 &PortExtension
->DeviceDescriptor
.bLength
,
4660 sizeof(PortExtension
->DeviceDescriptor
),
4661 &PortExtension
->ConfigDescriptor
.bLength
,
4662 sizeof(PortExtension
->ConfigDescriptor
));
4664 if (NT_SUCCESS(Status
))
4666 if (IsKeepDeviceData
)
4668 Status
= USBD_RestoreDeviceEx(HubExtension
,
4672 if (!NT_SUCCESS(Status
))
4674 Handle
= InterlockedExchangePointer(DeviceHandle
, NULL
);
4676 USBD_RemoveDeviceEx(HubExtension
, Handle
, 0);
4677 USBH_SyncDisablePort(HubExtension
, Port
);
4679 Status
= STATUS_NO_SUCH_DEVICE
;
4684 PortExtension
->PortPdoFlags
&= ~USBHUB_PDO_FLAG_REMOVING_PORT_PDO
;
4690 *DeviceHandle
= NULL
;
4694 NewDeviceHandle
= InterlockedExchangePointer(DeviceHandle
,
4697 if (NewDeviceHandle
)
4699 Status
= USBD_RemoveDeviceEx(HubExtension
, NewDeviceHandle
, 0);
4704 KeReleaseSemaphore(&HubExtension
->ResetDeviceSemaphore
,
4705 LOW_REALTIME_PRIORITY
,
4709 if (!InterlockedDecrement(&HubExtension
->PendingRequestCount
))
4711 KeSetEvent(&HubExtension
->PendingRequestEvent
,
4721 USBH_PdoDispatch(IN PUSBHUB_PORT_PDO_EXTENSION PortExtension
,
4724 PIO_STACK_LOCATION IoStack
;
4725 UCHAR MajorFunction
;
4726 BOOLEAN ShouldCompleteIrp
;
4730 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
4731 MajorFunction
= IoStack
->MajorFunction
;
4733 switch (MajorFunction
)
4737 DPRINT("USBH_PdoDispatch: IRP_MJ_CREATE / IRP_MJ_CLOSE (%d)\n",
4739 Status
= STATUS_SUCCESS
;
4740 USBH_CompleteIrp(Irp
, Status
);
4743 case IRP_MJ_DEVICE_CONTROL
:
4744 ControlCode
= IoStack
->Parameters
.DeviceIoControl
.IoControlCode
;
4745 DPRINT("USBH_PdoDispatch: IRP_MJ_DEVICE_CONTROL ControlCode - %x\n",
4748 if (ControlCode
== IOCTL_STORAGE_GET_MEDIA_SERIAL_NUMBER
)
4750 Status
= STATUS_NOT_SUPPORTED
;
4751 USBH_CompleteIrp(Irp
, Status
);
4755 if (ControlCode
== IOCTL_KS_PROPERTY
)
4757 DPRINT1("USBH_PdoDispatch: IOCTL_KS_PROPERTY FIXME\n");
4759 Status
= STATUS_NOT_SUPPORTED
;
4760 USBH_CompleteIrp(Irp
, Status
);
4764 Status
= Irp
->IoStatus
.Status
;
4765 USBH_CompleteIrp(Irp
, Status
);
4768 case IRP_MJ_INTERNAL_DEVICE_CONTROL
:
4769 Status
= USBH_PdoInternalControl(PortExtension
, Irp
);
4773 Status
= USBH_PdoPnP(PortExtension
,
4775 IoStack
->MinorFunction
,
4776 &ShouldCompleteIrp
);
4778 if (ShouldCompleteIrp
)
4780 USBH_CompleteIrp(Irp
, Status
);
4786 Status
= USBH_PdoPower(PortExtension
, Irp
, IoStack
->MinorFunction
);
4789 case IRP_MJ_SYSTEM_CONTROL
:
4790 DPRINT1("USBH_PdoDispatch: USBH_SystemControl() UNIMPLEMENTED. FIXME\n");
4791 Status
= STATUS_NOT_SUPPORTED
;//USBH_PortSystemControl(PortExtension, Irp);
4795 DPRINT("USBH_PdoDispatch: Unhandled MajorFunction - %d\n", MajorFunction
);
4796 Status
= Irp
->IoStatus
.Status
;
4797 USBH_CompleteIrp(Irp
, Status
);
4806 USBH_FdoDispatch(IN PUSBHUB_FDO_EXTENSION HubExtension
,
4809 PIO_STACK_LOCATION IoStack
;
4810 UCHAR MajorFunction
;
4813 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
4815 DPRINT("USBH_FdoDispatch: HubExtension - %p, Irp - %p, MajorFunction - %X\n",
4818 IoStack
->MajorFunction
);
4820 MajorFunction
= IoStack
->MajorFunction
;
4822 switch (MajorFunction
)
4826 Status
= STATUS_SUCCESS
;
4827 USBH_CompleteIrp(Irp
, Status
);
4830 case IRP_MJ_DEVICE_CONTROL
:
4831 Status
= USBH_DeviceControl(HubExtension
, Irp
);
4835 Status
= USBH_FdoPnP(HubExtension
, Irp
, IoStack
->MinorFunction
);
4839 Status
= USBH_FdoPower(HubExtension
, Irp
, IoStack
->MinorFunction
);
4842 case IRP_MJ_SYSTEM_CONTROL
:
4843 DPRINT1("USBH_FdoDispatch: USBH_SystemControl() UNIMPLEMENTED. FIXME\n");
4846 case IRP_MJ_INTERNAL_DEVICE_CONTROL
:
4848 Status
= USBH_PassIrp(HubExtension
->LowerDevice
, Irp
);
4857 USBH_AddDevice(IN PDRIVER_OBJECT DriverObject
,
4858 IN PDEVICE_OBJECT LowerPDO
)
4860 PDEVICE_OBJECT DeviceObject
;
4862 PUSBHUB_FDO_EXTENSION HubExtension
;
4863 PDEVICE_OBJECT LowerDevice
;
4865 DPRINT("USBH_AddDevice: DriverObject - %p, LowerPDO - %p\n",
4869 DeviceObject
= NULL
;
4871 Status
= IoCreateDevice(DriverObject
,
4872 sizeof(USBHUB_FDO_EXTENSION
),
4875 FILE_AUTOGENERATED_DEVICE_NAME
,
4879 if (!NT_SUCCESS(Status
))
4881 DPRINT1("USBH_AddDevice: IoCreateDevice() fail\n");
4885 IoDeleteDevice(DeviceObject
);
4891 DPRINT("USBH_AddDevice: DeviceObject - %p\n", DeviceObject
);
4893 HubExtension
= DeviceObject
->DeviceExtension
;
4894 RtlZeroMemory(HubExtension
, sizeof(USBHUB_FDO_EXTENSION
));
4896 HubExtension
->Common
.ExtensionType
= USBH_EXTENSION_TYPE_HUB
;
4898 LowerDevice
= IoAttachDeviceToDeviceStack(DeviceObject
, LowerPDO
);
4902 DPRINT1("USBH_AddDevice: IoAttachDeviceToDeviceStack() fail\n");
4906 IoDeleteDevice(DeviceObject
);
4909 return STATUS_UNSUCCESSFUL
;
4912 DPRINT("USBH_AddDevice: LowerDevice - %p\n", LowerDevice
);
4914 HubExtension
->Common
.SelfDevice
= DeviceObject
;
4916 HubExtension
->LowerPDO
= LowerPDO
;
4917 HubExtension
->LowerDevice
= LowerDevice
;
4919 KeInitializeSemaphore(&HubExtension
->IdleSemaphore
, 1, 1);
4921 DeviceObject
->Flags
|= DO_POWER_PAGABLE
;
4922 DeviceObject
->Flags
&= ~DO_DEVICE_INITIALIZING
;
4924 DPRINT("USBH_AddDevice: call IoWMIRegistrationControl() UNIMPLEMENTED. FIXME\n");
4931 USBH_DriverUnload(IN PDRIVER_OBJECT DriverObject
)
4933 DPRINT("USBH_DriverUnload: UNIMPLEMENTED\n");
4935 if (GenericUSBDeviceString
)
4937 ExFreePool(GenericUSBDeviceString
);
4938 GenericUSBDeviceString
= NULL
;
4944 USBH_HubDispatch(IN PDEVICE_OBJECT DeviceObject
,
4947 PCOMMON_DEVICE_EXTENSION DeviceExtension
;
4948 ULONG ExtensionType
;
4952 DeviceExtension
= DeviceObject
->DeviceExtension
;
4953 ExtensionType
= DeviceExtension
->ExtensionType
;
4955 if (ExtensionType
== USBH_EXTENSION_TYPE_HUB
)
4957 DPRINT("USBH_HubDispatch: DeviceObject - %p, Irp - %p\n",
4961 Status
= USBH_FdoDispatch((PUSBHUB_FDO_EXTENSION
)DeviceExtension
, Irp
);
4963 else if (ExtensionType
== USBH_EXTENSION_TYPE_PORT
)
4965 PIO_STACK_LOCATION IoStack
= IoGetCurrentIrpStackLocation(Irp
);
4966 UCHAR MajorFunction
= IoStack
->MajorFunction
;
4967 BOOLEAN IsDprint
= TRUE
;
4969 if (MajorFunction
== IRP_MJ_INTERNAL_DEVICE_CONTROL
)
4971 ULONG ControlCode
= IoStack
->Parameters
.DeviceIoControl
.IoControlCode
;
4973 if (ControlCode
== IOCTL_INTERNAL_USB_SUBMIT_URB
)
4981 DPRINT("USBH_HubDispatch: DeviceObject - %p, Irp - %p\n",
4986 Status
= USBH_PdoDispatch((PUSBHUB_PORT_PDO_EXTENSION
)DeviceExtension
, Irp
);
4990 DPRINT1("USBH_HubDispatch: Unknown ExtensionType - %x\n", ExtensionType
);
4992 Status
= STATUS_ASSERTION_FAILURE
;
5000 USBH_RegQueryGenericUSBDeviceString(PVOID USBDeviceString
)
5002 RTL_QUERY_REGISTRY_TABLE QueryTable
[2];
5004 DPRINT("USBH_RegQueryGenericUSBDeviceString ... \n");
5006 RtlZeroMemory(QueryTable
, sizeof(QueryTable
));
5008 QueryTable
[0].QueryRoutine
= USBH_GetConfigValue
;
5009 QueryTable
[0].Flags
= RTL_QUERY_REGISTRY_REQUIRED
;
5010 QueryTable
[0].Name
= L
"GenericUSBDeviceString";
5011 QueryTable
[0].EntryContext
= USBDeviceString
;
5012 QueryTable
[0].DefaultType
= REG_NONE
;
5013 QueryTable
[0].DefaultData
= 0;
5014 QueryTable
[0].DefaultLength
= 0;
5016 return RtlQueryRegistryValues(RTL_REGISTRY_CONTROL
,
5025 DriverEntry(IN PDRIVER_OBJECT DriverObject
,
5026 IN PUNICODE_STRING RegistryPath
)
5028 DPRINT("USBHUB: DriverEntry - %wZ\n", RegistryPath
);
5030 DriverObject
->DriverExtension
->AddDevice
= USBH_AddDevice
;
5031 DriverObject
->DriverUnload
= USBH_DriverUnload
;
5033 DriverObject
->MajorFunction
[IRP_MJ_CREATE
] = USBH_HubDispatch
;
5034 DriverObject
->MajorFunction
[IRP_MJ_CLOSE
] = USBH_HubDispatch
;
5036 DriverObject
->MajorFunction
[IRP_MJ_DEVICE_CONTROL
] = USBH_HubDispatch
;
5037 DriverObject
->MajorFunction
[IRP_MJ_INTERNAL_DEVICE_CONTROL
] = USBH_HubDispatch
;
5039 DriverObject
->MajorFunction
[IRP_MJ_PNP
] = USBH_HubDispatch
;
5040 DriverObject
->MajorFunction
[IRP_MJ_POWER
] = USBH_HubDispatch
;
5041 DriverObject
->MajorFunction
[IRP_MJ_SYSTEM_CONTROL
] = USBH_HubDispatch
;
5043 USBH_RegQueryGenericUSBDeviceString(&GenericUSBDeviceString
);
5045 return STATUS_SUCCESS
;