[USBHUB_NEW]

- The lower level driver completes the SCE IRP whenever the change state has been modified for a port. When handling the SCE IRP completion only check for flags in change state. The Change flags must be cleared else the hub driver will get non stop SCE IRP completions.
- Allocate IRP from Pool vice calling IoAllocateIrp. Dont free the IRP in the completion routine as the port driver, oddly, frees them.
- GetUsbDeviceDescriptor: Remove use of MDL and use only buffer instead to make our new usbehci happy.
- When calling the interface routines, correctly use the BusContext returned from the interface instead of the RootHubPdo. This worked on windows as it just happened they were the same.
- Implement RootHubInitCallbackFunction, which only job currently is to send the first SCE IRP.
- For Start Device for child device objects fake success for now. Will be implemented later.
- Implement returning IRP_MN_QUERY_IDs, IRP_MN_QUERY_DEVICE_TEXTs and IRP_MN_QUERY_BUS_INFORMATION.
- Add basic handling for IRP_MJ_POWER.
- Misc code changes.
 

svn path=/branches/usb-bringup/; revision=51620
This commit is contained in:
Michael Martin 2011-05-07 14:49:02 +00:00
parent 5573560a44
commit e9fe271ad6
4 changed files with 388 additions and 159 deletions

View file

@ -244,16 +244,18 @@ DeviceStatusChangeThread(
IN PVOID Context) IN PVOID Context)
{ {
NTSTATUS Status; NTSTATUS Status;
PDEVICE_OBJECT DeviceObject; PDEVICE_OBJECT DeviceObject, RootHubDeviceObject;
PHUB_DEVICE_EXTENSION HubDeviceExtension; PHUB_DEVICE_EXTENSION HubDeviceExtension;
PWORK_ITEM_DATA WorkItemData; PWORK_ITEM_DATA WorkItemData;
PORT_STATUS_CHANGE PortStatus; PORT_STATUS_CHANGE PortStatus;
LONG PortId; LONG PortId;
DPRINT1("Entered DeviceStatusChangeThread, Context %x\n", Context);
static LONG failsafe = 0;
WorkItemData = (PWORK_ITEM_DATA)Context; WorkItemData = (PWORK_ITEM_DATA)Context;
DeviceObject = (PDEVICE_OBJECT)WorkItemData->Context; DeviceObject = (PDEVICE_OBJECT)WorkItemData->Context;
HubDeviceExtension = (PHUB_DEVICE_EXTENSION)DeviceObject->DeviceExtension; HubDeviceExtension = (PHUB_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
RootHubDeviceObject = HubDeviceExtension->RootHubPhysicalDeviceObject;
// //
// Loop all ports // Loop all ports
// //
@ -262,7 +264,7 @@ DeviceStatusChangeThread(
// //
// Get Port Status // Get Port Status
// //
Status = GetPortStatusAndChange(HubDeviceExtension->RootHubPhysicalDeviceObject, PortId, &PortStatus); Status = GetPortStatusAndChange(RootHubDeviceObject, PortId, &PortStatus);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
DPRINT1("Failed to get port status for port %d, Status %x\n", PortId, Status); DPRINT1("Failed to get port status for port %d, Status %x\n", PortId, Status);
@ -273,56 +275,105 @@ DeviceStatusChangeThread(
DPRINT1("Port %d Status %x\n", PortId, PortStatus.Status); DPRINT1("Port %d Status %x\n", PortId, PortStatus.Status);
DPRINT1("Port %d Change %x\n", PortId, PortStatus.Change); DPRINT1("Port %d Change %x\n", PortId, PortStatus.Change);
// //
// Check for new device connection // Check for new device connection
// //
if ((PortStatus.Change == USB_PORT_STATUS_CONNECT) && (PortStatus.Status & USB_PORT_STATUS_CONNECT)) if (PortStatus.Change & USB_PORT_STATUS_CONNECT)
{ {
// //
// Clear Connection Status // Clear Port Connect
// //
Status = ClearPortFeature(HubDeviceExtension->RootHubPhysicalDeviceObject, PortId, C_PORT_CONNECTION); Status = ClearPortFeature(RootHubDeviceObject, PortId, C_PORT_CONNECTION);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
DPRINT1("Failed to clear connection change for port %d\n", PortId); DPRINT1("Failed to clear connection change for port %d\n", PortId);
} }
// No SCE completion done for clearing C_PORT_CONNECT
// //
// Reset Port // Is this a connect or disconnect?
// //
Status = SetPortFeature(HubDeviceExtension->RootHubPhysicalDeviceObject, PortId, PORT_RESET); if (!(PortStatus.Status & USB_PORT_STATUS_CONNECT))
if (!NT_SUCCESS(Status))
{ {
DPRINT1("Failed to reset port %d\n", PortId); DPRINT1("Device disconnected from port %d\n", PortId);
//
// FIXME: Remove the device, and deallocate memory
//
}
else
{
DPRINT1("Device connected from port %d\n", PortId);
// No SCE completion done for clearing C_PORT_CONNECT
//
// Reset Port
//
Status = SetPortFeature(RootHubDeviceObject, PortId, PORT_RESET);
if (!NT_SUCCESS(Status))
{
DPRINT1("Failed to reset port %d\n", PortId);
}
} }
} }
else if ((PortStatus.Change == USB_PORT_STATUS_ENABLE) && else if (PortStatus.Change & USB_PORT_STATUS_ENABLE)
(PortStatus.Status & (USB_PORT_STATUS_CONNECT | USB_PORT_STATUS_ENABLE)))
{ {
// //
// Clear Enable // Clear Enable
// //
Status = ClearPortFeature(HubDeviceExtension->RootHubPhysicalDeviceObject, PortId, C_PORT_ENABLE); Status = ClearPortFeature(RootHubDeviceObject, PortId, C_PORT_ENABLE);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
DPRINT1("Failed to clear enable change on port %d\n", PortId); DPRINT1("Failed to clear enable change on port %d\n", PortId);
} }
} }
else if ((PortStatus.Change == USB_PORT_STATUS_RESET) && else if (PortStatus.Change & USB_PORT_STATUS_RESET)
(PortStatus.Status & (USB_PORT_STATUS_CONNECT | USB_PORT_STATUS_ENABLE)))
{ {
// //
// Clear Reset // Clear Reset
// //
Status = ClearPortFeature(HubDeviceExtension->RootHubPhysicalDeviceObject, PortId, C_PORT_RESET); Status = ClearPortFeature(RootHubDeviceObject, PortId, C_PORT_RESET);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
DPRINT1("Failed to clear reset change on port %d\n", PortId); DPRINT1("Failed to clear reset change on port %d\n", PortId);
} }
// FIXME: Double Check Port Status //
// Get Port Status
//
Status = GetPortStatusAndChange(RootHubDeviceObject, PortId, &PortStatus);
if (!NT_SUCCESS(Status))
{
DPRINT1("Failed to get port status for port %d, Status %x\n", PortId, Status);
// FIXME: Do we really want to halt further SCE requests?
return;
}
DPRINT1("Port %d Status %x\n", PortId, PortStatus.Status);
DPRINT1("Port %d Change %x\n", PortId, PortStatus.Change);
if(PortStatus.Change & USB_PORT_STATUS_RESET)
{
DPRINT1("Port did not clear reset! Possible Hardware problem!\n");
}
//
// Make sure its Connected and Enabled
//
if (!(PortStatus.Status & (USB_PORT_STATUS_CONNECT | USB_PORT_STATUS_ENABLE)))
{
DPRINT1("Usb Device is not connected and enabled!\n");
//
// Attempt another reset
//
Status = SetPortFeature(RootHubDeviceObject, PortId, PORT_RESET);
if (!NT_SUCCESS(Status))
{
DPRINT1("Failed to reset port %d\n", PortId);
}
continue;
}
// //
// Create the device object only if the port manipulation was started by a device connect // Create the device object only if the port manipulation was started by a device connect
@ -335,14 +386,26 @@ DeviceStatusChangeThread(
} }
} }
//
// FIXME: Still in testing
//
failsafe++;
if (failsafe > 100)
{
DPRINT1("SCE completed over 100 times but no action has been taken to clear the Change of any ports.\n");
//
// Return and dont send any more SCE Requests
//
return;
}
ExFreePool(WorkItemData); ExFreePool(WorkItemData);
// //
// Send another SCE Request // Send another SCE Request
// //
DPRINT1("Sending another SCE!\n");
QueryStatusChangeEndpoint(DeviceObject); QueryStatusChangeEndpoint(DeviceObject);
} }
NTSTATUS NTSTATUS
@ -359,9 +422,10 @@ StatusChangeEndpointCompletion(
HubDeviceExtension = (PHUB_DEVICE_EXTENSION)RealDeviceObject->DeviceExtension; HubDeviceExtension = (PHUB_DEVICE_EXTENSION)RealDeviceObject->DeviceExtension;
// //
// Free the Irp // NOTE: USBPORT frees this IRP
// //
IoFreeIrp(Irp); DPRINT1("Received Irp %x, HubDeviceExtension->PendingSCEIrp %x\n", Irp, HubDeviceExtension->PendingSCEIrp);
//IoFreeIrp(Irp);
// //
// Create and initialize work item data // Create and initialize work item data
@ -373,6 +437,7 @@ StatusChangeEndpointCompletion(
return STATUS_INSUFFICIENT_RESOURCES; return STATUS_INSUFFICIENT_RESOURCES;
} }
WorkItemData->Context = RealDeviceObject; WorkItemData->Context = RealDeviceObject;
DPRINT1("Initialize work item\n");
ExInitializeWorkItem(&WorkItemData->WorkItem, (PWORKER_THREAD_ROUTINE)DeviceStatusChangeThread, (PVOID)WorkItemData); ExInitializeWorkItem(&WorkItemData->WorkItem, (PWORKER_THREAD_ROUTINE)DeviceStatusChangeThread, (PVOID)WorkItemData);
// //
@ -391,15 +456,23 @@ QueryStatusChangeEndpoint(
IN PDEVICE_OBJECT DeviceObject) IN PDEVICE_OBJECT DeviceObject)
{ {
NTSTATUS Status; NTSTATUS Status;
PDEVICE_OBJECT RootHubDeviceObject;
PIO_STACK_LOCATION Stack; PIO_STACK_LOCATION Stack;
PHUB_DEVICE_EXTENSION HubDeviceExtension; PHUB_DEVICE_EXTENSION HubDeviceExtension;
PURB PendingSCEUrb;
HubDeviceExtension = (PHUB_DEVICE_EXTENSION)DeviceObject->DeviceExtension; HubDeviceExtension = (PHUB_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
RootHubDeviceObject = HubDeviceExtension->RootHubPhysicalDeviceObject;
//
// Allocate a URB
//
PendingSCEUrb = ExAllocatePoolWithTag(NonPagedPool, sizeof(URB), USB_HUB_TAG);
// //
// Initialize URB for Status Change Endpoint request // Initialize URB for Status Change Endpoint request
// //
UsbBuildInterruptOrBulkTransferRequest(&HubDeviceExtension->PendingSCEUrb, UsbBuildInterruptOrBulkTransferRequest(PendingSCEUrb,
sizeof(struct _URB_BULK_OR_INTERRUPT_TRANSFER), sizeof(struct _URB_BULK_OR_INTERRUPT_TRANSFER),
HubDeviceExtension->PipeHandle, HubDeviceExtension->PipeHandle,
HubDeviceExtension->PortStatusChange, HubDeviceExtension->PortStatusChange,
@ -411,13 +484,20 @@ QueryStatusChangeEndpoint(
// //
// Set the device handle to null for roothub // Set the device handle to null for roothub
// //
HubDeviceExtension->PendingSCEUrb.UrbHeader.UsbdDeviceHandle = NULL; PendingSCEUrb->UrbHeader.UsbdDeviceHandle = NULL;//HubDeviceExtension->RootHubHandle;
// //
// Allocate an Irp // Allocate an Irp
// //
HubDeviceExtension->PendingSCEIrp = IoAllocateIrp(HubDeviceExtension->RootHubPhysicalDeviceObject->StackSize,
FALSE); HubDeviceExtension->PendingSCEIrp = ExAllocatePoolWithTag(NonPagedPool,
IoSizeOfIrp(RootHubDeviceObject->StackSize),
USB_HUB_TAG);
/*
HubDeviceExtension->PendingSCEIrp = IoAllocateIrp(RootHubDeviceObject->StackSize,
FALSE);
*/
DPRINT1("Allocated IRP %x\n", HubDeviceExtension->PendingSCEIrp);
if (!HubDeviceExtension->PendingSCEIrp) if (!HubDeviceExtension->PendingSCEIrp)
{ {
@ -428,6 +508,10 @@ QueryStatusChangeEndpoint(
// //
// Initialize the IRP // Initialize the IRP
// //
IoInitializeIrp(HubDeviceExtension->PendingSCEIrp,
IoSizeOfIrp(RootHubDeviceObject->StackSize),
RootHubDeviceObject->StackSize);
HubDeviceExtension->PendingSCEIrp->IoStatus.Status = STATUS_NOT_SUPPORTED; HubDeviceExtension->PendingSCEIrp->IoStatus.Status = STATUS_NOT_SUPPORTED;
HubDeviceExtension->PendingSCEIrp->IoStatus.Information = 0; HubDeviceExtension->PendingSCEIrp->IoStatus.Information = 0;
HubDeviceExtension->PendingSCEIrp->Flags = 0; HubDeviceExtension->PendingSCEIrp->Flags = 0;
@ -437,8 +521,8 @@ QueryStatusChangeEndpoint(
// Get the Next Stack Location and Initialize it // Get the Next Stack Location and Initialize it
// //
Stack = IoGetNextIrpStackLocation(HubDeviceExtension->PendingSCEIrp); Stack = IoGetNextIrpStackLocation(HubDeviceExtension->PendingSCEIrp);
Stack->DeviceObject = HubDeviceExtension->RootHubPhysicalDeviceObject; Stack->DeviceObject = DeviceObject;
Stack->Parameters.Others.Argument1 = &HubDeviceExtension->PendingSCEUrb; Stack->Parameters.Others.Argument1 = PendingSCEUrb;
Stack->Parameters.Others.Argument2 = NULL; Stack->Parameters.Others.Argument2 = NULL;
Stack->MajorFunction = IRP_MJ_INTERNAL_DEVICE_CONTROL; Stack->MajorFunction = IRP_MJ_INTERNAL_DEVICE_CONTROL;
Stack->Parameters.DeviceIoControl.IoControlCode = IOCTL_INTERNAL_USB_SUBMIT_URB; Stack->Parameters.DeviceIoControl.IoControlCode = IOCTL_INTERNAL_USB_SUBMIT_URB;
@ -456,7 +540,9 @@ QueryStatusChangeEndpoint(
// //
// Send to RootHub // Send to RootHub
// //
Status = IoCallDriver(HubDeviceExtension->RootHubPhysicalDeviceObject, HubDeviceExtension->PendingSCEIrp); DPRINT1("DeviceObject is %x\n", DeviceObject);
DPRINT1("Iocalldriver %x with irp %x\n", RootHubDeviceObject, HubDeviceExtension->PendingSCEIrp);
Status = IoCallDriver(RootHubDeviceObject, HubDeviceExtension->PendingSCEIrp);
return STATUS_PENDING; return STATUS_PENDING;
} }
@ -524,16 +610,17 @@ GetUsbDeviceDescriptor(
IN ULONG TransferBufferLength) IN ULONG TransferBufferLength)
{ {
NTSTATUS Status; NTSTATUS Status;
PDEVICE_OBJECT RootHubDeviceObject;
PURB Urb; PURB Urb;
PHUB_DEVICE_EXTENSION HubDeviceExtension; PHUB_DEVICE_EXTENSION HubDeviceExtension;
PHUB_CHILDDEVICE_EXTENSION ChildDeviceExtension; PHUB_CHILDDEVICE_EXTENSION ChildDeviceExtension;
PMDL BufferMdl;
// //
// Get the Hubs Device Extension // Get the Hubs Device Extension
// //
ChildDeviceExtension = (PHUB_CHILDDEVICE_EXTENSION)ChildDeviceObject->DeviceExtension; ChildDeviceExtension = (PHUB_CHILDDEVICE_EXTENSION)ChildDeviceObject->DeviceExtension;
HubDeviceExtension = (PHUB_DEVICE_EXTENSION) ChildDeviceExtension->ParentDeviceObject->DeviceExtension; HubDeviceExtension = (PHUB_DEVICE_EXTENSION) ChildDeviceExtension->ParentDeviceObject->DeviceExtension;
RootHubDeviceObject = HubDeviceExtension->RootHubPhysicalDeviceObject;
// //
// Allocate a URB // Allocate a URB
@ -550,29 +637,6 @@ GetUsbDeviceDescriptor(
// //
RtlZeroMemory(Urb, sizeof(URB)); RtlZeroMemory(Urb, sizeof(URB));
//
// Create a MDL for buffer
//
BufferMdl = IoAllocateMdl(TransferBuffer,
TransferBufferLength,
FALSE,
FALSE,
NULL);
//
// Update Physical Pages
//
_SEH2_TRY
{
MmBuildMdlForNonPagedPool(BufferMdl);
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
DPRINT1("MmBuildMdlForNonPagedPool Failed!\n");
Status = _SEH2_GetExceptionCode();
}
_SEH2_END;
// //
// Create URB for getting device descriptor // Create URB for getting device descriptor
// //
@ -581,8 +645,8 @@ GetUsbDeviceDescriptor(
DescriptorType, DescriptorType,
Index, Index,
LangId, LangId,
TransferBuffer,
NULL, NULL,
BufferMdl,
TransferBufferLength, TransferBufferLength,
NULL); NULL);
@ -594,16 +658,11 @@ GetUsbDeviceDescriptor(
// //
// Query the Root Hub // Query the Root Hub
// //
Status = SubmitRequestToRootHub(HubDeviceExtension->RootHubPhysicalDeviceObject, Status = SubmitRequestToRootHub(RootHubDeviceObject,
IOCTL_INTERNAL_USB_SUBMIT_URB, IOCTL_INTERNAL_USB_SUBMIT_URB,
Urb, Urb,
NULL); NULL);
//
// Free Mdl
//
IoFreeMdl(BufferMdl);
return Status; return Status;
} }
@ -636,7 +695,18 @@ GetUsbStringDescriptor(
0, 0,
StringDesc, StringDesc,
sizeof(USB_STRING_DESCRIPTOR)); sizeof(USB_STRING_DESCRIPTOR));
SizeNeeded = StringDesc->bLength;
//
// If lenght is 4 only then either this is a bad index or the device is not reporting
//
if (StringDesc->bLength == 4)
{
DPRINT1("USBHUB: Device Data Error\n");
return STATUS_UNSUCCESSFUL;
}
DPRINT1("StringDesc->bLength %d\n", StringDesc->bLength);
SizeNeeded = StringDesc->bLength + sizeof(WCHAR);
// //
// Free String // Free String
@ -647,14 +717,14 @@ GetUsbStringDescriptor(
// Recreate with appropriate size // Recreate with appropriate size
// //
StringDesc = ExAllocatePoolWithTag(NonPagedPool, StringDesc = ExAllocatePoolWithTag(NonPagedPool,
SizeNeeded + sizeof(USB_STRING_DESCRIPTOR), SizeNeeded,
USB_HUB_TAG); USB_HUB_TAG);
if (!StringDesc) if (!StringDesc)
{ {
DPRINT1("Failed to allocate buffer for string!\n"); DPRINT1("Failed to allocate buffer for string!\n");
return STATUS_INSUFFICIENT_RESOURCES; return STATUS_INSUFFICIENT_RESOURCES;
} }
RtlZeroMemory(StringDesc, SizeNeeded);
// //
// Get the string // Get the string
// //
@ -663,7 +733,7 @@ GetUsbStringDescriptor(
Index, Index,
0, 0,
StringDesc, StringDesc,
SizeNeeded + sizeof(USB_STRING_DESCRIPTOR)); SizeNeeded);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
DPRINT1("Failed to get string from device\n"); DPRINT1("Failed to get string from device\n");
@ -672,11 +742,11 @@ GetUsbStringDescriptor(
} }
// //
// Allocate Buffer and Save it // Allocate Buffer to return
// //
*TransferBuffer = ExAllocatePoolWithTag(NonPagedPool, *TransferBuffer = ExAllocatePoolWithTag(NonPagedPool,
SizeNeeded, SizeNeeded,
USB_HUB_TAG); USB_HUB_TAG);
if (!*TransferBuffer) if (!*TransferBuffer)
{ {
DPRINT1("Failed to allocate buffer for string!\n"); DPRINT1("Failed to allocate buffer for string!\n");
@ -689,7 +759,7 @@ GetUsbStringDescriptor(
// //
// Copy the string to destination // Copy the string to destination
// //
RtlCopyMemory(*TransferBuffer, StringDesc->bString, SizeNeeded); RtlCopyMemory(*TransferBuffer, StringDesc->bString, SizeNeeded - FIELD_OFFSET(USB_STRING_DESCRIPTOR, bLength));
ExFreePool(StringDesc); ExFreePool(StringDesc);
@ -707,18 +777,16 @@ CreateUsbChildDeviceObject(
PHUB_DEVICE_EXTENSION HubDeviceExtension; PHUB_DEVICE_EXTENSION HubDeviceExtension;
PHUB_CHILDDEVICE_EXTENSION UsbChildExtension; PHUB_CHILDDEVICE_EXTENSION UsbChildExtension;
PUSB_BUS_INTERFACE_HUB_V5 HubInterface; PUSB_BUS_INTERFACE_HUB_V5 HubInterface;
ULONG ChildDeviceCount; ULONG ChildDeviceCount, UsbDeviceNumber = 0;
WCHAR CharDeviceName[64]; WCHAR CharDeviceName[64];
ULONG UsbDeviceNumber = 0;
UNICODE_STRING DeviceName; UNICODE_STRING DeviceName;
USB_DEVICE_DESCRIPTOR DeviceDesc; ULONG ConfigDescSize, DeviceDescSize;
USB_CONFIGURATION_DESCRIPTOR ConfigDesc; PVOID HubInterfaceBusContext;
ULONG DeviceDescSize, ConfigDescSize;
HubDeviceExtension = (PHUB_DEVICE_EXTENSION) UsbHubDeviceObject->DeviceExtension; HubDeviceExtension = (PHUB_DEVICE_EXTENSION) UsbHubDeviceObject->DeviceExtension;
HubInterface = &HubDeviceExtension->HubInterface; HubInterface = &HubDeviceExtension->HubInterface;
RootHubDeviceObject = HubDeviceExtension->RootHubPhysicalDeviceObject; RootHubDeviceObject = HubDeviceExtension->RootHubPhysicalDeviceObject;
HubInterfaceBusContext = HubDeviceExtension->UsbDInterface.BusContext;
// //
// Find an empty slot in the child device array // Find an empty slot in the child device array
// //
@ -726,6 +794,7 @@ CreateUsbChildDeviceObject(
{ {
if (HubDeviceExtension->ChildDeviceObject[ChildDeviceCount] == NULL) if (HubDeviceExtension->ChildDeviceObject[ChildDeviceCount] == NULL)
{ {
DPRINT1("Found unused entry at %d\n", ChildDeviceCount);
break; break;
} }
} }
@ -735,7 +804,7 @@ CreateUsbChildDeviceObject(
// //
if (ChildDeviceCount == USB_MAXCHILDREN) if (ChildDeviceCount == USB_MAXCHILDREN)
{ {
DPRINT1("Too many child devices!\n"); DPRINT1("USBHUB: Too many child devices!\n");
return STATUS_UNSUCCESSFUL; return STATUS_UNSUCCESSFUL;
} }
@ -780,7 +849,7 @@ CreateUsbChildDeviceObject(
// //
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
DPRINT1("IoCreateDevice failed with status %x\n", Status); DPRINT1("USBHUB: IoCreateDevice failed with status %x\n", Status);
return Status; return Status;
} }
@ -800,45 +869,49 @@ CreateUsbChildDeviceObject(
// //
// Create the UsbDeviceObject // Create the UsbDeviceObject
// //
Status = HubInterface->CreateUsbDevice(RootHubDeviceObject, Status = HubInterface->CreateUsbDevice(HubInterfaceBusContext,
(PVOID)&UsbChildExtension->UsbDeviceHandle, (PVOID)&UsbChildExtension->UsbDeviceHandle,
HubDeviceExtension->RootHubHandle, HubDeviceExtension->RootHubHandle,
0x503, //hack 0x501, //hack
PortId); PortId);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
DPRINT1("CreateUsbDevice failed with status %x\n", Status); DPRINT1("USBHUB: CreateUsbDevice failed with status %x\n", Status);
goto Cleanup; goto Cleanup;
} }
// //
// Initialize UsbDevice // Initialize UsbDevice
// //
Status = HubInterface->InitializeUsbDevice(RootHubDeviceObject, UsbChildExtension->UsbDeviceHandle); Status = HubInterface->InitializeUsbDevice(HubInterfaceBusContext, UsbChildExtension->UsbDeviceHandle);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
DPRINT1("InitializeUsbDevice failed with status %x\n", Status); DPRINT1("USBHUB: InitializeUsbDevice failed with status %x\n", Status);
goto Cleanup; goto Cleanup;
} }
DeviceDescSize = sizeof(USB_DEVICE_DESCRIPTOR); DPRINT1("Usb Device Handle %x\n", UsbChildExtension->UsbDeviceHandle);
ConfigDescSize = sizeof(USB_CONFIGURATION_DESCRIPTOR); ConfigDescSize = sizeof(USB_CONFIGURATION_DESCRIPTOR);
DeviceDescSize = sizeof(USB_DEVICE_DESCRIPTOR);
// //
// Get the descriptors // Get the descriptors
// //
Status = HubInterface->GetUsbDescriptors(RootHubDeviceObject, Status = HubInterface->GetUsbDescriptors(HubInterfaceBusContext,
UsbChildExtension->UsbDeviceHandle, UsbChildExtension->UsbDeviceHandle,
(PUCHAR)&DeviceDesc, (PUCHAR)&UsbChildExtension->DeviceDesc,
&DeviceDescSize, &DeviceDescSize,
(PUCHAR)&ConfigDesc, (PUCHAR)&UsbChildExtension->ConfigDesc,
&ConfigDescSize); &ConfigDescSize);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
DPRINT1("GetUsbDescriptors failed with status %x\n", Status); DPRINT1("USBHUB: GetUsbDescriptors failed with status %x\n", Status);
goto Cleanup; goto Cleanup;
} }
DumpDeviceDescriptor(&UsbChildExtension->DeviceDesc);
// //
// Allocate memory for DeviceId // Allocate memory for DeviceId
// //
@ -847,7 +920,7 @@ CreateUsbChildDeviceObject(
// //
// Construct DeviceId from vendor and product values // Construct DeviceId from vendor and product values
// //
swprintf(UsbChildExtension->DeviceId, L"USB\\Vid_%04x&Pid_%04x", DeviceDesc.idVendor, DeviceDesc.idProduct); swprintf(UsbChildExtension->DeviceId, L"USB\\Vid_%04x&Pid_%04x", UsbChildExtension->DeviceDesc.idVendor, UsbChildExtension->DeviceDesc.idProduct);
DPRINT1("Usb Device Id %S\n", UsbChildExtension->DeviceId); DPRINT1("Usb Device Id %S\n", UsbChildExtension->DeviceId);
@ -859,26 +932,26 @@ CreateUsbChildDeviceObject(
// Get the product string // Get the product string
// //
Status = GetUsbStringDescriptor(NewChildDeviceObject, Status = GetUsbStringDescriptor(NewChildDeviceObject,
DeviceDesc.iProduct, UsbChildExtension->DeviceDesc.iProduct,
0, 0,
(PVOID*)&UsbChildExtension->TextDescription); (PVOID*)&UsbChildExtension->TextDescription);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
DPRINT1("GetUsbStringDescriptor failed with status %x\n", Status); DPRINT1("USBHUB: GetUsbStringDescriptor failed with status %x\n", Status);
goto Cleanup; goto Cleanup;
} }
DPRINT1("Usb TextDescription %S\n", UsbChildExtension->TextDescription); DPRINT1("Usb TextDescription %S\n", UsbChildExtension->TextDescription);
Status = GetUsbStringDescriptor(NewChildDeviceObject, Status = GetUsbStringDescriptor(NewChildDeviceObject,
DeviceDesc.iSerialNumber, UsbChildExtension->DeviceDesc.iSerialNumber,
0, 0,
(PVOID*)&UsbChildExtension->InstanceId); (PVOID*)&UsbChildExtension->InstanceId);
DPRINT1("Usb InstanceId %S\n", UsbChildExtension->InstanceId); DPRINT1("Usb InstanceId %S\n", UsbChildExtension->InstanceId);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
DPRINT1("GetUsbStringDescriptor failed with status %x\n", Status); DPRINT1("USBHUB: GetUsbStringDescriptor failed with status %x\n", Status);
goto Cleanup; goto Cleanup;
} }
@ -891,7 +964,6 @@ Cleanup:
IoDeleteDevice(NewChildDeviceObject); IoDeleteDevice(NewChildDeviceObject);
return Status; return Status;
} }
NTSTATUS NTSTATUS
@ -954,6 +1026,20 @@ USBHUB_FdoQueryBusRelations(
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
VOID
RootHubInitCallbackFunction(
PVOID Context)
{
PDEVICE_OBJECT DeviceObject = (PDEVICE_OBJECT)Context;
DPRINT1("Sending the initial SCE Request %x\n", DeviceObject);
//
// Send the first SCE Request
//
QueryStatusChangeEndpoint(DeviceObject);
}
NTSTATUS NTSTATUS
USBHUB_FdoHandlePnp( USBHUB_FdoHandlePnp(
IN PDEVICE_OBJECT DeviceObject, IN PDEVICE_OBJECT DeviceObject,
@ -963,6 +1049,8 @@ 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;
HubDeviceExtension = (PHUB_DEVICE_EXTENSION) DeviceObject->DeviceExtension; HubDeviceExtension = (PHUB_DEVICE_EXTENSION) DeviceObject->DeviceExtension;
@ -973,11 +1061,11 @@ USBHUB_FdoHandlePnp(
case IRP_MN_START_DEVICE: case IRP_MN_START_DEVICE:
{ {
PURB Urb; PURB Urb;
ULONG Result = 0;
PUSB_INTERFACE_DESCRIPTOR Pid; PUSB_INTERFACE_DESCRIPTOR Pid;
ULONG 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;
DPRINT1("IRP_MJ_PNP / IRP_MN_START_DEVICE\n"); DPRINT1("IRP_MJ_PNP / IRP_MN_START_DEVICE\n");
@ -995,6 +1083,7 @@ USBHUB_FdoHandlePnp(
&HubDeviceExtension->RootHubPhysicalDeviceObject, &HubDeviceExtension->RootHubPhysicalDeviceObject,
&HubDeviceExtension->RootHubFunctionalDeviceObject); &HubDeviceExtension->RootHubFunctionalDeviceObject);
RootHubDeviceObject = HubDeviceExtension->RootHubPhysicalDeviceObject;
ASSERT(HubDeviceExtension->RootHubPhysicalDeviceObject); ASSERT(HubDeviceExtension->RootHubPhysicalDeviceObject);
ASSERT(HubDeviceExtension->RootHubFunctionalDeviceObject); ASSERT(HubDeviceExtension->RootHubFunctionalDeviceObject);
DPRINT1("RootPdo %x, RootFdo %x\n", DPRINT1("RootPdo %x, RootFdo %x\n",
@ -1004,7 +1093,7 @@ USBHUB_FdoHandlePnp(
// //
// Send the StartDevice to RootHub // Send the StartDevice to RootHub
// //
Status = ForwardIrpAndWait(HubDeviceExtension->RootHubPhysicalDeviceObject, Irp); Status = ForwardIrpAndWait(RootHubDeviceObject, Irp);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
@ -1015,14 +1104,14 @@ USBHUB_FdoHandlePnp(
// //
// Get the current number of hubs // Get the current number of hubs
// //
Status = SubmitRequestToRootHub(HubDeviceExtension->RootHubPhysicalDeviceObject, Status = SubmitRequestToRootHub(RootHubDeviceObject,
IOCTL_INTERNAL_USB_GET_HUB_COUNT, IOCTL_INTERNAL_USB_GET_HUB_COUNT,
&HubDeviceExtension->NumberOfHubs, NULL); &HubDeviceExtension->NumberOfHubs, NULL);
// //
// Get the Hub Interface // Get the Hub Interface
// //
Status = QueryInterface(HubDeviceExtension->RootHubPhysicalDeviceObject, 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),
5, 5,
@ -1034,10 +1123,12 @@ USBHUB_FdoHandlePnp(
return STATUS_UNSUCCESSFUL; return STATUS_UNSUCCESSFUL;
} }
HubInterfaceBusContext = HubDeviceExtension->HubInterface.BusContext;
// //
// Get the USBDI Interface // Get the USBDI Interface
// //
Status = QueryInterface(HubDeviceExtension->RootHubPhysicalDeviceObject, 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),
2, 2,
@ -1049,10 +1140,12 @@ USBHUB_FdoHandlePnp(
return Status; return Status;
} }
UsbDInterfaceBusContext = HubDeviceExtension->UsbDInterface.BusContext;
// //
// Get Root Hub Device Handle // Get Root Hub Device Handle
// //
Status = SubmitRequestToRootHub(HubDeviceExtension->RootHubPhysicalDeviceObject, Status = SubmitRequestToRootHub(RootHubDeviceObject,
IOCTL_INTERNAL_USB_GET_DEVICE_HANDLE, IOCTL_INTERNAL_USB_GET_DEVICE_HANDLE,
&HubDeviceExtension->RootHubHandle, &HubDeviceExtension->RootHubHandle,
NULL); NULL);
@ -1066,7 +1159,7 @@ USBHUB_FdoHandlePnp(
// //
// Get Hub Device Information // Get Hub Device Information
// //
Status = HubDeviceExtension->HubInterface.QueryDeviceInformation(HubDeviceExtension->RootHubPhysicalDeviceObject, Status = HubDeviceExtension->HubInterface.QueryDeviceInformation(HubInterfaceBusContext,
HubDeviceExtension->RootHubHandle, HubDeviceExtension->RootHubHandle,
&HubDeviceExtension->DeviceInformation, &HubDeviceExtension->DeviceInformation,
sizeof(USB_DEVICE_INFORMATION_0), sizeof(USB_DEVICE_INFORMATION_0),
@ -1093,9 +1186,9 @@ USBHUB_FdoHandlePnp(
sizeof(USB_DEVICE_DESCRIPTOR), sizeof(USB_DEVICE_DESCRIPTOR),
NULL); NULL);
Urb->UrbHeader.UsbdDeviceHandle = HubDeviceExtension->RootHubHandle; Urb->UrbHeader.UsbdDeviceHandle = NULL;//HubDeviceExtension->RootHubHandle;
Status = SubmitRequestToRootHub(HubDeviceExtension->RootHubPhysicalDeviceObject, Status = SubmitRequestToRootHub(RootHubDeviceObject,
IOCTL_INTERNAL_USB_SUBMIT_URB, IOCTL_INTERNAL_USB_SUBMIT_URB,
Urb, Urb,
NULL); NULL);
@ -1120,9 +1213,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);
Urb->UrbHeader.UsbdDeviceHandle = HubDeviceExtension->RootHubHandle; DPRINT1("RootHub Handle %x\n", HubDeviceExtension->RootHubHandle);
Urb->UrbHeader.UsbdDeviceHandle = NULL;//HubDeviceExtension->RootHubHandle;
Status = SubmitRequestToRootHub(HubDeviceExtension->RootHubPhysicalDeviceObject, Status = SubmitRequestToRootHub(RootHubDeviceObject,
IOCTL_INTERNAL_USB_SUBMIT_URB, IOCTL_INTERNAL_USB_SUBMIT_URB,
Urb, Urb,
NULL); NULL);
@ -1136,8 +1230,8 @@ USBHUB_FdoHandlePnp(
DumpConfigurationDescriptor(&HubDeviceExtension->HubConfigDescriptor); DumpConfigurationDescriptor(&HubDeviceExtension->HubConfigDescriptor);
Status = HubDeviceExtension->HubInterface.GetExtendedHubInformation(HubDeviceExtension->RootHubPhysicalDeviceObject, Status = HubDeviceExtension->HubInterface.GetExtendedHubInformation(HubInterfaceBusContext,
HubDeviceExtension->RootHubPhysicalDeviceObject, RootHubDeviceObject,
&HubDeviceExtension->UsbExtHubInfo, &HubDeviceExtension->UsbExtHubInfo,
sizeof(USB_EXTHUB_INFORMATION_0), sizeof(USB_EXTHUB_INFORMATION_0),
&Result); &Result);
@ -1157,24 +1251,21 @@ USBHUB_FdoHandlePnp(
sizeof(Urb->UrbControlVendorClassRequest), sizeof(Urb->UrbControlVendorClassRequest),
USBD_TRANSFER_DIRECTION_IN | USBD_SHORT_TRANSFER_OK, USBD_TRANSFER_DIRECTION_IN | USBD_SHORT_TRANSFER_OK,
0, 0,
USB_REQUEST_GET_DESCRIPTOR,
USB_DEVICE_CLASS_RESERVED, USB_DEVICE_CLASS_RESERVED,
0, 0,
0,
&HubDeviceExtension->HubDescriptor, &HubDeviceExtension->HubDescriptor,
NULL, NULL,
sizeof(USB_HUB_DESCRIPTOR), sizeof(USB_HUB_DESCRIPTOR),
NULL); NULL);
Urb->UrbHeader.UsbdDeviceHandle = HubDeviceExtension->RootHubHandle; Urb->UrbHeader.UsbdDeviceHandle = NULL;//HubDeviceExtension->RootHubHandle;
Status = SubmitRequestToRootHub(HubDeviceExtension->RootHubPhysicalDeviceObject, Status = SubmitRequestToRootHub(RootHubDeviceObject,
IOCTL_INTERNAL_USB_SUBMIT_URB, IOCTL_INTERNAL_USB_SUBMIT_URB,
Urb, Urb,
NULL); NULL);
//
// FIXME: This is returning nothing.
//
DPRINT1("bDescriptorType %x\n", HubDeviceExtension->HubDescriptor.bDescriptorType); DPRINT1("bDescriptorType %x\n", HubDeviceExtension->HubDescriptor.bDescriptorType);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
@ -1184,6 +1275,28 @@ USBHUB_FdoHandlePnp(
return STATUS_UNSUCCESSFUL; 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 // Allocate memory for PortStatusChange to hold 2 USHORTs for each port on hub
// //
@ -1191,13 +1304,6 @@ USBHUB_FdoHandlePnp(
sizeof(ULONG) * HubDeviceExtension->UsbExtHubInfo.NumberOfPorts, sizeof(ULONG) * HubDeviceExtension->UsbExtHubInfo.NumberOfPorts,
USB_HUB_TAG); USB_HUB_TAG);
//
// Initialize the Hub
//
Status = HubDeviceExtension->HubInterface.Initialize20Hub(HubDeviceExtension->RootHubPhysicalDeviceObject,
HubDeviceExtension->RootHubHandle, 1);
DPRINT1("Status %x\n", Status);
// //
// Get the first Configuration Descriptor // Get the first Configuration Descriptor
// //
@ -1212,7 +1318,7 @@ USBHUB_FdoHandlePnp(
(PUSBD_INTERFACE_LIST_ENTRY)&InterfaceList); (PUSBD_INTERFACE_LIST_ENTRY)&InterfaceList);
ASSERT(ConfigUrb != NULL); ASSERT(ConfigUrb != NULL);
Status = SubmitRequestToRootHub(HubDeviceExtension->RootHubPhysicalDeviceObject, Status = SubmitRequestToRootHub(RootHubDeviceObject,
IOCTL_INTERNAL_USB_SUBMIT_URB, IOCTL_INTERNAL_USB_SUBMIT_URB,
ConfigUrb, ConfigUrb,
NULL); NULL);
@ -1221,22 +1327,54 @@ USBHUB_FdoHandlePnp(
HubDeviceExtension->PipeHandle = ConfigUrb->UrbSelectConfiguration.Interface.Pipes[0].PipeHandle; HubDeviceExtension->PipeHandle = ConfigUrb->UrbSelectConfiguration.Interface.Pipes[0].PipeHandle;
DPRINT1("Configuration Handle %x\n", HubDeviceExtension->ConfigurationHandle); DPRINT1("Configuration Handle %x\n", HubDeviceExtension->ConfigurationHandle);
//
// Initialize the Hub
//
Status = HubDeviceExtension->HubInterface.Initialize20Hub(HubInterfaceBusContext,
HubDeviceExtension->RootHubHandle, 1);
DPRINT1("Status %x\n", Status);
ExFreePool(ConfigUrb); ExFreePool(ConfigUrb);
// //
// Enable power on all ports // Enable power on all ports
// //
DPRINT1("Enabling PortPower on all ports!\n");
for (PortId = 1; PortId <= HubDeviceExtension->HubDescriptor.bNumberOfPorts; PortId++) for (PortId = 1; PortId <= HubDeviceExtension->HubDescriptor.bNumberOfPorts; PortId++)
{ {
Status = SetPortFeature(HubDeviceExtension->RootHubPhysicalDeviceObject, PortId, PORT_POWER); 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)) if (!NT_SUCCESS(Status))
DPRINT1("Failed to power on port %d\n", PortId); DPRINT1("Failed to power on port %d\n", PortId);
} }
DPRINT1("RootHubInitNotification %x\n", HubDeviceExtension->HubInterface.RootHubInitNotification);
// //
// Send the first SCE Request
// //
QueryStatusChangeEndpoint(DeviceObject); //
if (HubDeviceExtension->HubInterface.RootHubInitNotification)
{
Status = HubDeviceExtension->HubInterface.RootHubInitNotification(HubInterfaceBusContext,
DeviceObject,
(PRH_INIT_CALLBACK)RootHubInitCallbackFunction);
}
else
{
//
// Send the first SCE Request
//
QueryStatusChangeEndpoint(DeviceObject);
}
if (!NT_SUCCESS(Status))
{
DPRINT1("Failed to set callback\n");
}
ExFreePool(Urb); ExFreePool(Urb);
break; break;

View file

@ -4,7 +4,7 @@
* FILE: drivers/usb/usbhub/fdo.c * FILE: drivers/usb/usbhub/fdo.c
* PURPOSE: Handle PDO * PURPOSE: Handle PDO
* PROGRAMMERS: * PROGRAMMERS:
* Hervé Poussineau (hpoussin@reactos.org) * Hervé Poussineau (hpoussin@reactos.org)
* Michael Martin (michael.martin@reactos.org) * Michael Martin (michael.martin@reactos.org)
* Johannes Anderwald (johannes.anderwald@reactos.org) * Johannes Anderwald (johannes.anderwald@reactos.org)
*/ */
@ -72,13 +72,22 @@ USBHUB_PdoStartDevice(
IN PDEVICE_OBJECT DeviceObject, IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp) IN PIRP Irp)
{ {
PHUB_DEVICE_EXTENSION DeviceExtension; PHUB_CHILDDEVICE_EXTENSION ChildDeviceExtension;
NTSTATUS Status = STATUS_UNSUCCESSFUL; //NTSTATUS Status;
DPRINT1("USBHUB_PdoStartDevice %x\n", DeviceObject); DPRINT1("USBHUB_PdoStartDevice %x\n", DeviceObject);
DeviceExtension = (PHUB_DEVICE_EXTENSION)DeviceObject->DeviceExtension; ChildDeviceExtension = (PHUB_CHILDDEVICE_EXTENSION)DeviceObject->DeviceExtension;
//
// This should be a PDO
//
ASSERT(ChildDeviceExtension->Common.IsFDO == FALSE);
//
// FIXME: Fow now assume success
//
UNIMPLEMENTED UNIMPLEMENTED
return Status; return STATUS_SUCCESS;
} }
NTSTATUS NTSTATUS
@ -88,9 +97,9 @@ USBHUB_PdoQueryId(
OUT ULONG_PTR* Information) OUT ULONG_PTR* Information)
{ {
PHUB_CHILDDEVICE_EXTENSION ChildDeviceExtension; PHUB_CHILDDEVICE_EXTENSION ChildDeviceExtension;
ULONG IdType; ULONG IdType, StringLength = 0;
PWCHAR SourceString = NULL; PWCHAR SourceString = NULL, ReturnString = NULL;
NTSTATUS Status = STATUS_SUCCESS; NTSTATUS Status = STATUS_NOT_SUPPORTED;
IdType = IoGetCurrentIrpStackLocation(Irp)->Parameters.QueryId.IdType; IdType = IoGetCurrentIrpStackLocation(Irp)->Parameters.QueryId.IdType;
ChildDeviceExtension = (PHUB_CHILDDEVICE_EXTENSION)DeviceObject->DeviceExtension; ChildDeviceExtension = (PHUB_CHILDDEVICE_EXTENSION)DeviceObject->DeviceExtension;
@ -101,26 +110,48 @@ USBHUB_PdoQueryId(
{ {
DPRINT1("IRP_MJ_PNP / IRP_MN_QUERY_ID / BusQueryDeviceID\n"); DPRINT1("IRP_MJ_PNP / IRP_MN_QUERY_ID / BusQueryDeviceID\n");
SourceString = ChildDeviceExtension->DeviceId; SourceString = ChildDeviceExtension->DeviceId;
Status = STATUS_SUCCESS;
break; break;
} }
case BusQueryHardwareIDs: case BusQueryHardwareIDs:
{ {
ULONG Index = 0, LastIndex;
PWCHAR Ptr;
DPRINT1("IRP_MJ_PNP / IRP_MN_QUERY_ID / BusQueryHardwareIDs\n"); DPRINT1("IRP_MJ_PNP / IRP_MN_QUERY_ID / BusQueryHardwareIDs\n");
SourceString = ChildDeviceExtension->HardwareIds;
Status = STATUS_NOT_SUPPORTED; StringLength = wcslen(ChildDeviceExtension->DeviceId);
StringLength += wcslen(L"&Rev_XXXX") + 1;
StringLength += wcslen(ChildDeviceExtension->DeviceId) + 1;
StringLength = StringLength * sizeof(WCHAR);
ReturnString = ExAllocatePool(PagedPool, StringLength);
Ptr = ReturnString;
LastIndex = Index;
Index += swprintf(&Ptr[Index],
L"%s&Rev_%04lx", ChildDeviceExtension->DeviceId,
ChildDeviceExtension->DeviceDesc.bcdDevice) + 1;
Ptr[Index] = UNICODE_NULL;
DPRINT1("%S\n", &Ptr[LastIndex]);
LastIndex = Index;
Index += swprintf(&Ptr[Index], L"%s", ChildDeviceExtension->DeviceId) + 1;
Ptr[Index] = UNICODE_NULL;
DPRINT1("%S\n", &Ptr[LastIndex]);
Status = STATUS_SUCCESS;
break; break;
} }
case BusQueryCompatibleIDs: case BusQueryCompatibleIDs:
{ {
DPRINT1("IRP_MJ_PNP / IRP_MN_QUERY_ID / BusQueryCompatibleIDs\n"); DPRINT1("IRP_MJ_PNP / IRP_MN_QUERY_ID / BusQueryCompatibleIDs\n");
SourceString = ChildDeviceExtension->CompatibleIds; //SourceString = ChildDeviceExtension->CompatibleIds;
Status = STATUS_NOT_SUPPORTED; //return STATUS_NOT_SUPPORTED;
break; break;
} }
case BusQueryInstanceID: case BusQueryInstanceID:
{ {
DPRINT1("IRP_MJ_PNP / IRP_MN_QUERY_ID / BusQueryInstanceID\n"); DPRINT1("IRP_MJ_PNP / IRP_MN_QUERY_ID / BusQueryInstanceID\n");
SourceString = ChildDeviceExtension->InstanceId; SourceString = ChildDeviceExtension->InstanceId;
Status = STATUS_SUCCESS;
break; break;
} }
default: default:
@ -128,7 +159,17 @@ USBHUB_PdoQueryId(
return STATUS_NOT_SUPPORTED; return STATUS_NOT_SUPPORTED;
} }
*Information = (ULONG_PTR)SourceString; if (SourceString)
{
StringLength = (wcslen(SourceString) + 1) * sizeof(WCHAR);
DPRINT1("StringLen %d\n", StringLength);
ReturnString = ExAllocatePool(PagedPool, StringLength);
RtlCopyMemory(ReturnString, SourceString, StringLength);
DPRINT1("%S\n", ReturnString);
}
*Information = (ULONG_PTR)ReturnString;
return Status; return Status;
} }
@ -140,30 +181,47 @@ USBHUB_PdoQueryDeviceText(
{ {
PHUB_CHILDDEVICE_EXTENSION ChildDeviceExtension; PHUB_CHILDDEVICE_EXTENSION ChildDeviceExtension;
DEVICE_TEXT_TYPE DeviceTextType; DEVICE_TEXT_TYPE DeviceTextType;
PWCHAR SourceString = NULL, ReturnString = NULL;
NTSTATUS Status = STATUS_SUCCESS;
LCID LocaleId; LCID LocaleId;
ULONG StrLen;
DeviceTextType = IoGetCurrentIrpStackLocation(Irp)->Parameters.QueryDeviceText.DeviceTextType; DeviceTextType = IoGetCurrentIrpStackLocation(Irp)->Parameters.QueryDeviceText.DeviceTextType;
LocaleId = IoGetCurrentIrpStackLocation(Irp)->Parameters.QueryDeviceText.LocaleId; LocaleId = IoGetCurrentIrpStackLocation(Irp)->Parameters.QueryDeviceText.LocaleId;
ChildDeviceExtension = (PHUB_CHILDDEVICE_EXTENSION)DeviceObject->DeviceExtension; ChildDeviceExtension = (PHUB_CHILDDEVICE_EXTENSION)DeviceObject->DeviceExtension;
//
// FIXME: LocaleId
//
switch (DeviceTextType) switch (DeviceTextType)
{ {
case DeviceTextDescription: case DeviceTextDescription:
case DeviceTextLocationInformation: case DeviceTextLocationInformation:
{ {
if (DeviceTextType == DeviceTextDescription) DPRINT1("IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_TEXT / DeviceTextDescription\n");
{ SourceString = ChildDeviceExtension->TextDescription;
*Information = (ULONG_PTR)ChildDeviceExtension->TextDescription; DPRINT1("%S\n", SourceString);
DPRINT1("IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_TEXT / DeviceTextDescription\n"); break;
}
else
DPRINT1("IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_TEXT / DeviceTextLocationInformation\n");
return STATUS_SUCCESS;
} }
default: default:
{
DPRINT1("IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_TEXT / unknown device text type 0x%lx\n", DeviceTextType); DPRINT1("IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_TEXT / unknown device text type 0x%lx\n", DeviceTextType);
return STATUS_NOT_SUPPORTED; Status = STATUS_NOT_SUPPORTED;
break;
}
} }
if (SourceString)
{
StrLen = (wcslen(SourceString) + 1) * sizeof(WCHAR);
ReturnString = ExAllocatePool(PagedPool, StrLen);
RtlCopyMemory(ReturnString, SourceString, StrLen);
DPRINT1("%S\n", ReturnString);
*Information = (ULONG_PTR)ReturnString;
}
return Status;
} }
NTSTATUS NTSTATUS
@ -196,13 +254,13 @@ USBHUB_PdoHandlePnp(
DeviceCapabilities = (PDEVICE_CAPABILITIES)Stack->Parameters.DeviceCapabilities.Capabilities; DeviceCapabilities = (PDEVICE_CAPABILITIES)Stack->Parameters.DeviceCapabilities.Capabilities;
// FIXME: capabilities can change with connected device // FIXME: capabilities can change with connected device
DeviceCapabilities->LockSupported = TRUE; DeviceCapabilities->LockSupported = TRUE;
DeviceCapabilities->EjectSupported = FALSE; DeviceCapabilities->EjectSupported = TRUE;
DeviceCapabilities->Removable = FALSE; DeviceCapabilities->Removable = TRUE;
DeviceCapabilities->DockDevice = FALSE; DeviceCapabilities->DockDevice = FALSE;
DeviceCapabilities->UniqueID = FALSE; DeviceCapabilities->UniqueID = TRUE;
DeviceCapabilities->SilentInstall = TRUE; DeviceCapabilities->SilentInstall = TRUE;
DeviceCapabilities->RawDeviceOK = FALSE; DeviceCapabilities->RawDeviceOK = FALSE;
DeviceCapabilities->SurpriseRemovalOK = FALSE; DeviceCapabilities->SurpriseRemovalOK = TRUE;
DeviceCapabilities->HardwareDisabled = FALSE; DeviceCapabilities->HardwareDisabled = FALSE;
//DeviceCapabilities->NoDisplayInUI = FALSE; //DeviceCapabilities->NoDisplayInUI = FALSE;
DeviceCapabilities->DeviceState[0] = PowerDeviceD0; DeviceCapabilities->DeviceState[0] = PowerDeviceD0;
@ -237,7 +295,6 @@ USBHUB_PdoHandlePnp(
case IRP_MN_QUERY_RESOURCE_REQUIREMENTS: case IRP_MN_QUERY_RESOURCE_REQUIREMENTS:
{ {
PIO_RESOURCE_REQUIREMENTS_LIST ResourceList; PIO_RESOURCE_REQUIREMENTS_LIST ResourceList;
DPRINT1("IRP_MJ_PNP / IRP_MN_QUERY_RESOURCE_REQUIREMENTS\n"); DPRINT1("IRP_MJ_PNP / IRP_MN_QUERY_RESOURCE_REQUIREMENTS\n");
ResourceList = ExAllocatePool(PagedPool, sizeof(IO_RESOURCE_REQUIREMENTS_LIST)); ResourceList = ExAllocatePool(PagedPool, sizeof(IO_RESOURCE_REQUIREMENTS_LIST));
if (!ResourceList) if (!ResourceList)
@ -268,9 +325,30 @@ USBHUB_PdoHandlePnp(
Status = USBHUB_PdoQueryId(DeviceObject, Irp, &Information); Status = USBHUB_PdoQueryId(DeviceObject, Irp, &Information);
break; break;
} }
case IRP_MN_QUERY_BUS_INFORMATION:
{
PPNP_BUS_INFORMATION BusInfo;
BusInfo = (PPNP_BUS_INFORMATION)ExAllocatePool(PagedPool, sizeof(PNP_BUS_INFORMATION));
RtlCopyMemory(&BusInfo->BusTypeGuid,
&GUID_BUS_TYPE_USB,
sizeof(BusInfo->BusTypeGuid));
BusInfo->LegacyBusType = PNPBus;
// FIXME
BusInfo->BusNumber = 0;
Information = (ULONG_PTR)BusInfo;
Status = STATUS_SUCCESS;
break;
}
case IRP_MN_REMOVE_DEVICE:
{
//
// FIXME
//
Status = STATUS_SUCCESS;
}
default: default:
{ {
DPRINT1("ERROR PDO IRP_MJ_PNP / unknown minor function 0x%lx\n", MinorFunction); DPRINT1("PDO IRP_MJ_PNP / unknown minor function 0x%lx\n", MinorFunction);
Information = Irp->IoStatus.Information; Information = Irp->IoStatus.Information;
Status = Irp->IoStatus.Status; Status = Irp->IoStatus.Status;
} }

View file

@ -165,7 +165,9 @@ USBHUB_DispatchInternalDeviceControl(
} }
NTSTATUS NTAPI NTSTATUS NTAPI
USBHUB_DispatchPnp(PDEVICE_OBJECT DeviceObject, PIRP Irp) USBHUB_DispatchPnp(
PDEVICE_OBJECT DeviceObject,
PIRP Irp)
{ {
DPRINT1("USBHUB: DispatchPnp\n"); DPRINT1("USBHUB: DispatchPnp\n");
if (((PHUB_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->Common.IsFDO) if (((PHUB_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->Common.IsFDO)
@ -174,6 +176,15 @@ USBHUB_DispatchPnp(PDEVICE_OBJECT DeviceObject, PIRP Irp)
return USBHUB_PdoHandlePnp(DeviceObject, Irp); return USBHUB_PdoHandlePnp(DeviceObject, Irp);
} }
NTSTATUS NTAPI
USBHUB_DispatchPower(
PDEVICE_OBJECT DeviceObject,
PIRP Irp)
{
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_NOT_SUPPORTED;
}
NTSTATUS NTAPI NTSTATUS NTAPI
DriverEntry( DriverEntry(
IN PDRIVER_OBJECT DriverObject, IN PDRIVER_OBJECT DriverObject,
@ -184,15 +195,13 @@ DriverEntry(
DriverObject->DriverExtension->AddDevice = USBHUB_AddDevice; DriverObject->DriverExtension->AddDevice = USBHUB_AddDevice;
DPRINT1("USBHUB: DriverEntry\n"); DPRINT1("USBHUB: DriverEntry\n");
for (i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++)
DriverObject->MajorFunction[i] = USBHUB_IrpStub;
DriverObject->MajorFunction[IRP_MJ_CREATE] = USBHUB_Create; DriverObject->MajorFunction[IRP_MJ_CREATE] = USBHUB_Create;
DriverObject->MajorFunction[IRP_MJ_CLOSE] = USBHUB_Close; DriverObject->MajorFunction[IRP_MJ_CLOSE] = USBHUB_Close;
DriverObject->MajorFunction[IRP_MJ_CLEANUP] = USBHUB_Cleanup; DriverObject->MajorFunction[IRP_MJ_CLEANUP] = USBHUB_Cleanup;
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = USBHUB_DispatchDeviceControl; DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = USBHUB_DispatchDeviceControl;
DriverObject->MajorFunction[IRP_MJ_INTERNAL_DEVICE_CONTROL] = USBHUB_DispatchInternalDeviceControl; DriverObject->MajorFunction[IRP_MJ_INTERNAL_DEVICE_CONTROL] = USBHUB_DispatchInternalDeviceControl;
DriverObject->MajorFunction[IRP_MJ_PNP] = USBHUB_DispatchPnp; DriverObject->MajorFunction[IRP_MJ_PNP] = USBHUB_DispatchPnp;
DriverObject->MajorFunction[IRP_MJ_POWER] =USBHUB_DispatchPower;
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }

View file

@ -1,6 +1,8 @@
#pragma once #pragma once
#include <ntifs.h>
#include <ntddk.h> #include <ntddk.h>
#include <wdmguid.h>
#include <hubbusif.h> #include <hubbusif.h>
#include <usbbusif.h> #include <usbbusif.h>
#include <usbioctl.h> #include <usbioctl.h>
@ -59,6 +61,8 @@ typedef struct _HUB_CHILDDEVICE_EXTENSION
PWCHAR HardwareIds; PWCHAR HardwareIds;
PWCHAR CompatibleIds; PWCHAR CompatibleIds;
PWCHAR TextDescription; PWCHAR TextDescription;
USB_DEVICE_DESCRIPTOR DeviceDesc;
USB_CONFIGURATION_DESCRIPTOR ConfigDesc;
UNICODE_STRING SymbolicLinkName; UNICODE_STRING SymbolicLinkName;
} HUB_CHILDDEVICE_EXTENSION, *PHUB_CHILDDEVICE_EXTENSION; } HUB_CHILDDEVICE_EXTENSION, *PHUB_CHILDDEVICE_EXTENSION;