Enumerate root hub connected to UHCI controller
Use Cromwell USB stack to initialize UHCI controller
Added: trunk/reactos/drivers/usb/cromwell/uhci/close.c
Added: trunk/reactos/drivers/usb/cromwell/uhci/create.c
Added: trunk/reactos/drivers/usb/cromwell/uhci/fdo.c
Added: trunk/reactos/drivers/usb/cromwell/uhci/misc.c
Added: trunk/reactos/drivers/usb/cromwell/uhci/pdo.c
Added: trunk/reactos/drivers/usb/cromwell/uhci/uhci.c
Deleted: trunk/reactos/drivers/usb/cromwell/uhci/uhci.def
Added: trunk/reactos/drivers/usb/cromwell/uhci/uhci.h
Modified: trunk/reactos/drivers/usb/cromwell/uhci/uhci.xml
Deleted: trunk/reactos/drivers/usb/cromwell/uhci/uhci_main.c

Added: trunk/reactos/drivers/usb/cromwell/uhci/close.c
--- trunk/reactos/drivers/usb/cromwell/uhci/close.c	2005-06-14 03:35:23 UTC (rev 15904)
+++ trunk/reactos/drivers/usb/cromwell/uhci/close.c	2005-06-14 12:31:51 UTC (rev 15905)
@@ -0,0 +1,28 @@
+/*
+ * 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;
+}
Property changes on: trunk/reactos/drivers/usb/cromwell/uhci/close.c
___________________________________________________________________
Name: svn:eol-style
   + native

Added: trunk/reactos/drivers/usb/cromwell/uhci/create.c
--- trunk/reactos/drivers/usb/cromwell/uhci/create.c	2005-06-14 03:35:23 UTC (rev 15904)
+++ trunk/reactos/drivers/usb/cromwell/uhci/create.c	2005-06-14 12:31:51 UTC (rev 15905)
@@ -0,0 +1,41 @@
+/*
+ * COPYRIGHT:       See COPYING in the top level directory
+ * PROJECT:         ReactOS UHCI controller driver (Cromwell type)
+ * FILE:            drivers/usb/cromwell/uhci/create.c
+ * PURPOSE:         IRP_MJ_CREATE operations
+ *
+ * PROGRAMMERS:     HervÚ Poussineau (hpoussin@reactos.com)
+ */
+
+#define NDEBUG
+#include "uhci.h"
+
+NTSTATUS STDCALL
+UhciCreate(
+	IN PDEVICE_OBJECT DeviceObject,
+	IN PIRP Irp)
+{
+	PIO_STACK_LOCATION Stack;
+	POHCI_DEVICE_EXTENSION DeviceExtension;
+	NTSTATUS Status;
+
+	DPRINT("UHCI: IRP_MJ_CREATE\n");
+	Stack = IoGetCurrentIrpStackLocation(Irp);
+	DeviceExtension = (POHCI_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
+
+	if (Stack->Parameters.Create.Options & FILE_DIRECTORY_FILE)
+	{
+		CHECKPOINT;
+		Status = STATUS_NOT_A_DIRECTORY;
+		goto ByeBye;
+	}
+
+	InterlockedIncrement((PLONG)&DeviceExtension->DeviceOpened);
+	Status = STATUS_SUCCESS;
+
+ByeBye:
+	Irp->IoStatus.Status = Status;
+	Irp->IoStatus.Information = 0;
+	IoCompleteRequest(Irp, IO_NO_INCREMENT);
+	return Status;
+}
Property changes on: trunk/reactos/drivers/usb/cromwell/uhci/create.c
___________________________________________________________________
Name: svn:eol-style
   + native

Added: trunk/reactos/drivers/usb/cromwell/uhci/fdo.c
--- trunk/reactos/drivers/usb/cromwell/uhci/fdo.c	2005-06-14 03:35:23 UTC (rev 15904)
+++ trunk/reactos/drivers/usb/cromwell/uhci/fdo.c	2005-06-14 12:31:51 UTC (rev 15905)
@@ -0,0 +1,422 @@
+/*
+ * 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"
+
+/* declare basic init functions and structures */
+int uhci_hcd_init(void);
+int STDCALL usb_init(void);
+
+extern struct pci_driver uhci_pci_driver;
+extern struct pci_device_id uhci_pci_ids[];
+
+static NTSTATUS
+InitLinuxWrapper(PDEVICE_OBJECT DeviceObject)
+{
+	NTSTATUS Status = STATUS_SUCCESS;
+
+	POHCI_DEVICE_EXTENSION DeviceExtension = (POHCI_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
+	
+	/* Create generic linux structure */
+	struct pci_dev *dev;
+	dev = ExAllocatePoolWithTag(PagedPool, sizeof(struct pci_dev), USB_UHCI_TAG);
+	DeviceExtension->pdev = dev;
+	
+	/* Initialize generic linux structure */
+	init_wrapper(dev);
+	dev->irq = DeviceExtension->InterruptVector;
+	dev->dev_ext = (PVOID)DeviceExtension;
+	dev->slot_name = ExAllocatePoolWithTag(NonPagedPool, 128, USB_UHCI_TAG); // 128 max len for slot name
+	
+	strcpy(dev->dev.name, "UnivHCI PCI-USB Controller");
+	strcpy(dev->slot_name, "UHCD PCI Slot");
+	
+	/* Init the OHCI HCD. Probe will be called automatically, but will fail because id=NULL */
+	Status = uhci_hcd_init();
+	if (!NT_SUCCESS(Status))
+	{
+		DPRINT("UHCI: uhci_hcd_init() failed with status 0x%08lx\n", Status);
+		/* FIXME: deinitialize linux wrapper */
+		ExFreePoolWithTag(dev, USB_UHCI_TAG);
+		return Status;
+	}
+
+	/* Init core usb */
+	usb_init();
+
+	/* Probe device with real id now */
+	uhci_pci_driver.probe(dev, uhci_pci_ids);
+
+//	DPRINT1("UHCI :SysIoBusNumA %d\n",DeviceExtension->SystemIoBusNumber);
+//	DeviceExtension->SystemIoBusNumber = dev->bus->number;
+//	DPRINT1("UHCI: SysIoBusNumB %d\n",DeviceExtension->SystemIoBusNumber);
+
+	return Status; 
+}
+
+#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 *)uhci_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 *)uhci_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 *)uhci_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:
+		{
+			DPRINT1("UHCI: IOCTL_GET_HCD_DRIVERKEY_NAME does not return correct string\n");
+			/* FIXME: should return sth like {36FC9E60-C465-11CF-8056-444553540000}\0000 */
+			if (LengthOut < sizeof(USB_HCD_DRIVERKEY_NAME))
+			{
+				Status = STATUS_BUFFER_TOO_SMALL;
+			}
+			else
+			{
+				PUSB_HCD_DRIVERKEY_NAME StringDescriptor;
+				ULONG StringSize;
+				StringDescriptor = (PUSB_HCD_DRIVERKEY_NAME)BufferOut;
+				Status = IoGetDeviceProperty(
+					((POHCI_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->PhysicalDeviceObject,
+					DevicePropertyDeviceDescription,
+					LengthOut - FIELD_OFFSET(USB_HCD_DRIVERKEY_NAME, DriverKeyName),
+					StringDescriptor->DriverKeyName,
+					&StringSize);
+				if (NT_SUCCESS(Status) || Status == STATUS_BUFFER_TOO_SMALL)
+				{
+					DPRINT("UHCI: IOCTL_GET_HCD_DRIVERKEY_NAME returns '%S'\n", StringDescriptor->DriverKeyName);
+					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_HCD_DRIVERKEY_NAME))
+			{
+				Status = STATUS_BUFFER_TOO_SMALL;
+			}
+			else
+			{
+				PUSB_HCD_DRIVERKEY_NAME StringDescriptor;
+				PUNICODE_STRING RootHubInterfaceName;
+				StringDescriptor = (PUSB_HCD_DRIVERKEY_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_HCD_DRIVERKEY_NAME, DriverKeyName);
+				if (StringDescriptor->ActualLength <= LengthOut)
+				{
+					/* Copy root hub name */
+					RtlCopyMemory(
+						StringDescriptor->DriverKeyName,
+						RootHubInterfaceName->Buffer,
+						RootHubInterfaceName->Length);
+					StringDescriptor->DriverKeyName[RootHubInterfaceName->Length / sizeof(WCHAR)] = '\0';
+					DPRINT("UHCI: IOCTL_USB_GET_ROOT_HUB_NAME returns '%S'\n", StringDescriptor->DriverKeyName);
+					Information = StringDescriptor->ActualLength;
+				}
+				else
+					Information = sizeof(USB_HCD_DRIVERKEY_NAME);
+				Status = STATUS_SUCCESS;
+			}
+			break;
+		}
+
+		/*case IOCTL_USB_GET_NODE_INFORMATION:
+		{
+			DPRINT1("UHCI: IOCTL_USB_GET_NODE_INFORMATION\n");
+			Status = STATUS_NOT_IMPLEMENTED;
+			break;
+		}*/
+		case IOCTL_USB_GET_NODE_CONNECTION_INFORMATION:
+		{
+			DPRINT1("UHCI: IOCTL_USB_GET_NODE_CONNECTION_INFORMATION\n");
+			Status = STATUS_NOT_IMPLEMENTED;
+			break;
+		}
+		case IOCTL_USB_GET_NODE_CONNECTION_NAME:
+		{
+			DPRINT1("UHCI: IOCTL_USB_GET_NODE_CONNECTION_NAME\n");
+			Status = STATUS_NOT_IMPLEMENTED;
+			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;
+}
Property changes on: trunk/reactos/drivers/usb/cromwell/uhci/fdo.c
___________________________________________________________________
Name: svn:eol-style
   + native

Added: trunk/reactos/drivers/usb/cromwell/uhci/misc.c
--- trunk/reactos/drivers/usb/cromwell/uhci/misc.c	2005-06-14 03:35:23 UTC (rev 15904)
+++ trunk/reactos/drivers/usb/cromwell/uhci/misc.c	2005-06-14 12:31:51 UTC (rev 15905)
@@ -0,0 +1,166 @@
+/*
+ * 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)
+	{
+		RtlInitAnsiString(&AnsiString, Source);
+		DestinationSize += RtlAnsiStringToUnicodeSize(&AnsiString)
+			+ sizeof(WCHAR) /* final NULL */;
+		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;
+}
Property changes on: trunk/reactos/drivers/usb/cromwell/uhci/misc.c
___________________________________________________________________
Name: svn:eol-style
   + native

Added: trunk/reactos/drivers/usb/cromwell/uhci/pdo.c
--- trunk/reactos/drivers/usb/cromwell/uhci/pdo.c	2005-06-14 03:35:23 UTC (rev 15904)
+++ trunk/reactos/drivers/usb/cromwell/uhci/pdo.c	2005-06-14 12:31:51 UTC (rev 15905)
@@ -0,0 +1,196 @@
+/*
+ * COPYRIGHT:       See COPYING in the top level directory
+ * PROJECT:         ReactOS UHCI controller driver (Cromwell type)
+ * FILE:            drivers/usb/cromwell/uhci/pdo.c
+ * PURPOSE:         IRP_MJ_PNP/IRP_MJ_DEVICE_CONTROL operations for PDOs
+ *
+ * PROGRAMMERS:     HervÚ Poussineau (hpoussin@reactos.com),
+ *                  James Tabor (jimtabor@adsl-64-217-116-74.dsl.hstntx.swbell.net)
+ */
+
+#define NDEBUG
+#include "uhci.h"
+
+extern struct usb_driver hub_driver;
+
+#define IO_METHOD_FROM_CTL_CODE(ctlCode) (ctlCode&0x00000003)
+
+NTSTATUS
+UhciDeviceControlPdo(
+	IN PDEVICE_OBJECT DeviceObject,
+	IN PIRP Irp)
+{
+	PIO_STACK_LOCATION Stack;
+	ULONG_PTR Information = 0;
+	NTSTATUS Status;
+	
+	DPRINT("UHCI: UhciDeviceControlPdo() called\n");
+	
+	Stack = IoGetCurrentIrpStackLocation(Irp);
+	Status = Irp->IoStatus.Status;
+	
+	switch (Stack->Parameters.DeviceIoControl.IoControlCode)
+	{
+		case IOCTL_INTERNAL_USB_GET_ROOT_USB_DEVICE:
+		{
+			POHCI_DEVICE_EXTENSION DeviceExtension;
+			
+			DPRINT("UHCI: IOCTL_INTERNAL_USB_GET_ROOT_USB_DEVICE\n");
+			if (Irp->AssociatedIrp.SystemBuffer == NULL
+				|| Stack->Parameters.DeviceIoControl.OutputBufferLength != sizeof(PVOID))
+			{
+				Status = STATUS_INVALID_PARAMETER;
+			}
+			else
+			{
+				PVOID* pRootHubPointer;
+				DeviceExtension = (POHCI_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
+				DeviceExtension = (POHCI_DEVICE_EXTENSION)DeviceExtension->FunctionalDeviceObject->DeviceExtension;
+				
+				pRootHubPointer = (PVOID*)Irp->AssociatedIrp.SystemBuffer;
+				*pRootHubPointer = (PVOID)DeviceExtension->pdev->bus; /* struct usb_device* */
+				Information = sizeof(PVOID);
+				Status = STATUS_SUCCESS;
+			}
+			break;
+		}
+		default:
+		{
+			DPRINT1("UHCI: Unknown IOCTL code 0x%lx\n", Stack->Parameters.DeviceIoControl.IoControlCode);
+			Information = Irp->IoStatus.Information;
+			Status = Irp->IoStatus.Status;
+		}
+	}
+	
+	Irp->IoStatus.Information = Information;
+	Irp->IoStatus.Status = Status;
+	IoCompleteRequest(Irp, IO_NO_INCREMENT);
+	return Status;
+}
+
+static NTSTATUS
+UhciPdoQueryId(
+	IN PDEVICE_OBJECT DeviceObject,
+	IN PIRP Irp,
+	OUT ULONG_PTR* Information)
+{
+	POHCI_DEVICE_EXTENSION DeviceExtension;
+	ULONG IdType;
+	UNICODE_STRING SourceString;
+	UNICODE_STRING String;
+	NTSTATUS Status;
+
+	IdType = IoGetCurrentIrpStackLocation(Irp)->Parameters.QueryId.IdType;
+	DeviceExtension = (POHCI_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
+	RtlInitUnicodeString(&String, NULL);
+
+	switch (IdType)
+	{
+		case BusQueryDeviceID:
+		{
+			DPRINT("UHCI: IRP_MJ_PNP / IRP_MN_QUERY_ID / BusQueryDeviceID\n");
+			RtlInitUnicodeString(&SourceString, L"USB\\ROOT_HUB");
+			break;
+		}
+		case BusQueryHardwareIDs:
+		{
+			DPRINT("UHCI: IRP_MJ_PNP / IRP_MN_QUERY_ID / BusQueryHardwareIDs\n");
+			/* FIXME: Should return
+				USB\ROOT_HUB&VID????&PID????&REV????
+				USB\ROOT_HUB&VID????&PID????
+				USB\ROOT_HUB
+			*/
+			UhciInitMultiSzString(&SourceString, "USB\\ROOT_HUB", NULL);
+			break;
+		}
+		case BusQueryCompatibleIDs:
+			DPRINT("UHCI: IRP_MJ_PNP / IRP_MN_QUERY_ID / BusQueryCompatibleIDs\n");
+			/* No compatible ID */
+			*Information = 0;
+			return STATUS_NOT_SUPPORTED;
+		case BusQueryInstanceID:
+		{
+			DPRINT("UHCI: IRP_MJ_PNP / IRP_MN_QUERY_ID / BusQueryInstanceID\n");
+			RtlInitUnicodeString(&SourceString, L"0000"); /* FIXME */
+			break;
+		}
+		default:
+			DPRINT1("UHCI: IRP_MJ_PNP / IRP_MN_QUERY_ID / unknown query id type 0x%lx\n", IdType);
+			return STATUS_NOT_SUPPORTED;
+	}
+
+	Status = UhciDuplicateUnicodeString(
+		&String,
+		&SourceString,
+		PagedPool);
+	*Information = (ULONG_PTR)String.Buffer;
+	return Status;
+}
+
+static NTSTATUS
+UhciPnpStartDevice(
+	IN PDEVICE_OBJECT DeviceObject)
+{
+	POHCI_DEVICE_EXTENSION DeviceExtension;
+	NTSTATUS Status;
+	
+	DeviceExtension = (POHCI_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
+	
+	/* Register device interface for root hub */
+	Status = IoRegisterDeviceInterface(
+		DeviceObject,
+		&GUID_DEVINTERFACE_USB_HUB,
+		NULL,
+		&DeviceExtension->HcdInterfaceName);
+	if (!NT_SUCCESS(Status))
+	{
+		DPRINT("UHCI: IoRegisterDeviceInterface() failed with status 0x%08lx\n", Status);
+		return Status;
+	}
+	
+	return Status;
+}
+
+NTSTATUS STDCALL
+UhciPnpPdo(
+	IN PDEVICE_OBJECT DeviceObject,
+	IN PIRP Irp)
+{
+	ULONG MinorFunction;
+	PIO_STACK_LOCATION Stack;
+	ULONG_PTR Information = 0;
+	NTSTATUS Status;
+	
+	Stack = IoGetCurrentIrpStackLocation(Irp);
+	MinorFunction = Stack->MinorFunction;
+
+	switch (MinorFunction)
+	{
+		case IRP_MN_START_DEVICE: /* 0x00 */
+		{
+			DPRINT("UHCI: IRP_MJ_PNP/IRP_MN_START_DEVICE\n");
+			Status = UhciPnpStartDevice(DeviceObject);
+			break;
+		}
+		case IRP_MN_QUERY_ID: /* 0x13 */
+		{
+			Status = UhciPdoQueryId(DeviceObject, Irp, &Information);
+			break;
+		}
+		default:
+		{
+			/* We can't forward request to the lower driver, because
+			 * we are a Pdo, so we don't have lower driver...
+			 */
+			DPRINT1("UHCI: IRP_MJ_PNP / unknown minor function 0x%lx\n", MinorFunction);
+			Information = Irp->IoStatus.Information;
+			Status = Irp->IoStatus.Status;
+		}
+	}
+
+	Irp->IoStatus.Information = Information;
+	Irp->IoStatus.Status = Status;
+	IoCompleteRequest(Irp, IO_NO_INCREMENT);
+	return Status;
+}
+
Property changes on: trunk/reactos/drivers/usb/cromwell/uhci/pdo.c
___________________________________________________________________
Name: svn:eol-style
   + native

Added: trunk/reactos/drivers/usb/cromwell/uhci/uhci.c
--- trunk/reactos/drivers/usb/cromwell/uhci/uhci.c	2005-06-14 03:35:23 UTC (rev 15904)
+++ trunk/reactos/drivers/usb/cromwell/uhci/uhci.c	2005-06-14 12:31:51 UTC (rev 15905)
@@ -0,0 +1,297 @@
+/*
+   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"
+
+/* declare basic init functions and structures */
+void uhci_hcd_cleanup(void);
+void STDCALL usb_exit(void);
+
+extern struct pci_driver uhci_pci_driver;
+
+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);
[truncated at 1000 lines; 696 more skipped]