2 * PROJECT: ReactOS USB Hub Driver
3 * LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
4 * PURPOSE: USBHub plug and play functions
5 * COPYRIGHT: Copyright 2017 Vadim Galyant <vgal@rambler.ru>
13 #define NDEBUG_USBHUB_PNP
14 #define NDEBUG_USBHUB_ENUM
19 USBH_IrpCompletion(IN PDEVICE_OBJECT DeviceObject
,
25 DPRINT("USBH_IrpCompletion: Irp - %p\n", Irp
);
28 KeSetEvent(Event
, EVENT_INCREMENT
, FALSE
);
29 return STATUS_MORE_PROCESSING_REQUIRED
;
34 USBH_HubPnPIrpComplete(IN PDEVICE_OBJECT DeviceObject
,
38 PUSBHUB_FDO_EXTENSION HubExtension
;
40 DPRINT("USBH_HubPnPIrpComplete: Irp - %p\n", Irp
);
42 HubExtension
= Context
;
44 if (!NT_SUCCESS(Irp
->IoStatus
.Status
))
46 DPRINT1("USBH_HubPnPIrpComplete: Irp failed - %lX\n", Irp
->IoStatus
.Status
);
47 HubExtension
->HubFlags
|= USBHUB_FDO_FLAG_DEVICE_FAILED
;
50 Irp
->IoStatus
.Status
= STATUS_MORE_PROCESSING_REQUIRED
;
52 KeSetEvent(&HubExtension
->LowerDeviceEvent
, EVENT_INCREMENT
, FALSE
);
54 return STATUS_MORE_PROCESSING_REQUIRED
;
59 USBH_QueryCapsComplete(IN PDEVICE_OBJECT DeviceObject
,
63 PIO_STACK_LOCATION IoStack
;
64 PDEVICE_CAPABILITIES Capabilities
;
66 DPRINT("USBH_QueryCapsComplete: ... \n");
68 ASSERT(NT_SUCCESS(Irp
->IoStatus
.Status
));
70 if (Irp
->PendingReturned
)
72 IoMarkIrpPending(Irp
);
75 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
76 Capabilities
= IoStack
->Parameters
.DeviceCapabilities
.Capabilities
;
78 Capabilities
->SurpriseRemovalOK
= 1;
80 return STATUS_CONTINUE_COMPLETION
;
85 USBHUB_GetBusInterface(IN PDEVICE_OBJECT DeviceObject
,
86 OUT PUSB_BUS_INTERFACE_HUB_V5 BusInterface
)
90 PIO_STACK_LOCATION IoStack
;
93 DPRINT("USBHUB_GetBusInterface: ... \n");
95 Irp
= IoAllocateIrp(DeviceObject
->StackSize
, FALSE
);
99 DPRINT1("USBHUB_GetBusInterface: IoAllocateIrp() failed\n");
100 return STATUS_INSUFFICIENT_RESOURCES
;
103 Irp
->IoStatus
.Status
= STATUS_NOT_SUPPORTED
;
105 KeInitializeEvent(&Event
, NotificationEvent
, FALSE
);
107 IoSetCompletionRoutine(Irp
,
114 IoStack
= IoGetNextIrpStackLocation(Irp
);
116 IoStack
->MajorFunction
= IRP_MJ_PNP
;
117 IoStack
->MinorFunction
= IRP_MN_QUERY_INTERFACE
;
119 IoStack
->Parameters
.QueryInterface
.InterfaceType
= &USB_BUS_INTERFACE_HUB_GUID
;
120 IoStack
->Parameters
.QueryInterface
.Size
= sizeof(USB_BUS_INTERFACE_HUB_V5
);
121 IoStack
->Parameters
.QueryInterface
.Version
= USB_BUSIF_HUB_VERSION_5
;
122 IoStack
->Parameters
.QueryInterface
.Interface
= (PINTERFACE
)BusInterface
;
123 IoStack
->Parameters
.QueryInterface
.InterfaceSpecificData
= DeviceObject
;
125 Status
= IoCallDriver(DeviceObject
, Irp
);
127 if (Status
== STATUS_PENDING
)
129 KeWaitForSingleObject(&Event
,
135 Status
= Irp
->IoStatus
.Status
;
145 USBHUB_GetBusInterfaceUSBDI(IN PDEVICE_OBJECT DeviceObject
,
146 OUT PUSB_BUS_INTERFACE_USBDI_V2 BusInterfaceUSBDI
)
150 PIO_STACK_LOCATION IoStack
;
153 DPRINT("USBHUB_GetBusInterfaceUSBDI: ... \n");
155 Irp
= IoAllocateIrp(DeviceObject
->StackSize
, FALSE
);
159 DPRINT1("USBHUB_GetBusInterfaceUSBDI: IoAllocateIrp() failed\n");
160 return STATUS_INSUFFICIENT_RESOURCES
;
163 Irp
->IoStatus
.Status
= STATUS_NOT_SUPPORTED
;
165 KeInitializeEvent(&Event
, NotificationEvent
, FALSE
);
167 IoSetCompletionRoutine(Irp
,
174 IoStack
= IoGetNextIrpStackLocation(Irp
);
176 IoStack
->MajorFunction
= IRP_MJ_PNP
;
177 IoStack
->MinorFunction
= IRP_MN_QUERY_INTERFACE
;
179 IoStack
->Parameters
.QueryInterface
.InterfaceType
= &USB_BUS_INTERFACE_USBDI_GUID
;
180 IoStack
->Parameters
.QueryInterface
.Size
= sizeof(USB_BUS_INTERFACE_USBDI_V2
);
181 IoStack
->Parameters
.QueryInterface
.Version
= USB_BUSIF_USBDI_VERSION_2
;
182 IoStack
->Parameters
.QueryInterface
.Interface
= (PINTERFACE
)BusInterfaceUSBDI
;
183 IoStack
->Parameters
.QueryInterface
.InterfaceSpecificData
= NULL
;
185 Status
= IoCallDriver(DeviceObject
, Irp
);
187 if (Status
== STATUS_PENDING
)
189 KeWaitForSingleObject(&Event
,
195 Status
= Irp
->IoStatus
.Status
;
205 USBH_QueryCapabilities(IN PDEVICE_OBJECT DeviceObject
,
206 IN PDEVICE_CAPABILITIES DeviceCapabilities
)
209 PIO_STACK_LOCATION IoStack
;
212 DPRINT("USBH_QueryCapabilities: ... \n");
214 RtlZeroMemory(DeviceCapabilities
, sizeof(DEVICE_CAPABILITIES
));
216 Irp
= IoAllocateIrp(DeviceObject
->StackSize
, FALSE
);
220 DPRINT1("USBH_QueryCapabilities: IoAllocateIrp() failed\n");
224 Irp
->IoStatus
.Status
= STATUS_NOT_SUPPORTED
;
226 KeInitializeEvent(&Event
, NotificationEvent
, FALSE
);
228 IoSetCompletionRoutine(Irp
,
235 IoStack
= IoGetNextIrpStackLocation(Irp
);
237 IoStack
->MajorFunction
= IRP_MJ_PNP
;
238 IoStack
->MinorFunction
= IRP_MN_QUERY_CAPABILITIES
;
240 IoStack
->Parameters
.DeviceCapabilities
.Capabilities
= DeviceCapabilities
;
241 IoStack
->Parameters
.DeviceCapabilities
.Capabilities
->Size
= sizeof(DEVICE_CAPABILITIES
);
242 IoStack
->Parameters
.DeviceCapabilities
.Capabilities
->Version
= 1;
243 IoStack
->Parameters
.DeviceCapabilities
.Capabilities
->Address
= MAXULONG
;
244 IoStack
->Parameters
.DeviceCapabilities
.Capabilities
->UINumber
= MAXULONG
;
246 if (IoCallDriver(DeviceObject
, Irp
) == STATUS_PENDING
)
248 KeWaitForSingleObject(&Event
,
260 USBH_OpenConfiguration(IN PUSBHUB_FDO_EXTENSION HubExtension
)
262 PUSB_INTERFACE_DESCRIPTOR Pid
;
265 USBD_INTERFACE_LIST_ENTRY InterfaceList
[2] = {{NULL
, NULL
}, {NULL
, NULL
}};
267 DPRINT("USBH_OpenConfiguration ... \n");
269 if (HubExtension
->HubFlags
& USBHUB_FDO_FLAG_USB20_HUB
&&
270 HubExtension
->LowerPDO
!= HubExtension
->RootHubPdo
)
272 Pid
= USBD_ParseConfigurationDescriptorEx(HubExtension
->HubConfigDescriptor
,
273 HubExtension
->HubConfigDescriptor
,
276 USB_DEVICE_CLASS_HUB
,
282 HubExtension
->HubFlags
|= USBHUB_FDO_FLAG_MULTIPLE_TTS
;
286 Pid
= USBD_ParseConfigurationDescriptorEx(HubExtension
->HubConfigDescriptor
,
287 HubExtension
->HubConfigDescriptor
,
290 USB_DEVICE_CLASS_HUB
,
299 Pid
= USBD_ParseConfigurationDescriptorEx(HubExtension
->HubConfigDescriptor
,
300 HubExtension
->HubConfigDescriptor
,
303 USB_DEVICE_CLASS_HUB
,
310 Pid
= USBD_ParseConfigurationDescriptorEx(HubExtension
->HubConfigDescriptor
,
311 HubExtension
->HubConfigDescriptor
,
314 USB_DEVICE_CLASS_HUB
,
321 return STATUS_UNSUCCESSFUL
;
326 if (Pid
->bInterfaceClass
!= USB_DEVICE_CLASS_HUB
)
328 return STATUS_UNSUCCESSFUL
;
331 InterfaceList
[0].InterfaceDescriptor
= Pid
;
333 Urb
= USBD_CreateConfigurationRequestEx(HubExtension
->HubConfigDescriptor
,
338 return STATUS_INSUFFICIENT_RESOURCES
;
341 Status
= USBH_FdoSyncSubmitUrb(HubExtension
->Common
.SelfDevice
, Urb
);
343 if (NT_SUCCESS(Status
))
345 RtlCopyMemory(&HubExtension
->PipeInfo
,
346 InterfaceList
[0].Interface
->Pipes
,
347 sizeof(USBD_PIPE_INFORMATION
));
349 HubExtension
->ConfigHandle
= Urb
->UrbSelectConfiguration
.ConfigurationHandle
;
359 USBD_Initialize20Hub(IN PUSBHUB_FDO_EXTENSION HubExtension
)
361 PUSB_BUSIFFN_INITIALIZE_20HUB Initialize20Hub
;
363 PUSB_DEVICE_HANDLE DeviceHandle
;
365 DPRINT("USBD_InitUsb2Hub ... \n");
367 Initialize20Hub
= HubExtension
->BusInterface
.Initialize20Hub
;
369 if (!Initialize20Hub
)
371 return STATUS_NOT_IMPLEMENTED
;
376 if (HubExtension
->HubFlags
& USBHUB_FDO_FLAG_MULTIPLE_TTS
)
378 TtCount
= HubExtension
->HubDescriptor
->bNumberOfPorts
;
381 DeviceHandle
= USBH_SyncGetDeviceHandle(HubExtension
->LowerDevice
);
383 return Initialize20Hub(HubExtension
->BusInterface
.BusContext
,
390 USBH_AbortInterruptPipe(IN PUSBHUB_FDO_EXTENSION HubExtension
)
392 struct _URB_PIPE_REQUEST
* Urb
;
395 DPRINT("USBH_AbortInterruptPipe: HubExtension - %p\n", HubExtension
);
397 Urb
= ExAllocatePoolWithTag(NonPagedPool
,
398 sizeof(struct _URB_PIPE_REQUEST
),
403 return STATUS_INSUFFICIENT_RESOURCES
;
406 RtlZeroMemory(Urb
, sizeof(struct _URB_PIPE_REQUEST
));
408 Urb
->Hdr
.Length
= sizeof(struct _URB_PIPE_REQUEST
);
409 Urb
->Hdr
.Function
= URB_FUNCTION_ABORT_PIPE
;
410 Urb
->PipeHandle
= HubExtension
->PipeInfo
.PipeHandle
;
412 Status
= USBH_FdoSyncSubmitUrb(HubExtension
->Common
.SelfDevice
,
415 if (NT_SUCCESS(Status
))
417 KeWaitForSingleObject(&HubExtension
->StatusChangeEvent
,
424 ExFreePoolWithTag(Urb
, USB_HUB_TAG
);
431 USBH_FdoCleanup(IN PUSBHUB_FDO_EXTENSION HubExtension
)
435 PUSBHUB_PORT_DATA PortData
;
436 PUSBHUB_PORT_PDO_EXTENSION PortExtension
;
437 PIRP PortIdleIrp
= NULL
;
438 PIRP PortWakeIrp
= NULL
;
445 DPRINT("USBH_FdoCleanup: HubExtension - %p\n", HubExtension
);
447 USBD_UnRegisterRootHubCallBack(HubExtension
);
449 HubExtension
->HubFlags
|= USBHUB_FDO_FLAG_DEVICE_STOPPING
;
451 if (HubExtension
->ResetRequestCount
)
453 IoCancelIrp(HubExtension
->ResetPortIrp
);
455 KeWaitForSingleObject(&HubExtension
->IdleEvent
,
462 IoFreeIrp(HubExtension
->ResetPortIrp
);
464 HubExtension
->ResetPortIrp
= NULL
;
466 if (HubExtension
->HubFlags
& USBHUB_FDO_FLAG_WAIT_IDLE_REQUEST
)
468 KeWaitForSingleObject(&HubExtension
->IdleEvent
,
475 IoAcquireCancelSpinLock(&Irql
);
477 if (HubExtension
->PendingWakeIrp
)
479 WakeIrp
= HubExtension
->PendingWakeIrp
;
480 HubExtension
->PendingWakeIrp
= NULL
;
483 if (HubExtension
->PendingIdleIrp
)
485 IdleIrp
= HubExtension
->PendingIdleIrp
;
486 HubExtension
->PendingIdleIrp
= NULL
;
489 IoReleaseCancelSpinLock(Irql
);
493 USBH_HubCancelWakeIrp(HubExtension
, WakeIrp
);
496 USBH_HubCompletePortWakeIrps(HubExtension
, STATUS_DELETE_PENDING
);
500 USBH_HubCancelIdleIrp(HubExtension
, IdleIrp
);
503 if (InterlockedDecrement(&HubExtension
->PendingRequestCount
) > 0)
505 KeWaitForSingleObject(&HubExtension
->PendingRequestEvent
,
512 if (HubExtension
->SCEIrp
)
514 Status
= USBH_AbortInterruptPipe(HubExtension
);
516 if (!NT_SUCCESS(Status
) && IoCancelIrp(HubExtension
->SCEIrp
))
518 KeWaitForSingleObject(&HubExtension
->StatusChangeEvent
,
525 IoFreeIrp(HubExtension
->SCEIrp
);
527 HubExtension
->SCEIrp
= NULL
;
530 if (!HubExtension
->PortData
||
531 !HubExtension
->HubDescriptor
)
536 PortData
= HubExtension
->PortData
;
537 NumberPorts
= HubExtension
->HubDescriptor
->bNumberOfPorts
;
539 for (Port
= 0; Port
< NumberPorts
; Port
++)
541 if (PortData
[Port
].DeviceObject
)
543 PortExtension
= PortData
[Port
].DeviceObject
->DeviceExtension
;
545 IoAcquireCancelSpinLock(&Irql
);
547 PortIdleIrp
= PortExtension
->IdleNotificationIrp
;
551 PortExtension
->PortPdoFlags
&= ~USBHUB_PDO_FLAG_IDLE_NOTIFICATION
;
552 PortExtension
->IdleNotificationIrp
= NULL
;
554 if (PortIdleIrp
->Cancel
)
561 IoSetCancelRoutine(PortIdleIrp
, NULL
);
565 PortWakeIrp
= PortExtension
->PdoWaitWakeIrp
;
569 PortExtension
->PortPdoFlags
&= ~USBHUB_PDO_FLAG_WAIT_WAKE
;
570 PortExtension
->PdoWaitWakeIrp
= NULL
;
572 if (PortWakeIrp
->Cancel
|| !IoSetCancelRoutine(PortWakeIrp
, NULL
))
576 if (!InterlockedDecrement(&HubExtension
->PendingRequestCount
))
578 KeSetEvent(&HubExtension
->PendingRequestEvent
,
585 IoReleaseCancelSpinLock(Irql
);
589 PortIdleIrp
->IoStatus
.Status
= STATUS_CANCELLED
;
590 IoCompleteRequest(PortIdleIrp
, IO_NO_INCREMENT
);
595 USBH_CompletePowerIrp(HubExtension
,
600 if (!(PortExtension
->PortPdoFlags
& USBHUB_PDO_FLAG_POWER_D3
))
602 DeviceHandle
= InterlockedExchangePointer(&PortExtension
->DeviceHandle
,
607 USBD_RemoveDeviceEx(HubExtension
, DeviceHandle
, 0);
610 PortExtension
->PortPdoFlags
|= USBHUB_PDO_FLAG_POWER_D3
;
614 USBH_SyncDisablePort(HubExtension
, Port
+ 1);
619 if (HubExtension
->SCEBitmap
)
621 ExFreePoolWithTag(HubExtension
->SCEBitmap
, USB_HUB_TAG
);
624 if (HubExtension
->HubDescriptor
)
626 ExFreePoolWithTag(HubExtension
->HubDescriptor
, USB_HUB_TAG
);
629 if (HubExtension
->HubConfigDescriptor
)
631 ExFreePoolWithTag(HubExtension
->HubConfigDescriptor
, USB_HUB_TAG
);
634 HubExtension
->HubFlags
&= ~USBHUB_FDO_FLAG_DEVICE_STARTED
;
636 HubExtension
->HubDescriptor
= NULL
;
637 HubExtension
->HubConfigDescriptor
= NULL
;
639 HubExtension
->SCEIrp
= NULL
;
640 HubExtension
->SCEBitmap
= NULL
;
645 USBH_StartHubFdoDevice(IN PUSBHUB_FDO_EXTENSION HubExtension
,
649 ULONG DisableRemoteWakeup
= 0;
651 PUSB_DEVICE_HANDLE DeviceHandle
;
652 USB_DEVICE_TYPE DeviceType
;
653 DEVICE_CAPABILITIES DeviceCapabilities
;
654 BOOLEAN IsBusPowered
;
655 static WCHAR DisableWakeValueName
[] = L
"DisableRemoteWakeup";
657 DPRINT("USBH_StartHubFdoDevice: ... \n");
659 KeInitializeEvent(&HubExtension
->IdleEvent
, NotificationEvent
, FALSE
);
660 KeInitializeEvent(&HubExtension
->ResetEvent
, NotificationEvent
, TRUE
);
661 KeInitializeEvent(&HubExtension
->PendingRequestEvent
, NotificationEvent
, FALSE
);
662 KeInitializeEvent(&HubExtension
->LowerDeviceEvent
, NotificationEvent
, FALSE
);
663 KeInitializeEvent(&HubExtension
->StatusChangeEvent
, NotificationEvent
, TRUE
);
664 KeInitializeEvent(&HubExtension
->RootHubNotificationEvent
,
668 KeInitializeSpinLock(&HubExtension
->RelationsWorkerSpinLock
);
669 KeInitializeSpinLock(&HubExtension
->CheckIdleSpinLock
);
671 KeInitializeSemaphore(&HubExtension
->ResetDeviceSemaphore
, 1, 1);
672 KeInitializeSemaphore(&HubExtension
->HubPortSemaphore
, 1, 1);
673 KeInitializeSemaphore(&HubExtension
->HubSemaphore
, 1, 1);
675 HubExtension
->HubFlags
= 0;
676 HubExtension
->HubConfigDescriptor
= NULL
;
677 HubExtension
->HubDescriptor
= NULL
;
678 HubExtension
->SCEIrp
= NULL
;
679 HubExtension
->SCEBitmap
= NULL
;
680 HubExtension
->SystemPowerState
.SystemState
= PowerSystemWorking
;
681 HubExtension
->PendingRequestCount
= 1;
682 HubExtension
->ResetRequestCount
= 0;
683 HubExtension
->PendingIdleIrp
= NULL
;
684 HubExtension
->PendingWakeIrp
= NULL
;
686 InitializeListHead(&HubExtension
->PdoList
);
688 HubExtension
->HubFlags
|= USBHUB_FDO_FLAG_WITEM_INIT
;
689 InitializeListHead(&HubExtension
->WorkItemList
);
690 KeInitializeSpinLock(&HubExtension
->WorkItemSpinLock
);
692 IoCopyCurrentIrpStackLocationToNext(Irp
);
694 IoSetCompletionRoutine(Irp
,
695 USBH_HubPnPIrpComplete
,
701 if (IoCallDriver(HubExtension
->LowerDevice
, Irp
) == STATUS_PENDING
)
703 KeWaitForSingleObject(&HubExtension
->LowerDeviceEvent
,
710 HubExtension
->RootHubPdo
= NULL
;
712 Status
= USBH_SyncGetRootHubPdo(HubExtension
->LowerDevice
,
713 &HubExtension
->RootHubPdo
,
714 &HubExtension
->RootHubPdo2
);
716 if (!NT_SUCCESS(Status
))
718 DPRINT1("USBH_SyncGetRootHubPdo() failed - %lX\n", Status
);
722 USBH_WriteFailReasonID(HubExtension
->LowerPDO
, USBHUB_FAIL_NO_FAIL
);
724 if (HubExtension
->HubFlags
& USBHUB_FDO_FLAG_DEVICE_FAILED
)
726 DPRINT1("USBH_StartHubFdoDevice: USBHUB_FDO_FLAG_DEVICE_FAILED - TRUE\n");
727 Status
= STATUS_UNSUCCESSFUL
;
731 HubExtension
->HubFlags
|= USBHUB_FDO_FLAG_REMOTE_WAKEUP
;
733 Status
= USBD_GetPdoRegistryParameter(HubExtension
->LowerPDO
,
734 &DisableRemoteWakeup
,
735 sizeof(DisableRemoteWakeup
),
736 DisableWakeValueName
,
737 sizeof(DisableWakeValueName
));
739 if (NT_SUCCESS(Status
) && DisableRemoteWakeup
)
741 DPRINT("USBH_StartHubFdoDevice: DisableRemoteWakeup - TRUE\n");
742 HubExtension
->HubFlags
&= ~USBHUB_FDO_FLAG_REMOTE_WAKEUP
;
745 HubExtension
->CurrentPowerState
.DeviceState
= PowerDeviceD0
;
747 USBH_SyncGetHubCount(HubExtension
->LowerDevice
,
750 Status
= USBHUB_GetBusInterface(HubExtension
->RootHubPdo
,
751 &HubExtension
->BusInterface
);
753 if (!NT_SUCCESS(Status
))
755 DPRINT1("USBH_StartHubFdoDevice: USBHUB_GetBusInterface() failed - %lX\n",
760 Status
= USBHUB_GetBusInterfaceUSBDI(HubExtension
->LowerDevice
,
761 &HubExtension
->BusInterfaceUSBDI
);
763 if (!NT_SUCCESS(Status
))
765 DPRINT1("USBH_StartHubFdoDevice: USBHUB_GetBusInterfaceUSBDI() failed - %lX\n",
770 DeviceHandle
= USBH_SyncGetDeviceHandle(HubExtension
->LowerDevice
);
774 Status
= USBH_GetDeviceType(HubExtension
, DeviceHandle
, &DeviceType
);
776 if (!NT_SUCCESS(Status
))
778 DPRINT1("USBH_StartHubFdoDevice: USBH_GetDeviceType() failed - %lX\n",
784 if (DeviceType
== Usb20Device
)
786 HubExtension
->HubFlags
|= USBHUB_FDO_FLAG_USB20_HUB
;
790 if (HubCount
> USBHUB_MAX_CASCADE_LEVELS
)
792 PUSBHUB_PORT_PDO_EXTENSION ParentPdoExtension
;
793 PUSBHUB_FDO_EXTENSION ParentHubExtension
;
795 PUSBHUB_PORT_DATA PortData
;
797 DPRINT1("USBH_StartHubFdoDevice: HubCount > 6 - %x\n", HubCount
);
799 USBH_WriteFailReasonID(HubExtension
->LowerPDO
,
800 USBHUB_FAIL_NESTED_TOO_DEEPLY
);
802 ParentPdoExtension
= HubExtension
->LowerPDO
->DeviceExtension
;
803 ParentHubExtension
= ParentPdoExtension
->HubExtension
;
805 ParentPort
= ParentPdoExtension
->PortNumber
- 1;
806 PortData
= &ParentHubExtension
->PortData
[ParentPort
];
807 PortData
->ConnectionStatus
= DeviceHubNestedTooDeeply
;
809 HubExtension
->HubFlags
|= USBHUB_FDO_FLAG_DEVICE_FAILED
;
812 USBH_QueryCapabilities(HubExtension
->LowerDevice
, &DeviceCapabilities
);
814 HubExtension
->SystemWake
= DeviceCapabilities
.SystemWake
;
815 HubExtension
->DeviceWake
= DeviceCapabilities
.DeviceWake
;
817 RtlCopyMemory(HubExtension
->DeviceState
,
818 &DeviceCapabilities
.DeviceState
,
819 POWER_SYSTEM_MAXIMUM
* sizeof(DEVICE_POWER_STATE
));
821 Status
= USBH_GetDeviceDescriptor(HubExtension
->Common
.SelfDevice
,
822 &HubExtension
->HubDeviceDescriptor
);
824 if (!NT_SUCCESS(Status
))
826 DPRINT1("USBH_StartHubFdoDevice: USBH_GetDeviceDescriptor() failed - %lX\n",
831 Status
= USBH_GetConfigurationDescriptor(HubExtension
->Common
.SelfDevice
,
832 &HubExtension
->HubConfigDescriptor
);
834 if (!NT_SUCCESS(Status
))
836 DPRINT1("USBH_StartHubFdoDevice: USBH_GetConfigurationDescriptor() failed - %lX\n",
841 Status
= USBH_SyncGetHubDescriptor(HubExtension
);
843 if (!NT_SUCCESS(Status
))
845 DPRINT1("USBH_StartHubFdoDevice: USBH_SyncGetHubDescriptor() failed - %lX\n",
850 IsBusPowered
= USBH_HubIsBusPowered(HubExtension
->Common
.SelfDevice
,
851 HubExtension
->HubConfigDescriptor
);
855 /* bus-powered hub is allowed a maximum of 100 mA only for each port */
856 HubExtension
->MaxPowerPerPort
= 100;
858 /* can have 4 ports (4 * 100 mA) and 100 mA remains for itself;
859 expressed in 2 mA units (i.e., 250 = 500 mA). */
860 HubExtension
->HubConfigDescriptor
->MaxPower
= 250;
864 /* self-powered hub is allowed a maximum of 500 mA for each port */
865 HubExtension
->MaxPowerPerPort
= 500;
868 Status
= USBH_OpenConfiguration(HubExtension
);
870 if (!NT_SUCCESS(Status
))
872 DPRINT1("USBH_StartHubFdoDevice: USBH_OpenConfiguration() failed - %lX\n",
877 if (HubExtension
->HubFlags
& USBHUB_FDO_FLAG_USB20_HUB
)
879 Status
= USBD_Initialize20Hub(HubExtension
);
882 if (!NT_SUCCESS(Status
))
887 HubExtension
->SCEIrp
= IoAllocateIrp(HubExtension
->Common
.SelfDevice
->StackSize
,
890 HubExtension
->ResetPortIrp
= IoAllocateIrp(HubExtension
->Common
.SelfDevice
->StackSize
,
893 if (!HubExtension
->SCEIrp
|| !HubExtension
->ResetPortIrp
)
895 Status
= STATUS_INSUFFICIENT_RESOURCES
;
899 HubExtension
->SCEBitmapLength
= HubExtension
->PipeInfo
.MaximumPacketSize
;
901 HubExtension
->SCEBitmap
= ExAllocatePoolWithTag(NonPagedPool
,
902 HubExtension
->SCEBitmapLength
,
905 if (!HubExtension
->SCEBitmap
)
907 Status
= STATUS_INSUFFICIENT_RESOURCES
;
911 RtlZeroMemory(HubExtension
->SCEBitmap
, HubExtension
->SCEBitmapLength
);
913 Status
= USBH_SyncPowerOnPorts(HubExtension
);
915 if (!NT_SUCCESS(Status
))
923 HubExtension
->HubFlags
|= USBHUB_FDO_FLAG_DEVICE_STARTED
;
926 Port
<= HubExtension
->HubDescriptor
->bNumberOfPorts
;
929 USBH_SyncClearPortStatus(HubExtension
,
931 USBHUB_FEATURE_C_PORT_CONNECTION
);
935 if (HubExtension
->LowerPDO
== HubExtension
->RootHubPdo
)
937 USBD_RegisterRootHubCallBack(HubExtension
);
941 HubExtension
->HubFlags
|= USBHUB_FDO_FLAG_DO_ENUMERATION
;
942 USBH_SubmitStatusChangeTransfer(HubExtension
);
949 if (HubExtension
->HubDescriptor
)
951 ExFreePoolWithTag(HubExtension
->HubDescriptor
, USB_HUB_TAG
);
952 HubExtension
->HubDescriptor
= NULL
;
955 if (HubExtension
->SCEIrp
)
957 IoFreeIrp(HubExtension
->SCEIrp
);
958 HubExtension
->SCEIrp
= NULL
;
961 if (HubExtension
->ResetPortIrp
)
963 IoFreeIrp(HubExtension
->ResetPortIrp
);
964 HubExtension
->ResetPortIrp
= NULL
;
967 if (HubExtension
->SCEBitmap
)
969 ExFreePoolWithTag(HubExtension
->SCEBitmap
, USB_HUB_TAG
);
970 HubExtension
->SCEBitmap
= NULL
;
973 if (HubExtension
->HubConfigDescriptor
)
975 ExFreePoolWithTag(HubExtension
->HubConfigDescriptor
, USB_HUB_TAG
);
976 HubExtension
->HubConfigDescriptor
= NULL
;
981 USBH_CompleteIrp(Irp
, Status
);
988 USBH_FdoStartDevice(IN PUSBHUB_FDO_EXTENSION HubExtension
,
993 DPRINT("USBH_FdoStartDevice: HubExtension - %p\n", HubExtension
);
995 HubExtension
->RootHubPdo
= NULL
;
997 Status
= USBH_SyncGetRootHubPdo(HubExtension
->LowerDevice
,
998 &HubExtension
->RootHubPdo
,
999 &HubExtension
->RootHubPdo2
);
1001 if (NT_SUCCESS(Status
))
1003 if (HubExtension
->RootHubPdo
)
1005 Status
= USBH_StartHubFdoDevice(HubExtension
, Irp
);
1009 DPRINT1("USBH_FdoStartDevice: FIXME. start ParentDevice\n");
1015 DPRINT1("USBH_FdoStartDevice: FIXME. USBH_SyncGetRootHubPdo return - %lX\n",
1019 USBH_CompleteIrp(Irp
, Status
);
1027 USBH_FdoQueryBusRelations(IN PUSBHUB_FDO_EXTENSION HubExtension
,
1030 PDEVICE_RELATIONS DeviceRelations
= NULL
;
1031 NTSTATUS Status
= STATUS_SUCCESS
;
1032 LIST_ENTRY GhostPdoList
;
1034 PLIST_ENTRY PdoList
;
1038 PUSBHUB_PORT_DATA PortData
;
1039 PDEVICE_OBJECT PdoDevice
;
1040 PUSBHUB_PORT_PDO_EXTENSION PdoExtension
;
1041 PUSBHUB_PORT_PDO_EXTENSION pdoExtension
;
1045 USB_PORT_STATUS UsbPortStatus
;
1049 DPRINT_ENUM("USBH_FdoQueryBusRelations: HubFlags - %lX\n",
1050 HubExtension
->HubFlags
);
1052 if (!(HubExtension
->HubFlags
& USBHUB_FDO_FLAG_DEVICE_STARTED
))
1054 Status
= STATUS_INVALID_DEVICE_STATE
;
1055 goto RelationsWorker
;
1058 if (!HubExtension
->HubDescriptor
)
1060 Status
= STATUS_UNSUCCESSFUL
;
1061 goto RelationsWorker
;
1064 if (!(HubExtension
->HubFlags
& USBHUB_FDO_FLAG_DO_ENUMERATION
))
1066 DPRINT_ENUM("USBH_FdoQueryBusRelations: Skip enumeration\n");
1067 goto RelationsWorker
;
1070 InterlockedIncrement(&HubExtension
->PendingRequestCount
);
1072 KeWaitForSingleObject(&HubExtension
->ResetDeviceSemaphore
,
1078 NumberPorts
= HubExtension
->HubDescriptor
->bNumberOfPorts
;
1079 DPRINT_ENUM("USBH_FdoQueryBusRelations: NumberPorts - %x\n", NumberPorts
);
1081 Length
= FIELD_OFFSET(DEVICE_RELATIONS
, Objects
) +
1082 NumberPorts
* sizeof(PDEVICE_OBJECT
);
1084 if (Irp
->IoStatus
.Information
)
1086 DPRINT1("FIXME: leaking old bus relations\n");
1089 DeviceRelations
= ExAllocatePoolWithTag(NonPagedPool
, Length
, USB_HUB_TAG
);
1091 if (!DeviceRelations
)
1093 HubExtension
->HubFlags
&= ~USBHUB_FDO_FLAG_NOT_ENUMERATED
;
1095 KeReleaseSemaphore(&HubExtension
->ResetDeviceSemaphore
,
1096 LOW_REALTIME_PRIORITY
,
1100 if (!InterlockedDecrement(&HubExtension
->PendingRequestCount
))
1102 KeSetEvent(&HubExtension
->PendingRequestEvent
, EVENT_INCREMENT
, FALSE
);
1105 Status
= STATUS_INSUFFICIENT_RESOURCES
;
1106 goto RelationsWorker
;
1109 RtlZeroMemory(DeviceRelations
, Length
);
1111 DeviceRelations
->Count
= 0;
1115 if (HubExtension
->HubFlags
& USBHUB_FDO_FLAG_ESD_RECOVERING
)
1117 HubExtension
->HubFlags
&= ~USBHUB_FDO_FLAG_NOT_ENUMERATED
;
1119 KeReleaseSemaphore(&HubExtension
->ResetDeviceSemaphore
,
1120 LOW_REALTIME_PRIORITY
,
1124 if (!InterlockedDecrement(&HubExtension
->PendingRequestCount
))
1126 KeSetEvent(&HubExtension
->PendingRequestEvent
, EVENT_INCREMENT
, FALSE
);
1129 Status
= STATUS_SUCCESS
;
1130 goto RelationsWorker
;
1133 HubExtension
->HubFlags
&= ~USBHUB_FDO_FLAG_ENUM_POST_RECOVER
;
1135 for (Port
= 1; Port
<= NumberPorts
; Port
++)
1137 PortData
= &HubExtension
->PortData
[Port
- 1];
1139 DPRINT_ENUM("USBH_FdoQueryBusRelations: Port - %x, ConnectStatus - %x\n",
1141 PortData
->PortStatus
.PortStatus
.Usb20PortStatus
.CurrentConnectStatus
);
1143 if (HubExtension
->HubFlags
& USBHUB_FDO_FLAG_DEVICE_FAILED
)
1148 Status
= USBH_SyncGetPortStatus(HubExtension
,
1150 &PortData
->PortStatus
,
1151 sizeof(USB_PORT_STATUS_AND_CHANGE
));
1153 if (!NT_SUCCESS(Status
))
1155 HubExtension
->HubFlags
|= USBHUB_FDO_FLAG_DEVICE_FAILED
;
1156 DeviceRelations
->Count
= 0;
1160 PdoDevice
= PortData
->DeviceObject
;
1162 if (PortData
->DeviceObject
)
1164 PdoExtension
= PdoDevice
->DeviceExtension
;
1166 if (PdoExtension
->PortPdoFlags
& USBHUB_PDO_FLAG_OVERCURRENT_PORT
)
1168 PortData
->PortStatus
.PortStatus
.Usb20PortStatus
.CurrentConnectStatus
= 1;
1172 if (HubExtension
->HubFlags
& USBHUB_FDO_FLAG_DEVICE_FAILED
)
1174 DPRINT1("USBH_FdoQueryBusRelations: DbgBreakPoint() \n");
1178 if (!PortData
->PortStatus
.PortStatus
.Usb20PortStatus
.CurrentConnectStatus
)
1182 PdoExtension
= PdoDevice
->DeviceExtension
;
1184 PdoExtension
->PortPdoFlags
|= USBHUB_PDO_FLAG_DELETE_PENDING
;
1185 PdoExtension
->EnumFlags
&= ~USBHUB_ENUM_FLAG_DEVICE_PRESENT
;
1187 SerialNumber
= InterlockedExchangePointer((PVOID
)&PdoExtension
->SerialNumber
,
1192 ExFreePoolWithTag(SerialNumber
, USB_HUB_TAG
);
1195 DeviceHandle
= InterlockedExchangePointer(&PdoExtension
->DeviceHandle
,
1200 USBD_RemoveDeviceEx(HubExtension
, DeviceHandle
, 0);
1201 USBH_SyncDisablePort(HubExtension
, Port
);
1205 PortData
->DeviceObject
= NULL
;
1206 PortData
->ConnectionStatus
= NoDeviceConnected
;
1212 ObReferenceObject(PdoDevice
);
1214 PdoDevice
->Flags
|= DO_POWER_PAGABLE
;
1215 PdoDevice
->Flags
&= ~DO_DEVICE_INITIALIZING
;
1217 DeviceRelations
->Objects
[DeviceRelations
->Count
++] = PdoDevice
;
1219 PdoExtension
= PdoDevice
->DeviceExtension
;
1220 PdoExtension
->PortPdoFlags
&= ~USBHUB_PDO_FLAG_POWER_D1_OR_D2
;
1227 NtStatus
= USBH_SyncResetPort(HubExtension
, Port
);
1229 if (!NT_SUCCESS(NtStatus
))
1231 if (HubExtension
->HubFlags
& USBHUB_FDO_FLAG_USB20_HUB
)
1233 PortData
->DeviceObject
= NULL
;
1234 PortData
->ConnectionStatus
= NoDeviceConnected
;
1240 NtStatus
= USBH_SyncGetPortStatus(HubExtension
,
1242 &PortData
->PortStatus
,
1243 sizeof(USB_PORT_STATUS_AND_CHANGE
));
1245 UsbPortStatus
= PortData
->PortStatus
.PortStatus
;
1247 if (NT_SUCCESS(NtStatus
))
1251 for (NtStatus
= USBH_CreateDevice(HubExtension
, Port
, UsbPortStatus
, ix
);
1252 !NT_SUCCESS(NtStatus
);
1253 NtStatus
= USBH_CreateDevice(HubExtension
, Port
, UsbPortStatus
, ix
))
1262 if (PortData
->DeviceObject
)
1264 IoDeleteDevice(PortData
->DeviceObject
);
1265 PortData
->DeviceObject
= NULL
;
1266 PortData
->ConnectionStatus
= NoDeviceConnected
;
1269 USBH_SyncResetPort(HubExtension
, Port
);
1274 if (NT_SUCCESS(NtStatus
))
1276 PdoExtension
= PortData
->DeviceObject
->DeviceExtension
;
1278 if (!(PdoExtension
->PortPdoFlags
& USBHUB_PDO_FLAG_PORT_LOW_SPEED
) &&
1279 !(PdoExtension
->PortPdoFlags
& USBHUB_PDO_FLAG_PORT_HIGH_SPEED
) &&
1280 !(HubExtension
->HubFlags
& USBHUB_FDO_FLAG_USB20_HUB
))
1282 DPRINT1("USBH_FdoQueryBusRelations: FIXME USBH_DeviceIs2xDualMode()\n");
1284 if (0)//USBH_DeviceIs2xDualMode(PdoExtension))
1286 PdoExtension
->PortPdoFlags
|= USBHUB_PDO_FLAG_HS_USB1_DUALMODE
;
1290 ObReferenceObject(PortData
->DeviceObject
);
1292 DeviceRelations
->Objects
[DeviceRelations
->Count
] = PortData
->DeviceObject
;
1294 PortData
->DeviceObject
->Flags
|= DO_POWER_PAGABLE
;
1295 PortData
->DeviceObject
->Flags
&= ~DO_DEVICE_INITIALIZING
;
1297 DeviceRelations
->Count
++;
1299 PortData
->ConnectionStatus
= DeviceConnected
;
1306 PortData
->ConnectionStatus
= DeviceFailedEnumeration
;
1308 if (NT_ERROR(USBH_SyncDisablePort(HubExtension
, Port
)))
1310 HubExtension
->HubFlags
|= USBHUB_FDO_FLAG_DEVICE_FAILED
;
1313 if (PortData
->DeviceObject
)
1315 ObReferenceObject(PortData
->DeviceObject
);
1316 PortData
->DeviceObject
->Flags
&= ~DO_DEVICE_INITIALIZING
;
1317 DeviceRelations
->Objects
[DeviceRelations
->Count
++] = PortData
->DeviceObject
;
1321 HubExtension
->HubFlags
&= ~USBHUB_FDO_FLAG_NOT_ENUMERATED
;
1323 KeReleaseSemaphore(&HubExtension
->ResetDeviceSemaphore
,
1324 LOW_REALTIME_PRIORITY
,
1328 if (!InterlockedDecrement(&HubExtension
->PendingRequestCount
))
1330 KeSetEvent(&HubExtension
->PendingRequestEvent
, EVENT_INCREMENT
, FALSE
);
1335 Irp
->IoStatus
.Status
= Status
;
1337 if (!NT_SUCCESS(Status
))
1339 //Irp->IoStatus.Information = 0;
1341 if (DeviceRelations
)
1343 ExFreePoolWithTag(DeviceRelations
, USB_HUB_TAG
);
1346 USBH_CompleteIrp(Irp
, Status
);
1351 KeAcquireSpinLock(&HubExtension
->RelationsWorkerSpinLock
, &OldIrql
);
1353 if (DeviceRelations
&& DeviceRelations
->Count
)
1355 for (Port
= 0; Port
< DeviceRelations
->Count
; Port
++)
1357 PdoDevice
= DeviceRelations
->Objects
[Port
];
1358 Entry
= HubExtension
->PdoList
.Flink
;
1360 while (Entry
!= &HubExtension
->PdoList
)
1362 pdoExtension
= CONTAINING_RECORD(Entry
,
1363 USBHUB_PORT_PDO_EXTENSION
,
1366 if (pdoExtension
== PdoDevice
->DeviceExtension
)
1368 PdoExt(PdoDevice
)->EnumFlags
|= USBHUB_ENUM_FLAG_GHOST_DEVICE
;
1372 Entry
= Entry
->Flink
;
1375 PdoExt(PdoDevice
)->EnumFlags
|= USBHUB_ENUM_FLAG_DEVICE_PRESENT
;
1380 for (Port
= 0; Port
< DeviceRelations
->Count
; Port
++)
1382 PdoDevice
= DeviceRelations
->Objects
[Port
];
1384 if (PdoExt(PdoDevice
)->EnumFlags
& USBHUB_ENUM_FLAG_GHOST_DEVICE
)
1386 for (GhostPort
= Port
;
1387 GhostPort
< DeviceRelations
->Count
;
1390 DeviceRelations
->Objects
[GhostPort
] =
1391 DeviceRelations
->Objects
[GhostPort
+ 1];
1394 ObDereferenceObject(PdoDevice
);
1396 DeviceRelations
->Count
--;
1398 if (PdoExt(PdoDevice
)->EnumFlags
& USBHUB_ENUM_FLAG_DEVICE_PRESENT
)
1400 PdoExt(PdoDevice
)->EnumFlags
&= ~USBHUB_ENUM_FLAG_GHOST_DEVICE
;
1406 Irp
->IoStatus
.Information
= (ULONG_PTR
)DeviceRelations
;
1408 InitializeListHead(&GhostPdoList
);
1409 PdoList
= &HubExtension
->PdoList
;
1411 while (!IsListEmpty(PdoList
))
1413 Entry
= RemoveHeadList(PdoList
);
1415 PdoExtension
= CONTAINING_RECORD(Entry
,
1416 USBHUB_PORT_PDO_EXTENSION
,
1419 PdoExtension
->EnumFlags
&= ~USBHUB_ENUM_FLAG_DEVICE_PRESENT
;
1421 if (PdoExtension
->EnumFlags
& USBHUB_ENUM_FLAG_GHOST_DEVICE
)
1423 InsertTailList(&GhostPdoList
, &PdoExtension
->PortLink
);
1427 KeReleaseSpinLock(&HubExtension
->RelationsWorkerSpinLock
, OldIrql
);
1429 while (!IsListEmpty(&GhostPdoList
))
1431 Entry
= RemoveHeadList(&GhostPdoList
);
1433 PdoExtension
= CONTAINING_RECORD(Entry
,
1434 USBHUB_PORT_PDO_EXTENSION
,
1437 IoDeleteDevice(PdoExtension
->Common
.SelfDevice
);
1440 return USBH_PassIrp(HubExtension
->LowerDevice
, Irp
);
1445 USBH_FdoStopDevice(IN PUSBHUB_FDO_EXTENSION HubExtension
,
1448 DPRINT1("USBH_FdoStopDevice: UNIMPLEMENTED. FIXME\n");
1450 return STATUS_SUCCESS
;
1455 USBH_FdoRemoveDevice(IN PUSBHUB_FDO_EXTENSION HubExtension
,
1458 PUSB_HUB_DESCRIPTOR HubDescriptor
;
1459 PUSBHUB_PORT_DATA PortData
;
1462 PDEVICE_OBJECT PortDevice
;
1463 PUSBHUB_PORT_PDO_EXTENSION PortExtension
;
1466 DPRINT("USBH_FdoRemoveDevice: HubExtension - %p\n", HubExtension
);
1468 HubDescriptor
= HubExtension
->HubDescriptor
;
1470 if (HubDescriptor
&& HubExtension
->PortData
)
1472 NumPorts
= HubDescriptor
->bNumberOfPorts
;
1474 for (ix
= 0; ix
< NumPorts
; ++ix
)
1476 PortData
= HubExtension
->PortData
+ ix
;
1478 PortDevice
= PortData
->DeviceObject
;
1482 PortData
->PortStatus
.AsUlong32
= 0;
1483 PortData
->DeviceObject
= NULL
;
1485 PortExtension
= PortDevice
->DeviceExtension
;
1486 PortExtension
->EnumFlags
&= ~USBHUB_ENUM_FLAG_DEVICE_PRESENT
;
1488 USBH_PdoRemoveDevice(PortExtension
, HubExtension
);
1493 if (HubExtension
->HubFlags
& USBHUB_FDO_FLAG_DEVICE_STARTED
)
1495 USBH_FdoCleanup(HubExtension
);
1498 if (HubExtension
->PortData
)
1500 ExFreePoolWithTag(HubExtension
->PortData
, USB_HUB_TAG
);
1501 HubExtension
->PortData
= NULL
;
1504 DPRINT1("USBH_FdoRemoveDevice: call IoWMIRegistrationControl UNIMPLEMENTED. FIXME\n");
1506 Status
= USBH_PassIrp(HubExtension
->LowerDevice
, Irp
);
1508 IoDetachDevice(HubExtension
->LowerDevice
);
1509 IoDeleteDevice(HubExtension
->Common
.SelfDevice
);
1516 USBH_FdoSurpriseRemoveDevice(IN PUSBHUB_FDO_EXTENSION HubExtension
,
1519 PUSBHUB_PORT_PDO_EXTENSION PortExtension
;
1520 PUSBHUB_PORT_DATA PortData
;
1524 DPRINT("USBH_FdoSurpriseRemoveDevice: HubExtension - %p, Irp - %p\n",
1528 if (!HubExtension
->PortData
||
1529 !HubExtension
->HubDescriptor
)
1534 PortData
= HubExtension
->PortData
;
1535 NumberPorts
= HubExtension
->HubDescriptor
->bNumberOfPorts
;
1537 for (Port
= 0; Port
< NumberPorts
; Port
++)
1539 if (PortData
[Port
].DeviceObject
)
1541 PortExtension
= PdoExt(PortData
[Port
].DeviceObject
);
1542 PortExtension
->PortPdoFlags
|= USBHUB_PDO_FLAG_DELETE_PENDING
;
1543 PortExtension
->EnumFlags
&= ~USBHUB_ENUM_FLAG_DEVICE_PRESENT
;
1545 PortData
[Port
].DeviceObject
= NULL
;
1546 PortData
[Port
].ConnectionStatus
= NoDeviceConnected
;
1553 USBH_PdoQueryId(IN PUSBHUB_PORT_PDO_EXTENSION PortExtension
,
1559 size_t Remaining
= sizeof(Buffer
);
1562 NTSTATUS Status
= STATUS_SUCCESS
;
1563 PUSB_DEVICE_DESCRIPTOR DeviceDescriptor
;
1564 PUSB_INTERFACE_DESCRIPTOR InterfaceDescriptor
;
1566 IdType
= IoGetCurrentIrpStackLocation(Irp
)->Parameters
.QueryId
.IdType
;
1567 DeviceDescriptor
= &PortExtension
->DeviceDescriptor
;
1568 InterfaceDescriptor
= &PortExtension
->InterfaceDescriptor
;
1570 RtlZeroMemory(Buffer
, sizeof(Buffer
));
1574 case BusQueryDeviceID
:
1575 DPRINT("USBH_PdoQueryId: BusQueryDeviceID\n");
1577 if (PortExtension
->PortPdoFlags
& USBHUB_PDO_FLAG_INIT_PORT_FAILED
)
1579 RtlStringCbPrintfExW(Buffer
,
1584 L
"USB\\Vid_0000&Pid0000");
1588 RtlStringCbPrintfExW(Buffer
,
1593 L
"USB\\Vid_%04x&Pid_%04x",
1594 DeviceDescriptor
->idVendor
,
1595 DeviceDescriptor
->idProduct
);
1598 Length
= sizeof(Buffer
) - (Remaining
- sizeof(UNICODE_NULL
));
1600 Id
= ExAllocatePoolWithTag(PagedPool
, Length
, USB_HUB_TAG
);
1607 RtlCopyMemory(Id
, Buffer
, Length
);
1608 DPRINT("USBH_PdoQueryId: BusQueryDeviceID - %S\n", Id
);
1611 case BusQueryHardwareIDs
:
1612 DPRINT("USBH_PdoQueryId: BusQueryHardwareIDs\n");
1614 if (PortExtension
->PortPdoFlags
& USBHUB_PDO_FLAG_INIT_PORT_FAILED
)
1616 RtlStringCbPrintfExW(Buffer
,
1625 RtlStringCbPrintfExW(Buffer
,
1630 L
"USB\\Vid_%04x&Pid_%04x&Rev_%04x",
1631 DeviceDescriptor
->idVendor
,
1632 DeviceDescriptor
->idProduct
,
1633 DeviceDescriptor
->bcdDevice
);
1636 Remaining
-= sizeof(UNICODE_NULL
);
1638 RtlStringCbPrintfExW(EndBuffer
,
1643 L
"USB\\Vid_%04x&Pid_%04x",
1644 DeviceDescriptor
->idVendor
,
1645 DeviceDescriptor
->idProduct
);
1648 Length
= sizeof(Buffer
) - (Remaining
- sizeof(UNICODE_NULL
));
1650 Id
= ExAllocatePoolWithTag(PagedPool
, Length
, USB_HUB_TAG
);
1657 RtlCopyMemory(Id
, Buffer
, Length
);
1659 if (PortExtension
->PortPdoFlags
& USBHUB_PDO_FLAG_INIT_PORT_FAILED
)
1661 DPRINT("USBH_PdoQueryId: BusQueryInstanceID - %S\n", Id
);
1665 USBHUB_DumpingIDs(Id
);
1670 case BusQueryCompatibleIDs
:
1671 DPRINT("USBH_PdoQueryId: BusQueryCompatibleIDs\n");
1673 if (PortExtension
->PortPdoFlags
& USBHUB_PDO_FLAG_INIT_PORT_FAILED
)
1675 RtlStringCbPrintfExW(Buffer
,
1682 else if (PortExtension
->PortPdoFlags
& USBHUB_PDO_FLAG_MULTI_INTERFACE
)
1684 RtlStringCbPrintfExW(Buffer
,
1689 L
"USB\\DevClass_%02x&SubClass_%02x&Prot_%02x",
1690 InterfaceDescriptor
->bInterfaceClass
,
1691 InterfaceDescriptor
->bInterfaceSubClass
,
1692 InterfaceDescriptor
->bInterfaceProtocol
);
1695 Remaining
-= sizeof(UNICODE_NULL
);
1697 RtlStringCbPrintfExW(EndBuffer
,
1702 L
"USB\\DevClass_%02x&SubClass_%02x",
1703 InterfaceDescriptor
->bInterfaceClass
,
1704 InterfaceDescriptor
->bInterfaceSubClass
);
1707 Remaining
-= sizeof(UNICODE_NULL
);
1709 RtlStringCbPrintfExW(EndBuffer
,
1714 L
"USB\\DevClass_%02x",
1715 InterfaceDescriptor
->bInterfaceClass
);
1718 Remaining
-= sizeof(UNICODE_NULL
);
1720 RtlStringCbPrintfExW(EndBuffer
,
1729 RtlStringCbPrintfExW(Buffer
,
1734 L
"USB\\Class_%02x&SubClass_%02x&Prot_%02x",
1735 InterfaceDescriptor
->bInterfaceClass
,
1736 InterfaceDescriptor
->bInterfaceSubClass
,
1737 InterfaceDescriptor
->bInterfaceProtocol
);
1740 Remaining
-= sizeof(UNICODE_NULL
);
1742 RtlStringCbPrintfExW(EndBuffer
,
1747 L
"USB\\Class_%02x&SubClass_%02x",
1748 InterfaceDescriptor
->bInterfaceClass
,
1749 InterfaceDescriptor
->bInterfaceSubClass
);
1752 Remaining
-= sizeof(UNICODE_NULL
);
1754 RtlStringCbPrintfExW(EndBuffer
,
1760 InterfaceDescriptor
->bInterfaceClass
);
1763 Length
= sizeof(Buffer
) - (Remaining
- sizeof(UNICODE_NULL
));
1765 Id
= ExAllocatePoolWithTag(PagedPool
, Length
, USB_HUB_TAG
);
1772 RtlCopyMemory(Id
, Buffer
, Length
);
1774 if (PortExtension
->PortPdoFlags
& USBHUB_PDO_FLAG_INIT_PORT_FAILED
)
1776 DPRINT("USBH_PdoQueryId: BusQueryInstanceID - %S\n", Id
);
1780 USBHUB_DumpingIDs(Id
);
1785 case BusQueryInstanceID
:
1786 DPRINT("USBH_PdoQueryId: BusQueryInstanceID\n");
1788 if (PortExtension
->SerialNumber
)
1790 Id
= ExAllocatePoolWithTag(PagedPool
,
1791 PortExtension
->SN_DescriptorLength
,
1796 RtlZeroMemory(Id
, PortExtension
->SN_DescriptorLength
);
1799 PortExtension
->SerialNumber
,
1800 PortExtension
->SN_DescriptorLength
);
1805 Length
= sizeof(PortExtension
->InstanceID
) +
1806 sizeof(UNICODE_NULL
);
1808 Id
= ExAllocatePoolWithTag(PagedPool
, Length
, USB_HUB_TAG
);
1812 RtlZeroMemory(Id
, Length
);
1815 PortExtension
->InstanceID
,
1816 sizeof(PortExtension
->InstanceID
));
1820 DPRINT("USBH_PdoQueryId: BusQueryInstanceID - %S\n", Id
);
1824 DPRINT1("USBH_PdoQueryId: unknown query id type 0x%lx\n", IdType
);
1825 return Irp
->IoStatus
.Status
;
1828 Irp
->IoStatus
.Information
= (ULONG_PTR
)Id
;
1832 Status
= STATUS_INSUFFICIENT_RESOURCES
;
1840 USBH_PdoQueryDeviceText(IN PUSBHUB_PORT_PDO_EXTENSION PortExtension
,
1843 PDEVICE_OBJECT DeviceObject
;
1844 PIO_STACK_LOCATION IoStack
;
1845 DEVICE_TEXT_TYPE DeviceTextType
;
1848 PUSB_STRING_DESCRIPTOR Descriptor
;
1855 DPRINT("USBH_PdoQueryDeviceText ... \n");
1857 DeviceObject
= PortExtension
->Common
.SelfDevice
;
1858 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
1859 DeviceTextType
= IoStack
->Parameters
.QueryDeviceText
.DeviceTextType
;
1861 if (DeviceTextType
!= DeviceTextDescription
&&
1862 DeviceTextType
!= DeviceTextLocationInformation
)
1864 return Irp
->IoStatus
.Status
;
1867 LanguageId
= LANGIDFROMLCID(IoStack
->Parameters
.QueryDeviceText
.LocaleId
);
1868 DefaultId
= MAKELANGID(LANG_ENGLISH
, SUBLANG_ENGLISH_US
);
1872 LanguageId
= DefaultId
;
1875 iProduct
= PortExtension
->DeviceDescriptor
.iProduct
;
1877 if (PortExtension
->DeviceHandle
&& iProduct
&&
1878 !PortExtension
->IgnoringHwSerial
&&
1879 !(PortExtension
->PortPdoFlags
& USBHUB_PDO_FLAG_INIT_PORT_FAILED
))
1881 Descriptor
= ExAllocatePoolWithTag(NonPagedPool
,
1882 MAXIMUM_USB_STRING_LENGTH
,
1887 RtlZeroMemory(Descriptor
, MAXIMUM_USB_STRING_LENGTH
);
1889 for (Status
= USBH_CheckDeviceLanguage(DeviceObject
, LanguageId
);
1891 Status
= USBH_CheckDeviceLanguage(DeviceObject
, DefaultId
))
1893 if (NT_SUCCESS(Status
))
1895 Status
= USBH_SyncGetStringDescriptor(DeviceObject
,
1899 MAXIMUM_USB_STRING_LENGTH
,
1903 if (NT_SUCCESS(Status
))
1909 if (LanguageId
== DefaultId
)
1914 LanguageId
= DefaultId
;
1917 if (Descriptor
->bLength
<= sizeof(USB_COMMON_DESCRIPTOR
))
1919 Status
= STATUS_UNSUCCESSFUL
;
1922 if (NT_SUCCESS(Status
))
1924 Length
= Descriptor
->bLength
-
1925 FIELD_OFFSET(USB_STRING_DESCRIPTOR
, bString
);
1927 DeviceText
= ExAllocatePoolWithTag(PagedPool
,
1928 Length
+ sizeof(UNICODE_NULL
),
1933 RtlZeroMemory(DeviceText
, Length
+ sizeof(UNICODE_NULL
));
1935 RtlCopyMemory(DeviceText
, Descriptor
->bString
, Length
);
1937 Irp
->IoStatus
.Information
= (ULONG_PTR
)DeviceText
;
1939 DPRINT("USBH_PdoQueryDeviceText: Descriptor->bString - %S\n",
1944 Status
= STATUS_INSUFFICIENT_RESOURCES
;
1950 ExFreePoolWithTag(Descriptor
, USB_HUB_TAG
);
1952 if (NT_SUCCESS(Status
))
1959 Status
= STATUS_INSUFFICIENT_RESOURCES
;
1964 Status
= STATUS_NOT_SUPPORTED
;
1967 if (!GenericUSBDeviceString
)
1972 NumSymbols
= wcslen(GenericUSBDeviceString
);
1973 Length
= (NumSymbols
+ 1) * sizeof(WCHAR
);
1975 DeviceText
= ExAllocatePoolWithTag(PagedPool
, Length
, USB_HUB_TAG
);
1979 return STATUS_INSUFFICIENT_RESOURCES
;
1982 RtlZeroMemory(DeviceText
, Length
);
1984 RtlCopyMemory(DeviceText
,
1985 GenericUSBDeviceString
,
1986 NumSymbols
* sizeof(WCHAR
));
1988 Irp
->IoStatus
.Information
= (ULONG_PTR
)DeviceText
;
1990 return STATUS_SUCCESS
;
1995 USBH_SymbolicLink(IN PUSBHUB_PORT_PDO_EXTENSION PortExtension
,
1996 IN
const GUID
* InterfaceClassGuid
,
1997 IN BOOLEAN IsEnable
)
1999 NTSTATUS Status
= STATUS_SUCCESS
;
2002 DPRINT("USBH_SymbolicLink ... \n");
2006 Status
= IoRegisterDeviceInterface(PortExtension
->Common
.SelfDevice
,
2009 &PortExtension
->SymbolicLinkName
);
2011 if (NT_SUCCESS(Status
))
2013 USBH_SetPdoRegistryParameter(PortExtension
->Common
.SelfDevice
,
2015 PortExtension
->SymbolicLinkName
.Buffer
,
2016 PortExtension
->SymbolicLinkName
.Length
,
2018 PLUGPLAY_REGKEY_DEVICE
);
2020 Status
= IoSetDeviceInterfaceState(&PortExtension
->SymbolicLinkName
,
2026 NameBuffer
= PortExtension
->SymbolicLinkName
.Buffer
;
2030 Status
= IoSetDeviceInterfaceState(&PortExtension
->SymbolicLinkName
,
2033 ExFreePool(PortExtension
->SymbolicLinkName
.Buffer
);
2035 PortExtension
->SymbolicLinkName
.Buffer
= NULL
;
2044 USBH_RestoreDevice(IN PUSBHUB_PORT_PDO_EXTENSION PortExtension
,
2045 IN BOOLEAN IsKeepDeviceData
)
2047 PUSBHUB_FDO_EXTENSION HubExtension
;
2048 PUSBHUB_PORT_DATA PortData
;
2052 DPRINT("USBH_RestoreDevice ... \n");
2054 HubExtension
= PortExtension
->HubExtension
;
2058 Status
= STATUS_UNSUCCESSFUL
;
2062 ASSERT(PortExtension
->PortNumber
> 0);
2063 PortData
= &HubExtension
->PortData
[PortExtension
->PortNumber
- 1];
2065 if (PortExtension
->Common
.SelfDevice
== PortData
->DeviceObject
)
2067 Status
= STATUS_UNSUCCESSFUL
;
2071 Status
= USBH_SyncGetPortStatus(HubExtension
,
2072 PortExtension
->PortNumber
,
2073 &PortData
->PortStatus
,
2074 sizeof(USB_PORT_STATUS_AND_CHANGE
));
2076 if (NT_SUCCESS(Status
))
2078 for (ix
= 0; ix
< 3; ix
++)
2080 Status
= USBH_ResetDevice((PUSBHUB_FDO_EXTENSION
)HubExtension
,
2081 PortExtension
->PortNumber
,
2085 if (NT_SUCCESS(Status
) || Status
== STATUS_NO_SUCH_DEVICE
)
2094 PortExtension
->PortPdoFlags
&= ~USBHUB_PDO_FLAG_POWER_D3
;
2096 if (NT_SUCCESS(Status
))
2098 PortExtension
->PortPdoFlags
&= ~USBHUB_PDO_FLAG_PORT_RESTORE_FAIL
;
2102 PortExtension
->PortPdoFlags
|= (USBHUB_PDO_FLAG_INIT_PORT_FAILED
|
2103 USBHUB_PDO_FLAG_PORT_RESTORE_FAIL
);
2111 USBH_PdoStartDevice(IN PUSBHUB_PORT_PDO_EXTENSION PortExtension
,
2114 PUSBHUB_FDO_EXTENSION HubExtension
;
2118 DPRINT("USBH_PdoStartDevice: PortExtension - %p\n", PortExtension
);
2120 if (!PortExtension
->HubExtension
&&
2121 PortExtension
->PortPdoFlags
& USBHUB_PDO_FLAG_POWER_D3
)
2123 PortExtension
->HubExtension
= PortExtension
->RootHubExtension
;
2126 HubExtension
= PortExtension
->HubExtension
;
2130 USBHUB_SetDeviceHandleData(HubExtension
,
2131 PortExtension
->Common
.SelfDevice
,
2132 PortExtension
->DeviceHandle
);
2135 if (PortExtension
->PortPdoFlags
& USBHUB_PDO_FLAG_HUB_DEVICE
)
2137 Guid
= &GUID_DEVINTERFACE_USB_HUB
;
2141 Guid
= &GUID_DEVINTERFACE_USB_DEVICE
;
2144 Status
= USBH_SymbolicLink(PortExtension
, Guid
, TRUE
);
2146 if (NT_SUCCESS(Status
))
2148 PortExtension
->PortPdoFlags
|= USBHUB_PDO_FLAG_REG_DEV_INTERFACE
;
2151 if (PortExtension
->PortPdoFlags
& USBHUB_PDO_FLAG_POWER_D3
)
2153 Status
= USBH_RestoreDevice(PortExtension
, 0);
2156 PortExtension
->PortPdoFlags
|= USBHUB_PDO_FLAG_DEVICE_STARTED
;
2158 PortExtension
->CurrentPowerState
.DeviceState
= PowerDeviceD0
;
2160 DPRINT1("USBH_PdoStartDevice: call IoWMIRegistrationControl UNIMPLEMENTED. FIXME\n");
2167 USBH_PdoRemoveDevice(IN PUSBHUB_PORT_PDO_EXTENSION PortExtension
,
2168 IN PUSBHUB_FDO_EXTENSION HubExtension
)
2170 NTSTATUS Status
= STATUS_SUCCESS
;
2171 PDEVICE_OBJECT PortDevice
;
2172 PUSBHUB_PORT_PDO_EXTENSION PortExt
;
2173 PUSBHUB_PORT_DATA PortData
;
2174 PIRP IdleNotificationIrp
;
2182 DPRINT("USBH_PdoRemoveDevice ... \n");
2184 PortDevice
= PortExtension
->Common
.SelfDevice
;
2185 PortExtension
->HubExtension
= NULL
;
2187 Port
= PortExtension
->PortNumber
;
2190 ASSERT(HubExtension
);
2192 if (HubExtension
->CurrentPowerState
.DeviceState
!= PowerDeviceD0
&&
2193 (HubExtension
->HubFlags
& USBHUB_FDO_FLAG_DEVICE_STARTED
) != 0)
2195 USBH_HubSetD0(HubExtension
);
2198 IoAcquireCancelSpinLock(&Irql
);
2199 IdleNotificationIrp
= PortExtension
->IdleNotificationIrp
;
2201 if (IdleNotificationIrp
)
2203 PortExtension
->IdleNotificationIrp
= NULL
;
2204 PortExtension
->PortPdoFlags
&= ~USBHUB_PDO_FLAG_IDLE_NOTIFICATION
;
2206 if (IdleNotificationIrp
->Cancel
)
2208 IdleNotificationIrp
= NULL
;
2211 if (IdleNotificationIrp
)
2213 IoSetCancelRoutine(IdleNotificationIrp
, NULL
);
2217 WakeIrp
= PortExtension
->PdoWaitWakeIrp
;
2221 PortExtension
->PdoWaitWakeIrp
= NULL
;
2222 PortExtension
->PortPdoFlags
&= ~USBHUB_PDO_FLAG_WAIT_WAKE
;
2224 if (WakeIrp
->Cancel
|| !IoSetCancelRoutine(WakeIrp
, NULL
))
2228 if (!InterlockedDecrement(&HubExtension
->PendingRequestCount
))
2230 KeSetEvent(&HubExtension
->PendingRequestEvent
,
2237 IoReleaseCancelSpinLock(Irql
);
2239 if (IdleNotificationIrp
)
2241 IdleNotificationIrp
->IoStatus
.Status
= STATUS_CANCELLED
;
2242 IoCompleteRequest(IdleNotificationIrp
, IO_NO_INCREMENT
);
2247 USBH_CompletePowerIrp(HubExtension
, WakeIrp
, STATUS_CANCELLED
);
2250 PortExtension
->PortPdoFlags
|= USBHUB_PDO_FLAG_POWER_D3
;
2252 if (PortExtension
->PortPdoFlags
& USBHUB_PDO_FLAG_REG_DEV_INTERFACE
)
2254 Status
= USBH_SymbolicLink(PortExtension
, NULL
, FALSE
);
2256 if (NT_SUCCESS(Status
))
2258 PortExtension
->PortPdoFlags
&= ~USBHUB_PDO_FLAG_REG_DEV_INTERFACE
;
2262 DeviceHandle
= InterlockedExchangePointer(&PortExtension
->DeviceHandle
,
2267 Status
= USBD_RemoveDeviceEx(HubExtension
, DeviceHandle
, 0);
2269 if (HubExtension
->PortData
&&
2270 HubExtension
->PortData
[Port
- 1].DeviceObject
== PortDevice
)
2272 USBH_SyncDisablePort(HubExtension
, Port
);
2276 if (NT_SUCCESS(Status
))
2278 PortExtension
->PortPdoFlags
&= ~USBHUB_PDO_FLAG_DEVICE_STARTED
;
2280 if (HubExtension
->PortData
)
2282 PortData
= &HubExtension
->PortData
[Port
- 1];
2284 if (PortExtension
->PortPdoFlags
& USBHUB_PDO_FLAG_DELETE_PENDING
)
2286 Pdo
= PortData
->DeviceObject
;
2290 PortData
->DeviceObject
= NULL
;
2291 PortData
->ConnectionStatus
= NoDeviceConnected
;
2293 if (PdoExt(Pdo
)->EnumFlags
& USBHUB_ENUM_FLAG_DEVICE_PRESENT
)
2295 PortExt
= PdoExt(Pdo
);
2297 InsertTailList(&HubExtension
->PdoList
,
2298 &PortExt
->PortLink
);
2304 if (!(PortExtension
->EnumFlags
& USBHUB_ENUM_FLAG_DEVICE_PRESENT
) &&
2305 !(PortExtension
->PortPdoFlags
& USBHUB_PDO_FLAG_NOT_CONNECTED
))
2307 PortExtension
->PortPdoFlags
|= USBHUB_PDO_FLAG_NOT_CONNECTED
;
2309 SerialNumber
= InterlockedExchangePointer((PVOID
)&PortExtension
->SerialNumber
,
2314 ExFreePoolWithTag(SerialNumber
, USB_HUB_TAG
);
2317 DPRINT1("USBH_PdoRemoveDevice: call IoWMIRegistrationControl UNIMPLEMENTED. FIXME\n");
2319 USBHUB_FlushAllTransfers(HubExtension
);
2321 IoDeleteDevice(PortDevice
);
2325 DPRINT("USBH_PdoRemoveDevice: call USBH_CheckIdleDeferred()\n");
2326 USBH_CheckIdleDeferred(HubExtension
);
2333 USBH_PdoStopDevice(IN PUSBHUB_PORT_PDO_EXTENSION PortExtension
,
2336 DPRINT1("USBH_PdoStopDevice: UNIMPLEMENTED. FIXME\n");
2338 return STATUS_SUCCESS
;
2343 USBH_FdoPnP(IN PUSBHUB_FDO_EXTENSION HubExtension
,
2348 PIO_STACK_LOCATION IoStack
;
2349 DEVICE_RELATION_TYPE RelationsType
;
2350 BOOLEAN IsCheckIdle
;
2352 DPRINT_PNP("USBH_FdoPnP: HubExtension - %p, Irp - %p, Minor - %X\n",
2357 if (HubExtension
->HubFlags
& USBHUB_FDO_FLAG_WAIT_IDLE_REQUEST
&&
2358 (Minor
== IRP_MN_REMOVE_DEVICE
|| Minor
== IRP_MN_STOP_DEVICE
))
2360 HubExtension
->HubFlags
|= USBHUB_FDO_FLAG_DEVICE_SUSPENDED
;
2363 KeWaitForSingleObject(&HubExtension
->IdleSemaphore
,
2369 DPRINT_PNP("USBH_FdoPnP: HubFlags - %lX\n", HubExtension
->HubFlags
);
2371 if (HubExtension
->HubFlags
& USBHUB_FDO_FLAG_GOING_IDLE
)
2373 HubExtension
->HubFlags
|= USBHUB_FDO_FLAG_DEVICE_SUSPENDED
;
2376 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
2377 RelationsType
= IoStack
->Parameters
.QueryDeviceRelations
.Type
;
2379 if ((HubExtension
->CurrentPowerState
.DeviceState
== PowerDeviceD0
) ||
2380 !(HubExtension
->HubFlags
& (USBHUB_FDO_FLAG_DEVICE_STOPPED
| USBHUB_FDO_FLAG_DEVICE_STARTED
)) ||
2381 (Minor
== IRP_MN_QUERY_DEVICE_RELATIONS
&& RelationsType
== TargetDeviceRelation
))
2383 IsCheckIdle
= FALSE
;
2387 DPRINT_PNP("USBH_FdoPnP: IsCheckIdle - TRUE\n");
2389 USBH_HubSetD0(HubExtension
);
2394 case IRP_MN_START_DEVICE
:
2395 DPRINT_PNP("FDO IRP_MN_START_DEVICE\n");
2396 IsCheckIdle
= FALSE
;
2397 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
2398 Status
= USBH_FdoStartDevice(HubExtension
, Irp
);
2401 case IRP_MN_QUERY_REMOVE_DEVICE
:
2402 DPRINT_PNP("FDO IRP_MN_QUERY_REMOVE_DEVICE\n");
2403 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
2404 Status
= USBH_PassIrp(HubExtension
->LowerDevice
, Irp
);
2407 case IRP_MN_REMOVE_DEVICE
:
2408 DPRINT_PNP("FDO IRP_MN_REMOVE_DEVICE\n");
2409 IsCheckIdle
= FALSE
;
2410 HubExtension
->HubFlags
|= USBHUB_FDO_FLAG_DEVICE_REMOVED
;
2411 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
2412 Status
= USBH_FdoRemoveDevice(HubExtension
, Irp
);
2415 case IRP_MN_CANCEL_REMOVE_DEVICE
:
2416 DPRINT_PNP("FDO IRP_MN_CANCEL_REMOVE_DEVICE\n");
2417 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
2418 Status
= USBH_PassIrp(HubExtension
->LowerDevice
, Irp
);
2421 case IRP_MN_STOP_DEVICE
:
2422 DPRINT_PNP("FDO IRP_MN_STOP_DEVICE\n");
2423 IsCheckIdle
= FALSE
;
2424 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
2425 Status
= USBH_FdoStopDevice(HubExtension
, Irp
);
2428 case IRP_MN_QUERY_STOP_DEVICE
:
2429 DPRINT_PNP("FDO IRP_MN_QUERY_STOP_DEVICE\n");
2430 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
2431 Status
= USBH_PassIrp(HubExtension
->LowerDevice
, Irp
);
2434 case IRP_MN_CANCEL_STOP_DEVICE
:
2435 DPRINT_PNP("FDO IRP_MN_CANCEL_STOP_DEVICE\n");
2436 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
2437 Status
= USBH_PassIrp(HubExtension
->LowerDevice
, Irp
);
2440 case IRP_MN_QUERY_DEVICE_RELATIONS
:
2441 DPRINT_PNP("FDO IRP_MN_QUERY_DEVICE_RELATIONS\n");
2443 if (RelationsType
!= BusRelations
)
2445 Status
= USBH_PassIrp(HubExtension
->LowerDevice
, Irp
);
2449 HubExtension
->HubFlags
|= USBHUB_FDO_FLAG_HUB_BUSY
;
2452 DPRINT_PNP("USBH_FdoPnP: IsCheckIdle - TRUE\n");
2454 Status
= USBH_FdoQueryBusRelations(HubExtension
, Irp
);
2456 HubExtension
->HubFlags
&= ~USBHUB_FDO_FLAG_HUB_BUSY
;
2459 case IRP_MN_QUERY_INTERFACE
:
2460 DPRINT_PNP("FDO IRP_MN_QUERY_INTERFACE\n");
2461 Status
= USBH_PassIrp(HubExtension
->LowerDevice
, Irp
);
2464 case IRP_MN_QUERY_CAPABILITIES
:
2465 DPRINT_PNP("FDO IRP_MN_QUERY_CAPABILITIES\n");
2466 IoCopyCurrentIrpStackLocationToNext(Irp
);
2468 IoSetCompletionRoutine(Irp
,
2469 USBH_QueryCapsComplete
,
2475 Status
= IoCallDriver(HubExtension
->LowerDevice
, Irp
);
2478 case IRP_MN_QUERY_RESOURCES
:
2479 DPRINT_PNP("FDO IRP_MN_QUERY_RESOURCES\n");
2480 Status
= USBH_PassIrp(HubExtension
->LowerDevice
, Irp
);
2483 case IRP_MN_QUERY_RESOURCE_REQUIREMENTS
:
2484 DPRINT_PNP("FDO IRP_MN_QUERY_RESOURCE_REQUIREMENTS\n");
2485 Status
= USBH_PassIrp(HubExtension
->LowerDevice
, Irp
);
2488 case IRP_MN_QUERY_DEVICE_TEXT
:
2489 DPRINT_PNP("FDO IRP_MN_QUERY_DEVICE_TEXT\n");
2490 Status
= USBH_PassIrp(HubExtension
->LowerDevice
, Irp
);
2493 case IRP_MN_FILTER_RESOURCE_REQUIREMENTS
:
2494 DPRINT_PNP("FDO IRP_MN_FILTER_RESOURCE_REQUIREMENTS\n");
2495 Status
= USBH_PassIrp(HubExtension
->LowerDevice
, Irp
);
2498 case IRP_MN_READ_CONFIG
:
2499 DPRINT_PNP("FDO IRP_MN_READ_CONFIG\n");
2500 Status
= USBH_PassIrp(HubExtension
->LowerDevice
, Irp
);
2503 case IRP_MN_WRITE_CONFIG
:
2504 DPRINT_PNP("FDO IRP_MN_WRITE_CONFIG\n");
2505 Status
= USBH_PassIrp(HubExtension
->LowerDevice
, Irp
);
2509 DPRINT_PNP("FDO IRP_MN_EJECT\n");
2510 Status
= USBH_PassIrp(HubExtension
->LowerDevice
, Irp
);
2513 case IRP_MN_SET_LOCK
:
2514 DPRINT_PNP("FDO IRP_MN_SET_LOCK\n");
2515 Status
= USBH_PassIrp(HubExtension
->LowerDevice
, Irp
);
2518 case IRP_MN_QUERY_ID
:
2519 DPRINT_PNP("FDO IRP_MN_QUERY_ID\n");
2520 Status
= USBH_PassIrp(HubExtension
->LowerDevice
, Irp
);
2523 case IRP_MN_QUERY_PNP_DEVICE_STATE
:
2524 DPRINT_PNP("FDO IRP_MN_QUERY_PNP_DEVICE_STATE\n");
2526 if (HubExtension
->HubFlags
& USBHUB_FDO_FLAG_DEVICE_FAILED
)
2528 Irp
->IoStatus
.Information
|= PNP_DEVICE_FAILED
;
2531 Status
= USBH_PassIrp(HubExtension
->LowerDevice
, Irp
);
2534 case IRP_MN_QUERY_BUS_INFORMATION
:
2535 DPRINT_PNP("FDO IRP_MN_QUERY_BUS_INFORMATION\n");
2536 Status
= USBH_PassIrp(HubExtension
->LowerDevice
, Irp
);
2539 case IRP_MN_DEVICE_USAGE_NOTIFICATION
:
2540 DPRINT_PNP("FDO IRP_MN_DEVICE_USAGE_NOTIFICATION\n");
2541 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
2542 Status
= USBH_PassIrp(HubExtension
->LowerDevice
, Irp
);
2545 case IRP_MN_SURPRISE_REMOVAL
:
2546 DPRINT_PNP("FDO IRP_MN_SURPRISE_REMOVAL\n");
2547 USBH_FdoSurpriseRemoveDevice(HubExtension
, Irp
);
2548 Status
= USBH_PassIrp(HubExtension
->LowerDevice
, Irp
);
2552 DPRINT_PNP("FDO unknown IRP_MN_???\n");
2553 Status
= USBH_PassIrp(HubExtension
->LowerDevice
, Irp
);
2557 KeReleaseSemaphore(&HubExtension
->IdleSemaphore
,
2558 LOW_REALTIME_PRIORITY
,
2564 DPRINT_PNP("USBH_FdoPnP: call USBH_CheckIdleDeferred()\n");
2565 USBH_CheckIdleDeferred(HubExtension
);
2568 HubExtension
->HubFlags
&= ~USBHUB_FDO_FLAG_STATE_CHANGING
;
2575 USBH_PdoPnP(IN PUSBHUB_PORT_PDO_EXTENSION PortExtension
,
2578 OUT BOOLEAN
* IsCompleteIrp
)
2581 PIO_STACK_LOCATION IoStack
;
2582 PPNP_BUS_INFORMATION BusInfo
;
2583 PDEVICE_CAPABILITIES DeviceCapabilities
;
2586 PUSBHUB_FDO_EXTENSION HubExtension
;
2587 PDEVICE_RELATIONS DeviceRelation
;
2589 DPRINT_PNP("USBH_PdoPnP: PortExtension - %p, Irp - %p, Minor - %X\n",
2594 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
2596 *IsCompleteIrp
= TRUE
;
2600 case IRP_MN_START_DEVICE
:
2601 DPRINT_PNP("PDO IRP_MN_START_DEVICE\n");
2602 return USBH_PdoStartDevice(PortExtension
, Irp
);
2604 case IRP_MN_QUERY_REMOVE_DEVICE
:
2605 DPRINT_PNP("PDO IRP_MN_QUERY_REMOVE_DEVICE\n");
2606 return STATUS_SUCCESS
;
2608 case IRP_MN_REMOVE_DEVICE
:
2609 DPRINT_PNP("PDO IRP_MN_REMOVE_DEVICE\n");
2610 return USBH_PdoRemoveDevice(PortExtension
, PortExtension
->HubExtension
);
2612 case IRP_MN_CANCEL_REMOVE_DEVICE
:
2613 DPRINT_PNP("PDO IRP_MN_CANCEL_REMOVE_DEVICE\n");
2614 return STATUS_SUCCESS
;
2616 case IRP_MN_STOP_DEVICE
:
2617 DPRINT_PNP("PDO IRP_MN_STOP_DEVICE\n");
2618 return USBH_PdoStopDevice(PortExtension
, Irp
);
2620 case IRP_MN_QUERY_STOP_DEVICE
:
2621 DPRINT_PNP("PDO IRP_MN_QUERY_STOP_DEVICE\n");
2622 return STATUS_SUCCESS
;
2624 case IRP_MN_CANCEL_STOP_DEVICE
:
2625 DPRINT_PNP("PDO IRP_MN_CANCEL_STOP_DEVICE\n");
2626 return STATUS_SUCCESS
;
2628 case IRP_MN_QUERY_DEVICE_RELATIONS
:
2629 DPRINT_PNP("PDO IRP_MN_QUERY_DEVICE_RELATIONS\n");
2631 if (IoStack
->Parameters
.QueryDeviceRelations
.Type
!= TargetDeviceRelation
)
2633 return Irp
->IoStatus
.Status
;
2636 DeviceRelation
= ExAllocatePoolWithTag(PagedPool
,
2637 sizeof(DEVICE_RELATIONS
),
2642 RtlZeroMemory(DeviceRelation
, sizeof(DEVICE_RELATIONS
));
2644 DeviceRelation
->Count
= 1;
2645 DeviceRelation
->Objects
[0] = PortExtension
->Common
.SelfDevice
;
2647 ObReferenceObject(DeviceRelation
->Objects
[0]);
2649 Status
= STATUS_SUCCESS
;
2653 Status
= STATUS_INSUFFICIENT_RESOURCES
;
2656 Irp
->IoStatus
.Information
= (ULONG_PTR
)DeviceRelation
;
2659 case IRP_MN_QUERY_INTERFACE
:
2660 DPRINT_PNP("PDO IRP_MN_QUERY_INTERFACE\n");
2664 if (IsEqualGUIDAligned(IoStack
->Parameters
.QueryInterface
.InterfaceType
,
2665 &USB_BUS_INTERFACE_USBDI_GUID
))
2667 IoStack
->Parameters
.QueryInterface
.InterfaceSpecificData
= PortExtension
->DeviceHandle
;
2670 HubExtension
= PortExtension
->HubExtension
;
2674 HubExtension
= PortExtension
->RootHubExtension
;
2677 Status
= USBH_PassIrp(HubExtension
->RootHubPdo
, Irp
);
2680 case IRP_MN_QUERY_CAPABILITIES
:
2681 DPRINT_PNP("PDO IRP_MN_QUERY_CAPABILITIES\n");
2683 DeviceCapabilities
= IoStack
->Parameters
.DeviceCapabilities
.Capabilities
;
2685 Size
= DeviceCapabilities
->Size
;
2686 Version
= DeviceCapabilities
->Version
;
2688 RtlCopyMemory(DeviceCapabilities
,
2689 &PortExtension
->Capabilities
,
2690 sizeof(DEVICE_CAPABILITIES
));
2692 DeviceCapabilities
->Size
= Size
;
2693 DeviceCapabilities
->Version
= Version
;
2695 Status
= STATUS_SUCCESS
;
2698 case IRP_MN_QUERY_RESOURCES
:
2699 DPRINT_PNP("PDO IRP_MN_QUERY_RESOURCES\n");
2700 Status
= Irp
->IoStatus
.Status
;
2703 case IRP_MN_QUERY_RESOURCE_REQUIREMENTS
:
2704 DPRINT_PNP("PDO IRP_MN_QUERY_RESOURCE_REQUIREMENTS\n");
2705 PortExtension
->PortPdoFlags
|= USBHUB_PDO_FLAG_ENUMERATED
;
2707 /* FIXME HKEY_LOCAL_MACHINE\SYSTEM\ControlSetXXX\Enum\USB\
2708 Vid_????&Pid_????\????????????\Device Parameters\
2709 if (ExtPropDescSemaphore)
2712 Status
= STATUS_SUCCESS
;
2715 case IRP_MN_QUERY_DEVICE_TEXT
:
2716 DPRINT_PNP("PDO IRP_MN_QUERY_DEVICE_TEXT\n");
2717 return USBH_PdoQueryDeviceText(PortExtension
, Irp
);
2719 case IRP_MN_FILTER_RESOURCE_REQUIREMENTS
:
2720 DPRINT_PNP("PDO IRP_MN_FILTER_RESOURCE_REQUIREMENTS\n");
2721 Status
= Irp
->IoStatus
.Status
;
2724 case IRP_MN_READ_CONFIG
:
2725 DPRINT_PNP("PDO IRP_MN_READ_CONFIG\n");
2727 Status
= Irp
->IoStatus
.Status
;
2730 case IRP_MN_WRITE_CONFIG
:
2731 DPRINT_PNP("PDO IRP_MN_WRITE_CONFIG\n");
2733 Status
= Irp
->IoStatus
.Status
;
2737 DPRINT_PNP("PDO IRP_MN_EJECT\n");
2739 Status
= Irp
->IoStatus
.Status
;
2742 case IRP_MN_SET_LOCK
:
2743 DPRINT_PNP("PDO IRP_MN_SET_LOCK\n");
2745 Status
= Irp
->IoStatus
.Status
;
2748 case IRP_MN_QUERY_ID
:
2749 DPRINT_PNP("PDO IRP_MN_QUERY_ID\n");
2750 return USBH_PdoQueryId(PortExtension
, Irp
);
2752 case IRP_MN_QUERY_PNP_DEVICE_STATE
:
2753 DPRINT_PNP("PDO IRP_MN_QUERY_PNP_DEVICE_STATE\n");
2754 if (PortExtension
->PortPdoFlags
& (USBHUB_PDO_FLAG_INSUFFICIENT_PWR
|
2755 USBHUB_PDO_FLAG_OVERCURRENT_PORT
|
2756 USBHUB_PDO_FLAG_PORT_RESTORE_FAIL
|
2757 USBHUB_PDO_FLAG_INIT_PORT_FAILED
))
2759 Irp
->IoStatus
.Information
|= PNP_DEVICE_FAILED
;
2762 Status
= STATUS_SUCCESS
;
2765 case IRP_MN_QUERY_BUS_INFORMATION
:
2766 DPRINT_PNP("PDO IRP_MN_QUERY_BUS_INFORMATION\n");
2768 BusInfo
= ExAllocatePoolWithTag(PagedPool
,
2769 sizeof(PNP_BUS_INFORMATION
),
2774 return STATUS_INSUFFICIENT_RESOURCES
;
2777 RtlZeroMemory(BusInfo
, sizeof(PNP_BUS_INFORMATION
));
2779 RtlCopyMemory(&BusInfo
->BusTypeGuid
,
2781 sizeof(BusInfo
->BusTypeGuid
));
2783 BusInfo
->LegacyBusType
= PNPBus
;
2784 BusInfo
->BusNumber
= 0;
2786 Irp
->IoStatus
.Information
= (ULONG_PTR
)BusInfo
;
2787 Status
= STATUS_SUCCESS
;
2790 case IRP_MN_DEVICE_USAGE_NOTIFICATION
:
2791 DPRINT_PNP("PDO IRP_MN_DEVICE_USAGE_NOTIFICATION\n");
2793 Status
= Irp
->IoStatus
.Status
;
2796 case IRP_MN_SURPRISE_REMOVAL
:
2797 DPRINT_PNP("PDO IRP_MN_SURPRISE_REMOVAL\n");
2798 if (PortExtension
->PortPdoFlags
& USBHUB_PDO_FLAG_REG_DEV_INTERFACE
)
2800 Status
= USBH_SymbolicLink(PortExtension
, NULL
, FALSE
);
2802 if (NT_SUCCESS(Status
))
2804 PortExtension
->PortPdoFlags
&= ~USBHUB_PDO_FLAG_REG_DEV_INTERFACE
;
2808 Status
= STATUS_SUCCESS
;
2812 DPRINT_PNP("PDO unknown IRP_MN_???\n");
2813 Status
= Irp
->IoStatus
.Status
;