- 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:
Johannes Anderwald 2012-02-29 17:08:32 +00:00
parent cbfb67842f
commit 7de856c877
2 changed files with 518 additions and 425 deletions

View file

@ -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
@ -1503,77 +1508,86 @@ RootHubInitCallbackFunction(
} }
NTSTATUS NTSTATUS
USBHUB_FdoHandlePnp( USBHUB_FdoStartDevice(
IN PDEVICE_OBJECT DeviceObject, IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp) IN PIRP Irp)
{ {
PIO_STACK_LOCATION Stack;
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;
Stack = IoGetCurrentIrpStackLocation(Irp);
switch (Stack->MinorFunction)
{
case IRP_MN_START_DEVICE:
{
PURB Urb; PURB Urb;
PUSB_INTERFACE_DESCRIPTOR Pid; PUSB_INTERFACE_DESCRIPTOR Pid;
ULONG Result = 0, PortId; ULONG Result = 0, PortId;
USBD_INTERFACE_LIST_ENTRY InterfaceList[2] = {{NULL, NULL}, {NULL, NULL}}; USBD_INTERFACE_LIST_ENTRY InterfaceList[2] = {{NULL, NULL}, {NULL, NULL}};
PURB ConfigUrb = NULL; PURB ConfigUrb = NULL;
ULONG HubStatus; 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"); DPRINT("IRP_MJ_PNP / IRP_MN_START_DEVICE\n");
//
// Allocated size including the sizeof USBD_INTERFACE_LIST_ENTRY // Allocated size including the sizeof USBD_INTERFACE_LIST_ENTRY
//
Urb = ExAllocatePoolWithTag(NonPagedPool, sizeof(URB) + sizeof(USBD_INTERFACE_LIST_ENTRY), USB_HUB_TAG); 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)); RtlZeroMemory(Urb, sizeof(URB) + sizeof(USBD_INTERFACE_LIST_ENTRY));
//
// Get the Root Hub Pdo // Get the Root Hub Pdo
// Status = SubmitRequestToRootHub(HubDeviceExtension->LowerDeviceObject,
SubmitRequestToRootHub(HubDeviceExtension->LowerDeviceObject,
IOCTL_INTERNAL_USB_GET_ROOTHUB_PDO, IOCTL_INTERNAL_USB_GET_ROOTHUB_PDO,
&HubDeviceExtension->RootHubPhysicalDeviceObject, &HubDeviceExtension->RootHubPhysicalDeviceObject,
&HubDeviceExtension->RootHubFunctionalDeviceObject); &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;
}
RootHubDeviceObject = HubDeviceExtension->RootHubPhysicalDeviceObject; // sanity checks
ASSERT(HubDeviceExtension->RootHubPhysicalDeviceObject); ASSERT(HubDeviceExtension->RootHubPhysicalDeviceObject);
ASSERT(HubDeviceExtension->RootHubFunctionalDeviceObject); ASSERT(HubDeviceExtension->RootHubFunctionalDeviceObject);
DPRINT("RootPdo %x, RootFdo %x\n",
HubDeviceExtension->RootHubPhysicalDeviceObject,
HubDeviceExtension->RootHubFunctionalDeviceObject);
// // get roothub
RootHubDeviceObject = HubDeviceExtension->RootHubPhysicalDeviceObject;
// Send the StartDevice to RootHub // Send the StartDevice to RootHub
//
Status = ForwardIrpAndWait(RootHubDeviceObject, Irp); Status = ForwardIrpAndWait(RootHubDeviceObject, Irp);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
// failed to start pdo
DPRINT1("Failed to start the RootHub PDO\n"); DPRINT1("Failed to start the RootHub PDO\n");
ASSERT(FALSE); ExFreePool(Urb);
return Status;
} }
//
// Get the current number of hubs // Get the current number of hubs
//
Status = SubmitRequestToRootHub(RootHubDeviceObject, Status = SubmitRequestToRootHub(RootHubDeviceObject,
IOCTL_INTERNAL_USB_GET_HUB_COUNT, IOCTL_INTERNAL_USB_GET_HUB_COUNT,
&HubDeviceExtension->NumberOfHubs, NULL); &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 // Get the Hub Interface
//
Status = QueryInterface(RootHubDeviceObject, Status = QueryInterface(RootHubDeviceObject,
USB_BUS_INTERFACE_HUB_GUID, USB_BUS_INTERFACE_HUB_GUID,
sizeof(USB_BUS_INTERFACE_HUB_V5), sizeof(USB_BUS_INTERFACE_HUB_V5),
@ -1582,15 +1596,15 @@ USBHUB_FdoHandlePnp(
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
// failed to get root hub interface
DPRINT1("Failed to get HUB_GUID interface with status 0x%08lx\n", Status); DPRINT1("Failed to get HUB_GUID interface with status 0x%08lx\n", Status);
return STATUS_UNSUCCESSFUL; ExFreePool(Urb);
return Status;
} }
HubInterfaceBusContext = HubDeviceExtension->HubInterface.BusContext; HubInterfaceBusContext = HubDeviceExtension->HubInterface.BusContext;
//
// Get the USBDI Interface // Get the USBDI Interface
//
Status = QueryInterface(RootHubDeviceObject, Status = QueryInterface(RootHubDeviceObject,
USB_BUS_INTERFACE_USBDI_GUID, USB_BUS_INTERFACE_USBDI_GUID,
sizeof(USB_BUS_INTERFACE_USBDI_V2), sizeof(USB_BUS_INTERFACE_USBDI_V2),
@ -1599,15 +1613,15 @@ USBHUB_FdoHandlePnp(
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
// failed to get usbdi interface
DPRINT1("Failed to get USBDI_GUID interface with status 0x%08lx\n", Status); DPRINT1("Failed to get USBDI_GUID interface with status 0x%08lx\n", Status);
ExFreePool(Urb);
return Status; return Status;
} }
UsbDInterfaceBusContext = HubDeviceExtension->UsbDInterface.BusContext; UsbDInterfaceBusContext = HubDeviceExtension->UsbDInterface.BusContext;
//
// Get Root Hub Device Handle // Get Root Hub Device Handle
//
Status = SubmitRequestToRootHub(RootHubDeviceObject, Status = SubmitRequestToRootHub(RootHubDeviceObject,
IOCTL_INTERNAL_USB_GET_DEVICE_HANDLE, IOCTL_INTERNAL_USB_GET_DEVICE_HANDLE,
&HubDeviceExtension->RootHubHandle, &HubDeviceExtension->RootHubHandle,
@ -1615,7 +1629,9 @@ USBHUB_FdoHandlePnp(
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
DPRINT1("GetRootHubDeviceHandle failed with status 0x%08lx\n", Status); // failed
DPRINT1("IOCTL_INTERNAL_USB_GET_DEVICE_HANDLE failed with status 0x%08lx\n", Status);
ExFreePool(Urb);
return Status; return Status;
} }
@ -1636,9 +1652,7 @@ USBHUB_FdoHandlePnp(
DPRINT1("HubAddress %x\n", HubDeviceExtension->DeviceInformation.HubAddress); DPRINT1("HubAddress %x\n", HubDeviceExtension->DeviceInformation.HubAddress);
DPRINT1("NumberofPipes %x\n", HubDeviceExtension->DeviceInformation.NumberOfOpenPipes); DPRINT1("NumberofPipes %x\n", HubDeviceExtension->DeviceInformation.NumberOfOpenPipes);
//
// Get Root Hubs Device Descriptor // Get Root Hubs Device Descriptor
//
UsbBuildGetDescriptorRequest(Urb, UsbBuildGetDescriptorRequest(Urb,
sizeof(Urb->UrbControlDescriptorRequest), sizeof(Urb->UrbControlDescriptorRequest),
USB_DEVICE_DESCRIPTOR_TYPE, USB_DEVICE_DESCRIPTOR_TYPE,
@ -1649,8 +1663,10 @@ USBHUB_FdoHandlePnp(
sizeof(USB_DEVICE_DESCRIPTOR), sizeof(USB_DEVICE_DESCRIPTOR),
NULL); NULL);
Urb->UrbHeader.UsbdDeviceHandle = NULL;//HubDeviceExtension->RootHubHandle; // set device handle
Urb->UrbHeader.UsbdDeviceHandle = HubDeviceExtension->RootHubHandle;
// get hub device descriptor
Status = SubmitRequestToRootHub(RootHubDeviceObject, Status = SubmitRequestToRootHub(RootHubDeviceObject,
IOCTL_INTERNAL_USB_SUBMIT_URB, IOCTL_INTERNAL_USB_SUBMIT_URB,
Urb, Urb,
@ -1658,14 +1674,13 @@ USBHUB_FdoHandlePnp(
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
// failed to get device descriptor of hub
DPRINT1("Failed to get HubDeviceDescriptor!\n"); DPRINT1("Failed to get HubDeviceDescriptor!\n");
ExFreePool(Urb);
return Status;
} }
DumpDeviceDescriptor(&HubDeviceExtension->HubDeviceDescriptor); // build configuration request
//
// Get Root Hubs Configuration Descriptor
//
UsbBuildGetDescriptorRequest(Urb, UsbBuildGetDescriptorRequest(Urb,
sizeof(Urb->UrbControlDescriptorRequest), sizeof(Urb->UrbControlDescriptorRequest),
USB_CONFIGURATION_DESCRIPTOR_TYPE, USB_CONFIGURATION_DESCRIPTOR_TYPE,
@ -1676,9 +1691,10 @@ USBHUB_FdoHandlePnp(
sizeof(USB_CONFIGURATION_DESCRIPTOR) + sizeof(USB_INTERFACE_DESCRIPTOR) + sizeof(USB_ENDPOINT_DESCRIPTOR), sizeof(USB_CONFIGURATION_DESCRIPTOR) + sizeof(USB_INTERFACE_DESCRIPTOR) + sizeof(USB_ENDPOINT_DESCRIPTOR),
NULL); NULL);
DPRINT("RootHub Handle %x\n", HubDeviceExtension->RootHubHandle); // set device handle
Urb->UrbHeader.UsbdDeviceHandle = NULL;//HubDeviceExtension->RootHubHandle; Urb->UrbHeader.UsbdDeviceHandle = HubDeviceExtension->RootHubHandle;
// request configuration descriptor
Status = SubmitRequestToRootHub(RootHubDeviceObject, Status = SubmitRequestToRootHub(RootHubDeviceObject,
IOCTL_INTERNAL_USB_SUBMIT_URB, IOCTL_INTERNAL_USB_SUBMIT_URB,
Urb, Urb,
@ -1686,13 +1702,26 @@ USBHUB_FdoHandlePnp(
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
// failed to get configuration descriptor
DPRINT1("Failed to get RootHub Configuration with status %x\n", Status); DPRINT1("Failed to get RootHub Configuration with status %x\n", Status);
ASSERT(FALSE); ExFreePool(Urb);
return Status;
} }
ASSERT(HubDeviceExtension->HubConfigDescriptor.wTotalLength);
DumpConfigurationDescriptor(&HubDeviceExtension->HubConfigDescriptor); // 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, Status = HubDeviceExtension->HubInterface.GetExtendedHubInformation(HubInterfaceBusContext,
RootHubDeviceObject, RootHubDeviceObject,
&HubDeviceExtension->UsbExtHubInfo, &HubDeviceExtension->UsbExtHubInfo,
@ -1700,15 +1729,23 @@ USBHUB_FdoHandlePnp(
&Result); &Result);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
// failed to get hub information
DPRINT1("Failed to extended hub information. Unable to determine the number of ports!\n"); DPRINT1("Failed to extended hub information. Unable to determine the number of ports!\n");
ASSERT(FALSE); 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); DPRINT1("HubDeviceExtension->UsbExtHubInfo.NumberOfPorts %x\n", HubDeviceExtension->UsbExtHubInfo.NumberOfPorts);
// // Build hub descriptor request
// Get the Hub Descriptor
//
UsbBuildVendorRequest(Urb, UsbBuildVendorRequest(Urb,
URB_FUNCTION_CLASS_DEVICE, URB_FUNCTION_CLASS_DEVICE,
sizeof(Urb->UrbControlVendorClassRequest), sizeof(Urb->UrbControlVendorClassRequest),
@ -1722,15 +1759,15 @@ USBHUB_FdoHandlePnp(
sizeof(USB_HUB_DESCRIPTOR), sizeof(USB_HUB_DESCRIPTOR),
NULL); NULL);
Urb->UrbHeader.UsbdDeviceHandle = NULL;//HubDeviceExtension->RootHubHandle; // set device handle
Urb->UrbHeader.UsbdDeviceHandle = HubDeviceExtension->RootHubHandle;
// send request
Status = SubmitRequestToRootHub(RootHubDeviceObject, Status = SubmitRequestToRootHub(RootHubDeviceObject,
IOCTL_INTERNAL_USB_SUBMIT_URB, IOCTL_INTERNAL_USB_SUBMIT_URB,
Urb, Urb,
NULL); NULL);
DPRINT1("bDescriptorType %x\n", HubDeviceExtension->HubDescriptor.bDescriptorType);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
DPRINT1("Failed to get Hub Descriptor!\n"); DPRINT1("Failed to get Hub Descriptor!\n");
@ -1738,6 +1775,12 @@ USBHUB_FdoHandlePnp(
return STATUS_UNSUCCESSFUL; 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; HubStatus = 0;
UsbBuildGetStatusRequest(Urb, UsbBuildGetStatusRequest(Urb,
URB_FUNCTION_GET_STATUS_FROM_DEVICE, URB_FUNCTION_GET_STATUS_FROM_DEVICE,
@ -1745,83 +1788,92 @@ USBHUB_FdoHandlePnp(
&HubStatus, &HubStatus,
0, 0,
NULL); NULL);
Urb->UrbHeader.UsbdDeviceHandle = NULL;//HubDeviceExtension->RootHubHandle; // set device handle
Urb->UrbHeader.UsbdDeviceHandle = HubDeviceExtension->RootHubHandle;
// send request
Status = SubmitRequestToRootHub(RootHubDeviceObject, Status = SubmitRequestToRootHub(RootHubDeviceObject,
IOCTL_INTERNAL_USB_SUBMIT_URB, IOCTL_INTERNAL_USB_SUBMIT_URB,
Urb, Urb,
NULL); NULL);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
// failed to get hub status
DPRINT1("Failed to get Hub Status!\n"); DPRINT1("Failed to get Hub Status!\n");
ExFreePool(Urb); ExFreePool(Urb);
return STATUS_UNSUCCESSFUL; return STATUS_UNSUCCESSFUL;
} }
DPRINT1("HubStatus %x\n", HubStatus);
//
// Allocate memory for PortStatusChange to hold 2 USHORTs for each port on hub // Allocate memory for PortStatusChange to hold 2 USHORTs for each port on hub
//
HubDeviceExtension->PortStatusChange = ExAllocatePoolWithTag(NonPagedPool, HubDeviceExtension->PortStatusChange = ExAllocatePoolWithTag(NonPagedPool,
sizeof(ULONG) * HubDeviceExtension->UsbExtHubInfo.NumberOfPorts, sizeof(ULONG) * HubDeviceExtension->UsbExtHubInfo.NumberOfPorts,
USB_HUB_TAG); USB_HUB_TAG);
//
// Get the first Configuration Descriptor // Get the first Configuration Descriptor
//
Pid = USBD_ParseConfigurationDescriptorEx(&HubDeviceExtension->HubConfigDescriptor, Pid = USBD_ParseConfigurationDescriptorEx(&HubDeviceExtension->HubConfigDescriptor,
&HubDeviceExtension->HubConfigDescriptor, &HubDeviceExtension->HubConfigDescriptor,
-1, -1, -1, -1, -1); -1, -1, -1, -1, -1);
if (Pid == NULL)
{
// failed parse hub descriptor
DPRINT1("Failed to parse configuration descriptor\n");
ExFreePool(Urb);
return STATUS_UNSUCCESSFUL;
}
ASSERT(Pid != NULL); // create configuration request
InterfaceList[0].InterfaceDescriptor = Pid; InterfaceList[0].InterfaceDescriptor = Pid;
ConfigUrb = USBD_CreateConfigurationRequestEx(&HubDeviceExtension->HubConfigDescriptor, ConfigUrb = USBD_CreateConfigurationRequestEx(&HubDeviceExtension->HubConfigDescriptor,
(PUSBD_INTERFACE_LIST_ENTRY)&InterfaceList); (PUSBD_INTERFACE_LIST_ENTRY)&InterfaceList);
ASSERT(ConfigUrb != NULL); if (ConfigUrb == NULL)
{
// failed to build urb
DPRINT1("Failed to allocate urb\n");
ExFreePool(Urb);
return STATUS_INSUFFICIENT_RESOURCES;
}
// send request
Status = SubmitRequestToRootHub(RootHubDeviceObject, Status = SubmitRequestToRootHub(RootHubDeviceObject,
IOCTL_INTERNAL_USB_SUBMIT_URB, IOCTL_INTERNAL_USB_SUBMIT_URB,
ConfigUrb, ConfigUrb,
NULL); 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->ConfigurationHandle = ConfigUrb->UrbSelectConfiguration.ConfigurationHandle;
HubDeviceExtension->PipeHandle = ConfigUrb->UrbSelectConfiguration.Interface.Pipes[0].PipeHandle; HubDeviceExtension->PipeHandle = ConfigUrb->UrbSelectConfiguration.Interface.Pipes[0].PipeHandle;
DPRINT("Configuration Handle %x\n", HubDeviceExtension->ConfigurationHandle); DPRINT("Configuration Handle %x\n", HubDeviceExtension->ConfigurationHandle);
// // free urb
ExFreePool(ConfigUrb);
// check if function is available // check if function is available
//
if (HubDeviceExtension->UsbDInterface.IsDeviceHighSpeed) if (HubDeviceExtension->UsbDInterface.IsDeviceHighSpeed)
{ {
//
// is it high speed bus // is it high speed bus
//
if (HubDeviceExtension->UsbDInterface.IsDeviceHighSpeed(HubInterfaceBusContext)) if (HubDeviceExtension->UsbDInterface.IsDeviceHighSpeed(HubInterfaceBusContext))
{ {
//
// initialize usb 2.0 hub // initialize usb 2.0 hub
//
Status = HubDeviceExtension->HubInterface.Initialize20Hub(HubInterfaceBusContext, Status = HubDeviceExtension->HubInterface.Initialize20Hub(HubInterfaceBusContext,
HubDeviceExtension->RootHubHandle, 1); HubDeviceExtension->RootHubHandle, 1);
DPRINT("Status %x\n", Status); DPRINT("Status %x\n", Status);
//
// FIXME handle error // FIXME handle error
//
ASSERT(Status == STATUS_SUCCESS); ASSERT(Status == STATUS_SUCCESS);
} }
} }
ExFreePool(ConfigUrb);
//
// Enable power on all ports // Enable power on all ports
//
DPRINT("Enabling PortPower on all ports!\n"); DPRINT("Enabling PortPower on all ports!\n");
for (PortId = 1; PortId <= HubDeviceExtension->HubDescriptor.bNumberOfPorts; PortId++) for (PortId = 1; PortId <= HubDeviceExtension->HubDescriptor.bNumberOfPorts; PortId++)
{ {
Status = SetPortFeature(RootHubDeviceObject, PortId, PORT_POWER); Status = SetPortFeature(RootHubDeviceObject, PortId, PORT_POWER);
@ -1833,11 +1885,7 @@ USBHUB_FdoHandlePnp(
DPRINT1("Failed to power on port %d\n", PortId); DPRINT1("Failed to power on port %d\n", PortId);
} }
DPRINT("RootHubInitNotification %x\n", HubDeviceExtension->HubInterface.RootHubInitNotification);
//
// init root hub notification // init root hub notification
//
if (HubDeviceExtension->HubInterface.RootHubInitNotification) if (HubDeviceExtension->HubInterface.RootHubInitNotification)
{ {
Status = HubDeviceExtension->HubInterface.RootHubInitNotification(HubInterfaceBusContext, Status = HubDeviceExtension->HubInterface.RootHubInitNotification(HubInterfaceBusContext,
@ -1846,13 +1894,13 @@ USBHUB_FdoHandlePnp(
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
DPRINT1("Failed to set callback\n"); DPRINT1("Failed to set callback\n");
ExFreePool(Urb);
return Status;
} }
} }
else else
{ {
//
// Send the first SCE Request // Send the first SCE Request
//
QueryStatusChangeEndpoint(DeviceObject); QueryStatusChangeEndpoint(DeviceObject);
// //
@ -1896,7 +1944,32 @@ USBHUB_FdoHandlePnp(
} }
} }
// free urb
ExFreePool(Urb); ExFreePool(Urb);
// done
return Status;
}
NTSTATUS
USBHUB_FdoHandlePnp(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp)
{
PIO_STACK_LOCATION Stack;
NTSTATUS Status = STATUS_SUCCESS;
ULONG_PTR Information = 0;
PHUB_DEVICE_EXTENSION HubDeviceExtension;
HubDeviceExtension = (PHUB_DEVICE_EXTENSION) DeviceObject->DeviceExtension;
Stack = IoGetCurrentIrpStackLocation(Irp);
switch (Stack->MinorFunction)
{
case IRP_MN_START_DEVICE:
{
Status = USBHUB_FdoStartDevice(DeviceObject, Irp);
break; break;
} }

View file

@ -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 ?
@ -1310,6 +1310,8 @@ 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 // sanity checks
@ -1351,6 +1353,24 @@ CHubController::HandleClassDevice(
// 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