From 1cede4f0774088de53447eb0bb4a5f56bccef0ee Mon Sep 17 00:00:00 2001 From: Johannes Anderwald Date: Thu, 26 Jan 2012 03:42:56 +0000 Subject: [PATCH] [USBCCGP] - 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 | 1 + drivers/usb/usbccgp/CMakeLists.txt | 13 + drivers/usb/usbccgp/descriptor.c | 386 +++++++++++++++++++++++++++++ drivers/usb/usbccgp/fdo.c | 289 +++++++++++++++++++++ drivers/usb/usbccgp/pdo.c | 24 ++ drivers/usb/usbccgp/usbccgp.c | 150 +++++++++++ drivers/usb/usbccgp/usbccgp.h | 96 +++++++ drivers/usb/usbccgp/usbccgp.rc | 5 + 8 files changed, 964 insertions(+) create mode 100644 drivers/usb/usbccgp/CMakeLists.txt create mode 100644 drivers/usb/usbccgp/descriptor.c create mode 100644 drivers/usb/usbccgp/fdo.c create mode 100644 drivers/usb/usbccgp/pdo.c create mode 100644 drivers/usb/usbccgp/usbccgp.c create mode 100644 drivers/usb/usbccgp/usbccgp.h create mode 100644 drivers/usb/usbccgp/usbccgp.rc diff --git a/drivers/usb/CMakeLists.txt b/drivers/usb/CMakeLists.txt index f88abfcac3b..48be424a694 100644 --- a/drivers/usb/CMakeLists.txt +++ b/drivers/usb/CMakeLists.txt @@ -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 index 00000000000..ab3c4c432de --- /dev/null +++ b/drivers/usb/usbccgp/CMakeLists.txt @@ -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 index 00000000000..9d7df069ce2 --- /dev/null +++ b/drivers/usb/usbccgp/descriptor.c @@ -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 index 00000000000..61c978d8091 --- /dev/null +++ b/drivers/usb/usbccgp/fdo.c @@ -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 index 00000000000..f33887c688d --- /dev/null +++ b/drivers/usb/usbccgp/pdo.c @@ -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 index 00000000000..042ec766afa --- /dev/null +++ b/drivers/usb/usbccgp/usbccgp.c @@ -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 index 00000000000..4aaf9b9b308 --- /dev/null +++ b/drivers/usb/usbccgp/usbccgp.h @@ -0,0 +1,96 @@ +#ifndef USBEHCI_H__ +#define USBEHCI_H__ + +#include +#define YDEBUG +#include +#include +#include +#include +#include + +// +// FIXME: +// #include +// +#include +#include +#include + +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 index 00000000000..df848aa5e4d --- /dev/null +++ b/drivers/usb/usbccgp/usbccgp.rc @@ -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