mirror of
https://github.com/reactos/reactos.git
synced 2024-08-30 23:28:58 +00:00
Add usb hub driver. It is linked with cromwell usb stack
svn path=/trunk/; revision=15896
This commit is contained in:
parent
6b3ec8469e
commit
925b767f99
|
@ -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>
|
50
reactos/drivers/usb/cromwell/hub/createclose.c
Normal file
50
reactos/drivers/usb/cromwell/hub/createclose.c
Normal file
|
@ -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;
|
||||
}
|
180
reactos/drivers/usb/cromwell/hub/fdo.c
Normal file
180
reactos/drivers/usb/cromwell/hub/fdo.c
Normal file
|
@ -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;
|
||||
}
|
16
reactos/drivers/usb/cromwell/hub/hub.xml
Normal file
16
reactos/drivers/usb/cromwell/hub/hub.xml
Normal file
|
@ -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>
|
166
reactos/drivers/usb/cromwell/hub/misc.c
Normal file
166
reactos/drivers/usb/cromwell/hub/misc.c
Normal file
|
@ -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;
|
||||
}
|
78
reactos/drivers/usb/cromwell/hub/pdo.c
Normal file
78
reactos/drivers/usb/cromwell/hub/pdo.c
Normal file
|
@ -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;
|
||||
}
|
||||
|
192
reactos/drivers/usb/cromwell/hub/usbhub.c
Normal file
192
reactos/drivers/usb/cromwell/hub/usbhub.c
Normal file
|
@ -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;
|
||||
}
|
||||
|
82
reactos/drivers/usb/cromwell/hub/usbhub.h
Normal file
82
reactos/drivers/usb/cromwell/hub/usbhub.h
Normal file
|
@ -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);
|
5
reactos/drivers/usb/cromwell/hub/usbhub.rc
Normal file
5
reactos/drivers/usb/cromwell/hub/usbhub.rc
Normal file
|
@ -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>
|
|
@ -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)
|
||||
|
|
|
@ -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-->
|
||||
|
|
Loading…
Reference in a new issue