Add usb hub driver. It is linked with cromwell usb stack
Modified: trunk/reactos/drivers/usb/cromwell/directory.xml
Added: trunk/reactos/drivers/usb/cromwell/hub/
Added: trunk/reactos/drivers/usb/cromwell/hub/createclose.c
Added: trunk/reactos/drivers/usb/cromwell/hub/fdo.c
Added: trunk/reactos/drivers/usb/cromwell/hub/hub.xml
Added: trunk/reactos/drivers/usb/cromwell/hub/misc.c
Added: trunk/reactos/drivers/usb/cromwell/hub/pdo.c
Added: trunk/reactos/drivers/usb/cromwell/hub/usbhub.c
Added: trunk/reactos/drivers/usb/cromwell/hub/usbhub.h
Added: trunk/reactos/drivers/usb/cromwell/hub/usbhub.rc
Modified: trunk/reactos/drivers/usb/cromwell/usb_wrapper.h
Modified: trunk/reactos/drivers/usb/directory.xml

Modified: trunk/reactos/drivers/usb/cromwell/directory.xml
--- trunk/reactos/drivers/usb/cromwell/directory.xml	2005-06-13 20:37:33 UTC (rev 15895)
+++ trunk/reactos/drivers/usb/cromwell/directory.xml	2005-06-13 20:41:59 UTC (rev 15896)
@@ -7,6 +7,9 @@
 <directory name="host">
         <xi:include href="host/host.xml" />
 </directory>
+<directory name="hub">
+	<xi:include href="hub/hub.xml" />
+</directory>
 <directory name="uhci">
         <xi:include href="uhci/uhci.xml" />
 </directory>
\ No newline at end of file

Added: trunk/reactos/drivers/usb/cromwell/hub/createclose.c
--- trunk/reactos/drivers/usb/cromwell/hub/createclose.c	2005-06-13 20:37:33 UTC (rev 15895)
+++ trunk/reactos/drivers/usb/cromwell/hub/createclose.c	2005-06-13 20:41:59 UTC (rev 15896)
@@ -0,0 +1,50 @@
+/*
+ * COPYRIGHT:       See COPYING in the top level directory
+ * PROJECT:         USB hub driver
+ * FILE:            drivers/usb/cromwell/usbhub/createclose.c
+ * PURPOSE:         IRP_MJ_CREATE and IRP_MJ_CLOSE operations
+ *
+ * PROGRAMMERS:     HervÚ Poussineau (hpoussin@reactos.com)
+ */
+
+#define NDEBUG
+#include "usbhub.h"
+
+NTSTATUS STDCALL
+UsbhubCreate(
+	IN PDEVICE_OBJECT DeviceObject,
+	IN PIRP Irp)
+{
+	DPRINT("Usbhub: IRP_MJ_CREATE\n");
+	
+	Irp->IoStatus.Status = STATUS_SUCCESS;
+	Irp->IoStatus.Information = 0;
+	IoCompleteRequest(Irp, IO_NO_INCREMENT);
+	return STATUS_SUCCESS;
+}
+
+NTSTATUS STDCALL
+UsbhubClose(
+	IN PDEVICE_OBJECT DeviceObject,
+	IN PIRP Irp)
+{
+	DPRINT("Usbhub: IRP_MJ_CLOSE\n");
+	
+	Irp->IoStatus.Status = STATUS_SUCCESS;
+	Irp->IoStatus.Information = 0;
+	IoCompleteRequest(Irp, IO_NO_INCREMENT);
+	return STATUS_SUCCESS;
+}
+
+NTSTATUS STDCALL
+UsbhubCleanup(
+	IN PDEVICE_OBJECT DeviceObject,
+	IN PIRP Irp)
+{
+	DPRINT("Usbhub: IRP_MJ_CLEANUP\n");
+	
+	Irp->IoStatus.Status = STATUS_SUCCESS;
+	Irp->IoStatus.Information = 0;
+	IoCompleteRequest(Irp, IO_NO_INCREMENT);
+	return STATUS_SUCCESS;
+}
Property changes on: trunk/reactos/drivers/usb/cromwell/hub/createclose.c
___________________________________________________________________
Name: svn:eol-style
   + native

Added: trunk/reactos/drivers/usb/cromwell/hub/fdo.c
--- trunk/reactos/drivers/usb/cromwell/hub/fdo.c	2005-06-13 20:37:33 UTC (rev 15895)
+++ trunk/reactos/drivers/usb/cromwell/hub/fdo.c	2005-06-13 20:41:59 UTC (rev 15896)
@@ -0,0 +1,180 @@
+/*
+ * COPYRIGHT:       See COPYING in the top level directory
+ * PROJECT:         USB hub driver
+ * FILE:            drivers/usb/cromwell/hub/fdo.c
+ * PURPOSE:         IRP_MJ_PNP operations for FDOs
+ *
+ * PROGRAMMERS:     HervÚ Poussineau (hpoussin@reactos.com)
+ */
+
+//#define NDEBUG
+#include "usbhub.h"
+
+extern struct usb_driver hub_driver;
+
+#define IO_METHOD_FROM_CTL_CODE(ctlCode) (ctlCode&0x00000003)
+
+static VOID
+UsbhubGetUserBuffers(
+	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
+UsbhubPnpFdo(
+	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:
+		{
+			DPRINT("Usbhub: IRP_MJ_PNP / IRP_MN_START_DEVICE\n");
+			Status = ForwardIrpAndWait(DeviceObject, Irp);
+			//if (NT_SUCCESS(Status) && NT_SUCCESS(Irp->IoStatus.Status))
+			//	Status = OHCD_PnPStartDevice(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:
+		{
+			DPRINT("Usbhub: IRP_MJ_PNP / IRP_MN_STOP_DEVICE\n");
+			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;
+		}
+
+		default:
+		{
+			DPRINT1("Usbhub: IRP_MJ_PNP / 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;
+}
+
+static inline struct device *hubdev (struct usb_device *dev)
+{
+	return &dev->actconfig->interface [0].dev;
+}
+
+NTSTATUS
+UsbhubDeviceControlFdo(
+	IN PDEVICE_OBJECT DeviceObject,
+	IN PIRP Irp)
+{
+	PIO_STACK_LOCATION Stack;
+	ULONG IoControlCode;
+	PHUB_DEVICE_EXTENSION DeviceExtension;
+	ULONG LengthIn, LengthOut;
+	ULONG_PTR Information = 0;
+	PVOID BufferIn, BufferOut;
+	NTSTATUS Status;
+
+	DPRINT("Usbhub: UsbhubDeviceControlFdo() called\n");
+
+	Stack = IoGetCurrentIrpStackLocation(Irp);
+	LengthIn = Stack->Parameters.DeviceIoControl.InputBufferLength;
+	LengthOut = Stack->Parameters.DeviceIoControl.OutputBufferLength;
+	DeviceExtension = (PHUB_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
+	IoControlCode = Stack->Parameters.DeviceIoControl.IoControlCode;
+	UsbhubGetUserBuffers(Irp, IoControlCode, &BufferIn, &BufferOut);
+
+	switch (IoControlCode)
+	{
+		case IOCTL_USB_GET_NODE_INFORMATION:
+		{
+			PUSB_NODE_INFORMATION NodeInformation;
+			struct usb_device* dev;
+			struct device* device;
+			struct usb_interface * intf;
+			struct usb_hub *hub;
+			struct usb_hub_descriptor *descriptor;
+			DPRINT("Usbhub: IOCTL_USB_GET_NODE_INFORMATION\n");
+			if (LengthOut < sizeof(USB_NODE_INFORMATION))
+				Status = STATUS_BUFFER_TOO_SMALL;
+			else if (BufferOut == NULL)
+				Status = STATUS_INVALID_PARAMETER;
+			else
+			{
+				NodeInformation = (PUSB_NODE_INFORMATION)BufferOut;
+				dev = ((PHUB_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->dev;
+				device = hubdev(dev);
+				intf = to_usb_interface(device);
+				hub = usb_get_intfdata(intf);
+				descriptor = hub->descriptor;
+				NodeInformation->NodeType = UsbHub;
+				RtlCopyMemory(
+					&NodeInformation->u.HubInformation.HubDescriptor,
+					descriptor,
+					sizeof(USB_HUB_DESCRIPTOR));
+				NodeInformation->u.HubInformation.HubIsBusPowered = TRUE; /* FIXME */
+				Information = sizeof(USB_NODE_INFORMATION);
+				Status = STATUS_SUCCESS;
+			}
+			break;
+		}
+		default:
+		{
+			/* Pass Irp to lower driver */
+			DPRINT1("Usbhub: Unknown IOCTL code 0x%lx\n", Stack->Parameters.DeviceIoControl.IoControlCode);
+			return ForwardIrpAndForget(DeviceObject, Irp);
+		}
+	}
+
+	Irp->IoStatus.Information = Information;
+	Irp->IoStatus.Status = Status;
+	IoCompleteRequest(Irp, IO_NO_INCREMENT);
+	return Status;
+}
Property changes on: trunk/reactos/drivers/usb/cromwell/hub/fdo.c
___________________________________________________________________
Name: svn:eol-style
   + native

Added: trunk/reactos/drivers/usb/cromwell/hub/hub.xml
--- trunk/reactos/drivers/usb/cromwell/hub/hub.xml	2005-06-13 20:37:33 UTC (rev 15895)
+++ trunk/reactos/drivers/usb/cromwell/hub/hub.xml	2005-06-13 20:41:59 UTC (rev 15896)
@@ -0,0 +1,16 @@
+<module name="hub" type="kernelmodedriver" installbase="system32/drivers" installname="usbhub.sys" warnings="true">
+	<define name="__USE_W32API" />
+	<define name="DEBUG_MODE" />
+	<include base="ntoskrnl">include</include>
+	<include>../linux</include>
+	<library>sys_base</library>
+	<library>ntoskrnl</library>
+	<library>hal</library>
+	<library>usbcore</library>
+	<file>createclose.c</file>
+	<file>fdo.c</file>
+	<file>misc.c</file>
+	<file>pdo.c</file>
+	<file>usbhub.c</file>
+	<file>usbhub.rc</file>
+</module>
Property changes on: trunk/reactos/drivers/usb/cromwell/hub/hub.xml
___________________________________________________________________
Name: svn:eol-style
   + native

Added: trunk/reactos/drivers/usb/cromwell/hub/misc.c
--- trunk/reactos/drivers/usb/cromwell/hub/misc.c	2005-06-13 20:37:33 UTC (rev 15895)
+++ trunk/reactos/drivers/usb/cromwell/hub/misc.c	2005-06-13 20:41:59 UTC (rev 15896)
@@ -0,0 +1,166 @@
+/*
+ * COPYRIGHT:       See COPYING in the top level directory
+ * PROJECT:         USB hub driver
+ * FILE:            drivers/usb/cromwell/hub/misc.c
+ * PURPOSE:         Misceallenous operations
+ *
+ * PROGRAMMERS:     HervÚ Poussineau (hpoussin@reactos.com),
+ */
+
+#define NDEBUG
+#include "usbhub.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 = ((PHUB_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->LowerDevice;
+	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 = ((PHUB_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->LowerDevice;
+
+	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
+UsbhubInitMultiSzString(
+	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_HUB_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_HUB_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
+UsbhubDuplicateUnicodeString(
+	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/hub/misc.c
___________________________________________________________________
Name: svn:eol-style
   + native

Added: trunk/reactos/drivers/usb/cromwell/hub/pdo.c
--- trunk/reactos/drivers/usb/cromwell/hub/pdo.c	2005-06-13 20:37:33 UTC (rev 15895)
+++ trunk/reactos/drivers/usb/cromwell/hub/pdo.c	2005-06-13 20:41:59 UTC (rev 15896)
@@ -0,0 +1,78 @@
+/*
+ * COPYRIGHT:       See COPYING in the top level directory
+ * PROJECT:         USB hub driver
+ * FILE:            drivers/usb/cromwell/hub/pdo.c
+ * PURPOSE:         IRP_MJ_PNP operations for PDOs
+ *
+ * PROGRAMMERS:     HervÚ Poussineau (hpoussin@reactos.com)
+ */
+
+//#define NDEBUG
+#include "usbhub.h"
+
+extern struct usb_driver hub_driver;
+
+#define IO_METHOD_FROM_CTL_CODE(ctlCode) (ctlCode&0x00000003)
+
+NTSTATUS
+UsbhubDeviceControlPdo(
+	IN PDEVICE_OBJECT DeviceObject,
+	IN PIRP Irp)
+{
+	PIO_STACK_LOCATION Stack;
+	ULONG_PTR Information = 0;
+	NTSTATUS Status;
+	
+	DPRINT("Usbhub: UsbhubDeviceControlPdo() called\n");
+	
+	Stack = IoGetCurrentIrpStackLocation(Irp);
+	Status = Irp->IoStatus.Status;
+	
+	switch (Stack->Parameters.DeviceIoControl.IoControlCode)
+	{
+		default:
+		{
+			DPRINT1("Usbhub: 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;
+}
+
+NTSTATUS STDCALL
+UsbhubPnpPdo(
+	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)
+	{
+		default:
+		{
+			/* We can't forward request to the lower driver, because
+			 * we are a Pdo, so we don't have lower driver...
+			 */
+			DPRINT1("Usbhub: 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/hub/pdo.c
___________________________________________________________________
Name: svn:eol-style
   + native

Added: trunk/reactos/drivers/usb/cromwell/hub/usbhub.c
--- trunk/reactos/drivers/usb/cromwell/hub/usbhub.c	2005-06-13 20:37:33 UTC (rev 15895)
+++ trunk/reactos/drivers/usb/cromwell/hub/usbhub.c	2005-06-13 20:41:59 UTC (rev 15896)
@@ -0,0 +1,192 @@
+/*
+ * ReactOS USB hub driver
+ * Copyright (C) 2004 Aleksey Bragin
+ *           (C) 2005 Mark Tempel
+ *           (C) 2005 HervÚ Poussineau
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ */
+
+/* INCLUDES *******************************************************************/
+//#define NDEBUG
+#include "usbhub.h"
+
+/* PUBLIC AND PRIVATE FUNCTIONS ***********************************************/
+
+static NTSTATUS
+GetRootHubPointer(
+	IN PDEVICE_OBJECT Pdo,
+	OUT PVOID* RootHubPointer)
+{
+	KEVENT Event;
+	PIRP Irp;
+	IO_STATUS_BLOCK IoStatus;
+	NTSTATUS Status;
+	
+	KeInitializeEvent (&Event, NotificationEvent, FALSE);
+	
+	Irp = IoBuildDeviceIoControlRequest(IOCTL_INTERNAL_USB_GET_ROOT_USB_DEVICE,
+		Pdo,
+		NULL, sizeof(NULL),
+		RootHubPointer, sizeof(*RootHubPointer),
+		FALSE,
+		&Event,
+		&IoStatus);
+	if (Irp == NULL)
+	{
+		DPRINT("Usbhub: IoBuildDeviceIoControlRequest() failed\n");
+		return STATUS_INSUFFICIENT_RESOURCES;
+	}
+	
+	Status = IoCallDriver(Pdo, Irp);
+	
+	if (Status == STATUS_PENDING)
+	{
+		DPRINT("Usbhub: Operation pending\n");
+		KeWaitForSingleObject(&Event, Suspended, KernelMode, FALSE, NULL);
+		Status = IoStatus.Status;
+	}
+	
+	return Status;
+}
+
+NTSTATUS STDCALL 
+UsbhubAddDevice(
+	IN PDRIVER_OBJECT DriverObject,
+	IN PDEVICE_OBJECT Pdo)
+{
+	PDEVICE_OBJECT Fdo;
+	PHUB_DEVICE_EXTENSION DeviceExtension;
+	NTSTATUS Status;
+	
+	Status = IoCreateDevice(DriverObject,
+		sizeof(HUB_DEVICE_EXTENSION),
+		NULL, /* DeviceName */
+		FILE_DEVICE_BUS_EXTENDER,
+		0,
+		FALSE,
+		&Fdo);
+	if (!NT_SUCCESS(Status))
+	{
+		DPRINT1("Usbhub: IoCreateDevice() failed with status 0x%08lx\n", Status);
+		return Status;
+	}
+	
+	// zerofill device extension
+	DeviceExtension = (PHUB_DEVICE_EXTENSION)Fdo->DeviceExtension;
+	RtlZeroMemory(DeviceExtension, sizeof(HUB_DEVICE_EXTENSION));
+	
+	/* Get a pointer to the linux structure created by the USB controller,
+	 * by sending IOCTL_INTERNAL_USB_GET_ROOT_USB_DEVICE to lower device.
+	 */
+	Status = GetRootHubPointer(Pdo, (PVOID*)&DeviceExtension->dev);
+	if (!NT_SUCCESS(Status))
+	{
+		DPRINT("Usbhub: GetRootHubPointer() failed with status 0x%08lx\n", Status);
+		IoDeleteDevice(Fdo);
+		return Status;
+	}
+	
+	DeviceExtension->IsFDO = TRUE;
+	Fdo->Flags |= DO_POWER_PAGABLE;
+	Status = IoAttachDeviceToDeviceStackSafe(Fdo, Pdo, &DeviceExtension->LowerDevice);
+	if (!NT_SUCCESS(Status))
+	{
+		DPRINT("Usbhub: IoAttachDeviceToDeviceStackSafe() failed with status 0x%08lx\n", Status);
+		IoDeleteDevice(Fdo);
+		return Status;
+	}
+	Fdo->Flags |= DO_BUFFERED_IO;
+	Fdo->Flags &= ~DO_DEVICE_INITIALIZING;
+	
+	return STATUS_SUCCESS;
+}
+
+static NTSTATUS STDCALL
+IrpStub(
+	IN PDEVICE_OBJECT DeviceObject,
+	IN PIRP Irp)
+{
+	NTSTATUS Status;
+
+	if (((PHUB_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->IsFDO)
+	{
+		DPRINT1("Usbhub: 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("Usbhub: 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
+DispatchDeviceControl(PDEVICE_OBJECT DeviceObject, PIRP Irp)
+{
+	if (((PHUB_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->IsFDO)
+		return UsbhubDeviceControlFdo(DeviceObject, Irp);
+	else
+		return UsbhubDeviceControlPdo(DeviceObject, Irp);
+}
+
+static NTSTATUS STDCALL
+DispatchPnp(PDEVICE_OBJECT DeviceObject, PIRP Irp)
+{
+	if (((PHUB_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->IsFDO)
+		return UsbhubPnpFdo(DeviceObject, Irp);
+	else
+		return UsbhubPnpPdo(DeviceObject, Irp);
+}
+
+/*
+ * Standard DriverEntry method.
+ */
+NTSTATUS STDCALL
+DriverEntry(
+	IN PDRIVER_OBJECT DriverObject,
+	IN PUNICODE_STRING RegistryPath)
+{
+	ULONG i;
+	
+	DriverObject->DriverExtension->AddDevice = UsbhubAddDevice;
+	
+	for (i = 0; i < IRP_MJ_MAXIMUM_FUNCTION; i++)
+		DriverObject->MajorFunction[i] = IrpStub;
+	
+	DriverObject->MajorFunction[IRP_MJ_CREATE] = UsbhubCreate;
+	DriverObject->MajorFunction[IRP_MJ_CLOSE] = UsbhubClose;
+	DriverObject->MajorFunction[IRP_MJ_CLEANUP] = UsbhubCleanup;
+	DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = DispatchDeviceControl;
+	DriverObject->MajorFunction[IRP_MJ_PNP] = DispatchPnp;
+	
+	return STATUS_SUCCESS;
+}
+
Property changes on: trunk/reactos/drivers/usb/cromwell/hub/usbhub.c
___________________________________________________________________
Name: svn:eol-style
   + native

Added: trunk/reactos/drivers/usb/cromwell/hub/usbhub.h
--- trunk/reactos/drivers/usb/cromwell/hub/usbhub.h	2005-06-13 20:37:33 UTC (rev 15895)
+++ trunk/reactos/drivers/usb/cromwell/hub/usbhub.h	2005-06-13 20:41:59 UTC (rev 15896)
@@ -0,0 +1,82 @@
+#include <debug.h>
+
+#include <ddk/ntddk.h>
+#include <ddk/usbioctl.h>
+
+#include "../usb_wrapper.h"
+#include "../core/hub.h"
+
+#define USB_HUB_TAG TAG('u','s','b','h')
+
+NTSTATUS STDCALL
+IoAttachDeviceToDeviceStackSafe(
+  IN PDEVICE_OBJECT SourceDevice,
+  IN PDEVICE_OBJECT TargetDevice,
+  OUT PDEVICE_OBJECT *AttachedToDeviceObject);
+
+typedef struct _HUB_DEVICE_EXTENSION
+{
+	BOOLEAN IsFDO;
+	struct usb_device* dev;
+	PDEVICE_OBJECT LowerDevice;
+} HUB_DEVICE_EXTENSION, *PHUB_DEVICE_EXTENSION;
+
+/* createclose.c */
+NTSTATUS STDCALL
+UsbhubCreate(
+	IN PDEVICE_OBJECT DeviceObject,
+	IN PIRP Irp);
+
+NTSTATUS STDCALL
+UsbhubClose(
+	IN PDEVICE_OBJECT DeviceObject,
+	IN PIRP Irp);
+
+NTSTATUS STDCALL
+UsbhubCleanup(
+	IN PDEVICE_OBJECT DeviceObject,
+	IN PIRP Irp);
+
+/* fdo.c */
+NTSTATUS STDCALL
+UsbhubPnpFdo(
+	IN PDEVICE_OBJECT DeviceObject,
+	IN PIRP Irp);
+
+NTSTATUS
+UsbhubDeviceControlFdo(
+	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
+UsbhubDuplicateUnicodeString(
+	OUT PUNICODE_STRING Destination,
+	IN PUNICODE_STRING Source,
+	IN POOL_TYPE PoolType);
+
+NTSTATUS
+UsbhubInitMultiSzString(
+	OUT PUNICODE_STRING Destination,
+	... /* list of PCSZ */);
+
+/* pdo.c */
+NTSTATUS STDCALL
+UsbhubPnpPdo(
+	IN PDEVICE_OBJECT DeviceObject,
+	IN PIRP Irp);
+
+NTSTATUS
+UsbhubDeviceControlPdo(
+	IN PDEVICE_OBJECT DeviceObject,
+	IN PIRP Irp);
Property changes on: trunk/reactos/drivers/usb/cromwell/hub/usbhub.h
___________________________________________________________________
Name: svn:eol-style
   + native

Added: trunk/reactos/drivers/usb/cromwell/hub/usbhub.rc
--- trunk/reactos/drivers/usb/cromwell/hub/usbhub.rc	2005-06-13 20:37:33 UTC (rev 15895)
+++ trunk/reactos/drivers/usb/cromwell/hub/usbhub.rc	2005-06-13 20:41:59 UTC (rev 15896)
@@ -0,0 +1,5 @@
+#define REACTOS_VERSION_DLL
+#define REACTOS_STR_FILE_DESCRIPTION	"USB Hub Driver\0"
+#define REACTOS_STR_INTERNAL_NAME	"usbhub\0"
+#define REACTOS_STR_ORIGINAL_FILENAME	"usbhub.sys\0"
+#include <reactos/version.rc>
Property changes on: trunk/reactos/drivers/usb/cromwell/hub/usbhub.rc
___________________________________________________________________
Name: svn:eol-style
   + native

Modified: trunk/reactos/drivers/usb/cromwell/usb_wrapper.h
--- trunk/reactos/drivers/usb/cromwell/usb_wrapper.h	2005-06-13 20:37:33 UTC (rev 15895)
+++ trunk/reactos/drivers/usb/cromwell/usb_wrapper.h	2005-06-13 20:41:59 UTC (rev 15896)
@@ -26,3 +26,5 @@
 #include "linux/usb.h"
 #include "linux/pci_ids.h"
 
+#define IOCTL_INTERNAL_USB_GET_ROOT_USB_DEVICE \
+	CTL_CODE(FILE_DEVICE_USB, 4000, METHOD_BUFFERED, FILE_ANY_ACCESS)

Modified: trunk/reactos/drivers/usb/directory.xml
--- trunk/reactos/drivers/usb/directory.xml	2005-06-13 20:37:33 UTC (rev 15895)
+++ trunk/reactos/drivers/usb/directory.xml	2005-06-13 20:41:59 UTC (rev 15896)
@@ -11,5 +11,5 @@
 	<xi:include href="usbhub/usbhub.xml" />
 </directory>
 <directory name="usbport">
-	<xi:include href="usbport/usbport.xml" /-->
-</directory>
+	<xi:include href="usbport/usbport.xml" />
+</directory-->