Move common code of USB miniport drivers into drivers/usb/miniport/common library
Added: trunk/reactos/drivers/usb/miniport/common/
Added: trunk/reactos/drivers/usb/miniport/common/cleanup.c
Added: trunk/reactos/drivers/usb/miniport/common/close.c
Added: trunk/reactos/drivers/usb/miniport/common/common.xml
Added: trunk/reactos/drivers/usb/miniport/common/create.c
Added: trunk/reactos/drivers/usb/miniport/common/fdo.c
Added: trunk/reactos/drivers/usb/miniport/common/misc.c
Added: trunk/reactos/drivers/usb/miniport/common/pdo.c
Added: trunk/reactos/drivers/usb/miniport/common/uhci.c
Added: trunk/reactos/drivers/usb/miniport/common/uhci.h
Modified: trunk/reactos/drivers/usb/miniport/directory.xml
Deleted: trunk/reactos/drivers/usb/miniport/usbuhci/cleanup.c
Deleted: trunk/reactos/drivers/usb/miniport/usbuhci/close.c
Deleted: trunk/reactos/drivers/usb/miniport/usbuhci/create.c
Deleted: trunk/reactos/drivers/usb/miniport/usbuhci/fdo.c
Deleted: trunk/reactos/drivers/usb/miniport/usbuhci/misc.c
Deleted: trunk/reactos/drivers/usb/miniport/usbuhci/pdo.c
Modified: trunk/reactos/drivers/usb/miniport/usbuhci/uhci.c
Deleted: trunk/reactos/drivers/usb/miniport/usbuhci/uhci.h
Modified: trunk/reactos/drivers/usb/miniport/usbuhci/usbuhci.xml

Copied: trunk/reactos/drivers/usb/miniport/common/cleanup.c (from rev 17754, trunk/reactos/drivers/usb/miniport/usbuhci/cleanup.c)

Copied: trunk/reactos/drivers/usb/miniport/common/close.c (from rev 17754, trunk/reactos/drivers/usb/miniport/usbuhci/close.c)

Added: trunk/reactos/drivers/usb/miniport/common/common.xml
--- trunk/reactos/drivers/usb/miniport/common/common.xml	2005-09-10 14:46:06 UTC (rev 17775)
+++ trunk/reactos/drivers/usb/miniport/common/common.xml	2005-09-10 15:17:07 UTC (rev 17776)
@@ -0,0 +1,13 @@
+<module name="usbminiportcommon" type="objectlibrary">
+	<define name="__USE_W32API" />
+	<define name="DEBUG_MODE" />
+	<include>../linux</include>
+	<include base="usbport"></include>
+	<file>cleanup.c</file>
+	<file>close.c</file>
+	<file>create.c</file>
+	<file>fdo.c</file>
+	<file>misc.c</file>
+	<file>pdo.c</file>
+	<file>uhci.c</file>
+</module>

Copied: trunk/reactos/drivers/usb/miniport/common/create.c (from rev 17754, trunk/reactos/drivers/usb/miniport/usbuhci/create.c)

Copied: trunk/reactos/drivers/usb/miniport/common/fdo.c (from rev 17754, trunk/reactos/drivers/usb/miniport/usbuhci/fdo.c)
--- trunk/reactos/drivers/usb/miniport/usbuhci/fdo.c	2005-09-08 21:54:42 UTC (rev 17754)
+++ trunk/reactos/drivers/usb/miniport/common/fdo.c	2005-09-10 15:17:07 UTC (rev 17776)
@@ -0,0 +1,350 @@
+/*
+ * COPYRIGHT:       See COPYING in the top level directory
+ * PROJECT:         ReactOS UHCI controller driver (Cromwell type)
+ * FILE:            drivers/usb/cromwell/uhci/fdo.c
+ * PURPOSE:         IRP_MJ_PNP/IRP_MJ_DEVICE_CONTROL operations for FDOs
+ *
+ * PROGRAMMERS:     HervÚ Poussineau (hpoussin@reactos.com),
+ *                  James Tabor (jimtabor@adsl-64-217-116-74.dsl.hstntx.swbell.net)
+ */
+
+#define NDEBUG
+#include "uhci.h"
+
+#define IO_METHOD_FROM_CTL_CODE(ctlCode) (ctlCode&0x00000003)
+
+static VOID
+UhciGetUserBuffers(
+	IN PIRP Irp,
+	IN ULONG IoControlCode,
+	OUT PVOID* BufferIn,
+	OUT PVOID* BufferOut)
+{
+	ASSERT(Irp);
+	ASSERT(BufferIn);
+	ASSERT(BufferOut);
+
+	switch (IO_METHOD_FROM_CTL_CODE(IoControlCode))
+	{
+		case METHOD_BUFFERED:
+			*BufferIn = *BufferOut = Irp->AssociatedIrp.SystemBuffer;
+			break;
+		case METHOD_IN_DIRECT:
+		case METHOD_OUT_DIRECT:
+			*BufferIn = Irp->AssociatedIrp.SystemBuffer;
+			*BufferOut = MmGetSystemAddressForMdl(Irp->MdlAddress);
+			break;
+		case METHOD_NEITHER:
+			*BufferIn = IoGetCurrentIrpStackLocation(Irp)->Parameters.DeviceIoControl.Type3InputBuffer;
+			*BufferOut = Irp->UserBuffer;
+			break;
+		default:
+			/* Should never happen */
+			*BufferIn = NULL;
+			*BufferOut = NULL;
+			break;
+	}
+}
+
+NTSTATUS STDCALL
+UhciFdoStartDevice(
+	IN PDEVICE_OBJECT DeviceObject,
+	IN PIRP	Irp)
+{
+	PIO_STACK_LOCATION Stack = IoGetCurrentIrpStackLocation(Irp);
+	PDRIVER_OBJECT DriverObject;
+	POHCI_DRIVER_EXTENSION DriverExtension;
+	POHCI_DEVICE_EXTENSION DeviceExtension;
+	PCM_RESOURCE_LIST AllocatedResources;
+
+	/*
+	* Get the initialization data we saved in VideoPortInitialize.
+	*/
+	DriverObject = DeviceObject->DriverObject;
+	DriverExtension = IoGetDriverObjectExtension(DriverObject, DriverObject);
+	DeviceExtension = (POHCI_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
+
+	/*
+	* Store	some resources in the DeviceExtension.
+	*/
+	AllocatedResources = Stack->Parameters.StartDevice.AllocatedResources;
+	if (AllocatedResources != NULL)
+	{
+		CM_FULL_RESOURCE_DESCRIPTOR    *FullList;
+		CM_PARTIAL_RESOURCE_DESCRIPTOR *Descriptor;
+		ULONG ResourceCount;
+		ULONG ResourceListSize;
+
+		/* Save the resource list */
+		ResourceCount = AllocatedResources->List[0].PartialResourceList.Count;
+
+		ResourceListSize = FIELD_OFFSET(CM_RESOURCE_LIST, List[0].PartialResourceList.
+			PartialDescriptors[ResourceCount]);
+
+		DeviceExtension->AllocatedResources = ExAllocatePool(PagedPool, ResourceListSize);
+		if (DeviceExtension->AllocatedResources == NULL)
+		{
+			return STATUS_INSUFFICIENT_RESOURCES;
+		}
+
+		RtlCopyMemory(DeviceExtension->AllocatedResources,
+			AllocatedResources,
+			ResourceListSize);
+
+		/* Get the interrupt level/vector -	needed by HwFindAdapter	sometimes */
+		for	(FullList = AllocatedResources->List;
+		   	FullList < AllocatedResources->List + AllocatedResources->Count;
+		   	FullList++)
+		{
+			/* FIXME: Is this ASSERT ok	for	resources from the PNP manager?	*/
+			/*ASSERT(FullList->InterfaceType == PCIBus &&
+				FullList->BusNumber	== DeviceExtension->SystemIoBusNumber &&
+				1 == FullList->PartialResourceList.Version &&
+				1 == FullList->PartialResourceList.Revision);*/
+			for	(Descriptor	= FullList->PartialResourceList.PartialDescriptors;
+				Descriptor < FullList->PartialResourceList.PartialDescriptors + FullList->PartialResourceList.Count;
+				Descriptor++)
+			{
+				if (Descriptor->Type == CmResourceTypeInterrupt)
+				{
+					DeviceExtension->InterruptLevel  = Descriptor->u.Interrupt.Level;
+					DeviceExtension->InterruptVector = Descriptor->u.Interrupt.Vector;
+				}
+				else if (Descriptor->Type == CmResourceTypePort)
+				{
+					DeviceExtension->BaseAddress    = Descriptor->u.Port.Start;
+					DeviceExtension->BaseAddrLength = Descriptor->u.Port.Length;
+					DeviceExtension->Flags          = Descriptor->Flags;
+
+					((struct hc_driver *)(*pci_ids)->driver_data)->flags &= ~HCD_MEMORY;
+				}
+				else if (Descriptor->Type == CmResourceTypeMemory)
+				{
+					DeviceExtension->BaseAddress    = Descriptor->u.Memory.Start;
+					DeviceExtension->BaseAddrLength = Descriptor->u.Memory.Length;
+					DeviceExtension->Flags          = Descriptor->Flags;
+
+					((struct hc_driver *)(*pci_ids)->driver_data)->flags |= HCD_MEMORY;
+				}
+			}
+		}
+	}
+	
+	/* Print assigned resources */
+	DPRINT("UHCI: Interrupt Vector 0x%lx, %S base 0x%lx, Length 0x%lx\n",
+		DeviceExtension->InterruptVector,
+		((struct hc_driver *)(*pci_ids)->driver_data)->flags & HCD_MEMORY ? L"Memory" : L"I/O",
+		DeviceExtension->BaseAddress,
+		DeviceExtension->BaseAddrLength);
+
+	/* Init wrapper with this object */
+	return InitLinuxWrapper(DeviceObject);
+}
+
+static NTSTATUS
+UhciFdoQueryBusRelations(
+	IN PDEVICE_OBJECT DeviceObject,
+	OUT PDEVICE_RELATIONS* pDeviceRelations)
+{
+	POHCI_DEVICE_EXTENSION DeviceExtension;
+	PDEVICE_RELATIONS DeviceRelations;
+	NTSTATUS Status = STATUS_SUCCESS;
+	
+	DeviceExtension = (POHCI_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
+	
+	/* Handling this IRP is easy, as we only
+	 * have one child: the root hub
+	 */
+	DeviceRelations = (PDEVICE_RELATIONS)ExAllocatePool(
+		PagedPool,
+		sizeof(DEVICE_RELATIONS));
+	if (!DeviceRelations)
+		return STATUS_INSUFFICIENT_RESOURCES;
+	
+	/* Fill returned structure */
+	DeviceRelations->Count = 1;
+	ObReferenceObject(DeviceExtension->RootHubPdo);
+	DeviceRelations->Objects[0] = DeviceExtension->RootHubPdo;
+	
+	*pDeviceRelations = DeviceRelations;
+	return Status;
+}
+
+NTSTATUS STDCALL
+UhciPnpFdo(
+	IN PDEVICE_OBJECT DeviceObject,
+	IN PIRP Irp)
+{
+	PIO_STACK_LOCATION IrpSp;
+	NTSTATUS Status;
+	ULONG MinorFunction;
+	ULONG_PTR Information = 0;
+	
+	IrpSp = IoGetCurrentIrpStackLocation(Irp);
+	MinorFunction = IrpSp->MinorFunction;
+
+	switch (MinorFunction)
+	{
+		case IRP_MN_START_DEVICE:
+		{
+			Status = ForwardIrpAndWait(DeviceObject, Irp);
+			if (NT_SUCCESS(Status) && NT_SUCCESS(Irp->IoStatus.Status))
+				Status = UhciFdoStartDevice(DeviceObject, Irp);
+			break;
+		}
+
+		case IRP_MN_REMOVE_DEVICE:
+		case IRP_MN_QUERY_REMOVE_DEVICE:
+		case IRP_MN_CANCEL_REMOVE_DEVICE:
+		case IRP_MN_SURPRISE_REMOVAL:
+
+		case IRP_MN_STOP_DEVICE:
+		{
+			Status = ForwardIrpAndWait(DeviceObject, Irp);
+			if (NT_SUCCESS(Status) && NT_SUCCESS(Irp->IoStatus.Status))
+				Status = STATUS_SUCCESS;
+			IoDeleteDevice(DeviceObject); // just delete device for now
+			break;
+		}
+		case IRP_MN_QUERY_STOP_DEVICE:
+		case IRP_MN_CANCEL_STOP_DEVICE:
+		{
+			Status = STATUS_SUCCESS;
+			break;
+		}
+		case IRP_MN_QUERY_DEVICE_RELATIONS: /* (optional) 0x7 */
+		{
+			switch (IrpSp->Parameters.QueryDeviceRelations.Type)
+			{
+				case BusRelations:
+				{
+					PDEVICE_RELATIONS DeviceRelations;
+					DPRINT("UHCI: IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_RELATIONS / BusRelations\n");
+					Status = UhciFdoQueryBusRelations(DeviceObject, &DeviceRelations);
+					Information = (ULONG_PTR)DeviceRelations;
+					break;
+				}
+				case RemovalRelations:
+				{
+					DPRINT1("UHCI: IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_RELATIONS / RemovalRelations\n");
+					return ForwardIrpAndForget(DeviceObject, Irp);
+				}
+				default:
+					DPRINT1("UHCI: IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_RELATIONS / Unknown type 0x%lx\n",
+						IrpSp->Parameters.QueryDeviceRelations.Type);
+					return ForwardIrpAndForget(DeviceObject, Irp);
+			}
+			break;
+		}
+
+		default:
+		{
+			DPRINT1("UHCI: unknown minor function 0x%lx\n", MinorFunction);
+			return ForwardIrpAndForget(DeviceObject, Irp);
+		}
+	}
+	Irp->IoStatus.Information = Information;
+	Irp->IoStatus.Status = Status;
+	IoCompleteRequest(Irp, IO_NO_INCREMENT);
+	return Status;
+}
+
+NTSTATUS
+UhciDeviceControlFdo(
+	IN PDEVICE_OBJECT DeviceObject,
+	IN PIRP Irp)
+{
+	PIO_STACK_LOCATION Stack;
+	ULONG IoControlCode;
+	POHCI_DEVICE_EXTENSION DeviceExtension;
+	ULONG LengthIn, LengthOut;
+	ULONG_PTR Information = 0;
+	PVOID BufferIn, BufferOut;
+	NTSTATUS Status;
+
+	DPRINT("UHCI: UsbDeviceControlFdo() called\n");
+
+	Stack = IoGetCurrentIrpStackLocation(Irp);
+	LengthIn = Stack->Parameters.DeviceIoControl.InputBufferLength;
+	LengthOut = Stack->Parameters.DeviceIoControl.OutputBufferLength;
+	DeviceExtension = (POHCI_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
+	IoControlCode = Stack->Parameters.DeviceIoControl.IoControlCode;
+	UhciGetUserBuffers(Irp, IoControlCode, &BufferIn, &BufferOut);
+
+	switch (IoControlCode)
+	{
+		case IOCTL_GET_HCD_DRIVERKEY_NAME:
+		{
+			DPRINT("UHCI: IOCTL_GET_HCD_DRIVERKEY_NAME\n");
+			if (LengthOut < sizeof(USB_HCD_DRIVERKEY_NAME))
+				Status = STATUS_BUFFER_TOO_SMALL;
+			else if (BufferOut == NULL)
+				Status = STATUS_INVALID_PARAMETER;
+			else
+			{
+				PUSB_HCD_DRIVERKEY_NAME StringDescriptor;
+				ULONG StringSize;
+				StringDescriptor = (PUSB_HCD_DRIVERKEY_NAME)BufferOut;
+				Status = IoGetDeviceProperty(
+					((POHCI_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->PhysicalDeviceObject,
+					DevicePropertyDriverKeyName,
+					LengthOut - FIELD_OFFSET(USB_HCD_DRIVERKEY_NAME, DriverKeyName),
+					StringDescriptor->DriverKeyName,
+					&StringSize);
+				if (NT_SUCCESS(Status) || Status == STATUS_BUFFER_TOO_SMALL)
+				{
+					StringDescriptor->ActualLength = StringSize + FIELD_OFFSET(USB_HCD_DRIVERKEY_NAME, DriverKeyName);
+					Information = LengthOut;
+					Status = STATUS_SUCCESS;
+				}
+			}
+			break;
+		}
+		case IOCTL_USB_GET_ROOT_HUB_NAME:
+		{
+			DPRINT("UHCI: IOCTL_USB_GET_ROOT_HUB_NAME\n");
+			if (LengthOut < sizeof(USB_ROOT_HUB_NAME))
+				Status = STATUS_BUFFER_TOO_SMALL;
+			else if (BufferOut == NULL)
+				Status = STATUS_INVALID_PARAMETER;
+			else
+			{
+				PUSB_ROOT_HUB_NAME StringDescriptor;
+				PUNICODE_STRING RootHubInterfaceName;
+				StringDescriptor = (PUSB_ROOT_HUB_NAME)BufferOut;
+				DeviceObject = ((POHCI_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->RootHubPdo;
+				RootHubInterfaceName = &((POHCI_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->HcdInterfaceName;
+
+				StringDescriptor->ActualLength = RootHubInterfaceName->Length + sizeof(WCHAR) + FIELD_OFFSET(USB_ROOT_HUB_NAME, RootHubName);
+				if (StringDescriptor->ActualLength <= LengthOut)
+				{
+					/* Copy root hub name */
+					RtlCopyMemory(
+						StringDescriptor->RootHubName,
+						RootHubInterfaceName->Buffer,
+						RootHubInterfaceName->Length);
+					StringDescriptor->RootHubName[RootHubInterfaceName->Length / sizeof(WCHAR)] = UNICODE_NULL;
+					DPRINT("UHCI: IOCTL_USB_GET_ROOT_HUB_NAME returns '%S'\n", StringDescriptor->RootHubName);
+					Information = StringDescriptor->ActualLength;
+				}
+				else
+					Information = sizeof(USB_ROOT_HUB_NAME);
+				Status = STATUS_SUCCESS;
+			}
+			break;
+		}
+
+		default:
+		{
+			/* Pass Irp to lower driver */
+			DPRINT1("UHCI: Unknown IOCTL code 0x%lx\n", Stack->Parameters.DeviceIoControl.IoControlCode);
+			IoSkipCurrentIrpStackLocation(Irp);
+			return IoCallDriver(DeviceExtension->NextDeviceObject, Irp);
+		}
+	}
+
+	Irp->IoStatus.Information = Information;
+	Irp->IoStatus.Status = Status;
+	IoCompleteRequest(Irp, IO_NO_INCREMENT);
+	return Status;
+}

Copied: trunk/reactos/drivers/usb/miniport/common/misc.c (from rev 17754, trunk/reactos/drivers/usb/miniport/usbuhci/misc.c)
--- trunk/reactos/drivers/usb/miniport/usbuhci/misc.c	2005-09-08 21:54:42 UTC (rev 17754)
+++ trunk/reactos/drivers/usb/miniport/common/misc.c	2005-09-10 15:17:07 UTC (rev 17776)
@@ -0,0 +1,170 @@
+/*
+ * COPYRIGHT:       See COPYING in the top level directory
+ * PROJECT:         ReactOS UHCI controller driver (Cromwell type)
+ * FILE:            drivers/usb/cromwell/uhci/misc.c
+ * PURPOSE:         Misceallenous operations
+ *
+ * PROGRAMMERS:     HervÚ Poussineau (hpoussin@reactos.com),
+ */
+
+#define NDEBUG
+#include "uhci.h"
+#include <stdarg.h>
+
+NTSTATUS STDCALL
+ForwardIrpAndWaitCompletion(
+	IN PDEVICE_OBJECT DeviceObject,
+	IN PIRP Irp,
+	IN PVOID Context)
+{
+	if (Irp->PendingReturned)
+		KeSetEvent((PKEVENT)Context, IO_NO_INCREMENT, FALSE);
+	return STATUS_MORE_PROCESSING_REQUIRED;
+}
+
+NTSTATUS
+ForwardIrpAndWait(
+	IN PDEVICE_OBJECT DeviceObject,
+	IN PIRP Irp)
+{
+	PDEVICE_OBJECT LowerDevice = ((POHCI_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->NextDeviceObject;
+	KEVENT Event;
+	NTSTATUS Status;
+
+	ASSERT(LowerDevice);
+
+	KeInitializeEvent(&Event, NotificationEvent, FALSE);
+	IoCopyCurrentIrpStackLocationToNext(Irp);
+
+	DPRINT("UHCI: Calling lower device %p [%wZ]\n", LowerDevice, &LowerDevice->DriverObject->DriverName);
+	IoSetCompletionRoutine(Irp, ForwardIrpAndWaitCompletion, &Event, TRUE, TRUE, TRUE);
+
+	Status = IoCallDriver(LowerDevice, Irp);
+	if (Status == STATUS_PENDING)
+	{
+		Status = KeWaitForSingleObject(&Event, Suspended, KernelMode, FALSE, NULL);
+		if (NT_SUCCESS(Status))
+			Status = Irp->IoStatus.Status;
+	}
+
+	return Status;
+}
+
+NTSTATUS STDCALL
+ForwardIrpAndForget(
+	IN PDEVICE_OBJECT DeviceObject,
+	IN PIRP Irp)
+{
+	PDEVICE_OBJECT LowerDevice = ((POHCI_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->NextDeviceObject;
+
+	ASSERT(LowerDevice);
+
+	IoSkipCurrentIrpStackLocation(Irp);
+	return IoCallDriver(LowerDevice, Irp);
+}
+
+/* I really want PCSZ strings as last arguments because
+ * PnP ids are ANSI-encoded in PnP device string
+ * identification */
+NTSTATUS
+UhciInitMultiSzString(
+	OUT PUNICODE_STRING Destination,
+	... /* list of PCSZ */)
+{
+	va_list args;
+	PCSZ Source;
+	ANSI_STRING AnsiString;
+	UNICODE_STRING UnicodeString;
+	ULONG DestinationSize = 0;
+	NTSTATUS Status = STATUS_SUCCESS;
+
+	ASSERT(Destination);
+
+	/* Calculate length needed for destination unicode string */
+	va_start(args, Destination);
+	Source = va_arg(args, PCSZ);
+	while (Source != NULL)
+	{
+		DPRINT1("Source = %s\n", Source);
+		RtlInitAnsiString(&AnsiString, Source);
+		DPRINT1("AnsiString = %Z\n", &AnsiString);
+		DPRINT1("NLS_MB_CODE_PAGE_TAG = %lu\n", (ULONG)NLS_MB_CODE_PAGE_TAG);
+		DestinationSize += RtlAnsiStringToUnicodeSize(&AnsiString)
+			+ sizeof(WCHAR) /* final NULL */;
+		DPRINT1("DestinationSize = %lu\n", DestinationSize);
+		Source = va_arg(args, PCSZ);
+	}
+	va_end(args);
+	if (DestinationSize == 0)
+	{
+		RtlInitUnicodeString(Destination, NULL);
+		return STATUS_SUCCESS;
+	}
+
+	/* Initialize destination string */
+	DestinationSize += sizeof(WCHAR); // final NULL
+	Destination->Buffer = (PWSTR)ExAllocatePoolWithTag(PagedPool, DestinationSize, USB_UHCI_TAG);
+	if (!Destination->Buffer)
+		return STATUS_INSUFFICIENT_RESOURCES;
+	Destination->Length = 0;
+	Destination->MaximumLength = (USHORT)DestinationSize;
+
+	/* Copy arguments to destination string */
+	/* Use a temporary unicode string, which buffer is shared with
+	 * destination string, to copy arguments */
+	UnicodeString.Length = Destination->Length;
+	UnicodeString.MaximumLength = Destination->MaximumLength;
+	UnicodeString.Buffer = Destination->Buffer;
+	va_start(args, Destination);
+	Source = va_arg(args, PCSZ);
+	while (Source != NULL)
+	{
+		RtlInitAnsiString(&AnsiString, Source);
+		Status = RtlAnsiStringToUnicodeString(&UnicodeString, &AnsiString, FALSE);
+		if (!NT_SUCCESS(Status))
+		{
+			ExFreePoolWithTag(Destination->Buffer, USB_UHCI_TAG);
+			break;
+		}
+		Destination->Length += UnicodeString.Length + sizeof(WCHAR);
+		UnicodeString.MaximumLength -= UnicodeString.Length + sizeof(WCHAR);
+		UnicodeString.Buffer += UnicodeString.Length / sizeof(WCHAR) + 1;
+		UnicodeString.Length = 0;
+		Source = va_arg(args, PCSZ);
+	}
+	va_end(args);
+	if (NT_SUCCESS(Status))
+	{
+		/* Finish multi-sz string */
+		Destination->Buffer[Destination->Length / sizeof(WCHAR)] = L'\0';
+		Destination->Length += sizeof(WCHAR);
+	}
+	return Status;
+}
+
+NTSTATUS
+UhciDuplicateUnicodeString(
+	OUT PUNICODE_STRING Destination,
+	IN PUNICODE_STRING Source,
+	IN POOL_TYPE PoolType)
+{
+	ASSERT(Destination);
+
+	if (Source == NULL)
+	{
+		RtlInitUnicodeString(Destination, NULL);
+		return STATUS_SUCCESS;
+	}
+
+	Destination->Buffer = ExAllocatePool(PoolType, Source->MaximumLength);
+	if (Destination->Buffer == NULL)
+	{
+		return STATUS_INSUFFICIENT_RESOURCES;
+	}
+
+	Destination->MaximumLength = Source->MaximumLength;
+	Destination->Length = Source->Length;
+	RtlCopyMemory(Destination->Buffer, Source->Buffer, Source->MaximumLength);
+
+	return STATUS_SUCCESS;
+}

Copied: trunk/reactos/drivers/usb/miniport/common/pdo.c (from rev 17754, trunk/reactos/drivers/usb/miniport/usbuhci/pdo.c)

Copied: trunk/reactos/drivers/usb/miniport/common/uhci.c (from rev 17754, trunk/reactos/drivers/usb/miniport/usbuhci/uhci.c)
--- trunk/reactos/drivers/usb/miniport/usbuhci/uhci.c	2005-09-08 21:54:42 UTC (rev 17754)
+++ trunk/reactos/drivers/usb/miniport/common/uhci.c	2005-09-10 15:17:07 UTC (rev 17776)
@@ -0,0 +1,274 @@
+/*
+   ReactOS specific functions for UHCI module
+   by Aleksey Bragin (aleksey@reactos.com)
+   and HervÚ Poussineau (hpoussin@reactos.com)
+   Some parts of code are inspired (or even just copied) from ReactOS Videoport driver
+*/
+#define NDEBUG
+#define INITGUID
+#include "uhci.h"
+
+static ULONG DeviceNumber = 0; /* FIXME: what is that? */
+
+static NTSTATUS
+CreateRootHubPdo(
+	IN PDRIVER_OBJECT DriverObject,
+	IN PDEVICE_OBJECT Fdo,
+	OUT PDEVICE_OBJECT* pPdo)
+{
+	PDEVICE_OBJECT Pdo;
+	POHCI_DEVICE_EXTENSION DeviceExtension;
+	NTSTATUS Status;
+	
+	DPRINT("UHCI: CreateRootHubPdo()\n");
+	
+	Status = IoCreateDevice(
+		DriverObject,
+		sizeof(OHCI_DEVICE_EXTENSION),
+		NULL, /* DeviceName */
+		FILE_DEVICE_BUS_EXTENDER,
+		FILE_DEVICE_SECURE_OPEN | FILE_AUTOGENERATED_DEVICE_NAME,
+		FALSE,
+		&Pdo);
+	if (!NT_SUCCESS(Status))
+	{
+		DPRINT("UHCI: IoCreateDevice() call failed with status 0x%08x\n", Status);
+		return Status;
+	}
+	
+	Pdo->Flags |= DO_BUS_ENUMERATED_DEVICE;
+	Pdo->Flags |= DO_POWER_PAGABLE;
+	
+	// zerofill device extension
+	DeviceExtension = (POHCI_DEVICE_EXTENSION)Pdo->DeviceExtension;
+	RtlZeroMemory(DeviceExtension, sizeof(OHCI_DEVICE_EXTENSION));
+	
+	DeviceExtension->IsFDO = FALSE;
+	DeviceExtension->FunctionalDeviceObject = Fdo;
+	
+	Pdo->Flags &= ~DO_DEVICE_INITIALIZING;
+	
+	*pPdo = Pdo;
+	return STATUS_SUCCESS;
+}
+
+NTSTATUS STDCALL
+AddDevice(
+	IN PDRIVER_OBJECT DriverObject,
+	IN PDEVICE_OBJECT pdo)
+{
+	PDEVICE_OBJECT fdo;
+	NTSTATUS Status;
+	WCHAR DeviceBuffer[20];
+	WCHAR LinkDeviceBuffer[20];
+	UNICODE_STRING DeviceName;
+	UNICODE_STRING LinkDeviceName;
+	POHCI_DRIVER_EXTENSION DriverExtension;
+	POHCI_DEVICE_EXTENSION DeviceExtension;
+
+	DPRINT("UHCI: AddDevice called\n");
+
+	// Allocate driver extension now
+	DriverExtension = IoGetDriverObjectExtension(DriverObject, DriverObject);
+	if (DriverExtension == NULL)
+	{
+		Status = IoAllocateDriverObjectExtension(
+					DriverObject,
+					DriverObject,
+					sizeof(OHCI_DRIVER_EXTENSION),
+					(PVOID *)&DriverExtension);
+
+		if (!NT_SUCCESS(Status))
+		{
+			DPRINT("UHCI: Allocating DriverObjectExtension failed.\n");
+			return Status;
+		}
+	}
+
+	// Create a unicode device name
+//	DeviceNumber = 0; //TODO: Allocate new device number every time
+	swprintf(DeviceBuffer, L"\\Device\\USBFDO-%lu", DeviceNumber);
+	RtlInitUnicodeString(&DeviceName, DeviceBuffer);
+
+	Status = IoCreateDevice(DriverObject,
+				sizeof(OHCI_DEVICE_EXTENSION),
+				&DeviceName,
+				FILE_DEVICE_BUS_EXTENDER,
+				0,
+				FALSE,
+				&fdo);
+
+	if (!NT_SUCCESS(Status))
+	{
+		DPRINT("UHCI: IoCreateDevice call failed with status 0x%08lx\n", Status);
+		return Status;
+	}
+
+	// zerofill device extension
+	DeviceExtension = (POHCI_DEVICE_EXTENSION)fdo->DeviceExtension;
+	RtlZeroMemory(DeviceExtension, sizeof(OHCI_DEVICE_EXTENSION));
+	
+	/* Create root hub Pdo */
+	Status = CreateRootHubPdo(DriverObject, fdo, &DeviceExtension->RootHubPdo);
+	if (!NT_SUCCESS(Status))
+	{
+		DPRINT("UHCI: CreateRootHubPdo() failed with status 0x%08lx\n", Status);
+		IoDeleteDevice(fdo);
+		return Status;
+	}
+
+	/* Register device interface for controller */
+	Status = IoRegisterDeviceInterface(
+		pdo,
+		&GUID_DEVINTERFACE_USB_HOST_CONTROLLER,
+		NULL,
+		&DeviceExtension->HcdInterfaceName);
+	if (!NT_SUCCESS(Status))
+	{
+		DPRINT("UHCI: IoRegisterDeviceInterface() failed with status 0x%08lx\n", Status);
+		IoDeleteDevice(DeviceExtension->RootHubPdo);
+		IoDeleteDevice(fdo);
+		return Status;
+	}
+
+	DeviceExtension->NextDeviceObject = IoAttachDeviceToDeviceStack(fdo, pdo);
+
+	fdo->Flags &= ~DO_DEVICE_INITIALIZING;
+
+	// Initialize device extension
+	DeviceExtension->IsFDO = TRUE;
+	DeviceExtension->DeviceNumber = DeviceNumber;
+	DeviceExtension->PhysicalDeviceObject = pdo;
+	DeviceExtension->FunctionalDeviceObject = fdo;
+	DeviceExtension->DriverExtension = DriverExtension;
+
+	/* FIXME: do a loop to find an available number */
+	swprintf(LinkDeviceBuffer, L"\\??\\HCD%lu", 0);
+
+	RtlInitUnicodeString(&LinkDeviceName, LinkDeviceBuffer);
+
+	Status = IoCreateSymbolicLink(&LinkDeviceName, &DeviceName);
+
+	if (!NT_SUCCESS(Status))
+	{
+		DPRINT("UHCI: IoCreateSymbolicLink call failed with status 0x%08x\n", Status);
+		IoDeleteDevice(DeviceExtension->RootHubPdo);
+		IoDeleteDevice(fdo);
+		return Status;
+	}
+
+	return STATUS_SUCCESS;
+}
+
+NTSTATUS STDCALL
+IrpStub(
+	IN PDEVICE_OBJECT DeviceObject,
+	IN PIRP Irp)
+{
+	NTSTATUS Status = STATUS_NOT_SUPPORTED;
+
+	if (((POHCI_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->IsFDO)
+	{
+		DPRINT1("UHCI: FDO stub for major function 0x%lx\n",
+			IoGetCurrentIrpStackLocation(Irp)->MajorFunction);
+#ifndef NDEBUG
+		DbgBreakPoint();
+#endif
+		return ForwardIrpAndForget(DeviceObject, Irp);
+	}
+	else
+	{
+		/* We can't forward request to the lower driver, because
+		 * we are a Pdo, so we don't have lower driver...
+		 */
+		DPRINT1("UHCI: PDO stub for major function 0x%lx\n",
+			IoGetCurrentIrpStackLocation(Irp)->MajorFunction);
+#ifndef NDEBUG
+		DbgBreakPoint();
+#endif
+	}
+
+	Status = Irp->IoStatus.Status;
+	IoCompleteRequest(Irp, IO_NO_INCREMENT);
+	return Status;
+}
+
+static NTSTATUS STDCALL
+DispatchCreate(PDEVICE_OBJECT DeviceObject, PIRP Irp)
+{
+	if (((POHCI_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->IsFDO)
+		return UhciCreate(DeviceObject, Irp);
+	else
+		return IrpStub(DeviceObject, Irp);
+}
+
+static NTSTATUS STDCALL
+DispatchClose(PDEVICE_OBJECT DeviceObject, PIRP Irp)
+{
+	if (((POHCI_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->IsFDO)
+		return UhciClose(DeviceObject, Irp);
+	else
+		return IrpStub(DeviceObject, Irp);
+}
+
+static NTSTATUS STDCALL
+DispatchCleanup(PDEVICE_OBJECT DeviceObject, PIRP Irp)
+{
+	if (((POHCI_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->IsFDO)
+		return UhciCleanup(DeviceObject, Irp);
+	else
+		return IrpStub(DeviceObject, Irp);
+}
+
+static NTSTATUS STDCALL
+DispatchDeviceControl(PDEVICE_OBJECT DeviceObject, PIRP Irp)
+{
+	if (((POHCI_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->IsFDO)
+		return UhciDeviceControlFdo(DeviceObject, Irp);
+	else
+		return UhciDeviceControlPdo(DeviceObject, Irp);
+}
+
+static NTSTATUS STDCALL
+DispatchPnp(PDEVICE_OBJECT DeviceObject, PIRP Irp)
+{
+	if (((POHCI_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->IsFDO)
+		return UhciPnpFdo(DeviceObject, Irp);
+	else
+		return UhciPnpPdo(DeviceObject, Irp);
+}
+
+static NTSTATUS STDCALL 
+DispatchPower(PDEVICE_OBJECT fido, PIRP Irp)
+{
+	DPRINT1("UHCI: IRP_MJ_POWER unimplemented\n");
+	Irp->IoStatus.Information = 0;
+	Irp->IoStatus.Status = STATUS_SUCCESS;
+	IoCompleteRequest(Irp, IO_NO_INCREMENT);
+	return STATUS_SUCCESS;
+}
+
+/*
+ * Standard DriverEntry method.
+ */
+NTSTATUS STDCALL
+DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegPath)
+{
+	ULONG i;
+	DPRINT("********* Cromwell UHCI *********\n");
+
+	DriverObject->DriverUnload = DriverUnload;
+	DriverObject->DriverExtension->AddDevice = AddDevice;
+
+	for (i = 0; i < IRP_MJ_MAXIMUM_FUNCTION; i++)
+		DriverObject->MajorFunction[i] = IrpStub;
+
+	DriverObject->MajorFunction[IRP_MJ_CREATE] = DispatchCreate;
+	DriverObject->MajorFunction[IRP_MJ_CLOSE] = DispatchClose;
+	DriverObject->MajorFunction[IRP_MJ_CLEANUP] = DispatchCleanup;
+	DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = DispatchDeviceControl;
+	DriverObject->MajorFunction[IRP_MJ_PNP] = DispatchPnp;
+	DriverObject->MajorFunction[IRP_MJ_POWER] = DispatchPower;
+
+	return STATUS_SUCCESS;
+}

Copied: trunk/reactos/drivers/usb/miniport/common/uhci.h (from rev 17754, trunk/reactos/drivers/usb/miniport/usbuhci/uhci.h)
--- trunk/reactos/drivers/usb/miniport/usbuhci/uhci.h	2005-09-08 21:54:42 UTC (rev 17754)
+++ trunk/reactos/drivers/usb/miniport/common/uhci.h	2005-09-10 15:17:07 UTC (rev 17776)
@@ -0,0 +1,84 @@
+//#include <ddk/ntddk.h>
+// config and include core/hcd.h, for hc_device struct struct usb_interface *usb_ifnum_to_if(struct usb_device *dev, unsigned ifnum)
+
+#include "../usb_wrapper.h"
+#include <ddk/usbdi.h>
+#include <ddk/usbiodef.h>
+#include <initguid.h>
+
+#include "hcd.h"
+
+#include "../usbohci/ohci_main.h"
+
+#define USB_UHCI_TAG TAG('u','s','b','u')
+
+/* cleanup.c */
+NTSTATUS STDCALL
+UhciCleanup(
+	IN PDEVICE_OBJECT DeviceObject,
+	IN PIRP Irp);
+
+/* close.c */
+NTSTATUS STDCALL
+UhciClose(
+	IN PDEVICE_OBJECT DeviceObject,
+	IN PIRP Irp);
+
+/* create.c */
+NTSTATUS STDCALL
+UhciCreate(
+	IN PDEVICE_OBJECT DeviceObject,
+	IN PIRP Irp);
+
+/* fdo.c */
+NTSTATUS STDCALL
+UhciPnpFdo(
+	IN PDEVICE_OBJECT DeviceObject,
+	IN PIRP Irp);
+
+NTSTATUS
+UhciDeviceControlFdo(
+	IN PDEVICE_OBJECT DeviceObject,
+	IN PIRP Irp);
+
+/* misc.c */
+NTSTATUS
+ForwardIrpAndWait(
+	IN PDEVICE_OBJECT DeviceObject,
+	IN PIRP Irp);
+
+NTSTATUS STDCALL
+ForwardIrpAndForget(
+	IN PDEVICE_OBJECT DeviceObject,
+	IN PIRP Irp);
+
+NTSTATUS
+UhciDuplicateUnicodeString(
+	OUT PUNICODE_STRING Destination,
+	IN PUNICODE_STRING Source,
+	IN POOL_TYPE PoolType);
+
+NTSTATUS
+UhciInitMultiSzString(
+	OUT PUNICODE_STRING Destination,
+	... /* list of PCSZ */);
+
+/* pdo.c */
+NTSTATUS STDCALL
+UhciPnpPdo(
+	IN PDEVICE_OBJECT DeviceObject,
+	IN PIRP Irp);
+
+NTSTATUS
+UhciDeviceControlPdo(
+	IN PDEVICE_OBJECT DeviceObject,
+	IN PIRP Irp);
+
+/* Needed by this object library */
+VOID STDCALL 
+DriverUnload(PDRIVER_OBJECT DriverObject);
+
+NTSTATUS
+InitLinuxWrapper(PDEVICE_OBJECT DeviceObject);
+
+extern struct pci_device_id** pci_ids;

Modified: trunk/reactos/drivers/usb/miniport/directory.xml
--- trunk/reactos/drivers/usb/miniport/directory.xml	2005-09-10 14:46:06 UTC (rev 17775)
+++ trunk/reactos/drivers/usb/miniport/directory.xml	2005-09-10 15:17:07 UTC (rev 17776)
@@ -1,3 +1,6 @@
+<directory name="common">
+	<xi:include href="common/common.xml" />
+</directory>
 <directory name="sys">
 	<xi:include href="sys/sys.xml" />
 </directory>

Deleted: trunk/reactos/drivers/usb/miniport/usbuhci/cleanup.c
--- trunk/reactos/drivers/usb/miniport/usbuhci/cleanup.c	2005-09-10 14:46:06 UTC (rev 17775)
+++ trunk/reactos/drivers/usb/miniport/usbuhci/cleanup.c	2005-09-10 15:17:07 UTC (rev 17776)
@@ -1,24 +0,0 @@
-/*
- * COPYRIGHT:       See COPYING in the top level directory
- * PROJECT:         ReactOS UHCI controller driver (Cromwell type)
- * FILE:            drivers/usb/cromwell/uhci/cleanup.c
- * PURPOSE:         IRP_MJ_CLEANUP operations
- *
- * PROGRAMMERS:     HervÚ Poussineau (hpoussin@reactos.com)
- */
-
-#define NDEBUG
-#include "uhci.h"
-
-NTSTATUS STDCALL
-UhciCleanup(
-	IN PDEVICE_OBJECT DeviceObject,
-	IN PIRP Irp)
-{
-	DPRINT("UHCI: IRP_MJ_CLEANUP\n");
-
-	Irp->IoStatus.Information = 0;
-	Irp->IoStatus.Status = STATUS_SUCCESS;
-	IoCompleteRequest(Irp, IO_NO_INCREMENT);
-	return STATUS_SUCCESS;
-}

Deleted: trunk/reactos/drivers/usb/miniport/usbuhci/close.c
--- trunk/reactos/drivers/usb/miniport/usbuhci/close.c	2005-09-10 14:46:06 UTC (rev 17775)
+++ trunk/reactos/drivers/usb/miniport/usbuhci/close.c	2005-09-10 15:17:07 UTC (rev 17776)
@@ -1,28 +0,0 @@
-/*
- * COPYRIGHT:       See COPYING in the top level directory
- * PROJECT:         ReactOS UHCI controller driver (Cromwell type)
- * FILE:            drivers/usb/cromwell/uhci/close.c
- * PURPOSE:         IRP_MJ_CLOSE operations
- *
- * PROGRAMMERS:     HervÚ Poussineau (hpoussin@reactos.com)
- */
-
-#define NDEBUG
-#include "uhci.h"
-
-NTSTATUS STDCALL
-UhciClose(
-	IN PDEVICE_OBJECT DeviceObject,
-	IN PIRP Irp)
-{
-	POHCI_DEVICE_EXTENSION pDeviceExtension;
-
-	DPRINT("UHCI: IRP_MJ_CLOSE\n");
-	pDeviceExtension = (POHCI_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
-	InterlockedDecrement((PLONG)&pDeviceExtension->DeviceOpened);
-
-	Irp->IoStatus.Information = 0;
-	Irp->IoStatus.Status = STATUS_SUCCESS;
-	IoCompleteRequest(Irp, IO_NO_INCREMENT);
-	return STATUS_SUCCESS;
-}

Deleted: trunk/reactos/drivers/usb/miniport/usbuhci/create.c
--- trunk/reactos/drivers/usb/miniport/usbuhci/create.c	2005-09-10 14:46:06 UTC (rev 17775)
+++ trunk/reactos/drivers/usb/miniport/usbuhci/create.c	2005-09-10 15:17:07 UTC (rev 17776)
@@ -1,41 +0,0 @@
-/*
- * COPYRIGHT:       See COPYING in the top level directory
[truncated at 1000 lines; 1350 more skipped]