2005-06-13 20:41:59 +00:00
|
|
|
|
/*
|
|
|
|
|
* ReactOS USB hub driver
|
|
|
|
|
* Copyright (C) 2004 Aleksey Bragin
|
|
|
|
|
* (C) 2005 Mark Tempel
|
2010-09-05 19:00:37 +00:00
|
|
|
|
* (C) 2005 Herv<EFBFBD> Poussineau
|
|
|
|
|
* (C) 2010 Michael Martin
|
2005-06-13 20:41:59 +00:00
|
|
|
|
*
|
|
|
|
|
* 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.
|
|
|
|
|
*
|
2009-10-27 10:34:16 +00:00
|
|
|
|
* 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.,
|
|
|
|
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
2005-06-13 20:41:59 +00:00
|
|
|
|
*
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
/* INCLUDES *******************************************************************/
|
|
|
|
|
//#define NDEBUG
|
|
|
|
|
#include "usbhub.h"
|
|
|
|
|
|
|
|
|
|
/* PUBLIC AND PRIVATE FUNCTIONS ***********************************************/
|
|
|
|
|
|
2008-11-30 11:16:55 +00:00
|
|
|
|
NTSTATUS NTAPI
|
2005-06-13 20:41:59 +00:00
|
|
|
|
UsbhubAddDevice(
|
2010-09-05 19:00:37 +00:00
|
|
|
|
IN PDRIVER_OBJECT DriverObject,
|
|
|
|
|
IN PDEVICE_OBJECT Pdo)
|
2005-06-13 20:41:59 +00:00
|
|
|
|
{
|
2010-09-05 19:00:37 +00:00
|
|
|
|
PDEVICE_OBJECT Fdo;
|
|
|
|
|
PHUB_DEVICE_EXTENSION DeviceExtension;
|
|
|
|
|
NTSTATUS Status;
|
|
|
|
|
|
|
|
|
|
Status = IoCreateDevice(DriverObject,
|
|
|
|
|
sizeof(HUB_DEVICE_EXTENSION),
|
|
|
|
|
NULL, /* DeviceName */
|
|
|
|
|
FILE_DEVICE_BUS_EXTENDER,
|
|
|
|
|
FILE_AUTOGENERATED_DEVICE_NAME,
|
|
|
|
|
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));
|
|
|
|
|
|
|
|
|
|
DeviceExtension->IsFDO = TRUE;
|
|
|
|
|
Fdo->Flags |= DO_POWER_PAGABLE;
|
2010-09-14 12:04:15 +00:00
|
|
|
|
//Status = IoAttachDeviceToDeviceStackSafe(Fdo, Pdo, &DeviceExtension->LowerDevice);
|
|
|
|
|
DeviceExtension->LowerDevice = IoAttachDeviceToDeviceStack(Fdo, Pdo);
|
2010-09-05 19:00:37 +00:00
|
|
|
|
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;
|
2005-06-13 20:41:59 +00:00
|
|
|
|
}
|
|
|
|
|
|
2008-11-30 11:16:55 +00:00
|
|
|
|
static NTSTATUS NTAPI
|
2005-06-13 20:41:59 +00:00
|
|
|
|
IrpStub(
|
2010-09-05 19:00:37 +00:00
|
|
|
|
IN PDEVICE_OBJECT DeviceObject,
|
|
|
|
|
IN PIRP Irp)
|
2005-06-13 20:41:59 +00:00
|
|
|
|
{
|
2010-09-05 19:00:37 +00:00
|
|
|
|
NTSTATUS Status;
|
|
|
|
|
|
|
|
|
|
if (((PHUB_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->IsFDO)
|
|
|
|
|
{
|
|
|
|
|
DPRINT1("Usbhub: FDO stub for major function 0x%lx\n",
|
|
|
|
|
IoGetCurrentIrpStackLocation(Irp)->MajorFunction);
|
|
|
|
|
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);
|
2005-06-13 20:41:59 +00:00
|
|
|
|
#ifndef NDEBUG
|
2010-09-05 19:00:37 +00:00
|
|
|
|
DbgBreakPoint();
|
2005-06-13 20:41:59 +00:00
|
|
|
|
#endif
|
2010-09-05 19:00:37 +00:00
|
|
|
|
}
|
2005-06-13 20:41:59 +00:00
|
|
|
|
|
2010-09-05 19:00:37 +00:00
|
|
|
|
Status = Irp->IoStatus.Status;
|
|
|
|
|
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
|
|
|
|
return Status;
|
2005-06-13 20:41:59 +00:00
|
|
|
|
}
|
|
|
|
|
|
2008-11-30 11:16:55 +00:00
|
|
|
|
static NTSTATUS NTAPI
|
2005-06-13 20:41:59 +00:00
|
|
|
|
DispatchDeviceControl(PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
|
|
|
|
{
|
2010-09-05 19:00:37 +00:00
|
|
|
|
DPRINT1("Usbhub: DispatchDeviceControl\n");
|
|
|
|
|
if (((PHUB_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->IsFDO)
|
|
|
|
|
return UsbhubDeviceControlFdo(DeviceObject, Irp);
|
|
|
|
|
else
|
|
|
|
|
return IrpStub(DeviceObject, Irp);
|
2006-05-15 16:38:49 +00:00
|
|
|
|
}
|
|
|
|
|
|
2008-11-30 11:16:55 +00:00
|
|
|
|
static NTSTATUS NTAPI
|
2006-05-15 16:38:49 +00:00
|
|
|
|
DispatchInternalDeviceControl(PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
|
|
|
|
{
|
2010-09-05 19:00:37 +00:00
|
|
|
|
DPRINT1("Usbhub: DispatchInternalDeviceControl\n");
|
|
|
|
|
if (((PHUB_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->IsFDO)
|
|
|
|
|
return IrpStub(DeviceObject, Irp);
|
|
|
|
|
else
|
|
|
|
|
return UsbhubInternalDeviceControlPdo(DeviceObject, Irp);
|
2005-06-13 20:41:59 +00:00
|
|
|
|
}
|
|
|
|
|
|
2008-11-30 11:16:55 +00:00
|
|
|
|
static NTSTATUS NTAPI
|
2005-06-13 20:41:59 +00:00
|
|
|
|
DispatchPnp(PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
|
|
|
|
{
|
2010-09-05 19:00:37 +00:00
|
|
|
|
DPRINT1("Usbhub: DispatchPnp\n");
|
|
|
|
|
if (((PHUB_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->IsFDO)
|
|
|
|
|
return UsbhubPnpFdo(DeviceObject, Irp);
|
|
|
|
|
else
|
|
|
|
|
return UsbhubPnpPdo(DeviceObject, Irp);
|
2005-06-13 20:41:59 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Standard DriverEntry method.
|
|
|
|
|
*/
|
2008-11-30 11:16:55 +00:00
|
|
|
|
NTSTATUS NTAPI
|
2005-06-13 20:41:59 +00:00
|
|
|
|
DriverEntry(
|
2010-09-05 19:00:37 +00:00
|
|
|
|
IN PDRIVER_OBJECT DriverObject,
|
|
|
|
|
IN PUNICODE_STRING RegistryPath)
|
2005-06-13 20:41:59 +00:00
|
|
|
|
{
|
2010-09-05 19:00:37 +00:00
|
|
|
|
ULONG i;
|
2007-10-19 23:21:45 +00:00
|
|
|
|
|
2010-09-05 19:00:37 +00:00
|
|
|
|
DriverObject->DriverExtension->AddDevice = UsbhubAddDevice;
|
|
|
|
|
DPRINT1("Usbhub: DriverEntry\n");
|
2007-10-19 23:21:45 +00:00
|
|
|
|
|
2010-09-05 19:00:37 +00:00
|
|
|
|
for (i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++)
|
|
|
|
|
DriverObject->MajorFunction[i] = IrpStub;
|
2007-10-19 23:21:45 +00:00
|
|
|
|
|
2010-09-05 19:00:37 +00:00
|
|
|
|
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_INTERNAL_DEVICE_CONTROL] = DispatchInternalDeviceControl;
|
|
|
|
|
DriverObject->MajorFunction[IRP_MJ_PNP] = DispatchPnp;
|
2007-10-19 23:21:45 +00:00
|
|
|
|
|
2010-09-05 19:00:37 +00:00
|
|
|
|
return STATUS_SUCCESS;
|
2005-06-13 20:41:59 +00:00
|
|
|
|
}
|
|
|
|
|
|