[USBCCGP]
authorJohannes Anderwald <johannes.anderwald@reactos.org>
Thu, 26 Jan 2012 03:42:56 +0000 (03:42 +0000)
committerJohannes Anderwald <johannes.anderwald@reactos.org>
Thu, 26 Jan 2012 03:42:56 +0000 (03:42 +0000)
- Start implement USB Composite generic parent driver which is used for USB composite devices
- Start implement FDO initialization, needs to implement parsing of usb interface assocaition descriptor to complete FDO initialization

svn path=/branches/usb-bringup-trunk/; revision=55195

drivers/usb/CMakeLists.txt
drivers/usb/usbccgp/CMakeLists.txt [new file with mode: 0644]
drivers/usb/usbccgp/descriptor.c [new file with mode: 0644]
drivers/usb/usbccgp/fdo.c [new file with mode: 0644]
drivers/usb/usbccgp/pdo.c [new file with mode: 0644]
drivers/usb/usbccgp/usbccgp.c [new file with mode: 0644]
drivers/usb/usbccgp/usbccgp.h [new file with mode: 0644]
drivers/usb/usbccgp/usbccgp.rc [new file with mode: 0644]

index f88abfc..48be424 100644 (file)
@@ -1,3 +1,4 @@
+add_subdirectory(usbccgp)
 add_subdirectory(usbd)
 add_subdirectory(usbehci_new)
 add_subdirectory(usbhub_new)
diff --git a/drivers/usb/usbccgp/CMakeLists.txt b/drivers/usb/usbccgp/CMakeLists.txt
new file mode 100644 (file)
index 0000000..ab3c4c4
--- /dev/null
@@ -0,0 +1,13 @@
+
+add_definitions(-DDEBUG_MODE)
+
+include_directories(${REACTOS_SOURCE_DIR}/ntoskrnl/include)
+
+add_library(usbccgp SHARED descriptor.c fdo.c misc.c pdo.c usbccgp.c usbccgp.rc)
+
+target_link_libraries(usbccgp ${PSEH_LIB})
+
+set_module_type(usbccgp kernelmodedriver)
+add_importlibs(usbccgp ntoskrnl hal usbd)
+
+add_cd_file(TARGET usbccgp DESTINATION reactos/system32/drivers NO_CAB FOR all)
diff --git a/drivers/usb/usbccgp/descriptor.c b/drivers/usb/usbccgp/descriptor.c
new file mode 100644 (file)
index 0000000..9d7df06
--- /dev/null
@@ -0,0 +1,386 @@
+/*
+ * PROJECT:     ReactOS Universal Serial Bus Bulk Enhanced Host Controller Interface
+ * LICENSE:     GPL - See COPYING in the top level directory
+ * FILE:        drivers/usb/usbccgp/descriptor.c
+ * PURPOSE:     USB  device driver.
+ * PROGRAMMERS:
+ *              Michael Martin (michael.martin@reactos.org)
+ *              Johannes Anderwald (johannes.anderwald@reactos.org)
+ *              Cameron Gutman
+ */
+
+#include "usbccgp.h"
+
+NTSTATUS
+NTAPI
+USBCCGP_GetDescriptor(
+    IN PDEVICE_OBJECT DeviceObject,
+    IN UCHAR DescriptorType,
+    IN ULONG DescriptorLength,
+    IN UCHAR DescriptorIndex,
+    IN LANGID LanguageId,
+    OUT PVOID *OutDescriptor)
+{
+    PURB Urb;
+    NTSTATUS Status;
+    PVOID Descriptor;
+
+    //
+    // sanity checks
+    //
+    ASSERT(DeviceObject);
+    ASSERT(OutDescriptor);
+    ASSERT(DescriptorLength);
+
+    //
+    // first allocate descriptor buffer
+    //
+    Descriptor = AllocateItem(NonPagedPool, DescriptorLength);
+    if (!Descriptor)
+    {
+        //
+        // no memory
+        //
+        return STATUS_INSUFFICIENT_RESOURCES;
+    }
+
+    //
+    // allocate urb
+    //
+    Urb = (PURB) AllocateItem(NonPagedPool, sizeof(URB));
+    if (!Urb)
+    {
+        //
+        // no memory
+        //
+        FreeItem(Descriptor);
+        return STATUS_INSUFFICIENT_RESOURCES;
+    }
+
+    //
+    // initialize urb
+    //
+    UsbBuildGetDescriptorRequest(Urb,
+                                 sizeof(Urb->UrbControlDescriptorRequest),
+                                 DescriptorType,
+                                 DescriptorIndex,
+                                 LanguageId,
+                                 Descriptor,
+                                 NULL,
+                                 DescriptorLength,
+                                 NULL);
+
+    //
+    // submit urb
+    //
+    Status = USBCCGP_SyncUrbRequest(DeviceObject, Urb);
+
+    //
+    // free urb
+    //
+    FreeItem(Urb);
+
+    if (NT_SUCCESS(Status))
+    {
+        //
+        // store result
+        //
+        *OutDescriptor = Descriptor;
+    }
+
+    //
+    // done
+    //
+    return Status;
+}
+
+
+NTSTATUS
+USBCCGP_GetDescriptors(
+    IN PDEVICE_OBJECT DeviceObject)
+{
+    NTSTATUS Status;
+    PFDO_DEVICE_EXTENSION DeviceExtension;
+    USHORT DescriptorLength;
+
+    //
+    // get device extension
+    //
+    DeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
+
+     //
+     // first get device descriptor
+     //
+     Status = USBCCGP_GetDescriptor(DeviceExtension->NextDeviceObject, USB_DEVICE_DESCRIPTOR_TYPE, sizeof(USB_DEVICE_DESCRIPTOR), 0, 0, (PVOID*)&DeviceExtension->DeviceDescriptor);
+     if (!NT_SUCCESS(Status))
+     {
+         //
+         // failed to get device descriptor
+         //
+         DeviceExtension->DeviceDescriptor = NULL;
+         return Status;
+     }
+
+     //
+     // now get basic configuration descriptor
+     //
+     Status = USBCCGP_GetDescriptor(DeviceExtension->NextDeviceObject, USB_CONFIGURATION_DESCRIPTOR_TYPE, sizeof(USB_CONFIGURATION_DESCRIPTOR), 0, 0, (PVOID*)&DeviceExtension->ConfigurationDescriptor);
+     if (!NT_SUCCESS(Status))
+     {
+         //
+         // failed to get configuration descriptor
+         //
+         FreeItem(DeviceExtension->DeviceDescriptor);
+         DeviceExtension->DeviceDescriptor = NULL;
+         return Status;
+     }
+
+     //
+     // backup length
+     //
+     DescriptorLength = DeviceExtension->ConfigurationDescriptor->wTotalLength;
+
+     //
+     // release basic descriptor
+     //
+     FreeItem(DeviceExtension->ConfigurationDescriptor);
+     DeviceExtension->ConfigurationDescriptor = NULL;
+
+     //
+     // allocate full descriptor
+     //
+     Status = USBCCGP_GetDescriptor(DeviceExtension->NextDeviceObject, USB_CONFIGURATION_DESCRIPTOR_TYPE, DescriptorLength, 0, 0, (PVOID*)&DeviceExtension->ConfigurationDescriptor);
+     if (!NT_SUCCESS(Status))
+     {
+         //
+         // failed to get configuration descriptor
+         //
+         FreeItem(DeviceExtension->DeviceDescriptor);
+         DeviceExtension->DeviceDescriptor = NULL;
+         return Status;
+     }
+     return Status;
+}
+
+NTSTATUS
+NTAPI
+USBCCGP_ScanConfigurationDescriptor(
+    IN OUT PFDO_DEVICE_EXTENSION FDODeviceExtension,
+    IN PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor)
+{
+    PUSB_INTERFACE_DESCRIPTOR InterfaceDescriptor;
+    ULONG InterfaceIndex = 0;
+
+    //
+    // sanity checks
+    //
+    ASSERT(ConfigurationDescriptor);
+    ASSERT(ConfigurationDescriptor->bNumInterfaces);
+
+    //
+    // allocate array holding the interface descriptors
+    //
+    FDODeviceExtension->InterfaceList = AllocateItem(NonPagedPool, sizeof(USB_CONFIGURATION_DESCRIPTOR) * (ConfigurationDescriptor->bNumInterfaces + 1));
+    if (!FDODeviceExtension->InterfaceList)
+    {
+        //
+        // no memory
+        //
+        return STATUS_INSUFFICIENT_RESOURCES;
+    }
+
+    do
+    {
+        //
+        // parse configuration descriptor
+        //
+        InterfaceDescriptor = USBD_ParseConfigurationDescriptorEx(ConfigurationDescriptor, ConfigurationDescriptor, InterfaceIndex, 0, -1, -1, -1);
+        if (InterfaceDescriptor)
+        {
+            //
+            // store in interface list
+            //
+            FDODeviceExtension->InterfaceList[FDODeviceExtension->InterfaceListCount].InterfaceDescriptor = InterfaceDescriptor;
+            FDODeviceExtension->InterfaceListCount++;
+        }
+
+        //
+        // move to next interface
+        //
+        InterfaceIndex++;
+
+    }while(InterfaceIndex < ConfigurationDescriptor->bNumInterfaces);
+
+    //
+    // sanity check
+    //
+    ASSERT(FDODeviceExtension->InterfaceListCount);
+
+    //
+    // done
+    //
+    return STATUS_SUCCESS;
+}
+
+VOID
+DumpConfigurationDescriptor(PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor)
+{
+    DPRINT1("Dumping ConfigurationDescriptor %x\n", ConfigurationDescriptor);
+    DPRINT1("bLength %x\n", ConfigurationDescriptor->bLength);
+    DPRINT1("bDescriptorType %x\n", ConfigurationDescriptor->bDescriptorType);
+    DPRINT1("wTotalLength %x\n", ConfigurationDescriptor->wTotalLength);
+    DPRINT1("bNumInterfaces %x\n", ConfigurationDescriptor->bNumInterfaces);
+    DPRINT1("bConfigurationValue %x\n", ConfigurationDescriptor->bConfigurationValue);
+    DPRINT1("iConfiguration %x\n", ConfigurationDescriptor->iConfiguration);
+    DPRINT1("bmAttributes %x\n", ConfigurationDescriptor->bmAttributes);
+    DPRINT1("MaxPower %x\n", ConfigurationDescriptor->MaxPower);
+}
+
+NTSTATUS
+USBCCGP_SelectInterface(
+    IN PDEVICE_OBJECT DeviceObject,
+    IN PFDO_DEVICE_EXTENSION DeviceExtension,
+    IN ULONG InterfaceIndex)
+{
+    NTSTATUS Status;
+    PURB Urb;
+
+    //
+    // allocate urb
+    //
+    Urb = AllocateItem(NonPagedPool, sizeof(struct _URB_SELECT_INTERFACE));
+    if (!Urb)
+    {
+        //
+        // no memory
+        //
+        return STATUS_INSUFFICIENT_RESOURCES;
+    }
+
+    //
+    // now prepare interface urb
+    //
+    UsbBuildSelectInterfaceRequest(Urb, GET_SELECT_INTERFACE_REQUEST_SIZE(DeviceExtension->InterfaceList[InterfaceIndex].InterfaceDescriptor->bNumEndpoints), DeviceExtension->ConfigurationHandle, DeviceExtension->InterfaceList[InterfaceIndex].InterfaceDescriptor->bInterfaceNumber, DeviceExtension->InterfaceList[InterfaceIndex].InterfaceDescriptor->bAlternateSetting);
+
+    //
+    // copy interface information structure back - as offset for SelectConfiguration / SelectInterface request do differ
+    //
+    RtlCopyMemory(&Urb->UrbSelectInterface.Interface, DeviceExtension->InterfaceList[InterfaceIndex].Interface, DeviceExtension->InterfaceList[InterfaceIndex].Interface->Length);
+
+    //
+    // now select the interface
+    //
+    Status = USBCCGP_SyncUrbRequest(DeviceExtension->NextDeviceObject, Urb);
+
+    //
+    // did it succeeed
+    //
+    if (NT_SUCCESS(Status))
+    {
+        //
+        // update configuration info
+        //
+        ASSERT(Urb->UrbSelectInterface.Interface.Length == DeviceExtension->InterfaceList[InterfaceIndex].Interface->Length);
+        RtlCopyMemory(DeviceExtension->InterfaceList[InterfaceIndex].Interface, &Urb->UrbSelectInterface.Interface, Urb->UrbSelectInterface.Interface.Length);
+    }
+
+    //
+    // free urb
+    //
+    FreeItem(Urb);
+
+    //
+    // done
+    //
+    return Status;
+}
+
+NTSTATUS
+USBCCGP_SelectConfiguration(
+    IN PDEVICE_OBJECT DeviceObject,
+    IN PFDO_DEVICE_EXTENSION DeviceExtension)
+{
+    PUSBD_INTERFACE_INFORMATION InterfaceInformation;
+    NTSTATUS Status;
+    PURB Urb;
+    ULONG Index;
+
+    //
+    // now scan configuration descriptors
+    //
+    Status = USBCCGP_ScanConfigurationDescriptor(DeviceExtension, DeviceExtension->ConfigurationDescriptor);
+    if (!NT_SUCCESS(Status))
+    {
+        //
+        // failed to scan
+        //
+        return Status;
+    }
+
+    //
+    // now allocate the urb
+    //
+    Urb = USBD_CreateConfigurationRequestEx(DeviceExtension->ConfigurationDescriptor, DeviceExtension->InterfaceList);
+    if (!Urb)
+    {
+        //
+        // no memory
+        //
+        return STATUS_INSUFFICIENT_RESOURCES;
+    }
+
+    //
+    // submit urb
+    //
+    Status = USBCCGP_SyncUrbRequest(DeviceExtension->NextDeviceObject, Urb);
+    if (!NT_SUCCESS(Status))
+    {
+        //
+        // failed to set configuration
+        //
+        DPRINT1("USBCCGP_SyncUrbRequest failed to set interface %x\n", Status);
+        ExFreePool(Urb);
+        return Status;
+    }
+
+    //
+    // get interface information
+    //
+    InterfaceInformation = &Urb->UrbSelectConfiguration.Interface;
+
+    for(Index = 0; Index < DeviceExtension->InterfaceListCount; Index++)
+    {
+        //
+        // allocate buffer to store interface information
+        //
+        DeviceExtension->InterfaceList[Index].Interface = AllocateItem(NonPagedPool, InterfaceInformation[Index].Length);
+        if (!DeviceExtension->InterfaceList[Index].Interface)
+        {
+            //
+            // no memory
+            //
+            return STATUS_INSUFFICIENT_RESOURCES;
+        }
+
+        //
+        // copy interface information
+        //
+        RtlCopyMemory(DeviceExtension->InterfaceList[Index].Interface, InterfaceInformation, InterfaceInformation->Length);
+    }
+
+    //
+    // store pipe handle
+    //
+    DeviceExtension->ConfigurationHandle = Urb->UrbSelectConfiguration.ConfigurationHandle;
+
+    //
+    // free interface list & urb
+    //
+    ExFreePool(Urb);
+
+    //
+    // done
+    //
+    return Status;
+}
+
diff --git a/drivers/usb/usbccgp/fdo.c b/drivers/usb/usbccgp/fdo.c
new file mode 100644 (file)
index 0000000..61c978d
--- /dev/null
@@ -0,0 +1,289 @@
+/*
+ * PROJECT:     ReactOS Universal Serial Bus Bulk Enhanced Host Controller Interface
+ * LICENSE:     GPL - See COPYING in the top level directory
+ * FILE:        drivers/usb/usbccgp/fdo.c
+ * PURPOSE:     USB  device driver.
+ * PROGRAMMERS:
+ *              Michael Martin (michael.martin@reactos.org)
+ *              Johannes Anderwald (johannes.anderwald@reactos.org)
+ *              Cameron Gutman
+ */
+
+#include "usbccgp.h"
+
+NTSTATUS
+NTAPI
+FDO_QueryCapabilitiesCompletionRoutine(
+    IN PDEVICE_OBJECT DeviceObject,
+    IN PIRP Irp,
+    IN PVOID Context)
+{
+    //
+    // set event
+    //
+    KeSetEvent((PRKEVENT)Context, 0, FALSE);
+
+    //
+    // completion is done in the HidClassFDO_QueryCapabilities routine
+    //
+    return STATUS_MORE_PROCESSING_REQUIRED;
+}
+
+NTSTATUS
+FDO_QueryCapabilities(
+    IN PDEVICE_OBJECT DeviceObject,
+    IN OUT PDEVICE_CAPABILITIES Capabilities)
+{
+    PIRP Irp;
+    KEVENT Event;
+    NTSTATUS Status;
+    PIO_STACK_LOCATION IoStack;
+    PFDO_DEVICE_EXTENSION FDODeviceExtension;
+
+    //
+    // get device extension
+    //
+    FDODeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
+    ASSERT(FDODeviceExtension->Common.IsFDO);
+
+    //
+    // init event
+    //
+    KeInitializeEvent(&Event, NotificationEvent, FALSE);
+
+    //
+    // now allocte the irp
+    //
+    Irp = IoAllocateIrp(DeviceObject->StackSize, FALSE);
+    if (!Irp)
+    {
+        //
+        // no memory
+        //
+        return STATUS_INSUFFICIENT_RESOURCES;
+    }
+
+    //
+    // get next stack location
+    //
+    IoStack = IoGetNextIrpStackLocation(Irp);
+
+    //
+    // init stack location
+    //
+    IoStack->MajorFunction = IRP_MJ_PNP;
+    IoStack->MinorFunction = IRP_MN_QUERY_CAPABILITIES;
+    IoStack->Parameters.DeviceCapabilities.Capabilities = Capabilities;
+
+    //
+    // set completion routine
+    //
+    IoSetCompletionRoutine(Irp, FDO_QueryCapabilitiesCompletionRoutine, (PVOID)&Event, TRUE, TRUE, TRUE);
+
+    //
+    // init capabilities
+    //
+    RtlZeroMemory(Capabilities, sizeof(DEVICE_CAPABILITIES));
+    Capabilities->Size = sizeof(DEVICE_CAPABILITIES);
+    Capabilities->Version = 1; // FIXME hardcoded constant
+    Capabilities->Address = MAXULONG;
+    Capabilities->UINumber = MAXULONG;
+
+    //
+    // pnp irps have default completion code
+    //
+    Irp->IoStatus.Status = STATUS_NOT_SUPPORTED;
+
+    //
+    // call lower  device
+    //
+    Status = IoCallDriver(FDODeviceExtension->NextDeviceObject, Irp);
+    if (Status == STATUS_PENDING)
+    {
+        //
+        // wait for completion
+        //
+        KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
+    }
+
+    //
+    // get status
+    //
+    Status = Irp->IoStatus.Status;
+
+    //
+    // complete request
+    //
+    IoFreeIrp(Irp);
+
+    //
+    // done
+    //
+    return Status;
+}
+
+NTSTATUS
+FDO_DeviceRelations(
+    PDEVICE_OBJECT DeviceObject, 
+    PIRP Irp)
+{
+    UNIMPLEMENTED
+    ASSERT(FALSE);
+    return STATUS_NOT_IMPLEMENTED;
+}
+
+NTSTATUS
+FDO_StartDevice(
+    PDEVICE_OBJECT DeviceObject, 
+    PIRP Irp)
+{
+    NTSTATUS Status;
+    PFDO_DEVICE_EXTENSION FDODeviceExtension;
+
+    //
+    // get device extension
+    //
+    FDODeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
+    ASSERT(FDODeviceExtension->Common.IsFDO);
+
+    //
+    // first start lower device
+    //
+    Status = USBCCGP_SyncForwardIrp(FDODeviceExtension->NextDeviceObject, Irp);
+
+    if (!NT_SUCCESS(Status))
+    {
+        //
+        // failed to start lower device
+        //
+        DPRINT1("FDO_StartDevice lower device failed to start with %x\n", Status);
+        return Status;
+    }
+
+    // get descriptors
+    Status = USBCCGP_GetDescriptors(DeviceObject);
+    if (!NT_SUCCESS(Status))
+    {
+        // failed to start lower device
+        DPRINT1("FDO_StartDevice failed to get descriptors with %x\n", Status);
+        return Status;
+    }
+
+    // get capabilities
+    Status = FDO_QueryCapabilities(DeviceObject, &FDODeviceExtension->Capabilities);
+    if (!NT_SUCCESS(Status))
+    {
+        // failed to start lower device
+        DPRINT1("FDO_StartDevice failed to get capabilities with %x\n", Status);
+        return Status;
+    }
+
+    // now select the configuration
+    Status = USBCCGP_SelectConfiguration(DeviceObject, FDODeviceExtension);
+    if (!NT_SUCCESS(Status))
+    {
+        // failed to select interface
+        DPRINT1("FDO_StartDevice failed to get capabilities with %x\n", Status);
+        return Status;
+    }
+
+    //
+    // FIXME: parse usb interface association descriptor
+    // and create PDO for each function
+    //
+    ASSERT(FALSE);
+    return Status;
+}
+
+
+NTSTATUS
+FDO_HandlePnp(
+    PDEVICE_OBJECT DeviceObject,
+    PIRP Irp)
+{
+    PIO_STACK_LOCATION IoStack;
+    NTSTATUS Status;
+    PFDO_DEVICE_EXTENSION FDODeviceExtension;
+
+    // get device extension
+    FDODeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
+    ASSERT(FDODeviceExtension->Common.IsFDO);
+
+
+    // get stack location
+    IoStack = IoGetCurrentIrpStackLocation(Irp);
+
+    switch(IoStack->MinorFunction)
+    {
+        case IRP_MN_START_DEVICE:
+        {
+            Status = FDO_StartDevice(DeviceObject, Irp);
+            break;
+        }
+        case IRP_MN_QUERY_DEVICE_RELATIONS:
+        {
+            Status = FDO_DeviceRelations(DeviceObject, Irp);
+            break;
+        }
+        case IRP_MN_QUERY_CAPABILITIES:
+        {
+            //
+            // copy capabilities
+            //
+            RtlCopyMemory(IoStack->Parameters.DeviceCapabilities.Capabilities, &FDODeviceExtension->Capabilities, sizeof(DEVICE_CAPABILITIES));
+            Status = USBCCGP_SyncForwardIrp(FDODeviceExtension->NextDeviceObject, Irp);
+            if (NT_SUCCESS(Status))
+            {
+                //
+                // surprise removal ok
+                //
+                IoStack->Parameters.DeviceCapabilities.Capabilities->SurpriseRemovalOK = TRUE;
+            }
+            break;
+       }
+       default:
+       {
+            //
+            // forward irp to next device object
+            //
+            IoSkipCurrentIrpStackLocation(Irp);
+            return IoCallDriver(FDODeviceExtension->NextDeviceObject, Irp);
+       }
+
+    }
+
+    //
+    // complete request
+    //
+    Irp->IoStatus.Status = Status;
+    IoCompleteRequest(Irp, IO_NO_INCREMENT);
+    return Status;
+
+
+}
+
+NTSTATUS
+FDO_Dispatch(
+    PDEVICE_OBJECT DeviceObject, 
+    PIRP Irp)
+{
+    PIO_STACK_LOCATION IoStack;
+    NTSTATUS Status;
+
+    /* get stack location */
+    IoStack = IoGetCurrentIrpStackLocation(Irp);
+
+    switch(IoStack->MajorFunction)
+    {
+        case IRP_MJ_PNP:
+            return FDO_HandlePnp(DeviceObject, Irp);
+        default:
+            DPRINT1("FDO_Dispatch Function %x not implemented\n", IoStack->MajorFunction);
+            ASSERT(FALSE);
+            Status = Irp->IoStatus.Status;
+            IoCompleteRequest(Irp, IO_NO_INCREMENT);
+            return Status;
+    }
+}
+
+
diff --git a/drivers/usb/usbccgp/pdo.c b/drivers/usb/usbccgp/pdo.c
new file mode 100644 (file)
index 0000000..f33887c
--- /dev/null
@@ -0,0 +1,24 @@
+/*
+ * PROJECT:     ReactOS Universal Serial Bus Bulk Enhanced Host Controller Interface
+ * LICENSE:     GPL - See COPYING in the top level directory
+ * FILE:        drivers/usb/usbccgp/fdo.c
+ * PURPOSE:     USB  device driver.
+ * PROGRAMMERS:
+ *              Michael Martin (michael.martin@reactos.org)
+ *              Johannes Anderwald (johannes.anderwald@reactos.org)
+ *              Cameron Gutman
+ */
+
+#include "usbccgp.h"
+
+
+
+NTSTATUS
+PDO_Dispatch(
+    PDEVICE_OBJECT DeviceObject, 
+    PIRP Irp)
+{
+    UNIMPLEMENTED
+    ASSERT(FALSE);
+    return STATUS_NOT_IMPLEMENTED;
+}
diff --git a/drivers/usb/usbccgp/usbccgp.c b/drivers/usb/usbccgp/usbccgp.c
new file mode 100644 (file)
index 0000000..042ec76
--- /dev/null
@@ -0,0 +1,150 @@
+/*
+ * PROJECT:     ReactOS Universal Serial Bus Bulk Enhanced Host Controller Interface
+ * LICENSE:     GPL - See COPYING in the top level directory
+ * FILE:        drivers/usb/usbccgp/fdo.c
+ * PURPOSE:     USB  device driver.
+ * PROGRAMMERS:
+ *              Michael Martin (michael.martin@reactos.org)
+ *              Johannes Anderwald (johannes.anderwald@reactos.org)
+ *              Cameron Gutman
+ */
+
+#include "usbccgp.h"
+
+//
+// driver verifier
+//
+DRIVER_ADD_DEVICE USBCCGP_AddDevice;
+
+NTSTATUS
+NTAPI
+USBCCGP_AddDevice(
+    PDRIVER_OBJECT DriverObject,
+    PDEVICE_OBJECT PhysicalDeviceObject)
+{
+    NTSTATUS Status;
+    PDEVICE_OBJECT DeviceObject;
+    PFDO_DEVICE_EXTENSION FDODeviceExtension;
+
+    // lets create the device 
+    Status = IoCreateDevice(DriverObject, sizeof(FDO_DEVICE_EXTENSION), NULL, FILE_DEVICE_USB, FILE_AUTOGENERATED_DEVICE_NAME, FALSE, &DeviceObject);
+    if (!NT_SUCCESS(Status))
+    {
+        // failed to create device 
+        DPRINT1("USBCCGP_AddDevice failed to create device with %x\n", Status);
+        return Status;
+    }
+
+    // get device extension 
+    FDODeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
+
+    // init device extension 
+    RtlZeroMemory(FDODeviceExtension, sizeof(FDO_DEVICE_EXTENSION));
+    FDODeviceExtension->Common.IsFDO = TRUE;
+    FDODeviceExtension->DriverObject = DriverObject;
+    FDODeviceExtension->PhysicalDeviceObject = PhysicalDeviceObject;
+    FDODeviceExtension->NextDeviceObject = IoAttachDeviceToDeviceStack(DeviceObject, PhysicalDeviceObject);
+    if (!FDODeviceExtension->NextDeviceObject)
+    {
+        // failed to attach 
+        DPRINT1("USBCCGP_AddDevice failed to attach device\n");
+        IoDeleteDevice(DeviceObject);
+        return STATUS_DEVICE_REMOVED;
+    }
+
+    // set device flags 
+    DeviceObject->Flags |= DO_BUFFERED_IO | DO_POWER_PAGABLE;
+
+    // device is initialized 
+    DeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
+
+    // device initialized 
+    return Status;
+}
+
+NTSTATUS
+NTAPI
+USBCCGP_CreateClose(
+    PDEVICE_OBJECT DeviceObject, 
+    PIRP Irp)
+{
+    PCOMMON_DEVICE_EXTENSION DeviceExtension;
+    PFDO_DEVICE_EXTENSION FDODeviceExtension;
+
+    // get common device extension 
+    DeviceExtension = (PCOMMON_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
+
+    // is it a fdo 
+    if (DeviceExtension->IsFDO)
+    {
+        // forward and forget 
+        IoSkipCurrentIrpStackLocation(Irp);
+
+        // get fdo 
+        FDODeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
+
+        // call lower driver 
+        return IoCallDriver(FDODeviceExtension->NextDeviceObject, Irp);
+    }
+    else
+    {
+        // pdo not supported 
+        Irp->IoStatus.Status = STATUS_NOT_SUPPORTED;
+        IoCompleteRequest(Irp, IO_NO_INCREMENT);
+        return STATUS_NOT_SUPPORTED;
+    }
+}
+
+NTSTATUS
+NTAPI
+USBCCGP_Dispatch(
+    PDEVICE_OBJECT DeviceObject, 
+    PIRP Irp)
+{
+    PCOMMON_DEVICE_EXTENSION DeviceExtension;
+    PIO_STACK_LOCATION IoStack;
+
+    // get common device extension 
+    DeviceExtension = (PCOMMON_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
+
+    // get current stack location 
+    IoStack = IoGetCurrentIrpStackLocation(Irp);
+
+    if (IoStack->MajorFunction == IRP_MJ_CREATE || IoStack->MajorFunction == IRP_MJ_CLOSE)
+    {
+        // dispatch to default handler 
+        return USBCCGP_CreateClose(DeviceObject, Irp);
+    }
+
+    if (DeviceExtension->IsFDO)
+    {
+        // handle request for FDO 
+        return FDO_Dispatch(DeviceObject, Irp);
+    }
+    else
+    {
+        // handle request for PDO 
+        return PDO_Dispatch(DeviceObject, Irp);
+    }
+}
+
+NTSTATUS
+NTAPI
+DriverEntry(
+    PDRIVER_OBJECT DriverObject,
+    PUNICODE_STRING RegistryPath)
+{
+
+    // initialize driver object
+    DriverObject->DriverExtension->AddDevice = USBCCGP_AddDevice;
+    DriverObject->MajorFunction[IRP_MJ_CREATE] = USBCCGP_Dispatch;
+    DriverObject->MajorFunction[IRP_MJ_CLOSE] = USBCCGP_Dispatch;
+    DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = USBCCGP_Dispatch;
+    DriverObject->MajorFunction[IRP_MJ_INTERNAL_DEVICE_CONTROL] = USBCCGP_Dispatch;
+    DriverObject->MajorFunction[IRP_MJ_POWER] = USBCCGP_Dispatch;
+    DriverObject->MajorFunction[IRP_MJ_PNP] = USBCCGP_Dispatch;
+
+    // FIMXE query GenericCompositeUSBDeviceString 
+
+    return STATUS_SUCCESS;
+}
diff --git a/drivers/usb/usbccgp/usbccgp.h b/drivers/usb/usbccgp/usbccgp.h
new file mode 100644 (file)
index 0000000..4aaf9b9
--- /dev/null
@@ -0,0 +1,96 @@
+#ifndef USBEHCI_H__
+#define USBEHCI_H__
+
+#include <ntddk.h>
+#define YDEBUG
+#include <debug.h>
+#include <hubbusif.h>
+#include <usbbusif.h>
+#include <usbioctl.h>
+#include <usbdlib.h>
+
+//
+// FIXME: 
+// #include <usbprotocoldefs.h>
+//
+#include <usb.h>
+#include <stdio.h>
+#include <wdmguid.h>
+
+typedef struct
+{
+    BOOLEAN IsFDO;                                               // is device a FDO or PDO
+}COMMON_DEVICE_EXTENSION, *PCOMMON_DEVICE_EXTENSION;
+
+typedef struct
+{
+    COMMON_DEVICE_EXTENSION Common;                          // shared with PDO
+    PDRIVER_OBJECT DriverObject;                             // driver object
+    PDEVICE_OBJECT PhysicalDeviceObject;                     // physical device object
+    PDEVICE_OBJECT NextDeviceObject;                         // lower device object
+    PUSB_DEVICE_DESCRIPTOR DeviceDescriptor;                 // usb device descriptor
+    PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor;   // usb configuration descriptor
+    DEVICE_CAPABILITIES Capabilities;                        // device capabilities
+    PUSBD_INTERFACE_LIST_ENTRY InterfaceList;                // interface list
+    ULONG InterfaceListCount;                                // interface list count
+    USBD_CONFIGURATION_HANDLE ConfigurationHandle;           // configuration handle
+}FDO_DEVICE_EXTENSION, *PFDO_DEVICE_EXTENSION;
+
+#define USBCCPG_TAG 'cbsu'
+
+typedef struct
+{
+    COMMON_DEVICE_EXTENSION Common;                          // shared with FDO
+
+}PDO_DEVICE_EXTENSION, *PPDO_DEVICE_EXTENSION;
+
+/* descriptor.c */
+
+NTSTATUS
+USBCCGP_GetDescriptors(
+    IN PDEVICE_OBJECT DeviceObject);
+
+NTSTATUS
+USBCCGP_SelectConfiguration(
+    IN PDEVICE_OBJECT DeviceObject,
+    IN PFDO_DEVICE_EXTENSION DeviceExtension);
+
+/* misc.c */
+
+NTSTATUS
+NTAPI
+USBCCGP_SyncForwardIrp(
+    PDEVICE_OBJECT DeviceObject,
+    PIRP Irp);
+
+NTSTATUS
+USBCCGP_SyncUrbRequest(
+    IN PDEVICE_OBJECT DeviceObject,
+    OUT PURB UrbRequest);
+
+PVOID
+AllocateItem(
+    IN POOL_TYPE PoolType,
+    IN ULONG ItemSize);
+
+VOID
+FreeItem(
+    IN PVOID Item);
+
+/* fdo.c */
+
+NTSTATUS
+FDO_Dispatch(
+    PDEVICE_OBJECT DeviceObject, 
+    PIRP Irp);
+
+/* pdo.c */
+
+NTSTATUS
+PDO_Dispatch(
+    PDEVICE_OBJECT DeviceObject, 
+    PIRP Irp);
+
+
+
+#endif
diff --git a/drivers/usb/usbccgp/usbccgp.rc b/drivers/usb/usbccgp/usbccgp.rc
new file mode 100644 (file)
index 0000000..df848aa
--- /dev/null
@@ -0,0 +1,5 @@
+#define REACTOS_VERSION_DLL
+#define REACTOS_STR_FILE_DESCRIPTION   "USBCCGP Driver\0"
+#define REACTOS_STR_INTERNAL_NAME      "usccpg\0"
+#define REACTOS_STR_ORIGINAL_FILENAME  "usbccpg.sys\0"
+#include <reactos/version.rc>