Author: janderwald
Date: Wed Feb 29 17:08:32 2012
New Revision: 55923

URL: http://svn.reactos.org/svn/reactos?rev=55923&view=rev
Log:
[USBHUB]
- Clean up code, fix memory leaks, check returns codes, add asserts
- Use root device handle which is is prerequisite for usb hub support
[USBLIB]
- Fix root hub handle checks
- Add more code for hub support

Modified:
    trunk/reactos/drivers/usb/usbhub/fdo.c
    trunk/reactos/lib/drivers/libusb/hub_controller.cpp

Modified: trunk/reactos/drivers/usb/usbhub/fdo.c
URL: 
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/usb/usbhub/fdo.c?rev=55923&r1=55922&r2=55923&view=diff
==============================================================================
--- trunk/reactos/drivers/usb/usbhub/fdo.c [iso-8859-1] (original)
+++ trunk/reactos/drivers/usb/usbhub/fdo.c [iso-8859-1] Wed Feb 29 17:08:32 2012
@@ -133,6 +133,10 @@
                           sizeof(PORT_STATUS_CHANGE),
                           0);
 
+    // FIXME: support usb hubs
+    Urb->UrbHeader.UsbdDeviceHandle = NULL;
+
+
     //
     // Query the Root Hub
     //
@@ -185,6 +189,10 @@
                           0,
                           0,
                           0);
+
+    // FIXME support usbhubs
+    Urb->UrbHeader.UsbdDeviceHandle = NULL;
+
     //
     // Query the Root Hub
     //
@@ -237,6 +245,10 @@
                           0,
                           0,
                           0);
+
+    // FIXME: support usb hubs
+    Urb->UrbHeader.UsbdDeviceHandle = NULL;
+
     //
     // Query the Root Hub
     //
@@ -515,15 +527,12 @@
                                            USBD_TRANSFER_DIRECTION_IN | 
USBD_SHORT_TRANSFER_OK,
                                            NULL);
 
-    //
-    // Set the device handle to null for roothub
-    //
-    PendingSCEUrb->UrbHeader.UsbdDeviceHandle = 
NULL;//HubDeviceExtension->RootHubHandle;
+    // Set the device handle
+    PendingSCEUrb->UrbHeader.UsbdDeviceHandle = 
HubDeviceExtension->RootHubHandle;
 
     //
     // Allocate an Irp
     //
-
     HubDeviceExtension->PendingSCEIrp = ExAllocatePoolWithTag(NonPagedPool,
                                                               
IoSizeOfIrp(RootHubDeviceObject->StackSize),
                                                               USB_HUB_TAG);
@@ -798,12 +807,8 @@
         ExFreePool(StringDesc);
         return STATUS_INSUFFICIENT_RESOURCES;
     }
-       DPRINT("Buffer %p\n", Buffer);
+
     RtlZeroMemory(Buffer, SizeNeeded);
-
-       DPRINT("SizeNeeded %lu\n", SizeNeeded);
-       DPRINT("Offset %lu\n", FIELD_OFFSET(USB_STRING_DESCRIPTOR, bLength));
-    DPRINT("Length %lu\n", SizeNeeded - FIELD_OFFSET(USB_STRING_DESCRIPTOR, 
bLength));
 
     //
     // Copy the string to destination
@@ -1503,6 +1508,450 @@
 }
 
 NTSTATUS
+USBHUB_FdoStartDevice(
+   IN PDEVICE_OBJECT DeviceObject,
+   IN PIRP Irp)
+{
+    PURB Urb;
+    PUSB_INTERFACE_DESCRIPTOR Pid;
+    ULONG Result = 0, PortId;
+    USBD_INTERFACE_LIST_ENTRY InterfaceList[2] = {{NULL, NULL}, {NULL, NULL}};
+    PURB ConfigUrb = NULL;
+    ULONG HubStatus;
+    PIO_STACK_LOCATION Stack;
+    NTSTATUS Status = STATUS_SUCCESS;
+    PHUB_DEVICE_EXTENSION HubDeviceExtension;
+    PDEVICE_OBJECT RootHubDeviceObject;
+    PVOID HubInterfaceBusContext , UsbDInterfaceBusContext;
+    PORT_STATUS_CHANGE StatusChange;
+
+    // get current stack location
+    Stack = IoGetCurrentIrpStackLocation(Irp);
+
+    // get hub device extension
+    HubDeviceExtension = (PHUB_DEVICE_EXTENSION) DeviceObject->DeviceExtension;
+
+    DPRINT("IRP_MJ_PNP / IRP_MN_START_DEVICE\n");
+
+    // Allocated size including the sizeof USBD_INTERFACE_LIST_ENTRY
+    Urb = ExAllocatePoolWithTag(NonPagedPool, sizeof(URB) + 
sizeof(USBD_INTERFACE_LIST_ENTRY), USB_HUB_TAG);
+    if (!Urb)
+    {
+         // no memory
+         return STATUS_INSUFFICIENT_RESOURCES;
+    }
+
+    // zero urb
+    RtlZeroMemory(Urb, sizeof(URB) + sizeof(USBD_INTERFACE_LIST_ENTRY));
+
+    // Get the Root Hub Pdo
+    Status = SubmitRequestToRootHub(HubDeviceExtension->LowerDeviceObject,
+                                    IOCTL_INTERNAL_USB_GET_ROOTHUB_PDO,
+                                    
&HubDeviceExtension->RootHubPhysicalDeviceObject,
+                                    
&HubDeviceExtension->RootHubFunctionalDeviceObject);
+    if (!NT_SUCCESS(Status))
+    {
+        // failed to obtain hub pdo
+        DPRINT1("IOCTL_INTERNAL_USB_GET_ROOTHUB_PDO failed with %x\n", Status);
+        ExFreePool(Urb);
+        return Status;
+    }
+
+    // sanity checks
+    ASSERT(HubDeviceExtension->RootHubPhysicalDeviceObject);
+    ASSERT(HubDeviceExtension->RootHubFunctionalDeviceObject);
+
+    // get roothub
+    RootHubDeviceObject = HubDeviceExtension->RootHubPhysicalDeviceObject;
+
+    // Send the StartDevice to RootHub
+    Status = ForwardIrpAndWait(RootHubDeviceObject, Irp);
+
+    if (!NT_SUCCESS(Status))
+    {
+        // failed to start pdo
+        DPRINT1("Failed to start the RootHub PDO\n");
+        ExFreePool(Urb);
+        return Status;
+    }
+
+    // Get the current number of hubs
+    Status = SubmitRequestToRootHub(RootHubDeviceObject,
+                                    IOCTL_INTERNAL_USB_GET_HUB_COUNT,
+                                    &HubDeviceExtension->NumberOfHubs, NULL);
+    if (!NT_SUCCESS(Status))
+    {
+        // failed to get number of hubs
+        DPRINT1("IOCTL_INTERNAL_USB_GET_HUB_COUNT failed with %x\n", Status);
+        ExFreePool(Urb);
+        return Status;
+    }
+
+    // Get the Hub Interface
+    Status = QueryInterface(RootHubDeviceObject,
+                            USB_BUS_INTERFACE_HUB_GUID,
+                            sizeof(USB_BUS_INTERFACE_HUB_V5),
+                            USB_BUSIF_HUB_VERSION_5,
+                            (PVOID)&HubDeviceExtension->HubInterface);
+
+    if (!NT_SUCCESS(Status))
+    {
+        // failed to get root hub interface
+        DPRINT1("Failed to get HUB_GUID interface with status 0x%08lx\n", 
Status);
+        ExFreePool(Urb);
+        return Status;
+    }
+
+    HubInterfaceBusContext = HubDeviceExtension->HubInterface.BusContext;
+
+    // Get the USBDI Interface
+    Status = QueryInterface(RootHubDeviceObject,
+                            USB_BUS_INTERFACE_USBDI_GUID,
+                            sizeof(USB_BUS_INTERFACE_USBDI_V2),
+                            USB_BUSIF_USBDI_VERSION_2,
+                            (PVOID)&HubDeviceExtension->UsbDInterface);
+
+    if (!NT_SUCCESS(Status))
+    {
+        // failed to get usbdi interface
+        DPRINT1("Failed to get USBDI_GUID interface with status 0x%08lx\n", 
Status);
+        ExFreePool(Urb);
+        return Status;
+    }
+
+    UsbDInterfaceBusContext = HubDeviceExtension->UsbDInterface.BusContext;
+
+    // Get Root Hub Device Handle
+    Status = SubmitRequestToRootHub(RootHubDeviceObject,
+                                    IOCTL_INTERNAL_USB_GET_DEVICE_HANDLE,
+                                    &HubDeviceExtension->RootHubHandle,
+                                    NULL);
+
+    if (!NT_SUCCESS(Status))
+    {
+        // failed
+        DPRINT1("IOCTL_INTERNAL_USB_GET_DEVICE_HANDLE failed with status 
0x%08lx\n", Status);
+        ExFreePool(Urb);
+        return Status;
+    }
+
+    //
+    // Get Hub Device Information
+    //
+    Status = 
HubDeviceExtension->HubInterface.QueryDeviceInformation(HubInterfaceBusContext,
+                                                                        
HubDeviceExtension->RootHubHandle,
+                                                                        
&HubDeviceExtension->DeviceInformation,
+                                                                        
sizeof(USB_DEVICE_INFORMATION_0),
+                                                                        
&Result);
+
+    DPRINT1("Status %x, Result 0x%08lx\n", Status, Result);
+    DPRINT1("InformationLevel %x\n", 
HubDeviceExtension->DeviceInformation.InformationLevel);
+    DPRINT1("ActualLength %x\n", 
HubDeviceExtension->DeviceInformation.ActualLength);
+    DPRINT1("PortNumber %x\n", 
HubDeviceExtension->DeviceInformation.PortNumber);
+    DPRINT1("DeviceDescriptor %x\n", 
HubDeviceExtension->DeviceInformation.DeviceDescriptor);
+    DPRINT1("HubAddress %x\n", 
HubDeviceExtension->DeviceInformation.HubAddress);
+    DPRINT1("NumberofPipes %x\n", 
HubDeviceExtension->DeviceInformation.NumberOfOpenPipes);
+
+    // Get Root Hubs Device Descriptor
+    UsbBuildGetDescriptorRequest(Urb,
+                                    sizeof(Urb->UrbControlDescriptorRequest),
+                                    USB_DEVICE_DESCRIPTOR_TYPE,
+                                    0,
+                                    0,
+                                    &HubDeviceExtension->HubDeviceDescriptor,
+                                    NULL,
+                                    sizeof(USB_DEVICE_DESCRIPTOR),
+                                    NULL);
+
+    // set device handle
+    Urb->UrbHeader.UsbdDeviceHandle = HubDeviceExtension->RootHubHandle;
+
+    // get hub device descriptor
+    Status = SubmitRequestToRootHub(RootHubDeviceObject,
+                                    IOCTL_INTERNAL_USB_SUBMIT_URB,
+                                    Urb,
+                                    NULL);
+
+    if (!NT_SUCCESS(Status))
+    {
+        // failed to get device descriptor of hub
+        DPRINT1("Failed to get HubDeviceDescriptor!\n");
+        ExFreePool(Urb);
+        return Status;
+    }
+
+    // build configuration request
+    UsbBuildGetDescriptorRequest(Urb,
+                                    sizeof(Urb->UrbControlDescriptorRequest),
+                                    USB_CONFIGURATION_DESCRIPTOR_TYPE,
+                                    0,
+                                    0,
+                                    &HubDeviceExtension->HubConfigDescriptor,
+                                    NULL,
+                                    sizeof(USB_CONFIGURATION_DESCRIPTOR) + 
sizeof(USB_INTERFACE_DESCRIPTOR) + sizeof(USB_ENDPOINT_DESCRIPTOR),
+                                    NULL);
+
+    // set device handle
+    Urb->UrbHeader.UsbdDeviceHandle = HubDeviceExtension->RootHubHandle;
+
+    // request configuration descriptor
+    Status = SubmitRequestToRootHub(RootHubDeviceObject,
+                                    IOCTL_INTERNAL_USB_SUBMIT_URB,
+                                    Urb,
+                                    NULL);
+
+    if (!NT_SUCCESS(Status))
+    {
+        // failed to get configuration descriptor
+        DPRINT1("Failed to get RootHub Configuration with status %x\n", 
Status);
+        ExFreePool(Urb);
+        return Status;
+    }
+
+    // sanity checks
+    ASSERT(HubDeviceExtension->HubConfigDescriptor.wTotalLength == 
sizeof(USB_CONFIGURATION_DESCRIPTOR) + sizeof(USB_INTERFACE_DESCRIPTOR) + 
sizeof(USB_ENDPOINT_DESCRIPTOR));
+    ASSERT(HubDeviceExtension->HubConfigDescriptor.bDescriptorType == 
USB_CONFIGURATION_DESCRIPTOR_TYPE);
+    ASSERT(HubDeviceExtension->HubConfigDescriptor.bLength == 
sizeof(USB_CONFIGURATION_DESCRIPTOR));
+    ASSERT(HubDeviceExtension->HubConfigDescriptor.bNumInterfaces == 1);
+    ASSERT(HubDeviceExtension->HubInterfaceDescriptor.bLength == 
sizeof(USB_INTERFACE_DESCRIPTOR));
+    ASSERT(HubDeviceExtension->HubInterfaceDescriptor.bDescriptorType == 
USB_INTERFACE_DESCRIPTOR_TYPE);
+    ASSERT(HubDeviceExtension->HubInterfaceDescriptor.bNumEndpoints == 1);
+    ASSERT(HubDeviceExtension->HubEndPointDescriptor.bDescriptorType == 
USB_ENDPOINT_DESCRIPTOR_TYPE);
+    ASSERT(HubDeviceExtension->HubEndPointDescriptor.bLength == 
sizeof(USB_ENDPOINT_DESCRIPTOR));
+    ASSERT(HubDeviceExtension->HubEndPointDescriptor.bmAttributes == 
USB_ENDPOINT_TYPE_INTERRUPT);
+    ASSERT(HubDeviceExtension->HubEndPointDescriptor.bEndpointAddress == 
0x81); // interrupt in
+
+    // get hub information
+    Status = 
HubDeviceExtension->HubInterface.GetExtendedHubInformation(HubInterfaceBusContext,
+                                                                        
RootHubDeviceObject,
+                                                                        
&HubDeviceExtension->UsbExtHubInfo,
+                                                                        
sizeof(USB_EXTHUB_INFORMATION_0),
+                                                                        
&Result);
+    if (!NT_SUCCESS(Status))
+    {
+        // failed to get hub information
+        DPRINT1("Failed to extended hub information. Unable to determine the 
number of ports!\n");
+        ExFreePool(Urb);
+        return Status;
+    }
+
+    if (!HubDeviceExtension->UsbExtHubInfo.NumberOfPorts)
+    {
+        // bogus port driver
+        DPRINT1("Failed to retrieve the number of ports\n");
+        ExFreePool(Urb);
+        return STATUS_UNSUCCESSFUL;
+    }
+
+    DPRINT1("HubDeviceExtension->UsbExtHubInfo.NumberOfPorts %x\n", 
HubDeviceExtension->UsbExtHubInfo.NumberOfPorts);
+
+    // Build hub descriptor request
+    UsbBuildVendorRequest(Urb,
+                            URB_FUNCTION_CLASS_DEVICE,
+                            sizeof(Urb->UrbControlVendorClassRequest),
+                            USBD_TRANSFER_DIRECTION_IN | 
USBD_SHORT_TRANSFER_OK,
+                            0,
+                            USB_REQUEST_GET_DESCRIPTOR,
+                            USB_DEVICE_CLASS_RESERVED,
+                            0,
+                            &HubDeviceExtension->HubDescriptor,
+                            NULL,
+                            sizeof(USB_HUB_DESCRIPTOR),
+                            NULL);
+
+    // set device handle
+    Urb->UrbHeader.UsbdDeviceHandle = HubDeviceExtension->RootHubHandle;
+
+    // send request
+    Status = SubmitRequestToRootHub(RootHubDeviceObject,
+                                    IOCTL_INTERNAL_USB_SUBMIT_URB,
+                                    Urb,
+                                    NULL);
+
+    if (!NT_SUCCESS(Status))
+    {
+        DPRINT1("Failed to get Hub Descriptor!\n");
+        ExFreePool(Urb);
+        return STATUS_UNSUCCESSFUL;
+    }
+
+    // sanity checks
+    ASSERT(HubDeviceExtension->HubDescriptor.bDescriptorLength == 
sizeof(USB_HUB_DESCRIPTOR));
+    ASSERT(HubDeviceExtension->HubDescriptor.bNumberOfPorts == 
HubDeviceExtension->UsbExtHubInfo.NumberOfPorts);
+    ASSERT(HubDeviceExtension->HubDescriptor.bDescriptorType == 0x29);
+
+    // build get status request
+    HubStatus = 0;
+    UsbBuildGetStatusRequest(Urb,
+                                URB_FUNCTION_GET_STATUS_FROM_DEVICE,
+                                0,
+                                &HubStatus,
+                                0,
+                                NULL);
+    // set device handle
+    Urb->UrbHeader.UsbdDeviceHandle = HubDeviceExtension->RootHubHandle;
+
+    // send request
+    Status = SubmitRequestToRootHub(RootHubDeviceObject,
+                                    IOCTL_INTERNAL_USB_SUBMIT_URB,
+                                    Urb,
+                                    NULL);
+    if (!NT_SUCCESS(Status))
+    {
+        // failed to get hub status
+        DPRINT1("Failed to get Hub Status!\n");
+        ExFreePool(Urb);
+        return STATUS_UNSUCCESSFUL;
+    }
+
+    // Allocate memory for PortStatusChange to hold 2 USHORTs for each port on 
hub
+    HubDeviceExtension->PortStatusChange = ExAllocatePoolWithTag(NonPagedPool,
+                                                                    
sizeof(ULONG) * HubDeviceExtension->UsbExtHubInfo.NumberOfPorts,
+                                                                    
USB_HUB_TAG);
+
+    // Get the first Configuration Descriptor
+    Pid = 
USBD_ParseConfigurationDescriptorEx(&HubDeviceExtension->HubConfigDescriptor,
+                                                
&HubDeviceExtension->HubConfigDescriptor,
+                                                -1, -1, -1, -1, -1);
+    if (Pid == NULL)
+    {
+        // failed parse hub descriptor
+        DPRINT1("Failed to parse configuration descriptor\n");
+        ExFreePool(Urb);
+        return STATUS_UNSUCCESSFUL;
+    }
+
+    // create configuration request
+    InterfaceList[0].InterfaceDescriptor = Pid;
+    ConfigUrb = 
USBD_CreateConfigurationRequestEx(&HubDeviceExtension->HubConfigDescriptor,
+                                                    
(PUSBD_INTERFACE_LIST_ENTRY)&InterfaceList);
+    if (ConfigUrb == NULL)
+    {
+        // failed to build urb
+        DPRINT1("Failed to allocate urb\n");
+        ExFreePool(Urb);
+        return STATUS_INSUFFICIENT_RESOURCES;
+    }
+
+    // send request
+    Status = SubmitRequestToRootHub(RootHubDeviceObject,
+                                    IOCTL_INTERNAL_USB_SUBMIT_URB,
+                                    ConfigUrb,
+                                    NULL);
+    if (!NT_SUCCESS(Status))
+    {
+        // failed to select configuration
+        DPRINT1("Failed to select configuration with %x\n", Status);
+        ExFreePool(Urb);
+        ExFreePool(ConfigUrb);
+        return Status;
+    }
+
+    // store configuration & pipe handle
+    HubDeviceExtension->ConfigurationHandle = 
ConfigUrb->UrbSelectConfiguration.ConfigurationHandle;
+    HubDeviceExtension->PipeHandle = 
ConfigUrb->UrbSelectConfiguration.Interface.Pipes[0].PipeHandle;
+    DPRINT("Configuration Handle %x\n", 
HubDeviceExtension->ConfigurationHandle);
+
+    // free urb
+    ExFreePool(ConfigUrb);
+
+    // check if function is available
+    if (HubDeviceExtension->UsbDInterface.IsDeviceHighSpeed)
+    {
+        // is it high speed bus
+        if 
(HubDeviceExtension->UsbDInterface.IsDeviceHighSpeed(HubInterfaceBusContext))
+        {
+            // initialize usb 2.0 hub
+            Status = 
HubDeviceExtension->HubInterface.Initialize20Hub(HubInterfaceBusContext,
+                                                                        
HubDeviceExtension->RootHubHandle, 1);
+            DPRINT("Status %x\n", Status);
+
+            // FIXME handle error
+            ASSERT(Status == STATUS_SUCCESS);
+        }
+    }
+
+
+    // Enable power on all ports
+    DPRINT("Enabling PortPower on all ports!\n");
+    for (PortId = 1; PortId <= 
HubDeviceExtension->HubDescriptor.bNumberOfPorts; PortId++)
+    {
+        Status = SetPortFeature(RootHubDeviceObject, PortId, PORT_POWER);
+        if (!NT_SUCCESS(Status))
+            DPRINT1("Failed to power on port %d\n", PortId);
+
+        Status = ClearPortFeature(RootHubDeviceObject, PortId, 
C_PORT_CONNECTION);
+        if (!NT_SUCCESS(Status))
+            DPRINT1("Failed to power on port %d\n", PortId);
+    }
+
+    // init root hub notification
+    if (HubDeviceExtension->HubInterface.RootHubInitNotification)
+    {
+        Status = 
HubDeviceExtension->HubInterface.RootHubInitNotification(HubInterfaceBusContext,
+                                                                            
DeviceObject,
+                                                                            
RootHubInitCallbackFunction);
+        if (!NT_SUCCESS(Status))
+        {
+            DPRINT1("Failed to set callback\n");
+            ExFreePool(Urb);
+            return Status;
+        }
+    }
+    else
+    {
+        // Send the first SCE Request
+        QueryStatusChangeEndpoint(DeviceObject);
+
+        //
+        // reset ports
+        //
+        for (PortId = 1; PortId <= 
HubDeviceExtension->HubDescriptor.bNumberOfPorts; PortId++)
+        {
+            //
+            // get port status
+            //
+            Status = 
GetPortStatusAndChange(HubDeviceExtension->RootHubPhysicalDeviceObject, PortId, 
&StatusChange);
+            if (NT_SUCCESS(Status))
+            {
+                //
+                // is there a device connected
+                //
+                if (StatusChange.Status & USB_PORT_STATUS_CONNECT)
+                {
+                    //
+                    // reset port
+                    //
+                    Status = 
SetPortFeature(HubDeviceExtension->RootHubPhysicalDeviceObject, PortId, 
PORT_RESET);
+                    if (!NT_SUCCESS(Status))
+                    {
+                        DPRINT1("Failed to reset on port %d\n", PortId);
+                    }
+                    else
+                    {
+                        //
+                        // wait for the reset to be handled since we want to 
enumerate synchronously
+                        //
+                        
KeWaitForSingleObject(&HubDeviceExtension->ResetComplete,
+                                                Executive,
+                                                KernelMode,
+                                                FALSE,
+                                                NULL);
+                        KeClearEvent(&HubDeviceExtension->ResetComplete);
+                    }
+                }
+            }
+        }
+    }
+
+    // free urb
+    ExFreePool(Urb);
+
+    // done
+    return Status;
+}
+
+NTSTATUS
 USBHUB_FdoHandlePnp(
     IN PDEVICE_OBJECT DeviceObject,
     IN PIRP Irp)
@@ -1511,9 +1960,6 @@
     NTSTATUS Status = STATUS_SUCCESS;
     ULONG_PTR Information = 0;
     PHUB_DEVICE_EXTENSION HubDeviceExtension;
-    PDEVICE_OBJECT RootHubDeviceObject;
-    PVOID HubInterfaceBusContext , UsbDInterfaceBusContext;
-    PORT_STATUS_CHANGE StatusChange;
 
     HubDeviceExtension = (PHUB_DEVICE_EXTENSION) DeviceObject->DeviceExtension;
 
@@ -1523,380 +1969,7 @@
     {
         case IRP_MN_START_DEVICE:
         {
-            PURB Urb;
-            PUSB_INTERFACE_DESCRIPTOR Pid;
-            ULONG Result = 0, PortId;
-            USBD_INTERFACE_LIST_ENTRY InterfaceList[2] = {{NULL, NULL}, {NULL, 
NULL}};
-            PURB ConfigUrb = NULL;
-            ULONG HubStatus;
-
-            DPRINT("IRP_MJ_PNP / IRP_MN_START_DEVICE\n");
-
-            //
-            // Allocated size including the sizeof USBD_INTERFACE_LIST_ENTRY
-            //
-            Urb = ExAllocatePoolWithTag(NonPagedPool, sizeof(URB) + 
sizeof(USBD_INTERFACE_LIST_ENTRY), USB_HUB_TAG);
-            RtlZeroMemory(Urb, sizeof(URB) + 
sizeof(USBD_INTERFACE_LIST_ENTRY));
-
-            //
-            // Get the Root Hub Pdo
-            //
-            SubmitRequestToRootHub(HubDeviceExtension->LowerDeviceObject,
-                                   IOCTL_INTERNAL_USB_GET_ROOTHUB_PDO,
-                                   
&HubDeviceExtension->RootHubPhysicalDeviceObject,
-                                   
&HubDeviceExtension->RootHubFunctionalDeviceObject);
-
-            RootHubDeviceObject = 
HubDeviceExtension->RootHubPhysicalDeviceObject;
-            ASSERT(HubDeviceExtension->RootHubPhysicalDeviceObject);
-            ASSERT(HubDeviceExtension->RootHubFunctionalDeviceObject);
-            DPRINT("RootPdo %x, RootFdo %x\n",
-                    HubDeviceExtension->RootHubPhysicalDeviceObject,
-                    HubDeviceExtension->RootHubFunctionalDeviceObject);
-
-            //
-            // Send the StartDevice to RootHub
-            //
-            Status = ForwardIrpAndWait(RootHubDeviceObject, Irp);
-
-            if (!NT_SUCCESS(Status))
-            {
-                DPRINT1("Failed to start the RootHub PDO\n");
-                ASSERT(FALSE);
-            }
-
-            //
-            // Get the current number of hubs
-            //
-            Status = SubmitRequestToRootHub(RootHubDeviceObject,
-                                            IOCTL_INTERNAL_USB_GET_HUB_COUNT,
-                                            &HubDeviceExtension->NumberOfHubs, 
NULL);
-
-            //
-            // Get the Hub Interface
-            //
-            Status = QueryInterface(RootHubDeviceObject,
-                                    USB_BUS_INTERFACE_HUB_GUID,
-                                    sizeof(USB_BUS_INTERFACE_HUB_V5),
-                                    USB_BUSIF_HUB_VERSION_5,
-                                    (PVOID)&HubDeviceExtension->HubInterface);
-
-            if (!NT_SUCCESS(Status))
-            {
-                DPRINT1("Failed to get HUB_GUID interface with status 
0x%08lx\n", Status);
-                return STATUS_UNSUCCESSFUL;
-            }
-
-            HubInterfaceBusContext = 
HubDeviceExtension->HubInterface.BusContext;
-
-            //
-            // Get the USBDI Interface
-            //
-            Status = QueryInterface(RootHubDeviceObject,
-                                    USB_BUS_INTERFACE_USBDI_GUID,
-                                    sizeof(USB_BUS_INTERFACE_USBDI_V2),
-                                    USB_BUSIF_USBDI_VERSION_2,
-                                    (PVOID)&HubDeviceExtension->UsbDInterface);
-
-            if (!NT_SUCCESS(Status))
-            {
-                DPRINT1("Failed to get USBDI_GUID interface with status 
0x%08lx\n", Status);
-                return Status;
-            }
-
-            UsbDInterfaceBusContext = 
HubDeviceExtension->UsbDInterface.BusContext;
-
-            //
-            // Get Root Hub Device Handle
-            //
-            Status = SubmitRequestToRootHub(RootHubDeviceObject,
-                                            
IOCTL_INTERNAL_USB_GET_DEVICE_HANDLE,
-                                            &HubDeviceExtension->RootHubHandle,
-                                            NULL);
-
-            if (!NT_SUCCESS(Status))
-            {
-                DPRINT1("GetRootHubDeviceHandle failed with status 0x%08lx\n", 
Status);
-                return Status;
-            }
-
-            //
-            // Get Hub Device Information
-            //
-            Status = 
HubDeviceExtension->HubInterface.QueryDeviceInformation(HubInterfaceBusContext,
-                                                                             
HubDeviceExtension->RootHubHandle,
-                                                                             
&HubDeviceExtension->DeviceInformation,
-                                                                             
sizeof(USB_DEVICE_INFORMATION_0),
-                                                                             
&Result);
-
-            DPRINT1("Status %x, Result 0x%08lx\n", Status, Result);
-            DPRINT1("InformationLevel %x\n", 
HubDeviceExtension->DeviceInformation.InformationLevel);
-            DPRINT1("ActualLength %x\n", 
HubDeviceExtension->DeviceInformation.ActualLength);
-            DPRINT1("PortNumber %x\n", 
HubDeviceExtension->DeviceInformation.PortNumber);
-            DPRINT1("DeviceDescriptor %x\n", 
HubDeviceExtension->DeviceInformation.DeviceDescriptor);
-            DPRINT1("HubAddress %x\n", 
HubDeviceExtension->DeviceInformation.HubAddress);
-            DPRINT1("NumberofPipes %x\n", 
HubDeviceExtension->DeviceInformation.NumberOfOpenPipes);
-
-            //
-            // Get Root Hubs Device Descriptor
-            //
-            UsbBuildGetDescriptorRequest(Urb,
-                                         
sizeof(Urb->UrbControlDescriptorRequest),
-                                         USB_DEVICE_DESCRIPTOR_TYPE,
-                                         0,
-                                         0,
-                                         
&HubDeviceExtension->HubDeviceDescriptor,
-                                         NULL,
-                                         sizeof(USB_DEVICE_DESCRIPTOR),
-                                         NULL);
-
-            Urb->UrbHeader.UsbdDeviceHandle = 
NULL;//HubDeviceExtension->RootHubHandle;
-
-            Status = SubmitRequestToRootHub(RootHubDeviceObject,
-                                            IOCTL_INTERNAL_USB_SUBMIT_URB,
-                                            Urb,
-                                            NULL);
-
-            if (!NT_SUCCESS(Status))
-            {
-                DPRINT1("Failed to get HubDeviceDescriptor!\n");
-            }
-
-            DumpDeviceDescriptor(&HubDeviceExtension->HubDeviceDescriptor);
-
-            //
-            // Get Root Hubs Configuration Descriptor
-            //
-            UsbBuildGetDescriptorRequest(Urb,
-                                         
sizeof(Urb->UrbControlDescriptorRequest),
-                                         USB_CONFIGURATION_DESCRIPTOR_TYPE,
-                                         0,
-                                         0,
-                                         
&HubDeviceExtension->HubConfigDescriptor,
-                                         NULL,
-                                         sizeof(USB_CONFIGURATION_DESCRIPTOR) 
+ sizeof(USB_INTERFACE_DESCRIPTOR) + sizeof(USB_ENDPOINT_DESCRIPTOR),
-                                         NULL);
-
-            DPRINT("RootHub Handle %x\n", HubDeviceExtension->RootHubHandle);
-            Urb->UrbHeader.UsbdDeviceHandle = 
NULL;//HubDeviceExtension->RootHubHandle;
-
-            Status = SubmitRequestToRootHub(RootHubDeviceObject,
-                                            IOCTL_INTERNAL_USB_SUBMIT_URB,
-                                            Urb,
-                                            NULL);
-
-            if (!NT_SUCCESS(Status))
-            {
-                DPRINT1("Failed to get RootHub Configuration with status 
%x\n", Status);
-                ASSERT(FALSE);
-            }
-            ASSERT(HubDeviceExtension->HubConfigDescriptor.wTotalLength);
-
-            
DumpConfigurationDescriptor(&HubDeviceExtension->HubConfigDescriptor);
-
-            Status = 
HubDeviceExtension->HubInterface.GetExtendedHubInformation(HubInterfaceBusContext,
-                                                                               
 RootHubDeviceObject,
-                                                                               
 &HubDeviceExtension->UsbExtHubInfo,
-                                                                               
 sizeof(USB_EXTHUB_INFORMATION_0),
-                                                                               
 &Result);
-            if (!NT_SUCCESS(Status))
-            {
-                DPRINT1("Failed to extended hub information. Unable to 
determine the number of ports!\n");
-                ASSERT(FALSE);
-            }
-
-            DPRINT1("HubDeviceExtension->UsbExtHubInfo.NumberOfPorts %x\n", 
HubDeviceExtension->UsbExtHubInfo.NumberOfPorts);
-
-            //
-            // Get the Hub Descriptor
-            //
-            UsbBuildVendorRequest(Urb,
-                                  URB_FUNCTION_CLASS_DEVICE,
-                                  sizeof(Urb->UrbControlVendorClassRequest),
-                                  USBD_TRANSFER_DIRECTION_IN | 
USBD_SHORT_TRANSFER_OK,
-                                  0,
-                                  USB_REQUEST_GET_DESCRIPTOR,
-                                  USB_DEVICE_CLASS_RESERVED,
-                                  0,
-                                  &HubDeviceExtension->HubDescriptor,
-                                  NULL,
-                                  sizeof(USB_HUB_DESCRIPTOR),
-                                  NULL);
-
-            Urb->UrbHeader.UsbdDeviceHandle = 
NULL;//HubDeviceExtension->RootHubHandle;
-
-            Status = SubmitRequestToRootHub(RootHubDeviceObject,
-                                            IOCTL_INTERNAL_USB_SUBMIT_URB,
-                                            Urb,
-                                            NULL);
-
-            DPRINT1("bDescriptorType %x\n", 
HubDeviceExtension->HubDescriptor.bDescriptorType);
-
-            if (!NT_SUCCESS(Status))
-            {
-                DPRINT1("Failed to get Hub Descriptor!\n");
-                ExFreePool(Urb);
-                return STATUS_UNSUCCESSFUL;
-            }
-
-            HubStatus = 0;
-            UsbBuildGetStatusRequest(Urb,
-                                     URB_FUNCTION_GET_STATUS_FROM_DEVICE,
-                                     0,
-                                     &HubStatus,
-                                     0,
-                                     NULL);
-            Urb->UrbHeader.UsbdDeviceHandle = 
NULL;//HubDeviceExtension->RootHubHandle;
-
-            Status = SubmitRequestToRootHub(RootHubDeviceObject,
-                                            IOCTL_INTERNAL_USB_SUBMIT_URB,
-                                            Urb,
-                                            NULL);
-            if (!NT_SUCCESS(Status))
-            {
-                DPRINT1("Failed to get Hub Status!\n");
-                ExFreePool(Urb);
-                return STATUS_UNSUCCESSFUL;
-            }
-
-            DPRINT1("HubStatus %x\n", HubStatus);
-
-            //
-            // Allocate memory for PortStatusChange to hold 2 USHORTs for each 
port on hub
-            //
-            HubDeviceExtension->PortStatusChange = 
ExAllocatePoolWithTag(NonPagedPool,
-                                                                         
sizeof(ULONG) * HubDeviceExtension->UsbExtHubInfo.NumberOfPorts,
-                                                                         
USB_HUB_TAG);
-
-            //
-            // Get the first Configuration Descriptor
-            //
-            Pid = 
USBD_ParseConfigurationDescriptorEx(&HubDeviceExtension->HubConfigDescriptor,
-                                                      
&HubDeviceExtension->HubConfigDescriptor,
-                                                     -1, -1, -1, -1, -1);
-
-            ASSERT(Pid != NULL);
-
-            InterfaceList[0].InterfaceDescriptor = Pid;
-            ConfigUrb = 
USBD_CreateConfigurationRequestEx(&HubDeviceExtension->HubConfigDescriptor,
-                                                          
(PUSBD_INTERFACE_LIST_ENTRY)&InterfaceList);
-            ASSERT(ConfigUrb != NULL);
-
-            Status = SubmitRequestToRootHub(RootHubDeviceObject,
-                                            IOCTL_INTERNAL_USB_SUBMIT_URB,
-                                            ConfigUrb,
-                                            NULL);
-
-            HubDeviceExtension->ConfigurationHandle = 
ConfigUrb->UrbSelectConfiguration.ConfigurationHandle;
-            HubDeviceExtension->PipeHandle = 
ConfigUrb->UrbSelectConfiguration.Interface.Pipes[0].PipeHandle;
-            DPRINT("Configuration Handle %x\n", 
HubDeviceExtension->ConfigurationHandle);
-
-            //
-            // check if function is available
-            //
-            if (HubDeviceExtension->UsbDInterface.IsDeviceHighSpeed)
-            {
-                //
-                // is it high speed bus
-                //
-                if 
(HubDeviceExtension->UsbDInterface.IsDeviceHighSpeed(HubInterfaceBusContext))
-                {
-                    //
-                    // initialize usb 2.0 hub
-                    //
-                    Status = 
HubDeviceExtension->HubInterface.Initialize20Hub(HubInterfaceBusContext,
-                                                                              
HubDeviceExtension->RootHubHandle, 1);
-                    DPRINT("Status %x\n", Status);
-
-                    //
-                    // FIXME handle error
-                    //
-                    ASSERT(Status == STATUS_SUCCESS);
-                }
-            }
-
-            ExFreePool(ConfigUrb);
-
-            //
-            // Enable power on all ports
-            //
-
-            DPRINT("Enabling PortPower on all ports!\n");
-
-            for (PortId = 1; PortId <= 
HubDeviceExtension->HubDescriptor.bNumberOfPorts; PortId++)
-            {
-                Status = SetPortFeature(RootHubDeviceObject, PortId, 
PORT_POWER);
-                if (!NT_SUCCESS(Status))
-                    DPRINT1("Failed to power on port %d\n", PortId);
-
-                Status = ClearPortFeature(RootHubDeviceObject, PortId, 
C_PORT_CONNECTION);
-                if (!NT_SUCCESS(Status))
-                    DPRINT1("Failed to power on port %d\n", PortId);
-            }
-
-            DPRINT("RootHubInitNotification %x\n", 
HubDeviceExtension->HubInterface.RootHubInitNotification);
-
-            //
-            // init root hub notification
-            //
-            if (HubDeviceExtension->HubInterface.RootHubInitNotification)
-            {
-                Status = 
HubDeviceExtension->HubInterface.RootHubInitNotification(HubInterfaceBusContext,
-                                                                               
   DeviceObject,
-                                                                               
   RootHubInitCallbackFunction);
-                if (!NT_SUCCESS(Status))
-                {
-                    DPRINT1("Failed to set callback\n");
-                }
-            }
-            else
-            {
-                //
-                // Send the first SCE Request
-                //
-                QueryStatusChangeEndpoint(DeviceObject);
-
-                //
-                // reset ports
-                //
-                for (PortId = 1; PortId <= 
HubDeviceExtension->HubDescriptor.bNumberOfPorts; PortId++)
-                {
-                    //
-                    // get port status
-                    //
-                    Status = 
GetPortStatusAndChange(HubDeviceExtension->RootHubPhysicalDeviceObject, PortId, 
&StatusChange);
-                    if (NT_SUCCESS(Status))
-                    {
-                        //
-                        // is there a device connected
-                        //
-                        if (StatusChange.Status & USB_PORT_STATUS_CONNECT)
-                        {
-                            //
-                            // reset port
-                            //
-                            Status = 
SetPortFeature(HubDeviceExtension->RootHubPhysicalDeviceObject, PortId, 
PORT_RESET);
-                            if (!NT_SUCCESS(Status))
-                            {
-                                DPRINT1("Failed to reset on port %d\n", 
PortId);
-                            }
-                            else
-                            {
-                                //
-                                // wait for the reset to be handled since we 
want to enumerate synchronously
-                                //
-                                
KeWaitForSingleObject(&HubDeviceExtension->ResetComplete,
-                                                      Executive,
-                                                      KernelMode,
-                                                      FALSE,
-                                                      NULL);
-                                
KeClearEvent(&HubDeviceExtension->ResetComplete);
-                            }
-                        }
-                    }
-                }
-            }
-
-            ExFreePool(Urb);
+            Status = USBHUB_FdoStartDevice(DeviceObject, Irp);
             break;
         }
 

Modified: trunk/reactos/lib/drivers/libusb/hub_controller.cpp
URL: 
http://svn.reactos.org/svn/reactos/trunk/reactos/lib/drivers/libusb/hub_controller.cpp?rev=55923&r1=55922&r2=55923&view=diff
==============================================================================
--- trunk/reactos/lib/drivers/libusb/hub_controller.cpp [iso-8859-1] (original)
+++ trunk/reactos/lib/drivers/libusb/hub_controller.cpp [iso-8859-1] Wed Feb 29 
17:08:32 2012
@@ -836,7 +836,7 @@
     //
     // Is the Request for the root hub
     //
-    if (Urb->UrbHeader.UsbdDeviceHandle == 0)
+    if (Urb->UrbHeader.UsbdDeviceHandle == PVOID(this))
     {
         ASSERT(m_PendingSCEIrp == NULL);
         if (QueryStatusChageEndpoint(Irp))
@@ -1179,7 +1179,7 @@
     DeviceStatus = (PUSHORT)Urb->UrbControlGetStatusRequest.TransferBuffer;
 
 
-    if (Urb->UrbHeader.UsbdDeviceHandle == NULL)
+    if (Urb->UrbHeader.UsbdDeviceHandle == PVOID(this))
     {
         //
         // FIXME need more flags ?
@@ -1311,46 +1311,66 @@
                 case USB_DEVICE_CLASS_RESERVED: // FALL THROUGH
                 case USB_DEVICE_CLASS_HUB:
                 {
-                    //
-                    // sanity checks
-                    //
-                    
PC_ASSERT(Urb->UrbControlVendorClassRequest.TransferBuffer);
-                    
PC_ASSERT(Urb->UrbControlVendorClassRequest.TransferBufferLength >= 
sizeof(USB_HUB_DESCRIPTOR));
-
-                    //
-                    // get hub descriptor
-                    //
-                    UsbHubDescriptor = 
(PUSB_HUB_DESCRIPTOR)Urb->UrbControlVendorClassRequest.TransferBuffer;
-
-                    //
-                    // one hub is handled
-                    //
-                    UsbHubDescriptor->bDescriptorLength = 
sizeof(USB_HUB_DESCRIPTOR);
-                    Urb->UrbControlVendorClassRequest.TransferBufferLength = 
sizeof(USB_HUB_DESCRIPTOR);
-
-                    //
-                    // type should 0x29 according to msdn
-                    //
-                    UsbHubDescriptor->bDescriptorType = 0x29;
-
-                    //
-                    // get port count
-                    //
-                    Status = m_Hardware->GetDeviceDetails(&Dummy1, &Dummy1, 
&PortCount, &Dummy2);
-                    PC_ASSERT(Status == STATUS_SUCCESS);
-
-                    //
-                    // FIXME: retrieve values
-                    //
-                    UsbHubDescriptor->bNumberOfPorts = (UCHAR)PortCount;
-                    UsbHubDescriptor->wHubCharacteristics = 0x00;
-                    UsbHubDescriptor->bPowerOnToPowerGood = 0x01;
-                    UsbHubDescriptor->bHubControlCurrent = 0x00;
-
-                    //
-                    // done
-                    //
-                    Status = STATUS_SUCCESS;
+                    if (Urb->UrbHeader.UsbdDeviceHandle == PVOID(this))
+                    {
+                        //
+                        // sanity checks
+                        //
+                        
PC_ASSERT(Urb->UrbControlVendorClassRequest.TransferBuffer);
+                        
PC_ASSERT(Urb->UrbControlVendorClassRequest.TransferBufferLength >= 
sizeof(USB_HUB_DESCRIPTOR));
+
+                        //
+                        // get hub descriptor
+                        //
+                        UsbHubDescriptor = 
(PUSB_HUB_DESCRIPTOR)Urb->UrbControlVendorClassRequest.TransferBuffer;
+
+                        //
+                        // one hub is handled
+                        //
+                        UsbHubDescriptor->bDescriptorLength = 
sizeof(USB_HUB_DESCRIPTOR);
+                        Urb->UrbControlVendorClassRequest.TransferBufferLength 
= sizeof(USB_HUB_DESCRIPTOR);
+
+                        //
+                        // type should 0x29 according to msdn
+                        //
+                        UsbHubDescriptor->bDescriptorType = 0x29;
+
+                        //
+                        // get port count
+                        //
+                        Status = m_Hardware->GetDeviceDetails(&Dummy1, 
&Dummy1, &PortCount, &Dummy2);
+                        PC_ASSERT(Status == STATUS_SUCCESS);
+
+                        //
+                        // FIXME: retrieve values
+                        //
+                        UsbHubDescriptor->bNumberOfPorts = (UCHAR)PortCount;
+                        UsbHubDescriptor->wHubCharacteristics = 0x00;
+                        UsbHubDescriptor->bPowerOnToPowerGood = 0x01;
+                        UsbHubDescriptor->bHubControlCurrent = 0x00;
+
+                        //
+                        // done
+                        //
+                        Status = STATUS_SUCCESS;
+                    }
+                    else
+                    {
+                        if 
(!ValidateUsbDevice(PUSBDEVICE(Urb->UrbHeader.UsbdDeviceHandle)))
+                        {
+                            DPRINT1("HandleClassDevice invalid device handle 
%p\n", Urb->UrbHeader.UsbdDeviceHandle);
+                            //
+                            // invalid device handle
+                            //
+                            return STATUS_DEVICE_NOT_CONNECTED;
+                        }
+
+                        //
+                        // FIXME: implement support for real hubs
+                        //
+                        UNIMPLEMENTED
+                        Status = STATUS_NOT_IMPLEMENTED;
+                    }
                     break;
                }
                default:
@@ -1450,7 +1470,7 @@
             PC_ASSERT(Urb->UrbControlDescriptorRequest.TransferBufferLength >= 
sizeof(USB_DEVICE_DESCRIPTOR));
             PC_ASSERT(Urb->UrbControlDescriptorRequest.TransferBuffer);
 
-            if (Urb->UrbHeader.UsbdDeviceHandle == NULL)
+            if (Urb->UrbHeader.UsbdDeviceHandle == PVOID(this))
             {
                 //
                 // copy root hub device descriptor
@@ -1494,7 +1514,7 @@
             PC_ASSERT(Urb->UrbControlDescriptorRequest.TransferBuffer);
             PC_ASSERT(Urb->UrbControlDescriptorRequest.TransferBufferLength >= 
sizeof(USB_CONFIGURATION_DESCRIPTOR));
 
-            if (Urb->UrbHeader.UsbdDeviceHandle == NULL)
+            if (Urb->UrbHeader.UsbdDeviceHandle == PVOID(this))
             {
                 //
                 // request is for the root bus controller


Reply via email to