- 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),
0);
// FIXME: support usb hubs
Urb->UrbHeader.UsbdDeviceHandle = NULL;
//
// Query the Root Hub
//
@ -185,6 +189,10 @@ SetPortFeature(
0,
0,
0);
// FIXME support usbhubs
Urb->UrbHeader.UsbdDeviceHandle = NULL;
//
// Query the Root Hub
//
@ -237,6 +245,10 @@ ClearPortFeature(
0,
0,
0);
// FIXME: support usb hubs
Urb->UrbHeader.UsbdDeviceHandle = NULL;
//
// Query the Root Hub
//
@ -515,15 +527,12 @@ QueryStatusChangeEndpoint(
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 @@ GetUsbStringDescriptor(
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));
RtlZeroMemory(Buffer, SizeNeeded);
//
// Copy the string to destination
@ -1503,25 +1508,9 @@ RootHubInitCallbackFunction(
}
NTSTATUS
USBHUB_FdoHandlePnp(
USBHUB_FdoStartDevice(
IN PDEVICE_OBJECT DeviceObject,
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;
PUSB_INTERFACE_DESCRIPTOR Pid;
@ -1529,51 +1518,76 @@ USBHUB_FdoHandlePnp(
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
//
SubmitRequestToRootHub(HubDeviceExtension->LowerDeviceObject,
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;
}
RootHubDeviceObject = HubDeviceExtension->RootHubPhysicalDeviceObject;
// sanity checks
ASSERT(HubDeviceExtension->RootHubPhysicalDeviceObject);
ASSERT(HubDeviceExtension->RootHubFunctionalDeviceObject);
DPRINT("RootPdo %x, RootFdo %x\n",
HubDeviceExtension->RootHubPhysicalDeviceObject,
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");
ASSERT(FALSE);
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),
@ -1582,15 +1596,15 @@ USBHUB_FdoHandlePnp(
if (!NT_SUCCESS(Status))
{
// failed to get root hub interface
DPRINT1("Failed to get HUB_GUID interface with status 0x%08lx\n", Status);
return STATUS_UNSUCCESSFUL;
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),
@ -1599,15 +1613,15 @@ USBHUB_FdoHandlePnp(
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,
@ -1615,7 +1629,9 @@ USBHUB_FdoHandlePnp(
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;
}
@ -1636,9 +1652,7 @@ USBHUB_FdoHandlePnp(
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,
@ -1649,8 +1663,10 @@ USBHUB_FdoHandlePnp(
sizeof(USB_DEVICE_DESCRIPTOR),
NULL);
Urb->UrbHeader.UsbdDeviceHandle = NULL;//HubDeviceExtension->RootHubHandle;
// set device handle
Urb->UrbHeader.UsbdDeviceHandle = HubDeviceExtension->RootHubHandle;
// get hub device descriptor
Status = SubmitRequestToRootHub(RootHubDeviceObject,
IOCTL_INTERNAL_USB_SUBMIT_URB,
Urb,
@ -1658,14 +1674,13 @@ USBHUB_FdoHandlePnp(
if (!NT_SUCCESS(Status))
{
// failed to get device descriptor of hub
DPRINT1("Failed to get HubDeviceDescriptor!\n");
ExFreePool(Urb);
return Status;
}
DumpDeviceDescriptor(&HubDeviceExtension->HubDeviceDescriptor);
//
// Get Root Hubs Configuration Descriptor
//
// build configuration request
UsbBuildGetDescriptorRequest(Urb,
sizeof(Urb->UrbControlDescriptorRequest),
USB_CONFIGURATION_DESCRIPTOR_TYPE,
@ -1676,9 +1691,10 @@ USBHUB_FdoHandlePnp(
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;
// set device handle
Urb->UrbHeader.UsbdDeviceHandle = HubDeviceExtension->RootHubHandle;
// request configuration descriptor
Status = SubmitRequestToRootHub(RootHubDeviceObject,
IOCTL_INTERNAL_USB_SUBMIT_URB,
Urb,
@ -1686,13 +1702,26 @@ USBHUB_FdoHandlePnp(
if (!NT_SUCCESS(Status))
{
// failed to get configuration descriptor
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,
RootHubDeviceObject,
&HubDeviceExtension->UsbExtHubInfo,
@ -1700,15 +1729,23 @@ USBHUB_FdoHandlePnp(
&Result);
if (!NT_SUCCESS(Status))
{
// failed to get hub information
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);
//
// Get the Hub Descriptor
//
// Build hub descriptor request
UsbBuildVendorRequest(Urb,
URB_FUNCTION_CLASS_DEVICE,
sizeof(Urb->UrbControlVendorClassRequest),
@ -1722,15 +1759,15 @@ USBHUB_FdoHandlePnp(
sizeof(USB_HUB_DESCRIPTOR),
NULL);
Urb->UrbHeader.UsbdDeviceHandle = NULL;//HubDeviceExtension->RootHubHandle;
// set device handle
Urb->UrbHeader.UsbdDeviceHandle = HubDeviceExtension->RootHubHandle;
// send request
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");
@ -1738,6 +1775,12 @@ USBHUB_FdoHandlePnp(
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,
@ -1745,83 +1788,92 @@ USBHUB_FdoHandlePnp(
&HubStatus,
0,
NULL);
Urb->UrbHeader.UsbdDeviceHandle = NULL;//HubDeviceExtension->RootHubHandle;
// 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;
}
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);
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;
ConfigUrb = USBD_CreateConfigurationRequestEx(&HubDeviceExtension->HubConfigDescriptor,
(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,
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);
}
}
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);
@ -1833,11 +1885,7 @@ USBHUB_FdoHandlePnp(
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,
@ -1846,13 +1894,13 @@ USBHUB_FdoHandlePnp(
if (!NT_SUCCESS(Status))
{
DPRINT1("Failed to set callback\n");
ExFreePool(Urb);
return Status;
}
}
else
{
//
// Send the first SCE Request
//
QueryStatusChangeEndpoint(DeviceObject);
//
@ -1896,7 +1944,32 @@ USBHUB_FdoHandlePnp(
}
}
// free 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;
}

View file

@ -836,7 +836,7 @@ CHubController::HandleBulkOrInterruptTransfer(
//
// 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 @@ CHubController::HandleGetStatusFromDevice(
DeviceStatus = (PUSHORT)Urb->UrbControlGetStatusRequest.TransferBuffer;
if (Urb->UrbHeader.UsbdDeviceHandle == NULL)
if (Urb->UrbHeader.UsbdDeviceHandle == PVOID(this))
{
//
// FIXME need more flags ?
@ -1310,6 +1310,8 @@ CHubController::HandleClassDevice(
{
case USB_DEVICE_CLASS_RESERVED: // FALL THROUGH
case USB_DEVICE_CLASS_HUB:
{
if (Urb->UrbHeader.UsbdDeviceHandle == PVOID(this))
{
//
// sanity checks
@ -1351,6 +1353,24 @@ CHubController::HandleClassDevice(
// 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 @@ CHubController::HandleGetDescriptor(
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 @@ CHubController::HandleGetDescriptor(
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