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?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 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_con…
==============================================================================
--- 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