/* * ReactOS USB hub driver * Copyright (C) 2004 Aleksey Bragin * (C) 2005 Mark Tempel * (C) 2005 Herv� Poussineau * (C) 2010 Michael Martin * * 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., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * */ /* INCLUDES *******************************************************************/ //#define NDEBUG #include "usbhub.h" /* PUBLIC AND PRIVATE FUNCTIONS ***********************************************/ NTSTATUS NTAPI 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, 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; //Status = IoAttachDeviceToDeviceStackSafe(Fdo, Pdo, &DeviceExtension->LowerDevice); DeviceExtension->LowerDevice = IoAttachDeviceToDeviceStack(Fdo, Pdo); 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 NTAPI 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); 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 NTAPI DispatchDeviceControl(PDEVICE_OBJECT DeviceObject, PIRP Irp) { DPRINT1("Usbhub: DispatchDeviceControl\n"); if (((PHUB_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->IsFDO) return UsbhubDeviceControlFdo(DeviceObject, Irp); else return IrpStub(DeviceObject, Irp); } static NTSTATUS NTAPI DispatchInternalDeviceControl(PDEVICE_OBJECT DeviceObject, PIRP Irp) { DPRINT1("Usbhub: DispatchInternalDeviceControl\n"); if (((PHUB_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->IsFDO) return IrpStub(DeviceObject, Irp); else return UsbhubInternalDeviceControlPdo(DeviceObject, Irp); } static NTSTATUS NTAPI DispatchPnp(PDEVICE_OBJECT DeviceObject, PIRP Irp) { DPRINT1("Usbhub: DispatchPnp\n"); if (((PHUB_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->IsFDO) return UsbhubPnpFdo(DeviceObject, Irp); else return UsbhubPnpPdo(DeviceObject, Irp); } /* * Standard DriverEntry method. */ NTSTATUS NTAPI DriverEntry( IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath) { ULONG i; DriverObject->DriverExtension->AddDevice = UsbhubAddDevice; DPRINT1("Usbhub: DriverEntry\n"); 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_INTERNAL_DEVICE_CONTROL] = DispatchInternalDeviceControl; DriverObject->MajorFunction[IRP_MJ_PNP] = DispatchPnp; return STATUS_SUCCESS; }