From 925b767f99b4b2f8e0948da82e8ceb3fee45b3d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herv=C3=A9=20Poussineau?= Date: Mon, 13 Jun 2005 20:41:59 +0000 Subject: [PATCH] Add usb hub driver. It is linked with cromwell usb stack svn path=/trunk/; revision=15896 --- reactos/drivers/usb/cromwell/directory.xml | 3 + .../drivers/usb/cromwell/hub/createclose.c | 50 +++++ reactos/drivers/usb/cromwell/hub/fdo.c | 180 ++++++++++++++++ reactos/drivers/usb/cromwell/hub/hub.xml | 16 ++ reactos/drivers/usb/cromwell/hub/misc.c | 166 +++++++++++++++ reactos/drivers/usb/cromwell/hub/pdo.c | 78 +++++++ reactos/drivers/usb/cromwell/hub/usbhub.c | 192 ++++++++++++++++++ reactos/drivers/usb/cromwell/hub/usbhub.h | 82 ++++++++ reactos/drivers/usb/cromwell/hub/usbhub.rc | 5 + reactos/drivers/usb/cromwell/usb_wrapper.h | 2 + reactos/drivers/usb/directory.xml | 4 +- 11 files changed, 776 insertions(+), 2 deletions(-) create mode 100644 reactos/drivers/usb/cromwell/hub/createclose.c create mode 100644 reactos/drivers/usb/cromwell/hub/fdo.c create mode 100644 reactos/drivers/usb/cromwell/hub/hub.xml create mode 100644 reactos/drivers/usb/cromwell/hub/misc.c create mode 100644 reactos/drivers/usb/cromwell/hub/pdo.c create mode 100644 reactos/drivers/usb/cromwell/hub/usbhub.c create mode 100644 reactos/drivers/usb/cromwell/hub/usbhub.h create mode 100644 reactos/drivers/usb/cromwell/hub/usbhub.rc diff --git a/reactos/drivers/usb/cromwell/directory.xml b/reactos/drivers/usb/cromwell/directory.xml index eaa3fbbaaa7..af5453d66b3 100644 --- a/reactos/drivers/usb/cromwell/directory.xml +++ b/reactos/drivers/usb/cromwell/directory.xml @@ -7,6 +7,9 @@ + + + \ No newline at end of file diff --git a/reactos/drivers/usb/cromwell/hub/createclose.c b/reactos/drivers/usb/cromwell/hub/createclose.c new file mode 100644 index 00000000000..7001f24aad7 --- /dev/null +++ b/reactos/drivers/usb/cromwell/hub/createclose.c @@ -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; +} diff --git a/reactos/drivers/usb/cromwell/hub/fdo.c b/reactos/drivers/usb/cromwell/hub/fdo.c new file mode 100644 index 00000000000..0c1890b8d57 --- /dev/null +++ b/reactos/drivers/usb/cromwell/hub/fdo.c @@ -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; +} diff --git a/reactos/drivers/usb/cromwell/hub/hub.xml b/reactos/drivers/usb/cromwell/hub/hub.xml new file mode 100644 index 00000000000..1d67b40ae25 --- /dev/null +++ b/reactos/drivers/usb/cromwell/hub/hub.xml @@ -0,0 +1,16 @@ + + + + include + ../linux + sys_base + ntoskrnl + hal + usbcore + createclose.c + fdo.c + misc.c + pdo.c + usbhub.c + usbhub.rc + diff --git a/reactos/drivers/usb/cromwell/hub/misc.c b/reactos/drivers/usb/cromwell/hub/misc.c new file mode 100644 index 00000000000..16fcb331ff8 --- /dev/null +++ b/reactos/drivers/usb/cromwell/hub/misc.c @@ -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 + +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; +} diff --git a/reactos/drivers/usb/cromwell/hub/pdo.c b/reactos/drivers/usb/cromwell/hub/pdo.c new file mode 100644 index 00000000000..20274c12354 --- /dev/null +++ b/reactos/drivers/usb/cromwell/hub/pdo.c @@ -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; +} + diff --git a/reactos/drivers/usb/cromwell/hub/usbhub.c b/reactos/drivers/usb/cromwell/hub/usbhub.c new file mode 100644 index 00000000000..89c5af4b9b6 --- /dev/null +++ b/reactos/drivers/usb/cromwell/hub/usbhub.c @@ -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; +} + diff --git a/reactos/drivers/usb/cromwell/hub/usbhub.h b/reactos/drivers/usb/cromwell/hub/usbhub.h new file mode 100644 index 00000000000..4d402d9480b --- /dev/null +++ b/reactos/drivers/usb/cromwell/hub/usbhub.h @@ -0,0 +1,82 @@ +#include + +#include +#include + +#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); diff --git a/reactos/drivers/usb/cromwell/hub/usbhub.rc b/reactos/drivers/usb/cromwell/hub/usbhub.rc new file mode 100644 index 00000000000..92314b2b0ce --- /dev/null +++ b/reactos/drivers/usb/cromwell/hub/usbhub.rc @@ -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 diff --git a/reactos/drivers/usb/cromwell/usb_wrapper.h b/reactos/drivers/usb/cromwell/usb_wrapper.h index 2e99e4c1855..9d3ad6ae9ff 100644 --- a/reactos/drivers/usb/cromwell/usb_wrapper.h +++ b/reactos/drivers/usb/cromwell/usb_wrapper.h @@ -26,3 +26,5 @@ int swprintf(wchar_t *buf, const wchar_t *fmt, ...); #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) diff --git a/reactos/drivers/usb/directory.xml b/reactos/drivers/usb/directory.xml index 3c38d9b942b..04a748464ab 100644 --- a/reactos/drivers/usb/directory.xml +++ b/reactos/drivers/usb/directory.xml @@ -11,5 +11,5 @@ - - + +