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 if (HubExtension
->HubFlags
& USBHUB_FDO_FLAG_DEVICE_FAILED
)
1144 Status
= USBH_SyncGetPortStatus(HubExtension
,
1146 &PortData
->PortStatus
,
1147 sizeof(USB_PORT_STATUS_AND_CHANGE
));
1149 if (!NT_SUCCESS(Status
))
1151 DPRINT_ENUM("USBH_FdoQueryBusRelations: Status - %X\n", Status
);
1152 HubExtension
->HubFlags
|= USBHUB_FDO_FLAG_DEVICE_FAILED
;
1153 DeviceRelations
->Count
= 0;
1157 DPRINT_ENUM("USBH_FdoQueryBusRelations: Port - %x, ConnectStatus - %x\n",
1159 PortData
->PortStatus
.PortStatus
.Usb20PortStatus
.CurrentConnectStatus
);
1161 PdoDevice
= PortData
->DeviceObject
;
1163 if (PortData
->DeviceObject
)
1165 PdoExtension
= PdoDevice
->DeviceExtension
;
1167 if (PdoExtension
->PortPdoFlags
& USBHUB_PDO_FLAG_OVERCURRENT_PORT
)
1169 PortData
->PortStatus
.PortStatus
.Usb20PortStatus
.CurrentConnectStatus
= 1;
1173 if (HubExtension
->HubFlags
& USBHUB_FDO_FLAG_DEVICE_FAILED
)
1175 DPRINT1("USBH_FdoQueryBusRelations: DbgBreakPoint() \n");
1179 if (!PortData
->PortStatus
.PortStatus
.Usb20PortStatus
.CurrentConnectStatus
)
1183 PdoExtension
= PdoDevice
->DeviceExtension
;
1185 PdoExtension
->PortPdoFlags
|= USBHUB_PDO_FLAG_DELETE_PENDING
;
1186 PdoExtension
->EnumFlags
&= ~USBHUB_ENUM_FLAG_DEVICE_PRESENT
;
1188 SerialNumber
= InterlockedExchangePointer((PVOID
)&PdoExtension
->SerialNumber
,
1193 ExFreePoolWithTag(SerialNumber
, USB_HUB_TAG
);
1196 DeviceHandle
= InterlockedExchangePointer(&PdoExtension
->DeviceHandle
,
1201 USBD_RemoveDeviceEx(HubExtension
, DeviceHandle
, 0);
1202 USBH_SyncDisablePort(HubExtension
, Port
);
1206 PortData
->DeviceObject
= NULL
;
1207 PortData
->ConnectionStatus
= NoDeviceConnected
;
1213 ObReferenceObject(PdoDevice
);
1215 PdoDevice
->Flags
|= DO_POWER_PAGABLE
;
1216 PdoDevice
->Flags
&= ~DO_DEVICE_INITIALIZING
;
1218 DeviceRelations
->Objects
[DeviceRelations
->Count
++] = PdoDevice
;
1220 PdoExtension
= PdoDevice
->DeviceExtension
;
1221 PdoExtension
->PortPdoFlags
&= ~USBHUB_PDO_FLAG_POWER_D1_OR_D2
;
1228 NtStatus
= USBH_SyncResetPort(HubExtension
, Port
);
1230 if (!NT_SUCCESS(NtStatus
))
1232 if (HubExtension
->HubFlags
& USBHUB_FDO_FLAG_USB20_HUB
)
1234 PortData
->DeviceObject
= NULL
;
1235 PortData
->ConnectionStatus
= NoDeviceConnected
;
1241 NtStatus
= USBH_SyncGetPortStatus(HubExtension
,
1243 &PortData
->PortStatus
,
1244 sizeof(USB_PORT_STATUS_AND_CHANGE
));
1246 UsbPortStatus
= PortData
->PortStatus
.PortStatus
;
1248 if (NT_SUCCESS(NtStatus
))
1252 for (NtStatus
= USBH_CreateDevice(HubExtension
, Port
, UsbPortStatus
, ix
);
1253 !NT_SUCCESS(NtStatus
);
1254 NtStatus
= USBH_CreateDevice(HubExtension
, Port
, UsbPortStatus
, ix
))
1263 if (PortData
->DeviceObject
)
1265 IoDeleteDevice(PortData
->DeviceObject
);
1266 PortData
->DeviceObject
= NULL
;
1267 PortData
->ConnectionStatus
= NoDeviceConnected
;
1270 USBH_SyncResetPort(HubExtension
, Port
);
1275 if (NT_SUCCESS(NtStatus
))
1277 PdoExtension
= PortData
->DeviceObject
->DeviceExtension
;
1279 if (!(PdoExtension
->PortPdoFlags
& USBHUB_PDO_FLAG_PORT_LOW_SPEED
) &&
1280 !(PdoExtension
->PortPdoFlags
& USBHUB_PDO_FLAG_PORT_HIGH_SPEED
) &&
1281 !(HubExtension
->HubFlags
& USBHUB_FDO_FLAG_USB20_HUB
))
1283 DPRINT1("USBH_FdoQueryBusRelations: FIXME USBH_DeviceIs2xDualMode()\n");
1285 if (0)//USBH_DeviceIs2xDualMode(PdoExtension))
1287 PdoExtension
->PortPdoFlags
|= USBHUB_PDO_FLAG_HS_USB1_DUALMODE
;
1291 ObReferenceObject(PortData
->DeviceObject
);
1293 DeviceRelations
->Objects
[DeviceRelations
->Count
] = PortData
->DeviceObject
;
1295 PortData
->DeviceObject
->Flags
|= DO_POWER_PAGABLE
;
1296 PortData
->DeviceObject
->Flags
&= ~DO_DEVICE_INITIALIZING
;
1298 DeviceRelations
->Count
++;
1300 PortData
->ConnectionStatus
= DeviceConnected
;
1307 PortData
->ConnectionStatus
= DeviceFailedEnumeration
;
1309 if (NT_ERROR(USBH_SyncDisablePort(HubExtension
, Port
)))
1311 HubExtension
->HubFlags
|= USBHUB_FDO_FLAG_DEVICE_FAILED
;
1314 if (PortData
->DeviceObject
)
1316 ObReferenceObject(PortData
->DeviceObject
);
1317 PortData
->DeviceObject
->Flags
&= ~DO_DEVICE_INITIALIZING
;
1318 DeviceRelations
->Objects
[DeviceRelations
->Count
++] = PortData
->DeviceObject
;
1322 HubExtension
->HubFlags
&= ~USBHUB_FDO_FLAG_NOT_ENUMERATED
;
1324 KeReleaseSemaphore(&HubExtension
->ResetDeviceSemaphore
,
1325 LOW_REALTIME_PRIORITY
,
1329 if (!InterlockedDecrement(&HubExtension
->PendingRequestCount
))
1331 KeSetEvent(&HubExtension
->PendingRequestEvent
, EVENT_INCREMENT
, FALSE
);
1336 Irp
->IoStatus
.Status
= Status
;
1338 if (!NT_SUCCESS(Status
))
1340 //Irp->IoStatus.Information = 0;
1342 if (DeviceRelations
)
1344 ExFreePoolWithTag(DeviceRelations
, USB_HUB_TAG
);
1347 USBH_CompleteIrp(Irp
, Status
);
1352 KeAcquireSpinLock(&HubExtension
->RelationsWorkerSpinLock
, &OldIrql
);
1354 if (DeviceRelations
&& DeviceRelations
->Count
)
1356 for (Port
= 0; Port
< DeviceRelations
->Count
; Port
++)
1358 PdoDevice
= DeviceRelations
->Objects
[Port
];
1359 Entry
= HubExtension
->PdoList
.Flink
;
1361 while (Entry
!= &HubExtension
->PdoList
)
1363 pdoExtension
= CONTAINING_RECORD(Entry
,
1364 USBHUB_PORT_PDO_EXTENSION
,
1367 if (pdoExtension
== PdoDevice
->DeviceExtension
)
1369 PdoExt(PdoDevice
)->EnumFlags
|= USBHUB_ENUM_FLAG_GHOST_DEVICE
;
1373 Entry
= Entry
->Flink
;
1376 PdoExt(PdoDevice
)->EnumFlags
|= USBHUB_ENUM_FLAG_DEVICE_PRESENT
;
1381 for (Port
= 0; Port
< DeviceRelations
->Count
; Port
++)
1383 PdoDevice
= DeviceRelations
->Objects
[Port
];
1385 if (PdoExt(PdoDevice
)->EnumFlags
& USBHUB_ENUM_FLAG_GHOST_DEVICE
)
1387 for (GhostPort
= Port
;
1388 GhostPort
< DeviceRelations
->Count
;
1391 DeviceRelations
->Objects
[GhostPort
] =
1392 DeviceRelations
->Objects
[GhostPort
+ 1];
1395 ObDereferenceObject(PdoDevice
);
1397 DeviceRelations
->Count
--;
1399 if (PdoExt(PdoDevice
)->EnumFlags
& USBHUB_ENUM_FLAG_DEVICE_PRESENT
)
1401 PdoExt(PdoDevice
)->EnumFlags
&= ~USBHUB_ENUM_FLAG_GHOST_DEVICE
;
1407 Irp
->IoStatus
.Information
= (ULONG_PTR
)DeviceRelations
;
1409 InitializeListHead(&GhostPdoList
);
1410 PdoList
= &HubExtension
->PdoList
;
1412 while (!IsListEmpty(PdoList
))
1414 Entry
= RemoveHeadList(PdoList
);
1416 PdoExtension
= CONTAINING_RECORD(Entry
,
1417 USBHUB_PORT_PDO_EXTENSION
,
1420 PdoExtension
->EnumFlags
&= ~USBHUB_ENUM_FLAG_DEVICE_PRESENT
;
1422 if (PdoExtension
->EnumFlags
& USBHUB_ENUM_FLAG_GHOST_DEVICE
)
1424 InsertTailList(&GhostPdoList
, &PdoExtension
->PortLink
);
1428 KeReleaseSpinLock(&HubExtension
->RelationsWorkerSpinLock
, OldIrql
);
1430 while (!IsListEmpty(&GhostPdoList
))
1432 Entry
= RemoveHeadList(&GhostPdoList
);
1434 PdoExtension
= CONTAINING_RECORD(Entry
,
1435 USBHUB_PORT_PDO_EXTENSION
,
1438 IoDeleteDevice(PdoExtension
->Common
.SelfDevice
);
1441 return USBH_PassIrp(HubExtension
->LowerDevice
, Irp
);
1446 USBH_FdoStopDevice(IN PUSBHUB_FDO_EXTENSION HubExtension
,
1449 DPRINT1("USBH_FdoStopDevice: UNIMPLEMENTED. FIXME\n");
1451 return STATUS_SUCCESS
;
1456 USBH_FdoRemoveDevice(IN PUSBHUB_FDO_EXTENSION HubExtension
,
1459 PUSB_HUB_DESCRIPTOR HubDescriptor
;
1460 PUSBHUB_PORT_DATA PortData
;
1463 PDEVICE_OBJECT PortDevice
;
1464 PUSBHUB_PORT_PDO_EXTENSION PortExtension
;
1467 DPRINT("USBH_FdoRemoveDevice: HubExtension - %p\n", HubExtension
);
1469 HubDescriptor
= HubExtension
->HubDescriptor
;
1471 if (HubDescriptor
&& HubExtension
->PortData
)
1473 NumPorts
= HubDescriptor
->bNumberOfPorts
;
1475 for (ix
= 0; ix
< NumPorts
; ++ix
)
1477 PortData
= HubExtension
->PortData
+ ix
;
1479 PortDevice
= PortData
->DeviceObject
;
1483 PortData
->PortStatus
.AsUlong32
= 0;
1484 PortData
->DeviceObject
= NULL
;
1486 PortExtension
= PortDevice
->DeviceExtension
;
1487 PortExtension
->EnumFlags
&= ~USBHUB_ENUM_FLAG_DEVICE_PRESENT
;
1489 USBH_PdoRemoveDevice(PortExtension
, HubExtension
);
1494 if (HubExtension
->HubFlags
& USBHUB_FDO_FLAG_DEVICE_STARTED
)
1496 USBH_FdoCleanup(HubExtension
);
1499 if (HubExtension
->PortData
)
1501 ExFreePoolWithTag(HubExtension
->PortData
, USB_HUB_TAG
);
1502 HubExtension
->PortData
= NULL
;
1505 DPRINT1("USBH_FdoRemoveDevice: call IoWMIRegistrationControl UNIMPLEMENTED. FIXME\n");
1507 Status
= USBH_PassIrp(HubExtension
->LowerDevice
, Irp
);
1509 IoDetachDevice(HubExtension
->LowerDevice
);
1510 IoDeleteDevice(HubExtension
->Common
.SelfDevice
);
1517 USBH_FdoSurpriseRemoveDevice(IN PUSBHUB_FDO_EXTENSION HubExtension
,
1520 PUSBHUB_PORT_PDO_EXTENSION PortExtension
;
1521 PUSBHUB_PORT_DATA PortData
;
1525 DPRINT("USBH_FdoSurpriseRemoveDevice: HubExtension - %p, Irp - %p\n",
1529 if (!HubExtension
->PortData
||
1530 !HubExtension
->HubDescriptor
)
1535 PortData
= HubExtension
->PortData
;
1536 NumberPorts
= HubExtension
->HubDescriptor
->bNumberOfPorts
;
1538 for (Port
= 0; Port
< NumberPorts
; Port
++)
1540 if (PortData
[Port
].DeviceObject
)
1542 PortExtension
= PdoExt(PortData
[Port
].DeviceObject
);
1543 PortExtension
->PortPdoFlags
|= USBHUB_PDO_FLAG_DELETE_PENDING
;
1544 PortExtension
->EnumFlags
&= ~USBHUB_ENUM_FLAG_DEVICE_PRESENT
;
1546 PortData
[Port
].DeviceObject
= NULL
;
1547 PortData
[Port
].ConnectionStatus
= NoDeviceConnected
;
1554 USBH_PdoQueryId(IN PUSBHUB_PORT_PDO_EXTENSION PortExtension
,
1560 size_t Remaining
= sizeof(Buffer
);
1563 NTSTATUS Status
= STATUS_SUCCESS
;
1564 PUSB_DEVICE_DESCRIPTOR DeviceDescriptor
;
1565 PUSB_INTERFACE_DESCRIPTOR InterfaceDescriptor
;
1567 IdType
= IoGetCurrentIrpStackLocation(Irp
)->Parameters
.QueryId
.IdType
;
1568 DeviceDescriptor
= &PortExtension
->DeviceDescriptor
;
1569 InterfaceDescriptor
= &PortExtension
->InterfaceDescriptor
;
1571 RtlZeroMemory(Buffer
, sizeof(Buffer
));
1575 case BusQueryDeviceID
:
1576 DPRINT("USBH_PdoQueryId: BusQueryDeviceID\n");
1578 if (PortExtension
->PortPdoFlags
& USBHUB_PDO_FLAG_INIT_PORT_FAILED
)
1580 DPRINT("USBH_PdoQueryId: USBHUB_PDO_FLAG_INIT_PORT_FAILED\n");
1581 RtlStringCbPrintfExW(Buffer
,
1586 L
"USB\\Vid_0000&Pid_0000");
1590 RtlStringCbPrintfExW(Buffer
,
1595 L
"USB\\Vid_%04x&Pid_%04x",
1596 DeviceDescriptor
->idVendor
,
1597 DeviceDescriptor
->idProduct
);
1600 Length
= sizeof(Buffer
) - (Remaining
- sizeof(UNICODE_NULL
));
1602 Id
= ExAllocatePoolWithTag(PagedPool
, Length
, USB_HUB_TAG
);
1609 RtlCopyMemory(Id
, Buffer
, Length
);
1610 DPRINT("USBH_PdoQueryId: BusQueryDeviceID - %S\n", Id
);
1613 case BusQueryHardwareIDs
:
1614 DPRINT("USBH_PdoQueryId: BusQueryHardwareIDs\n");
1616 if (PortExtension
->PortPdoFlags
& USBHUB_PDO_FLAG_INIT_PORT_FAILED
)
1618 DPRINT("USBH_PdoQueryId: USBHUB_PDO_FLAG_INIT_PORT_FAILED\n");
1620 RtlStringCbPrintfExW(Buffer
,
1629 RtlStringCbPrintfExW(Buffer
,
1634 L
"USB\\Vid_%04x&Pid_%04x&Rev_%04x",
1635 DeviceDescriptor
->idVendor
,
1636 DeviceDescriptor
->idProduct
,
1637 DeviceDescriptor
->bcdDevice
);
1640 Remaining
-= sizeof(UNICODE_NULL
);
1642 RtlStringCbPrintfExW(EndBuffer
,
1647 L
"USB\\Vid_%04x&Pid_%04x",
1648 DeviceDescriptor
->idVendor
,
1649 DeviceDescriptor
->idProduct
);
1652 Length
= sizeof(Buffer
) - (Remaining
- 2 * sizeof(UNICODE_NULL
));
1654 Id
= ExAllocatePoolWithTag(PagedPool
, Length
, USB_HUB_TAG
);
1661 RtlCopyMemory(Id
, Buffer
, Length
);
1663 if (PortExtension
->PortPdoFlags
& USBHUB_PDO_FLAG_INIT_PORT_FAILED
)
1665 DPRINT("USBH_PdoQueryId: BusQueryHardwareID - %S\n", Id
);
1669 USBHUB_DumpingIDs(Id
);
1674 case BusQueryCompatibleIDs
:
1675 DPRINT("USBH_PdoQueryId: BusQueryCompatibleIDs\n");
1677 if (PortExtension
->PortPdoFlags
& USBHUB_PDO_FLAG_INIT_PORT_FAILED
)
1679 DPRINT("USBH_PdoQueryId: USBHUB_PDO_FLAG_INIT_PORT_FAILED\n");
1681 RtlStringCbPrintfExW(Buffer
,
1688 else if (PortExtension
->PortPdoFlags
& USBHUB_PDO_FLAG_MULTI_INTERFACE
)
1690 RtlStringCbPrintfExW(Buffer
,
1695 L
"USB\\DevClass_%02x&SubClass_%02x&Prot_%02x",
1696 InterfaceDescriptor
->bInterfaceClass
,
1697 InterfaceDescriptor
->bInterfaceSubClass
,
1698 InterfaceDescriptor
->bInterfaceProtocol
);
1701 Remaining
-= sizeof(UNICODE_NULL
);
1703 RtlStringCbPrintfExW(EndBuffer
,
1708 L
"USB\\DevClass_%02x&SubClass_%02x",
1709 InterfaceDescriptor
->bInterfaceClass
,
1710 InterfaceDescriptor
->bInterfaceSubClass
);
1713 Remaining
-= sizeof(UNICODE_NULL
);
1715 RtlStringCbPrintfExW(EndBuffer
,
1720 L
"USB\\DevClass_%02x",
1721 InterfaceDescriptor
->bInterfaceClass
);
1724 Remaining
-= sizeof(UNICODE_NULL
);
1726 RtlStringCbPrintfExW(EndBuffer
,
1735 RtlStringCbPrintfExW(Buffer
,
1740 L
"USB\\Class_%02x&SubClass_%02x&Prot_%02x",
1741 InterfaceDescriptor
->bInterfaceClass
,
1742 InterfaceDescriptor
->bInterfaceSubClass
,
1743 InterfaceDescriptor
->bInterfaceProtocol
);
1746 Remaining
-= sizeof(UNICODE_NULL
);
1748 RtlStringCbPrintfExW(EndBuffer
,
1753 L
"USB\\Class_%02x&SubClass_%02x",
1754 InterfaceDescriptor
->bInterfaceClass
,
1755 InterfaceDescriptor
->bInterfaceSubClass
);
1758 Remaining
-= sizeof(UNICODE_NULL
);
1760 RtlStringCbPrintfExW(EndBuffer
,
1766 InterfaceDescriptor
->bInterfaceClass
);
1769 Length
= sizeof(Buffer
) - (Remaining
- 2 * sizeof(UNICODE_NULL
));
1771 Id
= ExAllocatePoolWithTag(PagedPool
, Length
, USB_HUB_TAG
);
1778 RtlCopyMemory(Id
, Buffer
, Length
);
1780 if (PortExtension
->PortPdoFlags
& USBHUB_PDO_FLAG_INIT_PORT_FAILED
)
1782 DPRINT("USBH_PdoQueryId: BusQueryCompatibleID - %S\n", Id
);
1786 USBHUB_DumpingIDs(Id
);
1791 case BusQueryInstanceID
:
1792 DPRINT("USBH_PdoQueryId: BusQueryInstanceID\n");
1794 if (PortExtension
->SerialNumber
)
1796 Id
= ExAllocatePoolWithTag(PagedPool
,
1797 PortExtension
->SN_DescriptorLength
,
1802 RtlZeroMemory(Id
, PortExtension
->SN_DescriptorLength
);
1805 PortExtension
->SerialNumber
,
1806 PortExtension
->SN_DescriptorLength
);
1811 Length
= sizeof(PortExtension
->InstanceID
) +
1812 sizeof(UNICODE_NULL
);
1814 Id
= ExAllocatePoolWithTag(PagedPool
, Length
, USB_HUB_TAG
);
1818 RtlZeroMemory(Id
, Length
);
1821 PortExtension
->InstanceID
,
1822 sizeof(PortExtension
->InstanceID
));
1826 DPRINT("USBH_PdoQueryId: BusQueryInstanceID - %S\n", Id
);
1830 DPRINT1("USBH_PdoQueryId: unknown query id type 0x%lx\n", IdType
);
1831 return Irp
->IoStatus
.Status
;
1834 Irp
->IoStatus
.Information
= (ULONG_PTR
)Id
;
1838 Status
= STATUS_INSUFFICIENT_RESOURCES
;
1846 USBH_PdoQueryDeviceText(IN PUSBHUB_PORT_PDO_EXTENSION PortExtension
,
1849 PDEVICE_OBJECT DeviceObject
;
1850 PIO_STACK_LOCATION IoStack
;
1851 DEVICE_TEXT_TYPE DeviceTextType
;
1854 PUSB_STRING_DESCRIPTOR Descriptor
;
1861 DPRINT("USBH_PdoQueryDeviceText ... \n");
1863 DeviceObject
= PortExtension
->Common
.SelfDevice
;
1864 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
1865 DeviceTextType
= IoStack
->Parameters
.QueryDeviceText
.DeviceTextType
;
1867 if (DeviceTextType
!= DeviceTextDescription
&&
1868 DeviceTextType
!= DeviceTextLocationInformation
)
1870 return Irp
->IoStatus
.Status
;
1873 LanguageId
= LANGIDFROMLCID(IoStack
->Parameters
.QueryDeviceText
.LocaleId
);
1874 DefaultId
= MAKELANGID(LANG_ENGLISH
, SUBLANG_ENGLISH_US
);
1878 LanguageId
= DefaultId
;
1881 iProduct
= PortExtension
->DeviceDescriptor
.iProduct
;
1883 if (PortExtension
->DeviceHandle
&& iProduct
&&
1884 !PortExtension
->IgnoringHwSerial
&&
1885 !(PortExtension
->PortPdoFlags
& USBHUB_PDO_FLAG_INIT_PORT_FAILED
))
1887 Descriptor
= ExAllocatePoolWithTag(NonPagedPool
,
1888 MAXIMUM_USB_STRING_LENGTH
,
1893 RtlZeroMemory(Descriptor
, MAXIMUM_USB_STRING_LENGTH
);
1895 for (Status
= USBH_CheckDeviceLanguage(DeviceObject
, LanguageId
);
1897 Status
= USBH_CheckDeviceLanguage(DeviceObject
, DefaultId
))
1899 if (NT_SUCCESS(Status
))
1901 Status
= USBH_SyncGetStringDescriptor(DeviceObject
,
1905 MAXIMUM_USB_STRING_LENGTH
,
1909 if (NT_SUCCESS(Status
))
1915 if (LanguageId
== DefaultId
)
1920 LanguageId
= DefaultId
;
1923 if (Descriptor
->bLength
<= sizeof(USB_COMMON_DESCRIPTOR
))
1925 Status
= STATUS_UNSUCCESSFUL
;
1928 if (NT_SUCCESS(Status
))
1930 Length
= Descriptor
->bLength
-
1931 FIELD_OFFSET(USB_STRING_DESCRIPTOR
, bString
);
1933 DeviceText
= ExAllocatePoolWithTag(PagedPool
,
1934 Length
+ sizeof(UNICODE_NULL
),
1939 RtlZeroMemory(DeviceText
, Length
+ sizeof(UNICODE_NULL
));
1941 RtlCopyMemory(DeviceText
, Descriptor
->bString
, Length
);
1943 Irp
->IoStatus
.Information
= (ULONG_PTR
)DeviceText
;
1945 DPRINT("USBH_PdoQueryDeviceText: Descriptor->bString - %S\n",
1950 Status
= STATUS_INSUFFICIENT_RESOURCES
;
1956 ExFreePoolWithTag(Descriptor
, USB_HUB_TAG
);
1958 if (NT_SUCCESS(Status
))
1965 Status
= STATUS_INSUFFICIENT_RESOURCES
;
1970 Status
= STATUS_NOT_SUPPORTED
;
1973 if (!GenericUSBDeviceString
)
1978 NumSymbols
= wcslen(GenericUSBDeviceString
);
1979 Length
= (NumSymbols
+ 1) * sizeof(WCHAR
);
1981 DeviceText
= ExAllocatePoolWithTag(PagedPool
, Length
, USB_HUB_TAG
);
1985 return STATUS_INSUFFICIENT_RESOURCES
;
1988 RtlZeroMemory(DeviceText
, Length
);
1990 RtlCopyMemory(DeviceText
,
1991 GenericUSBDeviceString
,
1992 NumSymbols
* sizeof(WCHAR
));
1994 Irp
->IoStatus
.Information
= (ULONG_PTR
)DeviceText
;
1996 return STATUS_SUCCESS
;
2001 USBH_SymbolicLink(IN PUSBHUB_PORT_PDO_EXTENSION PortExtension
,
2002 IN
const GUID
* InterfaceClassGuid
,
2003 IN BOOLEAN IsEnable
)
2005 NTSTATUS Status
= STATUS_SUCCESS
;
2008 DPRINT("USBH_SymbolicLink ... \n");
2012 Status
= IoRegisterDeviceInterface(PortExtension
->Common
.SelfDevice
,
2015 &PortExtension
->SymbolicLinkName
);
2017 if (NT_SUCCESS(Status
))
2019 USBH_SetPdoRegistryParameter(PortExtension
->Common
.SelfDevice
,
2021 PortExtension
->SymbolicLinkName
.Buffer
,
2022 PortExtension
->SymbolicLinkName
.Length
,
2024 PLUGPLAY_REGKEY_DEVICE
);
2026 Status
= IoSetDeviceInterfaceState(&PortExtension
->SymbolicLinkName
,
2032 NameBuffer
= PortExtension
->SymbolicLinkName
.Buffer
;
2036 Status
= IoSetDeviceInterfaceState(&PortExtension
->SymbolicLinkName
,
2039 ExFreePool(PortExtension
->SymbolicLinkName
.Buffer
);
2041 PortExtension
->SymbolicLinkName
.Buffer
= NULL
;
2050 USBH_RestoreDevice(IN PUSBHUB_PORT_PDO_EXTENSION PortExtension
,
2051 IN BOOLEAN IsKeepDeviceData
)
2053 PUSBHUB_FDO_EXTENSION HubExtension
;
2054 PUSBHUB_PORT_DATA PortData
;
2058 DPRINT("USBH_RestoreDevice ... \n");
2060 HubExtension
= PortExtension
->HubExtension
;
2064 Status
= STATUS_UNSUCCESSFUL
;
2068 ASSERT(PortExtension
->PortNumber
> 0);
2069 PortData
= &HubExtension
->PortData
[PortExtension
->PortNumber
- 1];
2071 if (PortExtension
->Common
.SelfDevice
== PortData
->DeviceObject
)
2073 Status
= STATUS_UNSUCCESSFUL
;
2077 Status
= USBH_SyncGetPortStatus(HubExtension
,
2078 PortExtension
->PortNumber
,
2079 &PortData
->PortStatus
,
2080 sizeof(USB_PORT_STATUS_AND_CHANGE
));
2082 if (NT_SUCCESS(Status
))
2084 for (ix
= 0; ix
< 3; ix
++)
2086 Status
= USBH_ResetDevice((PUSBHUB_FDO_EXTENSION
)HubExtension
,
2087 PortExtension
->PortNumber
,
2091 if (NT_SUCCESS(Status
) || Status
== STATUS_NO_SUCH_DEVICE
)
2100 PortExtension
->PortPdoFlags
&= ~USBHUB_PDO_FLAG_POWER_D3
;
2102 if (NT_SUCCESS(Status
))
2104 PortExtension
->PortPdoFlags
&= ~USBHUB_PDO_FLAG_PORT_RESTORE_FAIL
;
2108 PortExtension
->PortPdoFlags
|= (USBHUB_PDO_FLAG_INIT_PORT_FAILED
|
2109 USBHUB_PDO_FLAG_PORT_RESTORE_FAIL
);
2117 USBH_PdoStartDevice(IN PUSBHUB_PORT_PDO_EXTENSION PortExtension
,
2120 PUSBHUB_FDO_EXTENSION HubExtension
;
2124 DPRINT("USBH_PdoStartDevice: PortExtension - %p\n", PortExtension
);
2126 if (!PortExtension
->HubExtension
&&
2127 PortExtension
->PortPdoFlags
& USBHUB_PDO_FLAG_POWER_D3
)
2129 PortExtension
->HubExtension
= PortExtension
->RootHubExtension
;
2132 HubExtension
= PortExtension
->HubExtension
;
2136 USBHUB_SetDeviceHandleData(HubExtension
,
2137 PortExtension
->Common
.SelfDevice
,
2138 PortExtension
->DeviceHandle
);
2141 if (PortExtension
->PortPdoFlags
& USBHUB_PDO_FLAG_HUB_DEVICE
)
2143 Guid
= &GUID_DEVINTERFACE_USB_HUB
;
2147 Guid
= &GUID_DEVINTERFACE_USB_DEVICE
;
2150 Status
= USBH_SymbolicLink(PortExtension
, Guid
, TRUE
);
2152 if (NT_SUCCESS(Status
))
2154 PortExtension
->PortPdoFlags
|= USBHUB_PDO_FLAG_REG_DEV_INTERFACE
;
2157 if (PortExtension
->PortPdoFlags
& USBHUB_PDO_FLAG_POWER_D3
)
2159 Status
= USBH_RestoreDevice(PortExtension
, 0);
2162 PortExtension
->PortPdoFlags
|= USBHUB_PDO_FLAG_DEVICE_STARTED
;
2164 PortExtension
->CurrentPowerState
.DeviceState
= PowerDeviceD0
;
2166 DPRINT1("USBH_PdoStartDevice: call IoWMIRegistrationControl UNIMPLEMENTED. FIXME\n");
2173 USBH_PdoRemoveDevice(IN PUSBHUB_PORT_PDO_EXTENSION PortExtension
,
2174 IN PUSBHUB_FDO_EXTENSION HubExtension
)
2176 NTSTATUS Status
= STATUS_SUCCESS
;
2177 PDEVICE_OBJECT PortDevice
;
2178 PUSBHUB_PORT_PDO_EXTENSION PortExt
;
2179 PUSBHUB_PORT_DATA PortData
;
2180 PIRP IdleNotificationIrp
;
2188 DPRINT("USBH_PdoRemoveDevice ... \n");
2190 PortDevice
= PortExtension
->Common
.SelfDevice
;
2191 PortExtension
->HubExtension
= NULL
;
2193 Port
= PortExtension
->PortNumber
;
2196 ASSERT(HubExtension
);
2198 if (HubExtension
->CurrentPowerState
.DeviceState
!= PowerDeviceD0
&&
2199 (HubExtension
->HubFlags
& USBHUB_FDO_FLAG_DEVICE_STARTED
) != 0)
2201 USBH_HubSetD0(HubExtension
);
2204 IoAcquireCancelSpinLock(&Irql
);
2205 IdleNotificationIrp
= PortExtension
->IdleNotificationIrp
;
2207 if (IdleNotificationIrp
)
2209 PortExtension
->IdleNotificationIrp
= NULL
;
2210 PortExtension
->PortPdoFlags
&= ~USBHUB_PDO_FLAG_IDLE_NOTIFICATION
;
2212 if (IdleNotificationIrp
->Cancel
)
2214 IdleNotificationIrp
= NULL
;
2217 if (IdleNotificationIrp
)
2219 IoSetCancelRoutine(IdleNotificationIrp
, NULL
);
2223 WakeIrp
= PortExtension
->PdoWaitWakeIrp
;
2227 PortExtension
->PdoWaitWakeIrp
= NULL
;
2228 PortExtension
->PortPdoFlags
&= ~USBHUB_PDO_FLAG_WAIT_WAKE
;
2230 if (WakeIrp
->Cancel
|| !IoSetCancelRoutine(WakeIrp
, NULL
))
2234 if (!InterlockedDecrement(&HubExtension
->PendingRequestCount
))
2236 KeSetEvent(&HubExtension
->PendingRequestEvent
,
2243 IoReleaseCancelSpinLock(Irql
);
2245 if (IdleNotificationIrp
)
2247 IdleNotificationIrp
->IoStatus
.Status
= STATUS_CANCELLED
;
2248 IoCompleteRequest(IdleNotificationIrp
, IO_NO_INCREMENT
);
2253 USBH_CompletePowerIrp(HubExtension
, WakeIrp
, STATUS_CANCELLED
);
2256 PortExtension
->PortPdoFlags
|= USBHUB_PDO_FLAG_POWER_D3
;
2258 if (PortExtension
->PortPdoFlags
& USBHUB_PDO_FLAG_REG_DEV_INTERFACE
)
2260 Status
= USBH_SymbolicLink(PortExtension
, NULL
, FALSE
);
2262 if (NT_SUCCESS(Status
))
2264 PortExtension
->PortPdoFlags
&= ~USBHUB_PDO_FLAG_REG_DEV_INTERFACE
;
2268 DeviceHandle
= InterlockedExchangePointer(&PortExtension
->DeviceHandle
,
2273 Status
= USBD_RemoveDeviceEx(HubExtension
, DeviceHandle
, 0);
2275 if (HubExtension
->PortData
&&
2276 HubExtension
->PortData
[Port
- 1].DeviceObject
== PortDevice
)
2278 USBH_SyncDisablePort(HubExtension
, Port
);
2282 if (NT_SUCCESS(Status
))
2284 PortExtension
->PortPdoFlags
&= ~USBHUB_PDO_FLAG_DEVICE_STARTED
;
2286 if (HubExtension
->PortData
)
2288 PortData
= &HubExtension
->PortData
[Port
- 1];
2290 if (PortExtension
->PortPdoFlags
& USBHUB_PDO_FLAG_DELETE_PENDING
)
2292 Pdo
= PortData
->DeviceObject
;
2296 PortData
->DeviceObject
= NULL
;
2297 PortData
->ConnectionStatus
= NoDeviceConnected
;
2299 if (PdoExt(Pdo
)->EnumFlags
& USBHUB_ENUM_FLAG_DEVICE_PRESENT
)
2301 PortExt
= PdoExt(Pdo
);
2303 InsertTailList(&HubExtension
->PdoList
,
2304 &PortExt
->PortLink
);
2310 if (!(PortExtension
->EnumFlags
& USBHUB_ENUM_FLAG_DEVICE_PRESENT
) &&
2311 !(PortExtension
->PortPdoFlags
& USBHUB_PDO_FLAG_NOT_CONNECTED
))
2313 PortExtension
->PortPdoFlags
|= USBHUB_PDO_FLAG_NOT_CONNECTED
;
2315 SerialNumber
= InterlockedExchangePointer((PVOID
)&PortExtension
->SerialNumber
,
2320 ExFreePoolWithTag(SerialNumber
, USB_HUB_TAG
);
2323 DPRINT1("USBH_PdoRemoveDevice: call IoWMIRegistrationControl UNIMPLEMENTED. FIXME\n");
2325 USBHUB_FlushAllTransfers(HubExtension
);
2327 IoDeleteDevice(PortDevice
);
2331 DPRINT("USBH_PdoRemoveDevice: call USBH_CheckIdleDeferred()\n");
2332 USBH_CheckIdleDeferred(HubExtension
);
2339 USBH_PdoStopDevice(IN PUSBHUB_PORT_PDO_EXTENSION PortExtension
,
2342 DPRINT1("USBH_PdoStopDevice: UNIMPLEMENTED. FIXME\n");
2344 return STATUS_SUCCESS
;
2349 USBH_FdoPnP(IN PUSBHUB_FDO_EXTENSION HubExtension
,
2354 PIO_STACK_LOCATION IoStack
;
2355 DEVICE_RELATION_TYPE RelationsType
;
2356 BOOLEAN IsCheckIdle
;
2358 DPRINT_PNP("USBH_FdoPnP: HubExtension - %p, Irp - %p, Minor - %X\n",
2363 if (HubExtension
->HubFlags
& USBHUB_FDO_FLAG_WAIT_IDLE_REQUEST
&&
2364 (Minor
== IRP_MN_REMOVE_DEVICE
|| Minor
== IRP_MN_STOP_DEVICE
))
2366 HubExtension
->HubFlags
|= USBHUB_FDO_FLAG_DEVICE_SUSPENDED
;
2369 KeWaitForSingleObject(&HubExtension
->IdleSemaphore
,
2375 DPRINT_PNP("USBH_FdoPnP: HubFlags - %lX\n", HubExtension
->HubFlags
);
2377 if (HubExtension
->HubFlags
& USBHUB_FDO_FLAG_GOING_IDLE
)
2379 HubExtension
->HubFlags
|= USBHUB_FDO_FLAG_DEVICE_SUSPENDED
;
2382 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
2383 RelationsType
= IoStack
->Parameters
.QueryDeviceRelations
.Type
;
2385 if ((HubExtension
->CurrentPowerState
.DeviceState
== PowerDeviceD0
) ||
2386 !(HubExtension
->HubFlags
& (USBHUB_FDO_FLAG_DEVICE_STOPPED
| USBHUB_FDO_FLAG_DEVICE_STARTED
)) ||
2387 (Minor
== IRP_MN_QUERY_DEVICE_RELATIONS
&& RelationsType
== TargetDeviceRelation
))
2389 IsCheckIdle
= FALSE
;
2393 DPRINT_PNP("USBH_FdoPnP: IsCheckIdle - TRUE\n");
2395 USBH_HubSetD0(HubExtension
);
2400 case IRP_MN_START_DEVICE
:
2401 DPRINT_PNP("FDO IRP_MN_START_DEVICE\n");
2402 IsCheckIdle
= FALSE
;
2403 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
2404 Status
= USBH_FdoStartDevice(HubExtension
, Irp
);
2407 case IRP_MN_QUERY_REMOVE_DEVICE
:
2408 DPRINT_PNP("FDO IRP_MN_QUERY_REMOVE_DEVICE\n");
2409 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
2410 Status
= USBH_PassIrp(HubExtension
->LowerDevice
, Irp
);
2413 case IRP_MN_REMOVE_DEVICE
:
2414 DPRINT_PNP("FDO IRP_MN_REMOVE_DEVICE\n");
2415 IsCheckIdle
= FALSE
;
2416 HubExtension
->HubFlags
|= USBHUB_FDO_FLAG_DEVICE_REMOVED
;
2417 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
2418 Status
= USBH_FdoRemoveDevice(HubExtension
, Irp
);
2421 case IRP_MN_CANCEL_REMOVE_DEVICE
:
2422 DPRINT_PNP("FDO IRP_MN_CANCEL_REMOVE_DEVICE\n");
2423 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
2424 Status
= USBH_PassIrp(HubExtension
->LowerDevice
, Irp
);
2427 case IRP_MN_STOP_DEVICE
:
2428 DPRINT_PNP("FDO IRP_MN_STOP_DEVICE\n");
2429 IsCheckIdle
= FALSE
;
2430 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
2431 Status
= USBH_FdoStopDevice(HubExtension
, Irp
);
2434 case IRP_MN_QUERY_STOP_DEVICE
:
2435 DPRINT_PNP("FDO IRP_MN_QUERY_STOP_DEVICE\n");
2436 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
2437 Status
= USBH_PassIrp(HubExtension
->LowerDevice
, Irp
);
2440 case IRP_MN_CANCEL_STOP_DEVICE
:
2441 DPRINT_PNP("FDO IRP_MN_CANCEL_STOP_DEVICE\n");
2442 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
2443 Status
= USBH_PassIrp(HubExtension
->LowerDevice
, Irp
);
2446 case IRP_MN_QUERY_DEVICE_RELATIONS
:
2447 DPRINT_PNP("FDO IRP_MN_QUERY_DEVICE_RELATIONS\n");
2449 if (RelationsType
!= BusRelations
)
2451 Status
= USBH_PassIrp(HubExtension
->LowerDevice
, Irp
);
2455 HubExtension
->HubFlags
|= USBHUB_FDO_FLAG_HUB_BUSY
;
2458 DPRINT_PNP("USBH_FdoPnP: IsCheckIdle - TRUE\n");
2460 Status
= USBH_FdoQueryBusRelations(HubExtension
, Irp
);
2462 HubExtension
->HubFlags
&= ~USBHUB_FDO_FLAG_HUB_BUSY
;
2465 case IRP_MN_QUERY_INTERFACE
:
2466 DPRINT_PNP("FDO IRP_MN_QUERY_INTERFACE\n");
2467 Status
= USBH_PassIrp(HubExtension
->LowerDevice
, Irp
);
2470 case IRP_MN_QUERY_CAPABILITIES
:
2471 DPRINT_PNP("FDO IRP_MN_QUERY_CAPABILITIES\n");
2472 IoCopyCurrentIrpStackLocationToNext(Irp
);
2474 IoSetCompletionRoutine(Irp
,
2475 USBH_QueryCapsComplete
,
2481 Status
= IoCallDriver(HubExtension
->LowerDevice
, Irp
);
2484 case IRP_MN_QUERY_RESOURCES
:
2485 DPRINT_PNP("FDO IRP_MN_QUERY_RESOURCES\n");
2486 Status
= USBH_PassIrp(HubExtension
->LowerDevice
, Irp
);
2489 case IRP_MN_QUERY_RESOURCE_REQUIREMENTS
:
2490 DPRINT_PNP("FDO IRP_MN_QUERY_RESOURCE_REQUIREMENTS\n");
2491 Status
= USBH_PassIrp(HubExtension
->LowerDevice
, Irp
);
2494 case IRP_MN_QUERY_DEVICE_TEXT
:
2495 DPRINT_PNP("FDO IRP_MN_QUERY_DEVICE_TEXT\n");
2496 Status
= USBH_PassIrp(HubExtension
->LowerDevice
, Irp
);
2499 case IRP_MN_FILTER_RESOURCE_REQUIREMENTS
:
2500 DPRINT_PNP("FDO IRP_MN_FILTER_RESOURCE_REQUIREMENTS\n");
2501 Status
= USBH_PassIrp(HubExtension
->LowerDevice
, Irp
);
2504 case IRP_MN_READ_CONFIG
:
2505 DPRINT_PNP("FDO IRP_MN_READ_CONFIG\n");
2506 Status
= USBH_PassIrp(HubExtension
->LowerDevice
, Irp
);
2509 case IRP_MN_WRITE_CONFIG
:
2510 DPRINT_PNP("FDO IRP_MN_WRITE_CONFIG\n");
2511 Status
= USBH_PassIrp(HubExtension
->LowerDevice
, Irp
);
2515 DPRINT_PNP("FDO IRP_MN_EJECT\n");
2516 Status
= USBH_PassIrp(HubExtension
->LowerDevice
, Irp
);
2519 case IRP_MN_SET_LOCK
:
2520 DPRINT_PNP("FDO IRP_MN_SET_LOCK\n");
2521 Status
= USBH_PassIrp(HubExtension
->LowerDevice
, Irp
);
2524 case IRP_MN_QUERY_ID
:
2525 DPRINT_PNP("FDO IRP_MN_QUERY_ID\n");
2526 Status
= USBH_PassIrp(HubExtension
->LowerDevice
, Irp
);
2529 case IRP_MN_QUERY_PNP_DEVICE_STATE
:
2530 DPRINT_PNP("FDO IRP_MN_QUERY_PNP_DEVICE_STATE\n");
2532 if (HubExtension
->HubFlags
& USBHUB_FDO_FLAG_DEVICE_FAILED
)
2534 Irp
->IoStatus
.Information
|= PNP_DEVICE_FAILED
;
2537 Status
= USBH_PassIrp(HubExtension
->LowerDevice
, Irp
);
2540 case IRP_MN_QUERY_BUS_INFORMATION
:
2541 DPRINT_PNP("FDO IRP_MN_QUERY_BUS_INFORMATION\n");
2542 Status
= USBH_PassIrp(HubExtension
->LowerDevice
, Irp
);
2545 case IRP_MN_DEVICE_USAGE_NOTIFICATION
:
2546 DPRINT_PNP("FDO IRP_MN_DEVICE_USAGE_NOTIFICATION\n");
2547 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
2548 Status
= USBH_PassIrp(HubExtension
->LowerDevice
, Irp
);
2551 case IRP_MN_SURPRISE_REMOVAL
:
2552 DPRINT_PNP("FDO IRP_MN_SURPRISE_REMOVAL\n");
2553 USBH_FdoSurpriseRemoveDevice(HubExtension
, Irp
);
2554 Status
= USBH_PassIrp(HubExtension
->LowerDevice
, Irp
);
2558 DPRINT_PNP("FDO unknown IRP_MN_???\n");
2559 Status
= USBH_PassIrp(HubExtension
->LowerDevice
, Irp
);
2563 KeReleaseSemaphore(&HubExtension
->IdleSemaphore
,
2564 LOW_REALTIME_PRIORITY
,
2570 DPRINT_PNP("USBH_FdoPnP: call USBH_CheckIdleDeferred()\n");
2571 USBH_CheckIdleDeferred(HubExtension
);
2574 HubExtension
->HubFlags
&= ~USBHUB_FDO_FLAG_STATE_CHANGING
;
2581 USBH_PdoPnP(IN PUSBHUB_PORT_PDO_EXTENSION PortExtension
,
2584 OUT BOOLEAN
* IsCompleteIrp
)
2587 PIO_STACK_LOCATION IoStack
;
2588 PPNP_BUS_INFORMATION BusInfo
;
2589 PDEVICE_CAPABILITIES DeviceCapabilities
;
2592 PUSBHUB_FDO_EXTENSION HubExtension
;
2593 PDEVICE_RELATIONS DeviceRelation
;
2595 DPRINT_PNP("USBH_PdoPnP: PortExtension - %p, Irp - %p, Minor - %X\n",
2600 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
2602 *IsCompleteIrp
= TRUE
;
2606 case IRP_MN_START_DEVICE
:
2607 DPRINT_PNP("PDO IRP_MN_START_DEVICE\n");
2608 return USBH_PdoStartDevice(PortExtension
, Irp
);
2610 case IRP_MN_QUERY_REMOVE_DEVICE
:
2611 DPRINT_PNP("PDO IRP_MN_QUERY_REMOVE_DEVICE\n");
2612 return STATUS_SUCCESS
;
2614 case IRP_MN_REMOVE_DEVICE
:
2615 DPRINT_PNP("PDO IRP_MN_REMOVE_DEVICE\n");
2616 return USBH_PdoRemoveDevice(PortExtension
, PortExtension
->HubExtension
);
2618 case IRP_MN_CANCEL_REMOVE_DEVICE
:
2619 DPRINT_PNP("PDO IRP_MN_CANCEL_REMOVE_DEVICE\n");
2620 return STATUS_SUCCESS
;
2622 case IRP_MN_STOP_DEVICE
:
2623 DPRINT_PNP("PDO IRP_MN_STOP_DEVICE\n");
2624 return USBH_PdoStopDevice(PortExtension
, Irp
);
2626 case IRP_MN_QUERY_STOP_DEVICE
:
2627 DPRINT_PNP("PDO IRP_MN_QUERY_STOP_DEVICE\n");
2628 return STATUS_SUCCESS
;
2630 case IRP_MN_CANCEL_STOP_DEVICE
:
2631 DPRINT_PNP("PDO IRP_MN_CANCEL_STOP_DEVICE\n");
2632 return STATUS_SUCCESS
;
2634 case IRP_MN_QUERY_DEVICE_RELATIONS
:
2635 DPRINT_PNP("PDO IRP_MN_QUERY_DEVICE_RELATIONS\n");
2637 if (IoStack
->Parameters
.QueryDeviceRelations
.Type
!= TargetDeviceRelation
)
2639 return Irp
->IoStatus
.Status
;
2642 DeviceRelation
= ExAllocatePoolWithTag(PagedPool
,
2643 sizeof(DEVICE_RELATIONS
),
2648 RtlZeroMemory(DeviceRelation
, sizeof(DEVICE_RELATIONS
));
2650 DeviceRelation
->Count
= 1;
2651 DeviceRelation
->Objects
[0] = PortExtension
->Common
.SelfDevice
;
2653 ObReferenceObject(DeviceRelation
->Objects
[0]);
2655 Status
= STATUS_SUCCESS
;
2659 Status
= STATUS_INSUFFICIENT_RESOURCES
;
2662 Irp
->IoStatus
.Information
= (ULONG_PTR
)DeviceRelation
;
2665 case IRP_MN_QUERY_INTERFACE
:
2666 DPRINT_PNP("PDO IRP_MN_QUERY_INTERFACE\n");
2670 if (IsEqualGUIDAligned(IoStack
->Parameters
.QueryInterface
.InterfaceType
,
2671 &USB_BUS_INTERFACE_USBDI_GUID
))
2673 IoStack
->Parameters
.QueryInterface
.InterfaceSpecificData
= PortExtension
->DeviceHandle
;
2676 HubExtension
= PortExtension
->HubExtension
;
2680 HubExtension
= PortExtension
->RootHubExtension
;
2683 Status
= USBH_PassIrp(HubExtension
->RootHubPdo
, Irp
);
2686 case IRP_MN_QUERY_CAPABILITIES
:
2687 DPRINT_PNP("PDO IRP_MN_QUERY_CAPABILITIES\n");
2689 DeviceCapabilities
= IoStack
->Parameters
.DeviceCapabilities
.Capabilities
;
2691 Size
= DeviceCapabilities
->Size
;
2692 Version
= DeviceCapabilities
->Version
;
2694 RtlCopyMemory(DeviceCapabilities
,
2695 &PortExtension
->Capabilities
,
2696 sizeof(DEVICE_CAPABILITIES
));
2698 DeviceCapabilities
->Size
= Size
;
2699 DeviceCapabilities
->Version
= Version
;
2701 Status
= STATUS_SUCCESS
;
2704 case IRP_MN_QUERY_RESOURCES
:
2705 DPRINT_PNP("PDO IRP_MN_QUERY_RESOURCES\n");
2706 Status
= Irp
->IoStatus
.Status
;
2709 case IRP_MN_QUERY_RESOURCE_REQUIREMENTS
:
2710 DPRINT_PNP("PDO IRP_MN_QUERY_RESOURCE_REQUIREMENTS\n");
2711 PortExtension
->PortPdoFlags
|= USBHUB_PDO_FLAG_ENUMERATED
;
2713 /* FIXME HKEY_LOCAL_MACHINE\SYSTEM\ControlSetXXX\Enum\USB\
2714 Vid_????&Pid_????\????????????\Device Parameters\
2715 if (ExtPropDescSemaphore)
2718 Status
= STATUS_SUCCESS
;
2721 case IRP_MN_QUERY_DEVICE_TEXT
:
2722 DPRINT_PNP("PDO IRP_MN_QUERY_DEVICE_TEXT\n");
2723 return USBH_PdoQueryDeviceText(PortExtension
, Irp
);
2725 case IRP_MN_FILTER_RESOURCE_REQUIREMENTS
:
2726 DPRINT_PNP("PDO IRP_MN_FILTER_RESOURCE_REQUIREMENTS\n");
2727 Status
= Irp
->IoStatus
.Status
;
2730 case IRP_MN_READ_CONFIG
:
2731 DPRINT_PNP("PDO IRP_MN_READ_CONFIG\n");
2733 Status
= Irp
->IoStatus
.Status
;
2736 case IRP_MN_WRITE_CONFIG
:
2737 DPRINT_PNP("PDO IRP_MN_WRITE_CONFIG\n");
2739 Status
= Irp
->IoStatus
.Status
;
2743 DPRINT_PNP("PDO IRP_MN_EJECT\n");
2745 Status
= Irp
->IoStatus
.Status
;
2748 case IRP_MN_SET_LOCK
:
2749 DPRINT_PNP("PDO IRP_MN_SET_LOCK\n");
2751 Status
= Irp
->IoStatus
.Status
;
2754 case IRP_MN_QUERY_ID
:
2755 DPRINT_PNP("PDO IRP_MN_QUERY_ID\n");
2756 return USBH_PdoQueryId(PortExtension
, Irp
);
2758 case IRP_MN_QUERY_PNP_DEVICE_STATE
:
2759 DPRINT_PNP("PDO IRP_MN_QUERY_PNP_DEVICE_STATE\n");
2760 if (PortExtension
->PortPdoFlags
& (USBHUB_PDO_FLAG_INSUFFICIENT_PWR
|
2761 USBHUB_PDO_FLAG_OVERCURRENT_PORT
|
2762 USBHUB_PDO_FLAG_PORT_RESTORE_FAIL
|
2763 USBHUB_PDO_FLAG_INIT_PORT_FAILED
))
2765 Irp
->IoStatus
.Information
|= PNP_DEVICE_FAILED
;
2768 Status
= STATUS_SUCCESS
;
2771 case IRP_MN_QUERY_BUS_INFORMATION
:
2772 DPRINT_PNP("PDO IRP_MN_QUERY_BUS_INFORMATION\n");
2774 BusInfo
= ExAllocatePoolWithTag(PagedPool
,
2775 sizeof(PNP_BUS_INFORMATION
),
2780 return STATUS_INSUFFICIENT_RESOURCES
;
2783 RtlZeroMemory(BusInfo
, sizeof(PNP_BUS_INFORMATION
));
2785 RtlCopyMemory(&BusInfo
->BusTypeGuid
,
2787 sizeof(BusInfo
->BusTypeGuid
));
2789 BusInfo
->LegacyBusType
= PNPBus
;
2790 BusInfo
->BusNumber
= 0;
2792 Irp
->IoStatus
.Information
= (ULONG_PTR
)BusInfo
;
2793 Status
= STATUS_SUCCESS
;
2796 case IRP_MN_DEVICE_USAGE_NOTIFICATION
:
2797 DPRINT_PNP("PDO IRP_MN_DEVICE_USAGE_NOTIFICATION\n");
2799 Status
= Irp
->IoStatus
.Status
;
2802 case IRP_MN_SURPRISE_REMOVAL
:
2803 DPRINT_PNP("PDO IRP_MN_SURPRISE_REMOVAL\n");
2804 if (PortExtension
->PortPdoFlags
& USBHUB_PDO_FLAG_REG_DEV_INTERFACE
)
2806 Status
= USBH_SymbolicLink(PortExtension
, NULL
, FALSE
);
2808 if (NT_SUCCESS(Status
))
2810 PortExtension
->PortPdoFlags
&= ~USBHUB_PDO_FLAG_REG_DEV_INTERFACE
;
2814 Status
= STATUS_SUCCESS
;
2818 DPRINT_PNP("PDO unknown IRP_MN_???\n");
2819 Status
= Irp
->IoStatus
.Status
;