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/CMakeLi…
==============================================================================
--- 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?r…
==============================================================================
--- 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…
==============================================================================
--- 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 (michael.martin(a)reactos.org)
+ * Johannes Anderwald (johannes.anderwald(a)reactos.org)
+ */
+#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?…
==============================================================================
--- 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?r…
==============================================================================
--- 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.…
==============================================================================
--- 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);