2 * PROJECT: ReactOS Universal Serial Bus Hub Driver
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: drivers/usb/usbhub/fdo.c
7 * Michael Martin (michael.martin@reactos.org)
8 * Johannes Anderwald (johannes.anderwald@reactos.org)
15 QueryStatusChangeEndpoint(
16 IN PDEVICE_OBJECT DeviceObject
);
19 CreateUsbChildDeviceObject(
20 IN PDEVICE_OBJECT UsbHubDeviceObject
,
22 OUT PDEVICE_OBJECT
*UsbChildDeviceObject
);
25 SubmitRequestToRootHub(
26 IN PDEVICE_OBJECT RootHubDeviceObject
,
27 IN ULONG IoControlCode
,
28 OUT PVOID OutParameter1
,
29 OUT PVOID OutParameter2
)
33 IO_STATUS_BLOCK IoStatus
;
35 PIO_STACK_LOCATION Stack
= NULL
;
37 KeInitializeEvent(&Event
, NotificationEvent
, FALSE
);
40 // Build Control Request
42 Irp
= IoBuildDeviceIoControlRequest(IoControlCode
,
52 DPRINT("Usbhub: IoBuildDeviceIoControlRequest() failed\n");
53 return STATUS_INSUFFICIENT_RESOURCES
;
57 // Initialize the status block before sending the IRP
59 IoStatus
.Status
= STATUS_NOT_SUPPORTED
;
60 IoStatus
.Information
= 0;
63 // Get Next Stack Location and Initialize it
65 Stack
= IoGetNextIrpStackLocation(Irp
);
66 Stack
->Parameters
.Others
.Argument1
= OutParameter1
;
67 Stack
->Parameters
.Others
.Argument2
= OutParameter2
;
72 Status
= IoCallDriver(RootHubDeviceObject
, Irp
);
75 // Its ok to block here as this function is called in an nonarbitrary thread
77 if (Status
== STATUS_PENDING
)
79 KeWaitForSingleObject(&Event
, Suspended
, KernelMode
, FALSE
, NULL
);
80 Status
= IoStatus
.Status
;
84 // The IO Manager will free the IRP
91 GetPortStatusAndChange(
92 IN PDEVICE_OBJECT RootHubDeviceObject
,
94 OUT PPORT_STATUS_CHANGE StatusChange
)
102 Urb
= ExAllocatePoolWithTag(NonPagedPool
, sizeof(URB
), USB_HUB_TAG
);
105 DPRINT1("Failed to allocate memory for URB!\n");
106 return STATUS_INSUFFICIENT_RESOURCES
;
112 RtlZeroMemory(Urb
, sizeof(URB
));
115 // Initialize URB for getting Port Status
117 UsbBuildVendorRequest(Urb
,
118 URB_FUNCTION_CLASS_OTHER
,
119 sizeof(Urb
->UrbControlVendorClassRequest
),
120 USBD_TRANSFER_DIRECTION_OUT
,
122 USB_REQUEST_GET_STATUS
,
127 sizeof(PORT_STATUS_CHANGE
),
131 // Query the Root Hub
133 Status
= SubmitRequestToRootHub(RootHubDeviceObject
, IOCTL_INTERNAL_USB_SUBMIT_URB
, Urb
, NULL
);
145 IN PDEVICE_OBJECT RootHubDeviceObject
,
155 Urb
= ExAllocatePoolWithTag(NonPagedPool
, sizeof(URB
), USB_HUB_TAG
);
158 DPRINT1("Failed to allocate memory for URB!\n");
159 return STATUS_INSUFFICIENT_RESOURCES
;
165 RtlZeroMemory(Urb
, sizeof(URB
));
168 // Initialize URB for Clearing Port Reset
170 UsbBuildVendorRequest(Urb
,
171 URB_FUNCTION_CLASS_OTHER
,
172 sizeof(Urb
->UrbControlVendorClassRequest
),
173 USBD_TRANSFER_DIRECTION_IN
,
175 USB_REQUEST_SET_FEATURE
,
183 // Query the Root Hub
185 Status
= SubmitRequestToRootHub(RootHubDeviceObject
, IOCTL_INTERNAL_USB_SUBMIT_URB
, Urb
, NULL
);
197 IN PDEVICE_OBJECT RootHubDeviceObject
,
207 Urb
= ExAllocatePoolWithTag(NonPagedPool
, sizeof(URB
), USB_HUB_TAG
);
210 DPRINT1("Failed to allocate memory for URB!\n");
211 return STATUS_INSUFFICIENT_RESOURCES
;
217 RtlZeroMemory(Urb
, sizeof(URB
));
220 // Initialize URB for Clearing Port Reset
222 UsbBuildVendorRequest(Urb
,
223 URB_FUNCTION_CLASS_OTHER
,
224 sizeof(Urb
->UrbControlVendorClassRequest
),
225 USBD_TRANSFER_DIRECTION_IN
,
227 USB_REQUEST_CLEAR_FEATURE
,
235 // Query the Root Hub
237 Status
= SubmitRequestToRootHub(RootHubDeviceObject
, IOCTL_INTERNAL_USB_SUBMIT_URB
, Urb
, NULL
);
248 DeviceStatusChangeThread(
252 PDEVICE_OBJECT DeviceObject
, RootHubDeviceObject
;
253 PHUB_DEVICE_EXTENSION HubDeviceExtension
;
254 PWORK_ITEM_DATA WorkItemData
;
255 PORT_STATUS_CHANGE PortStatus
;
258 static LONG failsafe
= 0;
260 DPRINT1("Entered DeviceStatusChangeThread, Context %x\n", Context
);
262 WorkItemData
= (PWORK_ITEM_DATA
)Context
;
263 DeviceObject
= (PDEVICE_OBJECT
)WorkItemData
->Context
;
264 HubDeviceExtension
= (PHUB_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
265 RootHubDeviceObject
= HubDeviceExtension
->RootHubPhysicalDeviceObject
;
269 for (PortId
= 1; PortId
<= HubDeviceExtension
->UsbExtHubInfo
.NumberOfPorts
; PortId
++)
274 Status
= GetPortStatusAndChange(RootHubDeviceObject
, PortId
, &PortStatus
);
275 if (!NT_SUCCESS(Status
))
277 DPRINT1("Failed to get port status for port %d, Status %x\n", PortId
, Status
);
278 // FIXME: Do we really want to halt further SCE requests?
282 DPRINT1("Port %d Status %x\n", PortId
, PortStatus
.Status
);
283 DPRINT1("Port %d Change %x\n", PortId
, PortStatus
.Change
);
287 // Check for new device connection
289 if (PortStatus
.Change
& USB_PORT_STATUS_CONNECT
)
292 // Clear Port Connect
294 Status
= ClearPortFeature(RootHubDeviceObject
, PortId
, C_PORT_CONNECTION
);
295 if (!NT_SUCCESS(Status
))
297 DPRINT1("Failed to clear connection change for port %d\n", PortId
);
301 // Is this a connect or disconnect?
303 if (!(PortStatus
.Status
& USB_PORT_STATUS_CONNECT
))
305 DPRINT1("Device disconnected from port %d\n", PortId
);
308 // FIXME: Remove the device, and deallocate memory
313 DPRINT1("Device connected from port %d\n", PortId
);
315 // No SCE completion done for clearing C_PORT_CONNECT
320 Status
= SetPortFeature(RootHubDeviceObject
, PortId
, PORT_RESET
);
321 if (!NT_SUCCESS(Status
))
323 DPRINT1("Failed to reset port %d\n", PortId
);
327 else if (PortStatus
.Change
& USB_PORT_STATUS_ENABLE
)
332 Status
= ClearPortFeature(RootHubDeviceObject
, PortId
, C_PORT_ENABLE
);
333 if (!NT_SUCCESS(Status
))
335 DPRINT1("Failed to clear enable change on port %d\n", PortId
);
338 else if (PortStatus
.Change
& USB_PORT_STATUS_RESET
)
343 Status
= ClearPortFeature(RootHubDeviceObject
, PortId
, C_PORT_RESET
);
344 if (!NT_SUCCESS(Status
))
346 DPRINT1("Failed to clear reset change on port %d\n", PortId
);
352 Status
= GetPortStatusAndChange(RootHubDeviceObject
, PortId
, &PortStatus
);
353 if (!NT_SUCCESS(Status
))
355 DPRINT1("Failed to get port status for port %d, Status %x\n", PortId
, Status
);
356 // FIXME: Do we really want to halt further SCE requests?
360 DPRINT1("Port %d Status %x\n", PortId
, PortStatus
.Status
);
361 DPRINT1("Port %d Change %x\n", PortId
, PortStatus
.Change
);
364 // Check that reset was cleared
366 if(PortStatus
.Change
& USB_PORT_STATUS_RESET
)
368 DPRINT1("Port did not clear reset! Possible Hardware problem!\n");
372 // Check if the device is still connected
374 if (!(PortStatus
.Status
& USB_PORT_STATUS_CONNECT
))
376 DPRINT1("Device has been disconnected\n");
381 // Make sure its Connected and Enabled
383 if (!(PortStatus
.Status
& (USB_PORT_STATUS_CONNECT
| USB_PORT_STATUS_ENABLE
)))
385 DPRINT1("Usb Device is not connected and enabled!\n");
387 // Attempt another reset
389 Status
= SetPortFeature(RootHubDeviceObject
, PortId
, PORT_RESET
);
390 if (!NT_SUCCESS(Status
))
392 DPRINT1("Failed to reset port %d\n", PortId
);
398 // Create the device object only if the port manipulation was started by a device connect
400 if (HubDeviceExtension
->PortStatusChange
[PortId
-1].Status
)
402 HubDeviceExtension
->PortStatusChange
[PortId
-1].Status
= 0;
403 Status
= CreateUsbChildDeviceObject(DeviceObject
, PortId
, NULL
);
409 // FIXME: Still in testing
414 DPRINT1("SCE completed over 100 times but no action has been taken to clear the Change of any ports.\n");
416 // Return and dont send any more SCE Requests
421 ExFreePool(WorkItemData
);
424 // Send another SCE Request
426 DPRINT1("Sending another SCE!\n");
427 QueryStatusChangeEndpoint(DeviceObject
);
431 StatusChangeEndpointCompletion(
432 IN PDEVICE_OBJECT DeviceObject
,
436 PDEVICE_OBJECT RealDeviceObject
;
437 PHUB_DEVICE_EXTENSION HubDeviceExtension
;
438 PWORK_ITEM_DATA WorkItemData
;
440 RealDeviceObject
= (PDEVICE_OBJECT
)Context
;
441 HubDeviceExtension
= (PHUB_DEVICE_EXTENSION
)RealDeviceObject
->DeviceExtension
;
444 // NOTE: USBPORT frees this IRP
446 DPRINT1("Received Irp %x, HubDeviceExtension->PendingSCEIrp %x\n", Irp
, HubDeviceExtension
->PendingSCEIrp
);
450 // Create and initialize work item data
452 WorkItemData
= ExAllocatePoolWithTag(NonPagedPool
, sizeof(WORK_ITEM_DATA
), USB_HUB_TAG
);
455 DPRINT1("Failed to allocate memory!n");
456 return STATUS_INSUFFICIENT_RESOURCES
;
458 WorkItemData
->Context
= RealDeviceObject
;
459 DPRINT1("Initialize work item\n");
460 ExInitializeWorkItem(&WorkItemData
->WorkItem
, (PWORKER_THREAD_ROUTINE
)DeviceStatusChangeThread
, (PVOID
)WorkItemData
);
463 // Queue the work item to handle initializing the device
465 ExQueueWorkItem(&WorkItemData
->WorkItem
, DelayedWorkQueue
);
468 // Return more processing required so the IO Manger doesn’t try to mess with IRP just freed
470 return STATUS_MORE_PROCESSING_REQUIRED
;
474 QueryStatusChangeEndpoint(
475 IN PDEVICE_OBJECT DeviceObject
)
478 PDEVICE_OBJECT RootHubDeviceObject
;
479 PIO_STACK_LOCATION Stack
;
480 PHUB_DEVICE_EXTENSION HubDeviceExtension
;
483 HubDeviceExtension
= (PHUB_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
484 RootHubDeviceObject
= HubDeviceExtension
->RootHubPhysicalDeviceObject
;
489 PendingSCEUrb
= ExAllocatePoolWithTag(NonPagedPool
, sizeof(URB
), USB_HUB_TAG
);
492 // Initialize URB for Status Change Endpoint request
494 UsbBuildInterruptOrBulkTransferRequest(PendingSCEUrb
,
495 sizeof(struct _URB_BULK_OR_INTERRUPT_TRANSFER
),
496 HubDeviceExtension
->PipeHandle
,
497 HubDeviceExtension
->PortStatusChange
,
499 sizeof(USHORT
) * 2 * HubDeviceExtension
->UsbExtHubInfo
.NumberOfPorts
,
500 USBD_TRANSFER_DIRECTION_IN
| USBD_SHORT_TRANSFER_OK
,
504 // Set the device handle to null for roothub
506 PendingSCEUrb
->UrbHeader
.UsbdDeviceHandle
= NULL
;//HubDeviceExtension->RootHubHandle;
512 HubDeviceExtension
->PendingSCEIrp
= ExAllocatePoolWithTag(NonPagedPool
,
513 IoSizeOfIrp(RootHubDeviceObject
->StackSize
),
516 HubDeviceExtension->PendingSCEIrp = IoAllocateIrp(RootHubDeviceObject->StackSize,
519 DPRINT1("Allocated IRP %x\n", HubDeviceExtension
->PendingSCEIrp
);
521 if (!HubDeviceExtension
->PendingSCEIrp
)
523 DPRINT1("USBHUB: Failed to allocate IRP for SCE request!\n");
524 return STATUS_INSUFFICIENT_RESOURCES
;
528 // Initialize the IRP
530 IoInitializeIrp(HubDeviceExtension
->PendingSCEIrp
,
531 IoSizeOfIrp(RootHubDeviceObject
->StackSize
),
532 RootHubDeviceObject
->StackSize
);
534 HubDeviceExtension
->PendingSCEIrp
->IoStatus
.Status
= STATUS_NOT_SUPPORTED
;
535 HubDeviceExtension
->PendingSCEIrp
->IoStatus
.Information
= 0;
536 HubDeviceExtension
->PendingSCEIrp
->Flags
= 0;
537 HubDeviceExtension
->PendingSCEIrp
->UserBuffer
= NULL
;
540 // Get the Next Stack Location and Initialize it
542 Stack
= IoGetNextIrpStackLocation(HubDeviceExtension
->PendingSCEIrp
);
543 Stack
->DeviceObject
= DeviceObject
;
544 Stack
->Parameters
.Others
.Argument1
= PendingSCEUrb
;
545 Stack
->Parameters
.Others
.Argument2
= NULL
;
546 Stack
->MajorFunction
= IRP_MJ_INTERNAL_DEVICE_CONTROL
;
547 Stack
->Parameters
.DeviceIoControl
.IoControlCode
= IOCTL_INTERNAL_USB_SUBMIT_URB
;
550 // Set the completion routine for when device is connected to root hub
552 IoSetCompletionRoutine(HubDeviceExtension
->PendingSCEIrp
,
553 (PIO_COMPLETION_ROUTINE
) StatusChangeEndpointCompletion
,
562 DPRINT1("DeviceObject is %x\n", DeviceObject
);
563 DPRINT1("Iocalldriver %x with irp %x\n", RootHubDeviceObject
, HubDeviceExtension
->PendingSCEIrp
);
564 Status
= IoCallDriver(RootHubDeviceObject
, HubDeviceExtension
->PendingSCEIrp
);
566 return STATUS_PENDING
;
571 IN PDEVICE_OBJECT DeviceObject
,
572 IN CONST GUID InterfaceType
,
579 IO_STATUS_BLOCK IoStatus
;
581 PIO_STACK_LOCATION Stack
= NULL
;
584 // Initialize the Event used to wait for Irp completion
586 KeInitializeEvent(&Event
, NotificationEvent
, FALSE
);
589 // Build Control Request
591 Irp
= IoBuildSynchronousFsdRequest(IRP_MJ_PNP
,
600 // Get Next Stack Location and Initialize it.
602 Stack
= IoGetNextIrpStackLocation(Irp
);
603 Stack
->MinorFunction
= IRP_MN_QUERY_INTERFACE
;
604 Stack
->Parameters
.QueryInterface
.InterfaceType
= &InterfaceType
;//USB_BUS_INTERFACE_HUB_GUID;
605 Stack
->Parameters
.QueryInterface
.Size
= Size
;
606 Stack
->Parameters
.QueryInterface
.Version
= Version
;
607 Stack
->Parameters
.QueryInterface
.Interface
= Interface
;
608 Stack
->Parameters
.QueryInterface
.InterfaceSpecificData
= NULL
;
610 Status
= IoCallDriver(DeviceObject
, Irp
);
612 if (Status
== STATUS_PENDING
)
614 DPRINT("Operation pending\n");
615 KeWaitForSingleObject(&Event
, Suspended
, KernelMode
, FALSE
, NULL
);
616 Status
= IoStatus
.Status
;
623 GetUsbDeviceDescriptor(
624 IN PDEVICE_OBJECT ChildDeviceObject
,
625 IN UCHAR DescriptorType
,
628 OUT PVOID TransferBuffer
,
629 IN ULONG TransferBufferLength
)
632 PDEVICE_OBJECT RootHubDeviceObject
;
634 PHUB_DEVICE_EXTENSION HubDeviceExtension
;
635 PHUB_CHILDDEVICE_EXTENSION ChildDeviceExtension
;
638 // Get the Hubs Device Extension
640 ChildDeviceExtension
= (PHUB_CHILDDEVICE_EXTENSION
)ChildDeviceObject
->DeviceExtension
;
641 HubDeviceExtension
= (PHUB_DEVICE_EXTENSION
) ChildDeviceExtension
->ParentDeviceObject
->DeviceExtension
;
642 RootHubDeviceObject
= HubDeviceExtension
->RootHubPhysicalDeviceObject
;
647 Urb
= ExAllocatePoolWithTag(NonPagedPool
, sizeof(URB
), USB_HUB_TAG
);
650 DPRINT1("Failed to allocate memory for URB!\n");
651 return STATUS_INSUFFICIENT_RESOURCES
;
657 RtlZeroMemory(Urb
, sizeof(URB
));
660 // Initialize URB for getting device descriptor
662 UsbBuildGetDescriptorRequest(Urb
,
663 sizeof(Urb
->UrbControlDescriptorRequest
),
669 TransferBufferLength
,
673 // Set the device handle
675 Urb
->UrbHeader
.UsbdDeviceHandle
= (PVOID
)ChildDeviceExtension
->UsbDeviceHandle
;
678 // Query the Root Hub
680 Status
= SubmitRequestToRootHub(RootHubDeviceObject
,
681 IOCTL_INTERNAL_USB_SUBMIT_URB
,
689 GetUsbStringDescriptor(
690 IN PDEVICE_OBJECT ChildDeviceObject
,
693 OUT PVOID
*TransferBuffer
,
697 PUSB_STRING_DESCRIPTOR StringDesc
= NULL
;
700 StringDesc
= ExAllocatePoolWithTag(NonPagedPool
,
701 sizeof(USB_STRING_DESCRIPTOR
),
705 DPRINT1("Failed to allocate buffer for string!\n");
706 return STATUS_INSUFFICIENT_RESOURCES
;
710 // Get the index string descriptor length
711 // FIXME: Implement LangIds
713 Status
= GetUsbDeviceDescriptor(ChildDeviceObject
,
714 USB_STRING_DESCRIPTOR_TYPE
,
718 sizeof(USB_STRING_DESCRIPTOR
));
719 if (!NT_SUCCESS(Status
))
721 DPRINT1("GetUsbDeviceDescriptor failed with status %x\n", Status
);
722 ExFreePool(StringDesc
);
725 DPRINT1("StringDesc->bLength %d\n", StringDesc
->bLength
);
728 // Did we get something more than the length of the first two fields of structure?
730 if (StringDesc
->bLength
== 2)
732 DPRINT1("USB Device Error!\n");
733 ExFreePool(StringDesc
);
734 return STATUS_DEVICE_DATA_ERROR
;
736 SizeNeeded
= StringDesc
->bLength
+ sizeof(WCHAR
);
741 ExFreePool(StringDesc
);
744 // Recreate with appropriate size
746 StringDesc
= ExAllocatePoolWithTag(NonPagedPool
,
751 DPRINT1("Failed to allocate buffer for string!\n");
752 return STATUS_INSUFFICIENT_RESOURCES
;
755 RtlZeroMemory(StringDesc
, SizeNeeded
);
760 Status
= GetUsbDeviceDescriptor(ChildDeviceObject
,
761 USB_STRING_DESCRIPTOR_TYPE
,
766 if (!NT_SUCCESS(Status
))
768 DPRINT1("GetUsbDeviceDescriptor failed with status %x\n", Status
);
769 ExFreePool(StringDesc
);
774 // Allocate Buffer to return
776 *TransferBuffer
= ExAllocatePoolWithTag(NonPagedPool
,
779 if (!*TransferBuffer
)
781 DPRINT1("Failed to allocate buffer for string!\n");
782 ExFreePool(StringDesc
);
783 return STATUS_INSUFFICIENT_RESOURCES
;
786 RtlZeroMemory(*TransferBuffer
, SizeNeeded
);
789 // Copy the string to destination
791 RtlCopyMemory(*TransferBuffer
, StringDesc
->bString
, SizeNeeded
- FIELD_OFFSET(USB_STRING_DESCRIPTOR
, bLength
));
794 ExFreePool(StringDesc
);
796 return STATUS_SUCCESS
;
801 PDEVICE_OBJECT UsbChildDeviceObject
)
806 PHUB_CHILDDEVICE_EXTENSION UsbChildExtension
;
808 UsbChildExtension
= (PHUB_CHILDDEVICE_EXTENSION
)UsbChildDeviceObject
->DeviceExtension
;
811 // Initialize the CompatibleIds String
813 UsbChildExtension
->usCompatibleIds
.Length
= 144;
814 UsbChildExtension
->usCompatibleIds
.MaximumLength
= UsbChildExtension
->usCompatibleIds
.Length
;
816 BufferPtr
= ExAllocatePoolWithTag(NonPagedPool
,
817 UsbChildExtension
->usCompatibleIds
.Length
,
821 DPRINT1("Failed to allocate memory\n");
822 return STATUS_INSUFFICIENT_RESOURCES
;
825 RtlZeroMemory(BufferPtr
, UsbChildExtension
->usCompatibleIds
.Length
);
829 // Construct the CompatibleIds
831 if (UsbChildExtension
->DeviceDesc
.bDeviceClass
== 0)
833 PUSB_INTERFACE_DESCRIPTOR InterDesc
= (PUSB_INTERFACE_DESCRIPTOR
)
834 ((ULONG_PTR
)UsbChildExtension
->FullConfigDesc
+ sizeof(USB_CONFIGURATION_DESCRIPTOR
));
836 Index
+= swprintf(&BufferPtr
[Index
],
837 L
"USB\\Class_%02x&SubClass_%02x&Prot_%02x",
838 InterDesc
->bInterfaceClass
,InterDesc
->bInterfaceSubClass
,InterDesc
->bInterfaceProtocol
) + 1;
839 Index
+= swprintf(&BufferPtr
[Index
],
840 L
"USB\\Class_%02x&SubClass_%02x",
841 InterDesc
->bInterfaceClass
,InterDesc
->bInterfaceSubClass
) + 1;
842 Index
+= swprintf(&BufferPtr
[Index
],
844 InterDesc
->bInterfaceClass
) + 1;
848 PUSB_DEVICE_DESCRIPTOR DevDesc
= &UsbChildExtension
->DeviceDesc
;
849 Index
+= swprintf(&BufferPtr
[Index
],
850 L
"USB\\Class_%02x&SubClass_%02x&Prot_%02x",
851 DevDesc
->bDeviceClass
,DevDesc
->bDeviceSubClass
,DevDesc
->bDeviceProtocol
) + 1;
852 Index
+= swprintf(&BufferPtr
[Index
],
853 L
"USB\\Class_%02x&SubClass_%02x",
854 DevDesc
->bDeviceClass
,DevDesc
->bDeviceSubClass
) + 1;
855 Index
+= swprintf(&BufferPtr
[Index
],
857 DevDesc
->bDeviceClass
) + 1;
859 BufferPtr
[Index
] = UNICODE_NULL
;
860 UsbChildExtension
->usCompatibleIds
.Buffer
= BufferPtr
;
861 DPRINT1("usCompatibleIds %wZ\n", &UsbChildExtension
->usCompatibleIds
);
864 // Initialize the DeviceId String
866 UsbChildExtension
->usDeviceId
.Length
= 44;
867 UsbChildExtension
->usDeviceId
.MaximumLength
= UsbChildExtension
->usDeviceId
.Length
;
868 BufferPtr
= ExAllocatePoolWithTag(NonPagedPool
,
869 UsbChildExtension
->usDeviceId
.Length
,
873 DPRINT1("Failed to allocate memory\n");
874 Status
= STATUS_INSUFFICIENT_RESOURCES
;
879 // Construct DeviceId
881 swprintf(BufferPtr
, L
"USB\\Vid_%04x&Pid_%04x\0", UsbChildExtension
->DeviceDesc
.idVendor
, UsbChildExtension
->DeviceDesc
.idProduct
);
882 UsbChildExtension
->usDeviceId
.Buffer
= BufferPtr
;
883 DPRINT1("usDeviceId %wZ\n", &UsbChildExtension
->usDeviceId
);
886 // Initialize the HardwareId String
888 UsbChildExtension
->usHardwareIds
.Length
= 110;
889 UsbChildExtension
->usHardwareIds
.MaximumLength
= UsbChildExtension
->usHardwareIds
.Length
;
890 BufferPtr
= ExAllocatePoolWithTag(NonPagedPool
, UsbChildExtension
->usHardwareIds
.Length
, USB_HUB_TAG
);
893 DPRINT1("Failed to allocate memory\n");
894 Status
= STATUS_INSUFFICIENT_RESOURCES
;
898 RtlZeroMemory(BufferPtr
, UsbChildExtension
->usHardwareIds
.Length
);
901 // Consturct HardwareIds
904 Index
+= swprintf(&BufferPtr
[Index
],
905 L
"USB\\Vid_%04x&Pid_%04x&Rev_%04x",
906 UsbChildExtension
->DeviceDesc
.idVendor
, UsbChildExtension
->DeviceDesc
.idProduct
, UsbChildExtension
->DeviceDesc
.bcdDevice
) + 1;
907 Index
+= swprintf(&BufferPtr
[Index
],
908 L
"USB\\Vid_%04x&Pid_%04x",
909 UsbChildExtension
->DeviceDesc
.idVendor
, UsbChildExtension
->DeviceDesc
.idProduct
) + 1;
910 BufferPtr
[Index
] = UNICODE_NULL
;
911 UsbChildExtension
->usHardwareIds
.Buffer
= BufferPtr
;
912 DPRINT1("usHardWareIds %wZ\n", &UsbChildExtension
->usHardwareIds
);
915 // FIXME: Handle Lang ids
919 // Get the product string if obe provided
921 if (UsbChildExtension
->DeviceDesc
.iProduct
)
923 Status
= GetUsbStringDescriptor(UsbChildDeviceObject
,
924 UsbChildExtension
->DeviceDesc
.iProduct
,
926 (PVOID
*)&UsbChildExtension
->usTextDescription
.Buffer
,
927 &UsbChildExtension
->usTextDescription
.Length
);
928 if (!NT_SUCCESS(Status
))
930 DPRINT1("USBHUB: GetUsbStringDescriptor failed with status %x\n", Status
);
934 UsbChildExtension
->usTextDescription
.MaximumLength
= UsbChildExtension
->usTextDescription
.Length
;
935 DPRINT1("Usb TextDescription %wZ\n", &UsbChildExtension
->usTextDescription
);
939 // Get the Serial Number string if obe provided
941 if (UsbChildExtension
->DeviceDesc
.iSerialNumber
)
943 Status
= GetUsbStringDescriptor(UsbChildDeviceObject
,
944 UsbChildExtension
->DeviceDesc
.iSerialNumber
,
946 (PVOID
*)&UsbChildExtension
->usInstanceId
.Buffer
,
947 &UsbChildExtension
->usInstanceId
.Length
);
948 if (!NT_SUCCESS(Status
))
950 DPRINT1("USBHUB: GetUsbStringDescriptor failed with status %x\n", Status
);
954 UsbChildExtension
->usInstanceId
.MaximumLength
= UsbChildExtension
->usInstanceId
.Length
;
955 DPRINT1("Usb InstanceId %wZ\n", &UsbChildExtension
->usInstanceId
);
960 // the device did not provide a serial number, lets create a pseudo instance id
962 Index
= swprintf(BufferPtr
, L
"USB\\Vid_%04x&Pid_%04x&1A0700BC\0", UsbChildExtension
->DeviceDesc
.idVendor
, UsbChildExtension
->DeviceDesc
.idProduct
) + 1;
963 UsbChildExtension
->usInstanceId
.Buffer
= (LPWSTR
)ExAllocatePool(NonPagedPool
, Index
* sizeof(WCHAR
));
964 if (UsbChildExtension
->usInstanceId
.Buffer
== NULL
)
966 DPRINT1("Error: failed to allocate %lu bytes\n", Index
* sizeof(WCHAR
));
973 RtlCopyMemory(UsbChildExtension
->usInstanceId
.Buffer
, BufferPtr
, wcslen(BufferPtr
) * sizeof(WCHAR
));
974 UsbChildExtension
->usInstanceId
.Length
= UsbChildExtension
->usDeviceId
.MaximumLength
= Index
* sizeof(WCHAR
);
976 DPRINT1("usDeviceId %wZ\n", &UsbChildExtension
->usInstanceId
);
986 if (UsbChildExtension
->usCompatibleIds
.Buffer
)
987 ExFreePool(UsbChildExtension
->usCompatibleIds
.Buffer
);
988 if (UsbChildExtension
->usDeviceId
.Buffer
)
989 ExFreePool(UsbChildExtension
->usDeviceId
.Buffer
);
990 if (UsbChildExtension
->usHardwareIds
.Buffer
)
991 ExFreePool(UsbChildExtension
->usHardwareIds
.Buffer
);
992 if (UsbChildExtension
->usTextDescription
.Buffer
)
993 ExFreePool(UsbChildExtension
->usTextDescription
.Buffer
);
994 if (UsbChildExtension
->usInstanceId
.Buffer
)
995 ExFreePool(UsbChildExtension
->usInstanceId
.Buffer
);
1001 CreateUsbChildDeviceObject(
1002 IN PDEVICE_OBJECT UsbHubDeviceObject
,
1004 OUT PDEVICE_OBJECT
*UsbChildDeviceObject
)
1007 PDEVICE_OBJECT RootHubDeviceObject
, NewChildDeviceObject
;
1008 PHUB_DEVICE_EXTENSION HubDeviceExtension
;
1009 PHUB_CHILDDEVICE_EXTENSION UsbChildExtension
;
1010 PUSB_BUS_INTERFACE_HUB_V5 HubInterface
;
1011 ULONG ChildDeviceCount
, UsbDeviceNumber
= 0;
1012 WCHAR CharDeviceName
[64];
1013 UNICODE_STRING DeviceName
;
1014 ULONG ConfigDescSize
, DeviceDescSize
;
1015 PVOID HubInterfaceBusContext
;
1016 USB_CONFIGURATION_DESCRIPTOR ConfigDesc
;
1018 HubDeviceExtension
= (PHUB_DEVICE_EXTENSION
) UsbHubDeviceObject
->DeviceExtension
;
1019 HubInterface
= &HubDeviceExtension
->HubInterface
;
1020 RootHubDeviceObject
= HubDeviceExtension
->RootHubPhysicalDeviceObject
;
1021 HubInterfaceBusContext
= HubDeviceExtension
->UsbDInterface
.BusContext
;
1023 // Find an empty slot in the child device array
1025 for (ChildDeviceCount
= 0; ChildDeviceCount
< USB_MAXCHILDREN
; ChildDeviceCount
++)
1027 if (HubDeviceExtension
->ChildDeviceObject
[ChildDeviceCount
] == NULL
)
1029 DPRINT1("Found unused entry at %d\n", ChildDeviceCount
);
1035 // Check if the limit has been reached for maximum usb devices
1037 if (ChildDeviceCount
== USB_MAXCHILDREN
)
1039 DPRINT1("USBHUB: Too many child devices!\n");
1040 return STATUS_UNSUCCESSFUL
;
1046 // Create a Device Name
1048 swprintf(CharDeviceName
, L
"\\Device\\USBPDO-%d", UsbDeviceNumber
);
1051 // Initialize UnicodeString
1053 RtlInitUnicodeString(&DeviceName
, CharDeviceName
);
1056 // Create a DeviceObject
1058 Status
= IoCreateDevice(UsbHubDeviceObject
->DriverObject
,
1059 sizeof(HUB_CHILDDEVICE_EXTENSION
),
1061 FILE_DEVICE_CONTROLLER
,
1062 FILE_AUTOGENERATED_DEVICE_NAME
,
1064 &NewChildDeviceObject
);
1067 // Check if the name is already in use
1069 if ((Status
== STATUS_OBJECT_NAME_EXISTS
) || (Status
== STATUS_OBJECT_NAME_COLLISION
))
1079 // Check for other errors
1081 if (!NT_SUCCESS(Status
))
1083 DPRINT1("USBHUB: IoCreateDevice failed with status %x\n", Status
);
1087 DPRINT1("USBHUB: Created Device %x\n", NewChildDeviceObject
);
1091 NewChildDeviceObject
->Flags
|= DO_BUS_ENUMERATED_DEVICE
;
1094 // Assign the device extensions
1096 UsbChildExtension
= (PHUB_CHILDDEVICE_EXTENSION
)NewChildDeviceObject
->DeviceExtension
;
1097 RtlZeroMemory(UsbChildExtension
, sizeof(HUB_CHILDDEVICE_EXTENSION
));
1098 UsbChildExtension
->ParentDeviceObject
= UsbHubDeviceObject
;
1099 UsbChildExtension
->PortNumber
= PortId
;
1102 // Create the UsbDeviceObject
1104 Status
= HubInterface
->CreateUsbDevice(HubInterfaceBusContext
,
1105 (PVOID
)&UsbChildExtension
->UsbDeviceHandle
,
1106 HubDeviceExtension
->RootHubHandle
,
1109 if (!NT_SUCCESS(Status
))
1111 DPRINT1("USBHUB: CreateUsbDevice failed with status %x\n", Status
);
1116 // Initialize UsbDevice
1118 Status
= HubInterface
->InitializeUsbDevice(HubInterfaceBusContext
, UsbChildExtension
->UsbDeviceHandle
);
1119 if (!NT_SUCCESS(Status
))
1121 DPRINT1("USBHUB: InitializeUsbDevice failed with status %x\n", Status
);
1125 DPRINT1("Usb Device Handle %x\n", UsbChildExtension
->UsbDeviceHandle
);
1127 ConfigDescSize
= sizeof(USB_CONFIGURATION_DESCRIPTOR
);
1128 DeviceDescSize
= sizeof(USB_DEVICE_DESCRIPTOR
);
1131 // Get the descriptors
1133 Status
= HubInterface
->GetUsbDescriptors(HubInterfaceBusContext
,
1134 UsbChildExtension
->UsbDeviceHandle
,
1135 (PUCHAR
)&UsbChildExtension
->DeviceDesc
,
1137 (PUCHAR
)&ConfigDesc
,
1139 if (!NT_SUCCESS(Status
))
1141 DPRINT1("USBHUB: GetUsbDescriptors failed with status %x\n", Status
);
1145 DumpDeviceDescriptor(&UsbChildExtension
->DeviceDesc
);
1146 DumpConfigurationDescriptor(&ConfigDesc
);
1149 // FIXME: Support more than one configuration and one interface?
1151 if (UsbChildExtension
->DeviceDesc
.bNumConfigurations
> 1)
1153 DPRINT1("Warning: Device has more than one configuration. Only one configuration (the first) is supported!\n");
1156 if (ConfigDesc
.bNumInterfaces
> 1)
1158 DPRINT1("Warning: Device has more that one interface. Only one interface (the first) is currently supported\n");
1161 ConfigDescSize
= ConfigDesc
.wTotalLength
;
1164 // Allocate memory for the first full descriptor, including interfaces and endpoints.
1166 UsbChildExtension
->FullConfigDesc
= ExAllocatePoolWithTag(PagedPool
, ConfigDescSize
, USB_HUB_TAG
);
1169 // Retrieve the full configuration descriptor
1171 Status
= GetUsbDeviceDescriptor(NewChildDeviceObject
,
1172 USB_CONFIGURATION_DESCRIPTOR_TYPE
,
1175 UsbChildExtension
->FullConfigDesc
,
1178 if (!NT_SUCCESS(Status
))
1180 DPRINT1("USBHUB: GetUsbDeviceDescriptor failed with status %x\n", Status
);
1184 DumpFullConfigurationDescriptor(UsbChildExtension
->FullConfigDesc
);
1187 // Construct all the strings that will described the device to PNP
1189 Status
= CreateDeviceIds(NewChildDeviceObject
);
1190 if (!NT_SUCCESS(Status
))
1192 DPRINT1("Failed to create strings needed to describe device to PNP.\n");
1196 HubDeviceExtension
->ChildDeviceObject
[ChildDeviceCount
] = NewChildDeviceObject
;
1198 IoInvalidateDeviceRelations(RootHubDeviceObject
, BusRelations
);
1199 return STATUS_SUCCESS
;
1204 // Remove the usb device if it was created
1206 if (UsbChildExtension
->UsbDeviceHandle
)
1207 HubInterface
->RemoveUsbDevice(HubInterfaceBusContext
, UsbChildExtension
->UsbDeviceHandle
, 0);
1210 // Free full configuration descriptor if one was allocated
1212 if (UsbChildExtension
->FullConfigDesc
)
1213 ExFreePool(UsbChildExtension
->FullConfigDesc
);
1216 // Delete the device object
1218 IoDeleteDevice(NewChildDeviceObject
);
1223 USBHUB_FdoQueryBusRelations(
1224 IN PDEVICE_OBJECT DeviceObject
,
1225 OUT PDEVICE_RELATIONS
* pDeviceRelations
)
1227 PHUB_DEVICE_EXTENSION HubDeviceExtension
;
1228 PDEVICE_RELATIONS DeviceRelations
;
1233 HubDeviceExtension
= (PHUB_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
1236 // Count the number of children
1238 for (i
= 0; i
< USB_MAXCHILDREN
; i
++)
1241 if (HubDeviceExtension
->ChildDeviceObject
[i
] == NULL
)
1248 NeededSize
= sizeof(DEVICE_RELATIONS
);
1250 NeededSize
+= (Children
- 1) * sizeof(PDEVICE_OBJECT
);
1253 // Allocate DeviceRelations
1255 DeviceRelations
= (PDEVICE_RELATIONS
)ExAllocatePool(PagedPool
,
1258 if (!DeviceRelations
)
1259 return STATUS_INSUFFICIENT_RESOURCES
;
1260 DeviceRelations
->Count
= Children
;
1264 // Fill in return structure
1266 for (i
= 0; i
< USB_MAXCHILDREN
; i
++)
1268 if (HubDeviceExtension
->ChildDeviceObject
[i
])
1270 ObReferenceObject(HubDeviceExtension
->ChildDeviceObject
[i
]);
1271 HubDeviceExtension
->ChildDeviceObject
[i
]->Flags
&= ~DO_DEVICE_INITIALIZING
;
1272 DeviceRelations
->Objects
[Children
++] = HubDeviceExtension
->ChildDeviceObject
[i
];
1276 ASSERT(Children
== DeviceRelations
->Count
);
1277 *pDeviceRelations
= DeviceRelations
;
1279 return STATUS_SUCCESS
;
1283 RootHubInitCallbackFunction(
1286 PDEVICE_OBJECT DeviceObject
= (PDEVICE_OBJECT
)Context
;
1288 DPRINT1("Sending the initial SCE Request %x\n", DeviceObject
);
1291 // Send the first SCE Request
1293 QueryStatusChangeEndpoint(DeviceObject
);
1297 USBHUB_FdoHandlePnp(
1298 IN PDEVICE_OBJECT DeviceObject
,
1301 PIO_STACK_LOCATION Stack
;
1302 NTSTATUS Status
= STATUS_SUCCESS
;
1303 ULONG_PTR Information
= 0;
1304 PHUB_DEVICE_EXTENSION HubDeviceExtension
;
1305 PDEVICE_OBJECT RootHubDeviceObject
;
1306 PVOID HubInterfaceBusContext
, UsbDInterfaceBusContext
;
1308 HubDeviceExtension
= (PHUB_DEVICE_EXTENSION
) DeviceObject
->DeviceExtension
;
1310 Stack
= IoGetCurrentIrpStackLocation(Irp
);
1312 switch (Stack
->MinorFunction
)
1314 case IRP_MN_START_DEVICE
:
1317 PUSB_INTERFACE_DESCRIPTOR Pid
;
1318 ULONG Result
= 0, PortId
;
1319 USBD_INTERFACE_LIST_ENTRY InterfaceList
[2] = {{NULL
, NULL
}, {NULL
, NULL
}};
1320 PURB ConfigUrb
= NULL
;
1323 DPRINT1("IRP_MJ_PNP / IRP_MN_START_DEVICE\n");
1326 // Allocated size including the sizeof USBD_INTERFACE_LIST_ENTRY
1328 Urb
= ExAllocatePoolWithTag(NonPagedPool
, sizeof(URB
) + sizeof(USBD_INTERFACE_LIST_ENTRY
), USB_HUB_TAG
);
1329 RtlZeroMemory(Urb
, sizeof(URB
) + sizeof(USBD_INTERFACE_LIST_ENTRY
));
1332 // Get the Root Hub Pdo
1334 SubmitRequestToRootHub(HubDeviceExtension
->LowerDeviceObject
,
1335 IOCTL_INTERNAL_USB_GET_ROOTHUB_PDO
,
1336 &HubDeviceExtension
->RootHubPhysicalDeviceObject
,
1337 &HubDeviceExtension
->RootHubFunctionalDeviceObject
);
1339 RootHubDeviceObject
= HubDeviceExtension
->RootHubPhysicalDeviceObject
;
1340 ASSERT(HubDeviceExtension
->RootHubPhysicalDeviceObject
);
1341 ASSERT(HubDeviceExtension
->RootHubFunctionalDeviceObject
);
1342 DPRINT1("RootPdo %x, RootFdo %x\n",
1343 HubDeviceExtension
->RootHubPhysicalDeviceObject
,
1344 HubDeviceExtension
->RootHubFunctionalDeviceObject
);
1347 // Send the StartDevice to RootHub
1349 Status
= ForwardIrpAndWait(RootHubDeviceObject
, Irp
);
1351 if (!NT_SUCCESS(Status
))
1353 DPRINT1("Failed to start the RootHub PDO\n");
1358 // Get the current number of hubs
1360 Status
= SubmitRequestToRootHub(RootHubDeviceObject
,
1361 IOCTL_INTERNAL_USB_GET_HUB_COUNT
,
1362 &HubDeviceExtension
->NumberOfHubs
, NULL
);
1365 // Get the Hub Interface
1367 Status
= QueryInterface(RootHubDeviceObject
,
1368 USB_BUS_INTERFACE_HUB_GUID
,
1369 sizeof(USB_BUS_INTERFACE_HUB_V5
),
1371 (PVOID
)&HubDeviceExtension
->HubInterface
);
1373 if (!NT_SUCCESS(Status
))
1375 DPRINT1("Failed to get HUB_GUID interface with status 0x%08lx\n", Status
);
1376 return STATUS_UNSUCCESSFUL
;
1379 HubInterfaceBusContext
= HubDeviceExtension
->HubInterface
.BusContext
;
1382 // Get the USBDI Interface
1384 Status
= QueryInterface(RootHubDeviceObject
,
1385 USB_BUS_INTERFACE_USBDI_GUID
,
1386 sizeof(USB_BUS_INTERFACE_USBDI_V2
),
1388 (PVOID
)&HubDeviceExtension
->UsbDInterface
);
1390 if (!NT_SUCCESS(Status
))
1392 DPRINT1("Failed to get USBDI_GUID interface with status 0x%08lx\n", Status
);
1396 UsbDInterfaceBusContext
= HubDeviceExtension
->UsbDInterface
.BusContext
;
1399 // Get Root Hub Device Handle
1401 Status
= SubmitRequestToRootHub(RootHubDeviceObject
,
1402 IOCTL_INTERNAL_USB_GET_DEVICE_HANDLE
,
1403 &HubDeviceExtension
->RootHubHandle
,
1406 if (!NT_SUCCESS(Status
))
1408 DPRINT1("GetRootHubDeviceHandle failed with status 0x%08lx\n", Status
);
1413 // Get Hub Device Information
1415 Status
= HubDeviceExtension
->HubInterface
.QueryDeviceInformation(HubInterfaceBusContext
,
1416 HubDeviceExtension
->RootHubHandle
,
1417 &HubDeviceExtension
->DeviceInformation
,
1418 sizeof(USB_DEVICE_INFORMATION_0
),
1421 DPRINT1("Status %x, Result 0x%08lx\n", Status
, Result
);
1422 DPRINT1("InformationLevel %x\n", HubDeviceExtension
->DeviceInformation
.InformationLevel
);
1423 DPRINT1("ActualLength %x\n", HubDeviceExtension
->DeviceInformation
.ActualLength
);
1424 DPRINT1("PortNumber %x\n", HubDeviceExtension
->DeviceInformation
.PortNumber
);
1425 DPRINT1("DeviceDescriptor %x\n", HubDeviceExtension
->DeviceInformation
.DeviceDescriptor
);
1426 DPRINT1("HubAddress %x\n", HubDeviceExtension
->DeviceInformation
.HubAddress
);
1427 DPRINT1("NumberofPipes %x\n", HubDeviceExtension
->DeviceInformation
.NumberOfOpenPipes
);
1430 // Get Root Hubs Device Descriptor
1432 UsbBuildGetDescriptorRequest(Urb
,
1433 sizeof(Urb
->UrbControlDescriptorRequest
),
1434 USB_DEVICE_DESCRIPTOR_TYPE
,
1437 &HubDeviceExtension
->HubDeviceDescriptor
,
1439 sizeof(USB_DEVICE_DESCRIPTOR
),
1442 Urb
->UrbHeader
.UsbdDeviceHandle
= NULL
;//HubDeviceExtension->RootHubHandle;
1444 Status
= SubmitRequestToRootHub(RootHubDeviceObject
,
1445 IOCTL_INTERNAL_USB_SUBMIT_URB
,
1449 if (!NT_SUCCESS(Status
))
1451 DPRINT1("Failed to get HubDeviceDescriptor!\n");
1454 DumpDeviceDescriptor(&HubDeviceExtension
->HubDeviceDescriptor
);
1457 // Get Root Hubs Configuration Descriptor
1459 UsbBuildGetDescriptorRequest(Urb
,
1460 sizeof(Urb
->UrbControlDescriptorRequest
),
1461 USB_CONFIGURATION_DESCRIPTOR_TYPE
,
1464 &HubDeviceExtension
->HubConfigDescriptor
,
1466 sizeof(USB_CONFIGURATION_DESCRIPTOR
) + sizeof(USB_INTERFACE_DESCRIPTOR
) + sizeof(USB_ENDPOINT_DESCRIPTOR
),
1469 DPRINT1("RootHub Handle %x\n", HubDeviceExtension
->RootHubHandle
);
1470 Urb
->UrbHeader
.UsbdDeviceHandle
= NULL
;//HubDeviceExtension->RootHubHandle;
1472 Status
= SubmitRequestToRootHub(RootHubDeviceObject
,
1473 IOCTL_INTERNAL_USB_SUBMIT_URB
,
1477 if (!NT_SUCCESS(Status
))
1479 DPRINT1("Failed to get RootHub Configuration with status %x\n", Status
);
1482 ASSERT(HubDeviceExtension
->HubConfigDescriptor
.wTotalLength
);
1484 DumpConfigurationDescriptor(&HubDeviceExtension
->HubConfigDescriptor
);
1486 Status
= HubDeviceExtension
->HubInterface
.GetExtendedHubInformation(HubInterfaceBusContext
,
1487 RootHubDeviceObject
,
1488 &HubDeviceExtension
->UsbExtHubInfo
,
1489 sizeof(USB_EXTHUB_INFORMATION_0
),
1491 if (!NT_SUCCESS(Status
))
1493 DPRINT1("Failed to extended hub information. Unable to determine the number of ports!\n");
1497 DPRINT1("HubDeviceExtension->UsbExtHubInfo.NumberOfPorts %x\n", HubDeviceExtension
->UsbExtHubInfo
.NumberOfPorts
);
1500 // Get the Hub Descriptor
1502 UsbBuildVendorRequest(Urb
,
1503 URB_FUNCTION_CLASS_DEVICE
,
1504 sizeof(Urb
->UrbControlVendorClassRequest
),
1505 USBD_TRANSFER_DIRECTION_IN
| USBD_SHORT_TRANSFER_OK
,
1507 USB_REQUEST_GET_DESCRIPTOR
,
1508 USB_DEVICE_CLASS_RESERVED
,
1510 &HubDeviceExtension
->HubDescriptor
,
1512 sizeof(USB_HUB_DESCRIPTOR
),
1515 Urb
->UrbHeader
.UsbdDeviceHandle
= NULL
;//HubDeviceExtension->RootHubHandle;
1517 Status
= SubmitRequestToRootHub(RootHubDeviceObject
,
1518 IOCTL_INTERNAL_USB_SUBMIT_URB
,
1522 DPRINT1("bDescriptorType %x\n", HubDeviceExtension
->HubDescriptor
.bDescriptorType
);
1524 if (!NT_SUCCESS(Status
))
1526 DPRINT1("Failed to get Hub Descriptor!\n");
1528 return STATUS_UNSUCCESSFUL
;
1532 UsbBuildGetStatusRequest(Urb
,
1533 URB_FUNCTION_GET_STATUS_FROM_DEVICE
,
1538 Urb
->UrbHeader
.UsbdDeviceHandle
= NULL
;//HubDeviceExtension->RootHubHandle;
1540 Status
= SubmitRequestToRootHub(RootHubDeviceObject
,
1541 IOCTL_INTERNAL_USB_SUBMIT_URB
,
1544 if (!NT_SUCCESS(Status
))
1546 DPRINT1("Failed to get Hub Status!\n");
1548 return STATUS_UNSUCCESSFUL
;
1551 DPRINT1("HubStatus %x\n", HubStatus
);
1554 // Allocate memory for PortStatusChange to hold 2 USHORTs for each port on hub
1556 HubDeviceExtension
->PortStatusChange
= ExAllocatePoolWithTag(NonPagedPool
,
1557 sizeof(ULONG
) * HubDeviceExtension
->UsbExtHubInfo
.NumberOfPorts
,
1561 // Get the first Configuration Descriptor
1563 Pid
= USBD_ParseConfigurationDescriptorEx(&HubDeviceExtension
->HubConfigDescriptor
,
1564 &HubDeviceExtension
->HubConfigDescriptor
,
1565 -1, -1, -1, -1, -1);
1567 ASSERT(Pid
!= NULL
);
1569 InterfaceList
[0].InterfaceDescriptor
= Pid
;
1570 ConfigUrb
= USBD_CreateConfigurationRequestEx(&HubDeviceExtension
->HubConfigDescriptor
,
1571 (PUSBD_INTERFACE_LIST_ENTRY
)&InterfaceList
);
1572 ASSERT(ConfigUrb
!= NULL
);
1574 Status
= SubmitRequestToRootHub(RootHubDeviceObject
,
1575 IOCTL_INTERNAL_USB_SUBMIT_URB
,
1579 HubDeviceExtension
->ConfigurationHandle
= ConfigUrb
->UrbSelectConfiguration
.ConfigurationHandle
;
1580 HubDeviceExtension
->PipeHandle
= ConfigUrb
->UrbSelectConfiguration
.Interface
.Pipes
[0].PipeHandle
;
1581 DPRINT1("Configuration Handle %x\n", HubDeviceExtension
->ConfigurationHandle
);
1584 // check if function is available
1586 if (HubDeviceExtension
->UsbDInterface
.IsDeviceHighSpeed
)
1589 // is it high speed bus
1591 if (HubDeviceExtension
->UsbDInterface
.IsDeviceHighSpeed(HubInterfaceBusContext
))
1594 // initialize usb 2.0 hub
1596 Status
= HubDeviceExtension
->HubInterface
.Initialize20Hub(HubInterfaceBusContext
,
1597 HubDeviceExtension
->RootHubHandle
, 1);
1598 DPRINT1("Status %x\n", Status
);
1601 // FIXME handle error
1603 ASSERT(Status
== STATUS_SUCCESS
);
1607 ExFreePool(ConfigUrb
);
1610 // Enable power on all ports
1613 DPRINT1("Enabling PortPower on all ports!\n");
1615 for (PortId
= 1; PortId
<= HubDeviceExtension
->HubDescriptor
.bNumberOfPorts
; PortId
++)
1617 Status
= SetPortFeature(RootHubDeviceObject
, PortId
, PORT_POWER
);
1618 if (!NT_SUCCESS(Status
))
1619 DPRINT1("Failed to power on port %d\n", PortId
);
1621 Status
= ClearPortFeature(RootHubDeviceObject
, PortId
, C_PORT_CONNECTION
);
1622 if (!NT_SUCCESS(Status
))
1623 DPRINT1("Failed to power on port %d\n", PortId
);
1626 DPRINT1("RootHubInitNotification %x\n", HubDeviceExtension
->HubInterface
.RootHubInitNotification
);
1629 // init roo hub notification
1631 if (HubDeviceExtension
->HubInterface
.RootHubInitNotification
)
1633 Status
= HubDeviceExtension
->HubInterface
.RootHubInitNotification(HubInterfaceBusContext
,
1635 (PRH_INIT_CALLBACK
)RootHubInitCallbackFunction
);
1636 if (!NT_SUCCESS(Status
))
1638 DPRINT1("Failed to set callback\n");
1644 // Send the first SCE Request
1646 QueryStatusChangeEndpoint(DeviceObject
);
1653 case IRP_MN_QUERY_DEVICE_RELATIONS
:
1655 switch (Stack
->Parameters
.QueryDeviceRelations
.Type
)
1659 PDEVICE_RELATIONS DeviceRelations
= NULL
;
1660 DPRINT1("IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_RELATIONS / BusRelations\n");
1662 Status
= USBHUB_FdoQueryBusRelations(DeviceObject
, &DeviceRelations
);
1664 Information
= (ULONG_PTR
)DeviceRelations
;
1667 case RemovalRelations
:
1669 DPRINT1("IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_RELATIONS / RemovalRelations\n");
1670 return ForwardIrpAndForget(DeviceObject
, Irp
);
1673 DPRINT1("IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_RELATIONS / Unknown type 0x%lx\n",
1674 Stack
->Parameters
.QueryDeviceRelations
.Type
);
1675 return ForwardIrpAndForget(DeviceObject
, Irp
);
1679 case IRP_MN_QUERY_BUS_INFORMATION
:
1681 DPRINT1("IRP_MN_QUERY_BUS_INFORMATION\n");
1684 case IRP_MN_QUERY_ID
:
1686 DPRINT1("IRP_MN_QUERY_ID\n");
1689 case IRP_MN_QUERY_CAPABILITIES
:
1691 DPRINT1("IRP_MN_QUERY_CAPABILITIES\n");
1696 DPRINT1(" IRP_MJ_PNP / unknown minor function 0x%lx\n", Stack
->MinorFunction
);
1697 return ForwardIrpAndForget(DeviceObject
, Irp
);
1701 Irp
->IoStatus
.Information
= Information
;
1702 Irp
->IoStatus
.Status
= Status
;
1703 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
1708 USBHUB_FdoHandleDeviceControl(
1709 IN PDEVICE_OBJECT DeviceObject
,
1712 DPRINT1("FdoHandleDeviceControl\n");
1714 return STATUS_NOT_IMPLEMENTED
;