Author: janderwald
Date: Wed Feb 29 18:51:07 2012
New Revision: 55927

URL: http://svn.reactos.org/svn/reactos?rev=55927&view=rev
Log:
[USBHUB]
- Check if FDO is root hub fdo
- Partly implement fdo hub initialization
- Implement IOCTL_INTERNAL_USB_GET_DEVICE_HANDLE, 
IOCTL_INTERNAL_USB_GET_ROOTHUB_PDO

Added:
    trunk/reactos/drivers/usb/usbhub/hub_fdo.c   (with props)
Modified:
    trunk/reactos/drivers/usb/usbhub/CMakeLists.txt
    trunk/reactos/drivers/usb/usbhub/fdo.c
    trunk/reactos/drivers/usb/usbhub/misc.c
    trunk/reactos/drivers/usb/usbhub/pdo.c
    trunk/reactos/drivers/usb/usbhub/usbhub.h

Modified: trunk/reactos/drivers/usb/usbhub/CMakeLists.txt
URL: 
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/usb/usbhub/CMakeLists.txt?rev=55927&r1=55926&r2=55927&view=diff
==============================================================================
--- trunk/reactos/drivers/usb/usbhub/CMakeLists.txt [iso-8859-1] (original)
+++ trunk/reactos/drivers/usb/usbhub/CMakeLists.txt [iso-8859-1] Wed Feb 29 
18:51:07 2012
@@ -3,7 +3,7 @@
 
 include_directories(${REACTOS_SOURCE_DIR}/ntoskrnl/include)
 
-add_library(usbhub SHARED fdo.c misc.c pdo.c usbhub.c usbhub.rc)
+add_library(usbhub SHARED fdo.c misc.c pdo.c hub_fdo.c usbhub.c usbhub.rc)
 
 target_link_libraries(usbhub ${PSEH_LIB})
 

Modified: trunk/reactos/drivers/usb/usbhub/fdo.c
URL: 
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/usb/usbhub/fdo.c?rev=55927&r1=55926&r2=55927&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 18:51:07 2012
@@ -27,71 +27,6 @@
     IN PDEVICE_OBJECT UsbHubDeviceObject,
     IN LONG PortId);
 
-NTSTATUS
-SubmitRequestToRootHub(
-    IN PDEVICE_OBJECT RootHubDeviceObject,
-    IN ULONG IoControlCode,
-    OUT PVOID OutParameter1,
-    OUT PVOID OutParameter2)
-{
-    KEVENT Event;
-    PIRP Irp;
-    IO_STATUS_BLOCK IoStatus;
-    NTSTATUS Status;
-    PIO_STACK_LOCATION Stack = NULL;
-
-    KeInitializeEvent(&Event, NotificationEvent, FALSE);
-
-    //
-    // Build Control Request
-    //
-    Irp = IoBuildDeviceIoControlRequest(IoControlCode,
-                                        RootHubDeviceObject,
-                                        NULL, 0,
-                                        NULL, 0,
-                                        TRUE,
-                                        &Event,
-                                        &IoStatus);
-
-    if (Irp == NULL)
-    {
-        DPRINT("Usbhub: IoBuildDeviceIoControlRequest() failed\n");
-        return STATUS_INSUFFICIENT_RESOURCES;
-    }
-
-    //
-    // Initialize the status block before sending the IRP
-    //
-    IoStatus.Status = STATUS_NOT_SUPPORTED;
-    IoStatus.Information = 0;
-
-    //
-    // Get Next Stack Location and Initialize it
-    //
-    Stack = IoGetNextIrpStackLocation(Irp);
-    Stack->Parameters.Others.Argument1 = OutParameter1;
-    Stack->Parameters.Others.Argument2 = OutParameter2;
-
-    //
-    // Call RootHub
-    //
-    Status = IoCallDriver(RootHubDeviceObject, Irp);
-
-    //
-    // Its ok to block here as this function is called in an nonarbitrary 
thread
-    //
-    if    (Status == STATUS_PENDING)
-    {
-        KeWaitForSingleObject(&Event, Suspended, KernelMode, FALSE, NULL);
-        Status = IoStatus.Status;
-    }
-
-    //
-    // The IO Manager will free the IRP
-    //
-
-    return Status;
-}
 
 NTSTATUS
 GetPortStatusAndChange(
@@ -1506,6 +1441,31 @@
         }
     }
 }
+
+BOOLEAN
+USBHUB_IsRootHubFDO(
+   IN PDEVICE_OBJECT DeviceObject)
+{
+    NTSTATUS Status;
+    PDEVICE_OBJECT RootHubPhysicalDeviceObject = NULL;
+    PHUB_DEVICE_EXTENSION HubDeviceExtension;
+
+    // get hub device extension
+    HubDeviceExtension = (PHUB_DEVICE_EXTENSION) DeviceObject->DeviceExtension;
+
+    // Get the Root Hub Pdo
+    Status = SubmitRequestToRootHub(HubDeviceExtension->LowerDeviceObject,
+                                    IOCTL_INTERNAL_USB_GET_ROOTHUB_PDO,
+                                    &RootHubPhysicalDeviceObject,
+                                    NULL);
+
+    // FIXME handle error
+    ASSERT(NT_SUCCESS(Status));
+
+    // physical device object is only obtained for root hubs
+    return (RootHubPhysicalDeviceObject != NULL);
+}
+
 
 NTSTATUS
 USBHUB_FdoStartDevice(
@@ -1969,7 +1929,15 @@
     {
         case IRP_MN_START_DEVICE:
         {
-            Status = USBHUB_FdoStartDevice(DeviceObject, Irp);
+            if (USBHUB_IsRootHubFDO(DeviceObject))
+            {
+                // start root hub fdo
+                Status = USBHUB_FdoStartDevice(DeviceObject, Irp);
+            }
+            else
+            {
+                Status = USBHUB_ParentFDOStartDevice(DeviceObject, Irp);
+            }
             break;
         }
 

Added: trunk/reactos/drivers/usb/usbhub/hub_fdo.c
URL: 
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/usb/usbhub/hub_fdo.c?rev=55927&view=auto
==============================================================================
--- trunk/reactos/drivers/usb/usbhub/hub_fdo.c (added)
+++ trunk/reactos/drivers/usb/usbhub/hub_fdo.c [iso-8859-1] Wed Feb 29 18:51:07 
2012
@@ -1,0 +1,212 @@
+/*
+ * PROJECT:         ReactOS Universal Serial Bus Hub Driver
+ * LICENSE:         GPL - See COPYING in the top level directory
+ * FILE:            drivers/usb/usbhub/hub_fdo.c
+ * PURPOSE:         Hub FDO
+ * PROGRAMMERS:
+ *                  Michael Martin ([email protected])
+ *                  Johannes Anderwald ([email protected])
+ */
+#include "usbhub.h"
+
+NTSTATUS
+USBHUB_ParentFDOStartDevice(
+    IN PDEVICE_OBJECT DeviceObject,
+    IN PIRP Irp)
+{
+    PHUB_DEVICE_EXTENSION HubDeviceExtension;
+    PURB Urb, ConfigurationUrb;
+    PUSB_INTERFACE_DESCRIPTOR InterfaceDescriptor;
+    PUSBD_INTERFACE_LIST_ENTRY InterfaceList;
+    ULONG Index;
+    NTSTATUS Status;
+
+    // get hub device extension
+    HubDeviceExtension = (PHUB_DEVICE_EXTENSION) DeviceObject->DeviceExtension;
+
+    // Send the StartDevice to lower device object
+    Status = ForwardIrpAndWait(HubDeviceExtension->LowerDeviceObject, Irp);
+
+    if (!NT_SUCCESS(Status))
+    {
+        // failed to start pdo
+        DPRINT1("Failed to start the RootHub PDO\n");
+        return Status;
+    }
+
+    // FIXME get capabilities
+
+    Urb = ExAllocatePool(NonPagedPool, sizeof(URB));
+    if (!Urb)
+    {
+        // no memory
+        DPRINT1("No memory\n");
+        return STATUS_INSUFFICIENT_RESOURCES;
+    }
+
+
+    // lets get device descriptor
+    UsbBuildGetDescriptorRequest(Urb,
+                                    sizeof(Urb->UrbControlDescriptorRequest),
+                                    USB_DEVICE_DESCRIPTOR_TYPE,
+                                    0,
+                                    0,
+                                    &HubDeviceExtension->HubDeviceDescriptor,
+                                    NULL,
+                                    sizeof(USB_DEVICE_DESCRIPTOR),
+                                    NULL);
+
+
+    // get hub device descriptor
+    Status = SubmitRequestToRootHub(HubDeviceExtension->LowerDeviceObject,
+                                    IOCTL_INTERNAL_USB_SUBMIT_URB,
+                                    Urb,
+                                    NULL);
+
+    if (!NT_SUCCESS(Status))
+    {
+        // failed to get device descriptor of hub
+        DPRINT1("Failed to get hub device descriptor with Status %x!\n", 
Status);
+        ExFreePool(Urb);
+        return Status;
+    }
+
+    // now get 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);
+
+    // request configuration descriptor
+    Status = SubmitRequestToRootHub(HubDeviceExtension->LowerDeviceObject,
+                                    IOCTL_INTERNAL_USB_SUBMIT_URB,
+                                    Urb,
+                                    NULL);
+
+    if (!NT_SUCCESS(Status))
+    {
+        // failed to get configuration descriptor
+        DPRINT1("Failed to get hub configuration descriptor 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
+
+    // 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);
+
+    // send request
+    Status = SubmitRequestToRootHub(HubDeviceExtension->LowerDeviceObject,
+                                    IOCTL_INTERNAL_USB_SUBMIT_URB,
+                                    Urb,
+                                    NULL);
+
+    if (!NT_SUCCESS(Status))
+    {
+        DPRINT1("Failed to get Hub Descriptor Status %x!\n", Status);
+        ExFreePool(Urb);
+        return STATUS_UNSUCCESSFUL;
+    }
+
+    // sanity checks
+    ASSERT(HubDeviceExtension->HubDescriptor.bDescriptorLength == 
sizeof(USB_HUB_DESCRIPTOR));
+    ASSERT(HubDeviceExtension->HubDescriptor.bNumberOfPorts);
+    ASSERT(HubDeviceExtension->HubDescriptor.bDescriptorType == 0x29);
+
+    // store number of ports
+    DPRINT1("NumberOfPorts %lu\n", 
HubDeviceExtension->HubDescriptor.bNumberOfPorts);
+    HubDeviceExtension->UsbExtHubInfo.NumberOfPorts = 
HubDeviceExtension->HubDescriptor.bNumberOfPorts;
+
+    // allocate interface list
+    InterfaceList = ExAllocatePool(NonPagedPool, 
sizeof(USBD_INTERFACE_LIST_ENTRY) * 
(HubDeviceExtension->HubConfigDescriptor.bNumInterfaces + 1));
+    if (!InterfaceList)
+    {
+        // no memory
+        DPRINT1("No memory\n");
+        return STATUS_INSUFFICIENT_RESOURCES;
+    }
+
+    // zero list
+    RtlZeroMemory(InterfaceList, sizeof(USBD_INTERFACE_LIST_ENTRY) * 
(HubDeviceExtension->HubConfigDescriptor.bNumInterfaces + 1));
+
+    // grab all interface descriptors
+    for(Index = 0; Index < 
HubDeviceExtension->HubConfigDescriptor.bNumInterfaces; Index++)
+    {
+        // Get the first Configuration Descriptor
+        InterfaceDescriptor = 
USBD_ParseConfigurationDescriptorEx(&HubDeviceExtension->HubConfigDescriptor,
+                                                                  
&HubDeviceExtension->HubConfigDescriptor,
+                                                                  Index, 0, 
-1, -1, -1);
+
+        // store in list
+        InterfaceList[Index].InterfaceDescriptor = InterfaceDescriptor;
+    }
+
+    // now create configuration request
+    ConfigurationUrb = 
USBD_CreateConfigurationRequestEx(&HubDeviceExtension->HubConfigDescriptor,
+                                                    
(PUSBD_INTERFACE_LIST_ENTRY)&InterfaceList);
+    if (ConfigurationUrb == NULL)
+    {
+        // failed to build urb
+        DPRINT1("Failed to build configuration urb\n");
+        ExFreePool(Urb);
+        return STATUS_INSUFFICIENT_RESOURCES;
+    }
+
+    // send request
+    Status = SubmitRequestToRootHub(HubDeviceExtension->LowerDeviceObject,
+                                    IOCTL_INTERNAL_USB_SUBMIT_URB,
+                                    ConfigurationUrb,
+                                    NULL);
+
+    if (!NT_SUCCESS(Status))
+    {
+        DPRINT1("Failed to get Hub Descriptor Status %x!\n", Status);
+        ExFreePool(Urb);
+        ExFreePool(ConfigurationUrb);
+        return STATUS_UNSUCCESSFUL;
+    }
+
+    // store configuration & pipe handle
+    HubDeviceExtension->ConfigurationHandle = 
ConfigurationUrb->UrbSelectConfiguration.ConfigurationHandle;
+    HubDeviceExtension->PipeHandle = 
ConfigurationUrb->UrbSelectConfiguration.Interface.Pipes[0].PipeHandle;
+    DPRINT("Hub Configuration Handle %x\n", 
HubDeviceExtension->ConfigurationHandle);
+
+    // free urb
+    ExFreePool(ConfigurationUrb);
+    ExFreePool(Urb);
+
+    // FIXME build SCE interrupt request
+
+    // FIXME create pdos
+
+    return Status;
+}
+

Propchange: trunk/reactos/drivers/usb/usbhub/hub_fdo.c
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: trunk/reactos/drivers/usb/usbhub/misc.c
URL: 
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/usb/usbhub/misc.c?rev=55927&r1=55926&r2=55927&view=diff
==============================================================================
--- trunk/reactos/drivers/usb/usbhub/misc.c [iso-8859-1] (original)
+++ trunk/reactos/drivers/usb/usbhub/misc.c [iso-8859-1] Wed Feb 29 18:51:07 
2012
@@ -143,3 +143,68 @@
     return IoCallDriver(LowerDevice, Irp);
 }
 
+NTSTATUS
+SubmitRequestToRootHub(
+    IN PDEVICE_OBJECT RootHubDeviceObject,
+    IN ULONG IoControlCode,
+    OUT PVOID OutParameter1,
+    OUT PVOID OutParameter2)
+{
+    KEVENT Event;
+    PIRP Irp;
+    IO_STATUS_BLOCK IoStatus;
+    NTSTATUS Status;
+    PIO_STACK_LOCATION Stack = NULL;
+
+    KeInitializeEvent(&Event, NotificationEvent, FALSE);
+
+    //
+    // Build Control Request
+    //
+    Irp = IoBuildDeviceIoControlRequest(IoControlCode,
+                                        RootHubDeviceObject,
+                                        NULL, 0,
+                                        NULL, 0,
+                                        TRUE,
+                                        &Event,
+                                        &IoStatus);
+
+    if (Irp == NULL)
+    {
+        DPRINT("Usbhub: IoBuildDeviceIoControlRequest() failed\n");
+        return STATUS_INSUFFICIENT_RESOURCES;
+    }
+
+    //
+    // Initialize the status block before sending the IRP
+    //
+    IoStatus.Status = STATUS_NOT_SUPPORTED;
+    IoStatus.Information = 0;
+
+    //
+    // Get Next Stack Location and Initialize it
+    //
+    Stack = IoGetNextIrpStackLocation(Irp);
+    Stack->Parameters.Others.Argument1 = OutParameter1;
+    Stack->Parameters.Others.Argument2 = OutParameter2;
+
+    //
+    // Call RootHub
+    //
+    Status = IoCallDriver(RootHubDeviceObject, Irp);
+
+    //
+    // Its ok to block here as this function is called in an nonarbitrary 
thread
+    //
+    if    (Status == STATUS_PENDING)
+    {
+        KeWaitForSingleObject(&Event, Suspended, KernelMode, FALSE, NULL);
+        Status = IoStatus.Status;
+    }
+
+    //
+    // The IO Manager will free the IRP
+    //
+
+    return Status;
+}

Modified: trunk/reactos/drivers/usb/usbhub/pdo.c
URL: 
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/usb/usbhub/pdo.c?rev=55927&r1=55926&r2=55927&view=diff
==============================================================================
--- trunk/reactos/drivers/usb/usbhub/pdo.c [iso-8859-1] (original)
+++ trunk/reactos/drivers/usb/usbhub/pdo.c [iso-8859-1] Wed Feb 29 18:51:07 2012
@@ -339,8 +339,39 @@
             DPRINT1("IOCTL_INTERNAL_USB_CYCLE_PORT\n");
             break;
         case IOCTL_INTERNAL_USB_GET_DEVICE_HANDLE:
+        {
             DPRINT1("IOCTL_INTERNAL_USB_GET_DEVICE_HANDLE\n");
-            break;
+            if (Stack->Parameters.Others.Argument1)
+            {
+                // store device handle
+                *(PVOID *)Stack->Parameters.Others.Argument1 = 
(PVOID)ChildDeviceExtension->UsbDeviceHandle;
+                Status = STATUS_SUCCESS;
+            }
+            else
+            {
+                // invalid parameter
+                Status = STATUS_INVALID_PARAMETER;
+            }
+            break;
+        }
+        case IOCTL_INTERNAL_USB_GET_ROOTHUB_PDO:
+        {
+            if (Stack->Parameters.Others.Argument1)
+            {
+                // inform caller that it is a real usb hub
+                *(PVOID *)Stack->Parameters.Others.Argument1 = NULL;
+            }
+
+            if (Stack->Parameters.Others.Argument2)
+            {
+                // output device object
+                *(PVOID *)Stack->Parameters.Others.Argument2 = DeviceObject;
+            }
+
+            // done
+            Status = STATUS_SUCCESS;
+            break;
+        }
         default:
         {
             DPRINT1("Unknown IOCTL code 0x%lx\n", 
Stack->Parameters.DeviceIoControl.IoControlCode);

Modified: trunk/reactos/drivers/usb/usbhub/usbhub.h
URL: 
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/usb/usbhub/usbhub.h?rev=55927&r1=55926&r2=55927&view=diff
==============================================================================
--- trunk/reactos/drivers/usb/usbhub/usbhub.h [iso-8859-1] (original)
+++ trunk/reactos/drivers/usb/usbhub/usbhub.h [iso-8859-1] Wed Feb 29 18:51:07 
2012
@@ -142,6 +142,13 @@
     IN PDEVICE_OBJECT DeviceObject,
     IN PIRP Irp);
 
+NTSTATUS
+SubmitRequestToRootHub(
+    IN PDEVICE_OBJECT RootHubDeviceObject,
+    IN ULONG IoControlCode,
+    OUT PVOID OutParameter1,
+    OUT PVOID OutParameter2);
+
 // pdo.c
 NTSTATUS
 USBHUB_PdoHandlePnp(
@@ -170,3 +177,10 @@
     IN PDEVICE_OBJECT RootHubDeviceObject,
     IN ULONG PortId,
     OUT PPORT_STATUS_CHANGE StatusChange);
+
+// hub_fdo.c
+
+NTSTATUS
+USBHUB_ParentFDOStartDevice(
+    IN PDEVICE_OBJECT DeviceObject,
+    IN PIRP Irp);


Reply via email to