[USBHUB]
[reactos.git] / reactos / drivers / usb / usbhub / usbhub.c
index 15e319d..f34c4e4 100644 (file)
 /*
- * 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.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
+ * PROJECT:         ReactOS Universal Serial Bus Hub Driver
+ * LICENSE:         GPL - See COPYING in the top level directory
+ * FILE:            drivers/usb/usbhub/fdo.c
+ * PURPOSE:         UsbHub Driver
+ * PROGRAMMERS:
+ *                  HervĂ© Poussineau (hpoussin@reactos.org)
+ *                  Michael Martin (michael.martin@reactos.org)
+ *                  Johannes Anderwald (johannes.anderwald@reactos.org)
  */
 
-/* INCLUDES *******************************************************************/
-//#define NDEBUG
 #include "usbhub.h"
 
-/* PUBLIC AND PRIVATE FUNCTIONS ***********************************************/
+NTSTATUS NTAPI
+USBHUB_Create(
+    IN PDEVICE_OBJECT DeviceObject,
+    IN PIRP Irp)
+{
+    DPRINT("USBHUB: IRP_MJ_CREATE\n");
 
-static NTSTATUS
-GetRootHubPointer(
-       IN PDEVICE_OBJECT Pdo,
-       OUT PVOID* RootHubPointer)
+    Irp->IoStatus.Status = STATUS_SUCCESS;
+    Irp->IoStatus.Information = 0;
+    IoCompleteRequest(Irp, IO_NO_INCREMENT);
+    return STATUS_SUCCESS;
+}
+
+NTSTATUS NTAPI
+USBHUB_Close(
+    IN PDEVICE_OBJECT DeviceObject,
+    IN PIRP Irp)
 {
-       KEVENT Event;
-       PIRP Irp;
-       IO_STATUS_BLOCK IoStatus;
-       NTSTATUS Status;
-
-       KeInitializeEvent (&Event, NotificationEvent, FALSE);
-
-       Irp = IoBuildDeviceIoControlRequest(IOCTL_INTERNAL_USB_GET_PARENT_HUB_INFO,
-               Pdo,
-               NULL, sizeof(NULL),
-               RootHubPointer, sizeof(*RootHubPointer),
-               FALSE,
-               &Event,
-               &IoStatus);
-       if (Irp == NULL)
-       {
-               DPRINT("Usbhub: IoBuildDeviceIoControlRequest() failed\n");
-               return STATUS_INSUFFICIENT_RESOURCES;
-       }
-
-       /* Initialize the status block before sending the IRP */
-       IoGetNextIrpStackLocation(Irp)->MajorFunction = IRP_MJ_INTERNAL_DEVICE_CONTROL;
-       IoStatus.Status = STATUS_NOT_SUPPORTED;
-       IoStatus.Information = 0;
-
-       Status = IoCallDriver(Pdo, Irp);
-
-       if (Status == STATUS_PENDING)
-       {
-               DPRINT("Usbhub: Operation pending\n");
-               KeWaitForSingleObject(&Event, Suspended, KernelMode, FALSE, NULL);
-               Status = IoStatus.Status;
-       }
-
-       return Status;
+    DPRINT("USBHUB: IRP_MJ_CLOSE\n");
+
+    Irp->IoStatus.Status = STATUS_SUCCESS;
+    Irp->IoStatus.Information = 0;
+    IoCompleteRequest(Irp, IO_NO_INCREMENT);
+    return STATUS_SUCCESS;
 }
 
 NTSTATUS NTAPI
-UsbhubAddDevice(
-       IN PDRIVER_OBJECT DriverObject,
-       IN PDEVICE_OBJECT Pdo)
+USBHUB_Cleanup(
+    IN PDEVICE_OBJECT DeviceObject,
+    IN PIRP Irp)
 {
-       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_PARENT_HUB_INFO 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->dev->dev.dev_ext = Pdo;
-
-       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;
+    DPRINT("USBHUB: IRP_MJ_CLEANUP\n");
+
+    Irp->IoStatus.Status = STATUS_SUCCESS;
+    Irp->IoStatus.Information = 0;
+    IoCompleteRequest(Irp, IO_NO_INCREMENT);
+    return STATUS_SUCCESS;
 }
 
-static NTSTATUS NTAPI
-IrpStub(
-       IN PDEVICE_OBJECT DeviceObject,
-       IN PIRP Irp)
+
+NTSTATUS NTAPI
+USBHUB_AddDevice(
+    IN PDRIVER_OBJECT DriverObject,
+    IN PDEVICE_OBJECT PhysicalDeviceObject)
 {
-       NTSTATUS Status;
+    PDEVICE_OBJECT DeviceObject;
+    PHUB_DEVICE_EXTENSION HubDeviceExtension;
+    NTSTATUS Status;
+    DPRINT("USBHUB: AddDevice\n");
+    //
+    // Create the Device Object
+    //
+    Status = IoCreateDevice(DriverObject,
+                            sizeof(HUB_DEVICE_EXTENSION),
+                            NULL,
+                            FILE_DEVICE_BUS_EXTENDER,
+                            FILE_AUTOGENERATED_DEVICE_NAME,
+                            FALSE,
+                            &DeviceObject);
+
+    if (!NT_SUCCESS(Status))
+    {
+        DPRINT1("USBHUB: IoCreateDevice() failed with status 0x%08lx\n", Status);
+        return Status;
+    }
+
+    //
+    // Zero Hub Extension
+    //
+    HubDeviceExtension = (PHUB_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
+    RtlZeroMemory(HubDeviceExtension, sizeof(HUB_DEVICE_EXTENSION));
+
+    //
+    // Set this to Fdo
+    //
+    HubDeviceExtension->Common.IsFDO = TRUE;
+    DeviceObject->Flags |= DO_POWER_PAGABLE;
+
+    //
+    // initialize reset complete event
+    //
+    KeInitializeEvent(&HubDeviceExtension->ResetComplete, NotificationEvent, FALSE);
+
+    //
+    // Attached to lower device
+    //
+    //Status = IoAttachDeviceToDeviceStackSafe(Fdo, Pdo, &DeviceExtension->LowerDevice);
+    HubDeviceExtension->LowerDeviceObject = IoAttachDeviceToDeviceStack(DeviceObject, PhysicalDeviceObject);
+    if (!NT_SUCCESS(Status))
+    {
+        DPRINT1("USBHUB: IoAttachDeviceToDeviceStackSafe() failed with status 0x%08lx\n", Status);
+        IoDeleteDevice(DeviceObject);
+        return Status;
+    }
+
+    DeviceObject->Flags |= DO_BUFFERED_IO;
+    DeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
+
+    return STATUS_SUCCESS;
+}
 
-       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);
+static NTSTATUS NTAPI
+USBHUB_IrpStub(
+    IN PDEVICE_OBJECT DeviceObject,
+    IN PIRP Irp)
+{
+    NTSTATUS Status;
+
+    if (((PHUB_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->Common.IsFDO)
+    {
+        DPRINT1("Usbhub: FDO stub for major function 0x%lx\n",
+            IoGetCurrentIrpStackLocation(Irp)->MajorFunction);
+        return ForwardIrpAndForget(DeviceObject, Irp);
+    }
+    else
+    {
+        //
+        // Cant forward as we are the PDO!
+        //
+        DPRINT1("USBHUB: ERROR- PDO stub for major function 0x%lx\n",
+            IoGetCurrentIrpStackLocation(Irp)->MajorFunction);
 #ifndef NDEBUG
-               DbgBreakPoint();
+        DbgBreakPoint();
 #endif
-       }
+    }
 
-       Status = Irp->IoStatus.Status;
-       IoCompleteRequest(Irp, IO_NO_INCREMENT);
-       return Status;
+    Status = Irp->IoStatus.Status;
+    IoCompleteRequest(Irp, IO_NO_INCREMENT);
+    return Status;
 }
 
-static NTSTATUS NTAPI
-DispatchDeviceControl(PDEVICE_OBJECT DeviceObject, PIRP Irp)
+
+NTSTATUS NTAPI
+USBHUB_DispatchDeviceControl(
+    PDEVICE_OBJECT DeviceObject,
+    PIRP Irp)
 {
-       if (((PHUB_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->IsFDO)
-               return UsbhubDeviceControlFdo(DeviceObject, Irp);
-       else
-               return IrpStub(DeviceObject, Irp);
+    DPRINT("Usbhub: DispatchDeviceControl\n");
+    if (((PHUB_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->Common.IsFDO)
+        return USBHUB_FdoHandleDeviceControl(DeviceObject, Irp);
+    else
+        return USBHUB_IrpStub(DeviceObject, Irp);
 }
 
-static NTSTATUS NTAPI
-DispatchInternalDeviceControl(PDEVICE_OBJECT DeviceObject, PIRP Irp)
+NTSTATUS NTAPI
+USBHUB_DispatchInternalDeviceControl(
+    PDEVICE_OBJECT DeviceObject,
+    PIRP Irp)
 {
-       if (((PHUB_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->IsFDO)
-               return IrpStub(DeviceObject, Irp);
-       else
-               return UsbhubInternalDeviceControlPdo(DeviceObject, Irp);
+    DPRINT("Usbhub: DispatchInternalDeviceControl\n");
+    if (((PHUB_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->Common.IsFDO)
+        return USBHUB_IrpStub(DeviceObject, Irp);
+    else
+        return USBHUB_PdoHandleInternalDeviceControl(DeviceObject, Irp);
 }
 
-static NTSTATUS NTAPI
-DispatchPnp(PDEVICE_OBJECT DeviceObject, PIRP Irp)
+NTSTATUS NTAPI
+USBHUB_DispatchPnp(
+    PDEVICE_OBJECT DeviceObject,
+    PIRP Irp)
 {
-       if (((PHUB_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->IsFDO)
-               return UsbhubPnpFdo(DeviceObject, Irp);
-       else
-               return UsbhubPnpPdo(DeviceObject, Irp);
+    DPRINT("USBHUB: DispatchPnp\n");
+    if (((PHUB_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->Common.IsFDO)
+        return USBHUB_FdoHandlePnp(DeviceObject, Irp);
+    else
+        return USBHUB_PdoHandlePnp(DeviceObject, Irp);
 }
 
-/*
- * Standard DriverEntry method.
- */
 NTSTATUS NTAPI
-DriverEntry(
-       IN PDRIVER_OBJECT DriverObject,
-       IN PUNICODE_STRING RegistryPath)
+USBHUB_DispatchPower(
+    PDEVICE_OBJECT DeviceObject,
+    PIRP Irp)
 {
-       ULONG i;
+    PIO_STACK_LOCATION IoStack;
+
+    IoStack = IoGetCurrentIrpStackLocation(Irp);
+    DPRINT1("Power Function %x\n", IoStack->MinorFunction);
+
+    if (IoStack->MinorFunction == IRP_MN_SET_POWER)
+    {
+        PoStartNextPowerIrp(Irp);
+        Irp->IoStatus.Status = STATUS_SUCCESS;
+        IoCompleteRequest(Irp, IO_NO_INCREMENT);
+        return STATUS_SUCCESS;
+
+    }
+    else if (IoStack->MinorFunction == IRP_MN_QUERY_POWER)
+    {
+        PoStartNextPowerIrp(Irp);
+        Irp->IoStatus.Status = STATUS_SUCCESS;
+        IoCompleteRequest(Irp, IO_NO_INCREMENT);
+        return STATUS_SUCCESS;
+
+    }
+    else if (IoStack->MinorFunction == IRP_MN_WAIT_WAKE)
+    {
+        PoStartNextPowerIrp(Irp);
+        Irp->IoStatus.Status = STATUS_SUCCESS;
+        IoCompleteRequest(Irp, IO_NO_INCREMENT);
+        return STATUS_SUCCESS;
+    }
+
+    PoStartNextPowerIrp(Irp);
+    Irp->IoStatus.Status = STATUS_SUCCESS;
+    IoCompleteRequest(Irp, IO_NO_INCREMENT);
+    return STATUS_SUCCESS;
+}
+
+VOID
+NTAPI
+USBHUB_Unload(
+    IN PDRIVER_OBJECT DriverObject)
+{
+    UNIMPLEMENTED
+}
 
-       DriverObject->DriverExtension->AddDevice = UsbhubAddDevice;
 
-       for (i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++)
-               DriverObject->MajorFunction[i] = IrpStub;
+NTSTATUS NTAPI
+DriverEntry(
+    IN PDRIVER_OBJECT DriverObject,
+    IN PUNICODE_STRING RegistryPath)
+{
+    DriverObject->DriverExtension->AddDevice = USBHUB_AddDevice;
+    DriverObject->DriverUnload = USBHUB_Unload;
+
+    DPRINT("USBHUB: DriverEntry\n");
 
-       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;
+    DriverObject->MajorFunction[IRP_MJ_CREATE] = USBHUB_Create;
+    DriverObject->MajorFunction[IRP_MJ_CLOSE] = USBHUB_Close;
+    DriverObject->MajorFunction[IRP_MJ_CLEANUP] = USBHUB_Cleanup;
+    DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = USBHUB_DispatchDeviceControl;
+    DriverObject->MajorFunction[IRP_MJ_INTERNAL_DEVICE_CONTROL] = USBHUB_DispatchInternalDeviceControl;
+    DriverObject->MajorFunction[IRP_MJ_PNP] = USBHUB_DispatchPnp;
+    DriverObject->MajorFunction[IRP_MJ_POWER] =USBHUB_DispatchPower;
 
-       return STATUS_SUCCESS;
+    return STATUS_SUCCESS;
 }