*/
#define INITGUID
-#define NDEBUG
#include "usbehci.h"
-#include <wdmguid.h>
+#include <hubbusif.h>
+#include <usbbusif.h>
#include "usbiffn.h"
+#include <wdmguid.h>
#include <stdio.h>
#include <debug.h>
6: Self-powered,
5: Remote wakeup,
4..0: reserved */
- 0x00, /* MaxPower; */
+ 0x00 /* MaxPower; */
+};
+const UCHAR ROOTHUB2_INTERFACE_DESCRIPTOR [] =
+{
/* one interface */
0x09, /* bLength: Interface; */
0x04, /* bDescriptorType; Interface */
0x09, /* bInterfaceClass; HUB_CLASSCODE */
0x01, /* bInterfaceSubClass; */
0x00, /* bInterfaceProtocol: */
- 0x00, /* iInterface; */
+ 0x00 /* iInterface; */
+};
+const UCHAR ROOTHUB2_ENDPOINT_DESCRIPTOR [] =
+{
/* one endpoint (status change endpoint) */
0x07, /* bLength; */
0x05, /* bDescriptorType; Endpoint */
UrbWorkerThread(PVOID Context)
{
PPDO_DEVICE_EXTENSION PdoDeviceExtension = (PPDO_DEVICE_EXTENSION)Context;
+ NTSTATUS Status;
+ LARGE_INTEGER DueTime;
+ PVOID PollEvents[] = { (PVOID) &PdoDeviceExtension->QueueDrainedEvent, (PVOID) &PdoDeviceExtension->Timer };
- while (PdoDeviceExtension->HaltUrbHandling == FALSE)
- {
- CompletePendingURBRequest(PdoDeviceExtension);
- KeStallExecutionProcessor(10);
- }
- DPRINT1("Thread terminated\n");
-}
+ DueTime.QuadPart = 0;
+ KeInitializeTimerEx(&PdoDeviceExtension->Timer, SynchronizationTimer);
+ KeSetTimerEx(&PdoDeviceExtension->Timer, DueTime, 100, NULL);
-/* FIXME: Do something better */
-PVOID InternalCreateUsbDevice(UCHAR DeviceNumber, ULONG Port, PUSB_DEVICE Parent, BOOLEAN Hub)
-{
- PUSB_DEVICE UsbDevicePointer = NULL;
- UsbDevicePointer = ExAllocatePool(NonPagedPool, sizeof(USB_DEVICE));
- if (!UsbDevicePointer)
+ while (TRUE)
{
- DPRINT1("Out of memory\n");
- return NULL;
- }
+ Status = KeWaitForMultipleObjects(2, PollEvents, WaitAll, Executive, KernelMode, FALSE, NULL, NULL);
- if ((Hub) && (!Parent))
- {
- DPRINT1("This is the root hub\n");
+ if (!PdoDeviceExtension->HaltQueue)
+ KeResetEvent(&PdoDeviceExtension->QueueDrainedEvent);
+ CompletePendingURBRequest(PdoDeviceExtension);
}
- UsbDevicePointer->Address = DeviceNumber;
- UsbDevicePointer->Port = Port;
- UsbDevicePointer->ParentDevice = Parent;
-
- UsbDevicePointer->IsHub = Hub;
-
- return UsbDevicePointer;
+ DPRINT1("Thread terminated\n");
}
NTSTATUS NTAPI
Urb = (PURB) Stack->Parameters.Others.Argument1;
DPRINT("Header Length %d\n", Urb->UrbHeader.Length);
DPRINT("Header Function %d\n", Urb->UrbHeader.Function);
-
/* Queue all request for now, kernel thread will complete them */
QueueURBRequest(PdoDeviceExtension, Irp);
Information = 0;
case IOCTL_INTERNAL_USB_ENABLE_PORT:
{
DPRINT1("IOCTL_INTERNAL_USB_ENABLE_PORT\n");
+ Information = 0;
+ Status = STATUS_SUCCESS;
break;
}
case IOCTL_INTERNAL_USB_GET_BUS_INFO:
}
case IOCTL_INTERNAL_USB_GET_DEVICE_HANDLE:
{
- DPRINT1("IOCTL_INTERNAL_USB_GET_DEVICE_HANDLE\n");
+ DPRINT1("IOCTL_INTERNAL_USB_GET_DEVICE_HANDLE %x\n", IOCTL_INTERNAL_USB_GET_DEVICE_HANDLE);
+ if (Stack->Parameters.Others.Argument1)
+ {
+ /* Return the root hubs devicehandle */
+ DPRINT1("Returning RootHub Handle %x\n", PdoDeviceExtension->UsbDevices[0]);
+ *(PVOID *)Stack->Parameters.Others.Argument1 = (PVOID)PdoDeviceExtension->UsbDevices[0];
+ Status = STATUS_SUCCESS;
+ }
+ else
+ Status = STATUS_INVALID_DEVICE_REQUEST;
+
break;
+
}
case IOCTL_INTERNAL_USB_GET_HUB_COUNT:
{
- DPRINT1("IOCTL_INTERNAL_USB_GET_HUB_COUNT\n");
-
+ DPRINT1("IOCTL_INTERNAL_USB_GET_HUB_COUNT %x\n", IOCTL_INTERNAL_USB_GET_HUB_COUNT);
+ ASSERT(Stack->Parameters.Others.Argument1 != NULL);
if (Stack->Parameters.Others.Argument1)
{
/* FIXME: Determine the number of hubs between the usb device and root hub */
- /* For now return 0 */
- *(PVOID *)Stack->Parameters.Others.Argument1 = 0;
+ DPRINT1("RootHubCount %x\n", *(PULONG)Stack->Parameters.Others.Argument1);
+ *(PULONG)Stack->Parameters.Others.Argument1 = 0;
}
+ Status = STATUS_SUCCESS;
break;
}
case IOCTL_INTERNAL_USB_GET_HUB_NAME:
if (Stack->Parameters.Others.Argument1)
*(PVOID *)Stack->Parameters.Others.Argument1 = FdoDeviceExtension->Pdo;
if (Stack->Parameters.Others.Argument2)
- *(PVOID *)Stack->Parameters.Others.Argument2 = IoGetAttachedDevice(FdoDeviceExtension->DeviceObject);
+ *(PVOID *)Stack->Parameters.Others.Argument2 = IoGetAttachedDeviceReference(FdoDeviceExtension->DeviceObject);
- Irp->IoStatus.Information = 0;
- Irp->IoStatus.Status = STATUS_SUCCESS;
- return STATUS_SUCCESS;
+ Information = 0;
+ Status = STATUS_SUCCESS;
break;
}
case IOCTL_INTERNAL_USB_SUBMIT_IDLE_NOTIFICATION:
{
+ PUSB_IDLE_CALLBACK_INFO CallBackInfo;
DPRINT1("IOCTL_INTERNAL_USB_SUBMIT_IDLE_NOTIFICATION\n");
+ /* FIXME: Set Callback for safe power down */
+ CallBackInfo = Stack->Parameters.DeviceIoControl.Type3InputBuffer;
+ DPRINT1("IdleCallback %x\n", CallBackInfo->IdleCallback);
+ DPRINT1("IdleContext %x\n", CallBackInfo->IdleContext);
+
+ PdoDeviceExtension->IdleCallback = CallBackInfo->IdleCallback;
+ PdoDeviceExtension->IdleContext = CallBackInfo->IdleContext;
+
+ Information = 0;
+ Status = STATUS_SUCCESS;
break;
}
default:
SourceString.Length = SourceString.MaximumLength = Index * sizeof(WCHAR);
SourceString.Buffer = Buffer;
break;
+
}
case BusQueryCompatibleIDs:
{
}
}
- /* Lifted from hpoussin */
Status = DuplicateUnicodeString(RTL_DUPLICATE_UNICODE_STRING_NULL_TERMINATE,
&SourceString,
&String);
PPDO_DEVICE_EXTENSION PdoDeviceExtension;
PFDO_DEVICE_EXTENSION FdoDeviceExtension;
UNICODE_STRING InterfaceSymLinkName;
+ LONG i;
PdoDeviceExtension = (PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
FdoDeviceExtension = (PFDO_DEVICE_EXTENSION)PdoDeviceExtension->ControllerFdo->DeviceExtension;
/* Create the root hub */
RootHubDevice = InternalCreateUsbDevice(1, 0, NULL, TRUE);
+ for (i = 0; i < 8; i++)
+ {
+ PdoDeviceExtension->Ports[i].PortStatus = USB_PORT_STATUS_ENABLE;
+ PdoDeviceExtension->Ports[i].PortChange = 0;
+ }
+
RtlCopyMemory(&RootHubDevice->DeviceDescriptor,
ROOTHUB2_DEVICE_DESCRIPTOR,
sizeof(ROOTHUB2_DEVICE_DESCRIPTOR));
RootHubDevice->DeviceDescriptor.idVendor = FdoDeviceExtension->VendorId;
RootHubDevice->DeviceDescriptor.idProduct = FdoDeviceExtension->DeviceId;
- RtlCopyMemory(&RootHubDevice->ConfigurationDescriptor,
+ /* FIXME: Do something better below */
+
+ RootHubDevice->Configs = ExAllocatePoolWithTag(NonPagedPool,
+ sizeof(PVOID) * RootHubDevice->DeviceDescriptor.bNumConfigurations,
+ USB_POOL_TAG);
+
+ RootHubDevice->Configs[0] = ExAllocatePoolWithTag(NonPagedPool,
+ sizeof(USB_CONFIGURATION) + sizeof(PVOID) * ROOTHUB2_CONFIGURATION_DESCRIPTOR[4],
+ USB_POOL_TAG);
+
+ RootHubDevice->Configs[0]->Interfaces[0] = ExAllocatePoolWithTag(NonPagedPool,
+ sizeof(USB_INTERFACE) + sizeof(PVOID) * ROOTHUB2_INTERFACE_DESCRIPTOR[4],
+ USB_POOL_TAG);
+
+ RootHubDevice->Configs[0]->Interfaces[0]->EndPoints[0] = ExAllocatePoolWithTag(NonPagedPool,
+ sizeof(USB_ENDPOINT),
+ USB_POOL_TAG);
+
+ RootHubDevice->ActiveConfig = RootHubDevice->Configs[0];
+ RootHubDevice->ActiveInterface = RootHubDevice->ActiveConfig->Interfaces[0];
+
+ RtlCopyMemory(&RootHubDevice->ActiveConfig->ConfigurationDescriptor,
ROOTHUB2_CONFIGURATION_DESCRIPTOR,
sizeof(ROOTHUB2_CONFIGURATION_DESCRIPTOR));
+ RtlCopyMemory(&RootHubDevice->ActiveConfig->Interfaces[0]->InterfaceDescriptor,
+ ROOTHUB2_INTERFACE_DESCRIPTOR,
+ sizeof(ROOTHUB2_INTERFACE_DESCRIPTOR));
+
+ RtlCopyMemory(&RootHubDevice->ActiveConfig->Interfaces[0]->EndPoints[0]->EndPointDescriptor,
+ ROOTHUB2_ENDPOINT_DESCRIPTOR,
+ sizeof(ROOTHUB2_ENDPOINT_DESCRIPTOR));
+ RootHubDevice->DeviceSpeed = UsbHighSpeed;
+ RootHubDevice->DeviceType = Usb20Device;
+
PdoDeviceExtension->UsbDevices[0] = RootHubDevice;
/* Create a thread to handle the URB's */
+
Status = PsCreateSystemThread(&PdoDeviceExtension->ThreadHandle,
THREAD_ALL_ACCESS,
NULL,
if (!NT_SUCCESS(Status))
{
DPRINT1("Failed to register interface\n");
+ ASSERT(FALSE);
}
else
{
Status = IoSetDeviceInterfaceState(&InterfaceSymLinkName, TRUE);
- DPRINT1("Set interface state %x\n", Status);
+ if (!NT_SUCCESS(Status))
+ ASSERT(FALSE);
}
-
Status = STATUS_SUCCESS;
break;
}
break;
}
case BusRelations:
+ {
+ PPDO_DEVICE_EXTENSION PdoDeviceExtension;
+ PdoDeviceExtension = (PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
+
+ DPRINT1("BusRelations!!!!!\n");
+
+ /* The hub driver has created the new device object and reported to pnp, as a result the pnp manager
+ has resent this IRP and type, so leave the next SCE request pending until a new device arrives.
+ Is there a better way to do this */
+ ExAcquireFastMutex(&PdoDeviceExtension->ListLock);
+ PdoDeviceExtension->HaltQueue = TRUE;
+ ExReleaseFastMutex(&PdoDeviceExtension->ListLock);
+ }
case RemovalRelations:
case EjectionRelations:
+ {
+ /* Ignore the request */
+ Information = Irp->IoStatus.Information;
+ Status = Irp->IoStatus.Status;
+ break;
+
+ }
default:
{
DPRINT1("IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_RELATIONS / Unhandled type 0x%lx\n",
{
DPRINT1("Failed to create string from GUID!\n");
}
- DPRINT1("Interface GUID requested %wZ\n", &GuidString);
- DPRINT1("QueryInterface.Size %x\n", Stack->Parameters.QueryInterface.Size);
- DPRINT1("QueryInterface.Version %x\n", Stack->Parameters.QueryInterface.Version);
+ DPRINT("Interface GUID requested %wZ\n", &GuidString);
+ DPRINT("QueryInterface.Size %x\n", Stack->Parameters.QueryInterface.Size);
+ DPRINT("QueryInterface.Version %x\n", Stack->Parameters.QueryInterface.Version);
+
+ /* Assume success */
Status = STATUS_SUCCESS;
Information = 0;
- /* FIXME: Check the actual Guid */
- if (Stack->Parameters.QueryInterface.Size == sizeof(USB_BUS_INTERFACE_USBDI_V2) && (Stack->Parameters.QueryInterface.Version == 2))
- {
- InterfaceDI = (PUSB_BUS_INTERFACE_USBDI_V2) Stack->Parameters.QueryInterface.Interface;
- InterfaceDI->Size = sizeof(USB_BUS_INTERFACE_USBDI_V2);
- InterfaceDI->Version = 2;
- InterfaceDI->BusContext = PdoDeviceExtension->DeviceObject;
- InterfaceDI->InterfaceReference = (PINTERFACE_REFERENCE)InterfaceReference;
- InterfaceDI->InterfaceDereference = (PINTERFACE_DEREFERENCE)InterfaceDereference;
- InterfaceDI->GetUSBDIVersion = GetUSBDIVersion;
- InterfaceDI->QueryBusTime = QueryBusTime;
- InterfaceDI->SubmitIsoOutUrb = SubmitIsoOutUrb;
- InterfaceDI->QueryBusInformation = QueryBusInformation;
- InterfaceDI->IsDeviceHighSpeed = IsDeviceHighSpeed;
- InterfaceDI->EnumLogEntry = EnumLogEntry;
- }
- /* FIXME: Check the actual Guid */
- else if (Stack->Parameters.QueryInterface.Size == sizeof(USB_BUS_INTERFACE_HUB_V5) &&
- (Stack->Parameters.QueryInterface.Version == 5))
+ if (IsEqualGUIDAligned(Stack->Parameters.QueryInterface.InterfaceType, &USB_BUS_INTERFACE_HUB_GUID))
{
InterfaceHub = (PUSB_BUS_INTERFACE_HUB_V5)Stack->Parameters.QueryInterface.Interface;
- InterfaceHub->Version = 5;
- InterfaceHub->Size = sizeof(USB_BUS_INTERFACE_HUB_V5);
- InterfaceHub->BusContext = PdoDeviceExtension->DeviceObject;
- InterfaceHub->InterfaceReference = (PINTERFACE_REFERENCE)InterfaceReference;
- InterfaceHub->InterfaceDereference = (PINTERFACE_DEREFERENCE)InterfaceDereference;
- InterfaceHub->CreateUsbDevice = CreateUsbDevice;
- InterfaceHub->InitializeUsbDevice = InitializeUsbDevice;
- InterfaceHub->GetUsbDescriptors = GetUsbDescriptors;
- InterfaceHub->RemoveUsbDevice = RemoveUsbDevice;
- InterfaceHub->RestoreUsbDevice = RestoreUsbDevice;
- InterfaceHub->GetPortHackFlags = GetPortHackFlags;
- InterfaceHub->QueryDeviceInformation = QueryDeviceInformation;
- InterfaceHub->GetControllerInformation = GetControllerInformation;
- InterfaceHub->ControllerSelectiveSuspend = ControllerSelectiveSuspend;
- InterfaceHub->GetExtendedHubInformation = GetExtendedHubInformation;
- InterfaceHub->GetRootHubSymbolicName = GetRootHubSymbolicName;
- InterfaceHub->GetDeviceBusContext = GetDeviceBusContext;
- InterfaceHub->Initialize20Hub = Initialize20Hub;
- InterfaceHub->RootHubInitNotification = RootHubInitNotification;
- InterfaceHub->FlushTransfers = FlushTransfers;
- InterfaceHub->SetDeviceHandleData = SetDeviceHandleData;
+ InterfaceHub->Version = Stack->Parameters.QueryInterface.Version;
+ if (Stack->Parameters.QueryInterface.Version >= 0)
+ {
+ InterfaceHub->Size = Stack->Parameters.QueryInterface.Size;
+ InterfaceHub->BusContext = PdoDeviceExtension->DeviceObject;
+ InterfaceHub->InterfaceReference = (PINTERFACE_REFERENCE)InterfaceReference;
+ InterfaceHub->InterfaceDereference = (PINTERFACE_DEREFERENCE)InterfaceDereference;
+ }
+ if (Stack->Parameters.QueryInterface.Version >= 1)
+ {
+ InterfaceHub->CreateUsbDevice = CreateUsbDevice;
+ InterfaceHub->InitializeUsbDevice = InitializeUsbDevice;
+ InterfaceHub->GetUsbDescriptors = GetUsbDescriptors;
+ InterfaceHub->RemoveUsbDevice = RemoveUsbDevice;
+ InterfaceHub->RestoreUsbDevice = RestoreUsbDevice;
+ InterfaceHub->GetPortHackFlags = GetPortHackFlags;
+ InterfaceHub->QueryDeviceInformation = QueryDeviceInformation;
+ }
+ if (Stack->Parameters.QueryInterface.Version >= 2)
+ {
+ InterfaceHub->GetControllerInformation = GetControllerInformation;
+ InterfaceHub->ControllerSelectiveSuspend = ControllerSelectiveSuspend;
+ InterfaceHub->GetExtendedHubInformation = GetExtendedHubInformation;
+ InterfaceHub->GetRootHubSymbolicName = GetRootHubSymbolicName;
+ InterfaceHub->GetDeviceBusContext = GetDeviceBusContext;
+ InterfaceHub->Initialize20Hub = Initialize20Hub;
+
+ }
+ if (Stack->Parameters.QueryInterface.Version >= 3)
+ {
+ InterfaceHub->RootHubInitNotification = RootHubInitNotification;
+ }
+ if (Stack->Parameters.QueryInterface.Version >= 4)
+ {
+ InterfaceHub->FlushTransfers = FlushTransfers;
+ }
+ if (Stack->Parameters.QueryInterface.Version >= 5)
+ {
+ InterfaceHub->SetDeviceHandleData = SetDeviceHandleData;
+ }
+ if (Stack->Parameters.QueryInterface.Version >= 6)
+ {
+ DPRINT1("USB_BUS_INTERFACE_HUB_GUID version not supported!\n");
+ }
+ break;
}
- else
+
+ if (IsEqualGUIDAligned(Stack->Parameters.QueryInterface.InterfaceType, &USB_BUS_INTERFACE_USBDI_GUID))
{
- DPRINT1("Not Supported\n");
- Status = STATUS_NOT_SUPPORTED;
+ InterfaceDI = (PUSB_BUS_INTERFACE_USBDI_V2) Stack->Parameters.QueryInterface.Interface;
+ InterfaceDI->Version = Stack->Parameters.QueryInterface.Version;
+ if (Stack->Parameters.QueryInterface.Version >= 0)
+ {
+ //InterfaceDI->Size = sizeof(USB_BUS_INTERFACE_USBDI_V2);
+ InterfaceDI->Size = Stack->Parameters.QueryInterface.Size;
+ InterfaceDI->BusContext = PdoDeviceExtension->DeviceObject;
+ InterfaceDI->InterfaceReference = (PINTERFACE_REFERENCE)InterfaceReference;
+ InterfaceDI->InterfaceDereference = (PINTERFACE_DEREFERENCE)InterfaceDereference;
+ InterfaceDI->GetUSBDIVersion = GetUSBDIVersion;
+ InterfaceDI->QueryBusTime = QueryBusTime;
+ InterfaceDI->SubmitIsoOutUrb = SubmitIsoOutUrb;
+ InterfaceDI->QueryBusInformation = QueryBusInformation;
+ }
+ if (Stack->Parameters.QueryInterface.Version >= 1)
+ {
+ InterfaceDI->IsDeviceHighSpeed = IsDeviceHighSpeed;
+ }
+ if (Stack->Parameters.QueryInterface.Version >= 2)
+ {
+ InterfaceDI->EnumLogEntry = EnumLogEntry;
+ }
+
+ if (Stack->Parameters.QueryInterface.Version >= 3)
+ {
+ DPRINT1("SB_BUS_INTERFACE_USBDI_GUID version not supported!\n");
+ }
+ break;
}
+
+ DPRINT1("GUID Not Supported\n");
+ Status = Irp->IoStatus.Status;
+ Information = Irp->IoStatus.Information;
+
break;
}
case IRP_MN_QUERY_BUS_INFORMATION:
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return Status;
}
-