mirror of
https://github.com/reactos/reactos.git
synced 2025-08-06 00:12:57 +00:00
[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 svn path=/trunk/; revision=55923
This commit is contained in:
parent
cbfb67842f
commit
7de856c877
2 changed files with 518 additions and 425 deletions
|
@ -133,6 +133,10 @@ GetPortStatusAndChange(
|
||||||
sizeof(PORT_STATUS_CHANGE),
|
sizeof(PORT_STATUS_CHANGE),
|
||||||
0);
|
0);
|
||||||
|
|
||||||
|
// FIXME: support usb hubs
|
||||||
|
Urb->UrbHeader.UsbdDeviceHandle = NULL;
|
||||||
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Query the Root Hub
|
// Query the Root Hub
|
||||||
//
|
//
|
||||||
|
@ -185,6 +189,10 @@ SetPortFeature(
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
0);
|
0);
|
||||||
|
|
||||||
|
// FIXME support usbhubs
|
||||||
|
Urb->UrbHeader.UsbdDeviceHandle = NULL;
|
||||||
|
|
||||||
//
|
//
|
||||||
// Query the Root Hub
|
// Query the Root Hub
|
||||||
//
|
//
|
||||||
|
@ -237,6 +245,10 @@ ClearPortFeature(
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
0);
|
0);
|
||||||
|
|
||||||
|
// FIXME: support usb hubs
|
||||||
|
Urb->UrbHeader.UsbdDeviceHandle = NULL;
|
||||||
|
|
||||||
//
|
//
|
||||||
// Query the Root Hub
|
// Query the Root Hub
|
||||||
//
|
//
|
||||||
|
@ -515,15 +527,12 @@ QueryStatusChangeEndpoint(
|
||||||
USBD_TRANSFER_DIRECTION_IN | USBD_SHORT_TRANSFER_OK,
|
USBD_TRANSFER_DIRECTION_IN | USBD_SHORT_TRANSFER_OK,
|
||||||
NULL);
|
NULL);
|
||||||
|
|
||||||
//
|
// Set the device handle
|
||||||
// Set the device handle to null for roothub
|
PendingSCEUrb->UrbHeader.UsbdDeviceHandle = HubDeviceExtension->RootHubHandle;
|
||||||
//
|
|
||||||
PendingSCEUrb->UrbHeader.UsbdDeviceHandle = NULL;//HubDeviceExtension->RootHubHandle;
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Allocate an Irp
|
// Allocate an Irp
|
||||||
//
|
//
|
||||||
|
|
||||||
HubDeviceExtension->PendingSCEIrp = ExAllocatePoolWithTag(NonPagedPool,
|
HubDeviceExtension->PendingSCEIrp = ExAllocatePoolWithTag(NonPagedPool,
|
||||||
IoSizeOfIrp(RootHubDeviceObject->StackSize),
|
IoSizeOfIrp(RootHubDeviceObject->StackSize),
|
||||||
USB_HUB_TAG);
|
USB_HUB_TAG);
|
||||||
|
@ -798,12 +807,8 @@ GetUsbStringDescriptor(
|
||||||
ExFreePool(StringDesc);
|
ExFreePool(StringDesc);
|
||||||
return STATUS_INSUFFICIENT_RESOURCES;
|
return STATUS_INSUFFICIENT_RESOURCES;
|
||||||
}
|
}
|
||||||
DPRINT("Buffer %p\n", Buffer);
|
|
||||||
RtlZeroMemory(Buffer, SizeNeeded);
|
|
||||||
|
|
||||||
DPRINT("SizeNeeded %lu\n", SizeNeeded);
|
RtlZeroMemory(Buffer, 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
|
// Copy the string to destination
|
||||||
|
@ -1502,6 +1507,450 @@ RootHubInitCallbackFunction(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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
|
NTSTATUS
|
||||||
USBHUB_FdoHandlePnp(
|
USBHUB_FdoHandlePnp(
|
||||||
IN PDEVICE_OBJECT DeviceObject,
|
IN PDEVICE_OBJECT DeviceObject,
|
||||||
|
@ -1511,9 +1960,6 @@ USBHUB_FdoHandlePnp(
|
||||||
NTSTATUS Status = STATUS_SUCCESS;
|
NTSTATUS Status = STATUS_SUCCESS;
|
||||||
ULONG_PTR Information = 0;
|
ULONG_PTR Information = 0;
|
||||||
PHUB_DEVICE_EXTENSION HubDeviceExtension;
|
PHUB_DEVICE_EXTENSION HubDeviceExtension;
|
||||||
PDEVICE_OBJECT RootHubDeviceObject;
|
|
||||||
PVOID HubInterfaceBusContext , UsbDInterfaceBusContext;
|
|
||||||
PORT_STATUS_CHANGE StatusChange;
|
|
||||||
|
|
||||||
HubDeviceExtension = (PHUB_DEVICE_EXTENSION) DeviceObject->DeviceExtension;
|
HubDeviceExtension = (PHUB_DEVICE_EXTENSION) DeviceObject->DeviceExtension;
|
||||||
|
|
||||||
|
@ -1523,380 +1969,7 @@ USBHUB_FdoHandlePnp(
|
||||||
{
|
{
|
||||||
case IRP_MN_START_DEVICE:
|
case IRP_MN_START_DEVICE:
|
||||||
{
|
{
|
||||||
PURB Urb;
|
Status = USBHUB_FdoStartDevice(DeviceObject, Irp);
|
||||||
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);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -836,7 +836,7 @@ CHubController::HandleBulkOrInterruptTransfer(
|
||||||
//
|
//
|
||||||
// Is the Request for the root hub
|
// Is the Request for the root hub
|
||||||
//
|
//
|
||||||
if (Urb->UrbHeader.UsbdDeviceHandle == 0)
|
if (Urb->UrbHeader.UsbdDeviceHandle == PVOID(this))
|
||||||
{
|
{
|
||||||
ASSERT(m_PendingSCEIrp == NULL);
|
ASSERT(m_PendingSCEIrp == NULL);
|
||||||
if (QueryStatusChageEndpoint(Irp))
|
if (QueryStatusChageEndpoint(Irp))
|
||||||
|
@ -1179,7 +1179,7 @@ CHubController::HandleGetStatusFromDevice(
|
||||||
DeviceStatus = (PUSHORT)Urb->UrbControlGetStatusRequest.TransferBuffer;
|
DeviceStatus = (PUSHORT)Urb->UrbControlGetStatusRequest.TransferBuffer;
|
||||||
|
|
||||||
|
|
||||||
if (Urb->UrbHeader.UsbdDeviceHandle == NULL)
|
if (Urb->UrbHeader.UsbdDeviceHandle == PVOID(this))
|
||||||
{
|
{
|
||||||
//
|
//
|
||||||
// FIXME need more flags ?
|
// FIXME need more flags ?
|
||||||
|
@ -1311,46 +1311,66 @@ CHubController::HandleClassDevice(
|
||||||
case USB_DEVICE_CLASS_RESERVED: // FALL THROUGH
|
case USB_DEVICE_CLASS_RESERVED: // FALL THROUGH
|
||||||
case USB_DEVICE_CLASS_HUB:
|
case USB_DEVICE_CLASS_HUB:
|
||||||
{
|
{
|
||||||
//
|
if (Urb->UrbHeader.UsbdDeviceHandle == PVOID(this))
|
||||||
// sanity checks
|
{
|
||||||
//
|
//
|
||||||
PC_ASSERT(Urb->UrbControlVendorClassRequest.TransferBuffer);
|
// sanity checks
|
||||||
PC_ASSERT(Urb->UrbControlVendorClassRequest.TransferBufferLength >= sizeof(USB_HUB_DESCRIPTOR));
|
//
|
||||||
|
PC_ASSERT(Urb->UrbControlVendorClassRequest.TransferBuffer);
|
||||||
|
PC_ASSERT(Urb->UrbControlVendorClassRequest.TransferBufferLength >= sizeof(USB_HUB_DESCRIPTOR));
|
||||||
|
|
||||||
//
|
//
|
||||||
// get hub descriptor
|
// get hub descriptor
|
||||||
//
|
//
|
||||||
UsbHubDescriptor = (PUSB_HUB_DESCRIPTOR)Urb->UrbControlVendorClassRequest.TransferBuffer;
|
UsbHubDescriptor = (PUSB_HUB_DESCRIPTOR)Urb->UrbControlVendorClassRequest.TransferBuffer;
|
||||||
|
|
||||||
//
|
//
|
||||||
// one hub is handled
|
// one hub is handled
|
||||||
//
|
//
|
||||||
UsbHubDescriptor->bDescriptorLength = sizeof(USB_HUB_DESCRIPTOR);
|
UsbHubDescriptor->bDescriptorLength = sizeof(USB_HUB_DESCRIPTOR);
|
||||||
Urb->UrbControlVendorClassRequest.TransferBufferLength = sizeof(USB_HUB_DESCRIPTOR);
|
Urb->UrbControlVendorClassRequest.TransferBufferLength = sizeof(USB_HUB_DESCRIPTOR);
|
||||||
|
|
||||||
//
|
//
|
||||||
// type should 0x29 according to msdn
|
// type should 0x29 according to msdn
|
||||||
//
|
//
|
||||||
UsbHubDescriptor->bDescriptorType = 0x29;
|
UsbHubDescriptor->bDescriptorType = 0x29;
|
||||||
|
|
||||||
//
|
//
|
||||||
// get port count
|
// get port count
|
||||||
//
|
//
|
||||||
Status = m_Hardware->GetDeviceDetails(&Dummy1, &Dummy1, &PortCount, &Dummy2);
|
Status = m_Hardware->GetDeviceDetails(&Dummy1, &Dummy1, &PortCount, &Dummy2);
|
||||||
PC_ASSERT(Status == STATUS_SUCCESS);
|
PC_ASSERT(Status == STATUS_SUCCESS);
|
||||||
|
|
||||||
//
|
//
|
||||||
// FIXME: retrieve values
|
// FIXME: retrieve values
|
||||||
//
|
//
|
||||||
UsbHubDescriptor->bNumberOfPorts = (UCHAR)PortCount;
|
UsbHubDescriptor->bNumberOfPorts = (UCHAR)PortCount;
|
||||||
UsbHubDescriptor->wHubCharacteristics = 0x00;
|
UsbHubDescriptor->wHubCharacteristics = 0x00;
|
||||||
UsbHubDescriptor->bPowerOnToPowerGood = 0x01;
|
UsbHubDescriptor->bPowerOnToPowerGood = 0x01;
|
||||||
UsbHubDescriptor->bHubControlCurrent = 0x00;
|
UsbHubDescriptor->bHubControlCurrent = 0x00;
|
||||||
|
|
||||||
//
|
//
|
||||||
// done
|
// done
|
||||||
//
|
//
|
||||||
Status = STATUS_SUCCESS;
|
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;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
|
@ -1450,7 +1470,7 @@ CHubController::HandleGetDescriptor(
|
||||||
PC_ASSERT(Urb->UrbControlDescriptorRequest.TransferBufferLength >= sizeof(USB_DEVICE_DESCRIPTOR));
|
PC_ASSERT(Urb->UrbControlDescriptorRequest.TransferBufferLength >= sizeof(USB_DEVICE_DESCRIPTOR));
|
||||||
PC_ASSERT(Urb->UrbControlDescriptorRequest.TransferBuffer);
|
PC_ASSERT(Urb->UrbControlDescriptorRequest.TransferBuffer);
|
||||||
|
|
||||||
if (Urb->UrbHeader.UsbdDeviceHandle == NULL)
|
if (Urb->UrbHeader.UsbdDeviceHandle == PVOID(this))
|
||||||
{
|
{
|
||||||
//
|
//
|
||||||
// copy root hub device descriptor
|
// copy root hub device descriptor
|
||||||
|
@ -1494,7 +1514,7 @@ CHubController::HandleGetDescriptor(
|
||||||
PC_ASSERT(Urb->UrbControlDescriptorRequest.TransferBuffer);
|
PC_ASSERT(Urb->UrbControlDescriptorRequest.TransferBuffer);
|
||||||
PC_ASSERT(Urb->UrbControlDescriptorRequest.TransferBufferLength >= sizeof(USB_CONFIGURATION_DESCRIPTOR));
|
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
|
// request is for the root bus controller
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue