mirror of
https://github.com/reactos/reactos.git
synced 2025-08-04 08:15:41 +00:00
[USBCCGP]
- Query bus interface and check if USBC_DEVICE_CONFIGURATION_INTERFACE_V1 is supported. This interface is implemented by attached usb filter drivers and is used to enumerate functions of the composite usb device - Implement enumeration of function by using usb interface association descriptors and by the USBC_DEVICE_CONFIGURATION_INTERFACE_V1 - Needs audio legacy method and union function descriptors to be fully functional - WIP, not yet tested - Fix build with mingw by declaring _DISK_GEOMETRY_EX outside the function svn path=/branches/usb-bringup-trunk/; revision=55197
This commit is contained in:
parent
b4c6fa3b4c
commit
2d7c9100e1
8 changed files with 828 additions and 5 deletions
|
@ -1,9 +1,12 @@
|
||||||
|
remove_definitions(-D_WIN32_WINNT=0x502)
|
||||||
|
add_definitions(-D_WIN32_WINNT=0x600)
|
||||||
|
|
||||||
|
|
||||||
add_definitions(-DDEBUG_MODE)
|
add_definitions(-DDEBUG_MODE)
|
||||||
|
|
||||||
include_directories(${REACTOS_SOURCE_DIR}/ntoskrnl/include)
|
include_directories(${REACTOS_SOURCE_DIR}/ntoskrnl/include)
|
||||||
|
|
||||||
add_library(usbccgp SHARED descriptor.c fdo.c misc.c pdo.c usbccgp.c usbccgp.rc)
|
add_library(usbccgp SHARED descriptor.c fdo.c function.c misc.c pdo.c usbccgp.c usbccgp.rc)
|
||||||
|
|
||||||
target_link_libraries(usbccgp ${PSEH_LIB})
|
target_link_libraries(usbccgp ${PSEH_LIB})
|
||||||
|
|
||||||
|
|
|
@ -187,9 +187,26 @@ FDO_StartDevice(
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// query bus interface
|
||||||
|
USBCCGP_QueryInterface(FDODeviceExtension->NextDeviceObject, &FDODeviceExtension->BusInterface);
|
||||||
|
|
||||||
|
// now enumerate the functions
|
||||||
|
Status = USBCCGP_EnumerateFunctions(DeviceObject);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
// failed to enumerate functions
|
||||||
|
DPRINT1("Failed to enumerate functions with %x\n", Status);
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// FIXME: parse usb interface association descriptor
|
// sanity checks
|
||||||
// and create PDO for each function
|
//
|
||||||
|
ASSERT(FDODeviceExtension->FunctionDescriptorCount);
|
||||||
|
ASSERT(FDODeviceExtension->FunctionDescriptor);
|
||||||
|
|
||||||
|
//
|
||||||
|
// FIXME:create PDO for each function
|
||||||
//
|
//
|
||||||
ASSERT(FALSE);
|
ASSERT(FALSE);
|
||||||
return Status;
|
return Status;
|
||||||
|
|
580
drivers/usb/usbccgp/function.c
Normal file
580
drivers/usb/usbccgp/function.c
Normal file
|
@ -0,0 +1,580 @@
|
||||||
|
/*
|
||||||
|
* 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
|
||||||
|
USBCCGP_QueryInterface(
|
||||||
|
IN PDEVICE_OBJECT DeviceObject,
|
||||||
|
OUT PUSBC_DEVICE_CONFIGURATION_INTERFACE_V1 BusInterface)
|
||||||
|
{
|
||||||
|
KEVENT Event;
|
||||||
|
NTSTATUS Status;
|
||||||
|
PIRP Irp;
|
||||||
|
IO_STATUS_BLOCK IoStatus;
|
||||||
|
PIO_STACK_LOCATION Stack;
|
||||||
|
|
||||||
|
//
|
||||||
|
// sanity checks
|
||||||
|
//
|
||||||
|
ASSERT(DeviceObject);
|
||||||
|
|
||||||
|
//
|
||||||
|
// initialize event
|
||||||
|
//
|
||||||
|
KeInitializeEvent(&Event, NotificationEvent, FALSE);
|
||||||
|
|
||||||
|
//
|
||||||
|
// init interface
|
||||||
|
//
|
||||||
|
RtlZeroMemory(BusInterface, sizeof(USBC_DEVICE_CONFIGURATION_INTERFACE_V1));
|
||||||
|
BusInterface->Version = USBC_DEVICE_CONFIGURATION_INTERFACE_VERSION_1;
|
||||||
|
BusInterface->Size = sizeof(USBC_DEVICE_CONFIGURATION_INTERFACE_V1);
|
||||||
|
|
||||||
|
//
|
||||||
|
// create irp
|
||||||
|
//
|
||||||
|
Irp = IoBuildSynchronousFsdRequest(IRP_MJ_PNP,
|
||||||
|
DeviceObject,
|
||||||
|
NULL,
|
||||||
|
0,
|
||||||
|
NULL,
|
||||||
|
&Event,
|
||||||
|
&IoStatus);
|
||||||
|
|
||||||
|
//
|
||||||
|
// was irp built
|
||||||
|
//
|
||||||
|
if (Irp == NULL)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// no memory
|
||||||
|
//
|
||||||
|
return STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// initialize request
|
||||||
|
//
|
||||||
|
Stack=IoGetNextIrpStackLocation(Irp);
|
||||||
|
Stack->MajorFunction = IRP_MJ_PNP;
|
||||||
|
Stack->MinorFunction = IRP_MN_QUERY_INTERFACE;
|
||||||
|
Stack->Parameters.QueryInterface.Size = sizeof(BUS_INTERFACE_STANDARD);
|
||||||
|
Stack->Parameters.QueryInterface.InterfaceType = (LPGUID)&USB_BUS_INTERFACE_USBC_CONFIGURATION_GUID;
|
||||||
|
Stack->Parameters.QueryInterface.Version = 2;
|
||||||
|
Stack->Parameters.QueryInterface.Interface = (PINTERFACE)&BusInterface;
|
||||||
|
Stack->Parameters.QueryInterface.InterfaceSpecificData = NULL;
|
||||||
|
Irp->IoStatus.Status = STATUS_NOT_SUPPORTED;
|
||||||
|
|
||||||
|
//
|
||||||
|
// call driver
|
||||||
|
//
|
||||||
|
Status= IoCallDriver(DeviceObject, Irp);
|
||||||
|
|
||||||
|
//
|
||||||
|
// did operation complete
|
||||||
|
//
|
||||||
|
if (Status == STATUS_PENDING)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// wait for completion
|
||||||
|
//
|
||||||
|
KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
|
||||||
|
|
||||||
|
//
|
||||||
|
// collect status
|
||||||
|
//
|
||||||
|
Status = IoStatus.Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
USBCCGP_CustomEnumWithInterface(
|
||||||
|
IN PDEVICE_OBJECT DeviceObject)
|
||||||
|
{
|
||||||
|
PFDO_DEVICE_EXTENSION FDODeviceExtension;
|
||||||
|
ULONG FunctionDescriptorBufferLength = 0;
|
||||||
|
NTSTATUS Status;
|
||||||
|
PUSBC_FUNCTION_DESCRIPTOR FunctionDescriptorBuffer = NULL;
|
||||||
|
|
||||||
|
//
|
||||||
|
// get device extension
|
||||||
|
//
|
||||||
|
FDODeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
||||||
|
ASSERT(FDODeviceExtension->Common.IsFDO);
|
||||||
|
|
||||||
|
if (FDODeviceExtension->BusInterface.StartDeviceCallback == NULL)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// not supported
|
||||||
|
//
|
||||||
|
return STATUS_NOT_SUPPORTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// invoke callback
|
||||||
|
//
|
||||||
|
Status = FDODeviceExtension->BusInterface.StartDeviceCallback(FDODeviceExtension->DeviceDescriptor,
|
||||||
|
FDODeviceExtension->ConfigurationDescriptor,
|
||||||
|
&FunctionDescriptorBuffer,
|
||||||
|
&FunctionDescriptorBufferLength,
|
||||||
|
DeviceObject,
|
||||||
|
FDODeviceExtension->PhysicalDeviceObject);
|
||||||
|
|
||||||
|
DPRINT1("USBCCGP_CustomEnumWithInterface Status %x\n", Status);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// failed
|
||||||
|
//
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
DPRINT1("FunctionDescriptorBufferLength %lu\n", FunctionDescriptorBufferLength);
|
||||||
|
DPRINT1("FunctionDescriptorBuffer %p\n", FunctionDescriptorBuffer);
|
||||||
|
|
||||||
|
//
|
||||||
|
// assume length % function buffer size
|
||||||
|
//
|
||||||
|
ASSERT(FunctionDescriptorBufferLength);
|
||||||
|
ASSERT(FunctionDescriptorBufferLength % sizeof(USBC_FUNCTION_DESCRIPTOR) == 0);
|
||||||
|
|
||||||
|
//
|
||||||
|
// store result
|
||||||
|
//
|
||||||
|
FDODeviceExtension->FunctionDescriptor = FunctionDescriptorBuffer;
|
||||||
|
FDODeviceExtension->FunctionDescriptorCount = FunctionDescriptorBufferLength / sizeof(USBC_FUNCTION_DESCRIPTOR);
|
||||||
|
|
||||||
|
//
|
||||||
|
// success
|
||||||
|
//
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
ULONG
|
||||||
|
USBCCGP_CountAssociationDescriptors(
|
||||||
|
IN PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor)
|
||||||
|
{
|
||||||
|
PUSB_INTERFACE_ASSOCIATION_DESCRIPTOR Descriptor;
|
||||||
|
PUCHAR Offset, End;
|
||||||
|
ULONG Count = 0;
|
||||||
|
|
||||||
|
//
|
||||||
|
// init offsets
|
||||||
|
//
|
||||||
|
Offset = (PUCHAR)ConfigurationDescriptor + ConfigurationDescriptor->bLength;
|
||||||
|
End = (PUCHAR)ConfigurationDescriptor + ConfigurationDescriptor->wTotalLength;
|
||||||
|
|
||||||
|
while(Offset < End)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// get association descriptor
|
||||||
|
//
|
||||||
|
Descriptor = (PUSB_INTERFACE_ASSOCIATION_DESCRIPTOR)Offset;
|
||||||
|
|
||||||
|
if (Descriptor->bLength == sizeof(USB_INTERFACE_ASSOCIATION_DESCRIPTOR) && Descriptor->bDescriptorType == USB_INTERFACE_ASSOCIATION_DESCRIPTOR_TYPE)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// found descriptor
|
||||||
|
//
|
||||||
|
Count++;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// move to next descriptor
|
||||||
|
//
|
||||||
|
Offset += Descriptor->bLength;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// done
|
||||||
|
//
|
||||||
|
return Count;
|
||||||
|
}
|
||||||
|
|
||||||
|
PUSB_INTERFACE_ASSOCIATION_DESCRIPTOR
|
||||||
|
USBCCGP_GetAssociationDescriptorAtIndex(
|
||||||
|
IN PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor,
|
||||||
|
IN ULONG Index)
|
||||||
|
{
|
||||||
|
PUSB_INTERFACE_ASSOCIATION_DESCRIPTOR Descriptor;
|
||||||
|
PUCHAR Offset, End;
|
||||||
|
ULONG Count = 0;
|
||||||
|
|
||||||
|
//
|
||||||
|
// init offsets
|
||||||
|
//
|
||||||
|
Offset = (PUCHAR)ConfigurationDescriptor + ConfigurationDescriptor->bLength;
|
||||||
|
End = (PUCHAR)ConfigurationDescriptor + ConfigurationDescriptor->wTotalLength;
|
||||||
|
|
||||||
|
while(Offset < End)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// get association descriptor
|
||||||
|
//
|
||||||
|
Descriptor = (PUSB_INTERFACE_ASSOCIATION_DESCRIPTOR)Offset;
|
||||||
|
|
||||||
|
if (Descriptor->bLength == sizeof(USB_INTERFACE_ASSOCIATION_DESCRIPTOR) && Descriptor->bDescriptorType == USB_INTERFACE_ASSOCIATION_DESCRIPTOR_TYPE)
|
||||||
|
{
|
||||||
|
if (Index == Count)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// found descriptor
|
||||||
|
//
|
||||||
|
return Descriptor;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// not the searched one
|
||||||
|
//
|
||||||
|
Count++;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// move to next descriptor
|
||||||
|
//
|
||||||
|
Offset += Descriptor->bLength;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// failed to find descriptor at the specified index
|
||||||
|
//
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
USBCCGP_InitInterfaceListOfFunctionDescriptor(
|
||||||
|
IN PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor,
|
||||||
|
IN PUSB_INTERFACE_ASSOCIATION_DESCRIPTOR AssociationDescriptor,
|
||||||
|
OUT PUSBC_FUNCTION_DESCRIPTOR FunctionDescriptor)
|
||||||
|
{
|
||||||
|
PUSB_INTERFACE_DESCRIPTOR Descriptor;
|
||||||
|
PUCHAR Offset, End;
|
||||||
|
ULONG Count = 0;
|
||||||
|
|
||||||
|
//
|
||||||
|
// init offsets
|
||||||
|
//
|
||||||
|
Offset = (PUCHAR)AssociationDescriptor + AssociationDescriptor->bLength;
|
||||||
|
End = (PUCHAR)ConfigurationDescriptor + ConfigurationDescriptor->wTotalLength;
|
||||||
|
|
||||||
|
while(Offset < End)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// get association descriptor
|
||||||
|
//
|
||||||
|
Descriptor = (PUSB_INTERFACE_DESCRIPTOR)Offset;
|
||||||
|
|
||||||
|
if (Descriptor->bLength == sizeof(USB_INTERFACE_DESCRIPTOR) && Descriptor->bDescriptorType == USB_INTERFACE_DESCRIPTOR_TYPE)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// store interface descriptor
|
||||||
|
//
|
||||||
|
FunctionDescriptor->InterfaceDescriptorList[Count] = Descriptor;
|
||||||
|
Count++;
|
||||||
|
|
||||||
|
if (Count == AssociationDescriptor->bInterfaceCount)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// got all interfaces
|
||||||
|
//
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Descriptor->bLength == sizeof(USB_INTERFACE_ASSOCIATION_DESCRIPTOR) && Descriptor->bDescriptorType == USB_INTERFACE_ASSOCIATION_DESCRIPTOR_TYPE)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// WTF? a association descriptor which overlaps the next association descriptor
|
||||||
|
//
|
||||||
|
DPRINT1("Invalid association descriptor\n");
|
||||||
|
ASSERT(FALSE);
|
||||||
|
return STATUS_UNSUCCESSFUL;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// move to next descriptor
|
||||||
|
//
|
||||||
|
Offset += Descriptor->bLength;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// invalid association descriptor
|
||||||
|
//
|
||||||
|
DPRINT1("Invalid association descriptor\n");
|
||||||
|
return STATUS_UNSUCCESSFUL;
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
USBCCGP_InitFunctionDescriptor(
|
||||||
|
IN PFDO_DEVICE_EXTENSION FDODeviceExtension,
|
||||||
|
IN ULONG FunctionNumber,
|
||||||
|
OUT PUSBC_FUNCTION_DESCRIPTOR FunctionDescriptor)
|
||||||
|
{
|
||||||
|
PUSB_INTERFACE_ASSOCIATION_DESCRIPTOR Descriptor;
|
||||||
|
NTSTATUS Status;
|
||||||
|
LPWSTR DescriptionBuffer;
|
||||||
|
WCHAR Buffer[100];
|
||||||
|
ULONG Index;
|
||||||
|
|
||||||
|
// init function number
|
||||||
|
FunctionDescriptor->FunctionNumber = (UCHAR)FunctionNumber;
|
||||||
|
|
||||||
|
// get association descriptor
|
||||||
|
Descriptor = USBCCGP_GetAssociationDescriptorAtIndex(FDODeviceExtension->ConfigurationDescriptor, FunctionNumber);
|
||||||
|
ASSERT(Descriptor);
|
||||||
|
|
||||||
|
// store number interfaces
|
||||||
|
FunctionDescriptor->NumberOfInterfaces = Descriptor->bInterfaceCount;
|
||||||
|
|
||||||
|
// allocate array for interface count
|
||||||
|
FunctionDescriptor->InterfaceDescriptorList = AllocateItem(NonPagedPool, sizeof(PUSB_INTERFACE_DESCRIPTOR) * Descriptor->bInterfaceCount);
|
||||||
|
if (FunctionDescriptor->InterfaceDescriptorList)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// no memory
|
||||||
|
//
|
||||||
|
return STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
}
|
||||||
|
|
||||||
|
// init interface list
|
||||||
|
Status = USBCCGP_InitInterfaceListOfFunctionDescriptor(FDODeviceExtension->ConfigurationDescriptor, Descriptor, FunctionDescriptor);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// failed
|
||||||
|
//
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// now init interface description
|
||||||
|
//
|
||||||
|
if (Descriptor->iFunction)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// get interface description
|
||||||
|
//
|
||||||
|
Status = USBCCGP_GetDescriptor(FDODeviceExtension->NextDeviceObject,
|
||||||
|
USB_STRING_DESCRIPTOR_TYPE,
|
||||||
|
100 * sizeof(WCHAR),
|
||||||
|
Descriptor->iFunction,
|
||||||
|
0x0409, //FIXME
|
||||||
|
(PVOID*)&DescriptionBuffer);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// no description
|
||||||
|
//
|
||||||
|
RtlInitUnicodeString(&FunctionDescriptor->FunctionDescription, L"");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// init description
|
||||||
|
//
|
||||||
|
RtlInitUnicodeString(&FunctionDescriptor->FunctionDescription, DescriptionBuffer);
|
||||||
|
}
|
||||||
|
DPRINT1("FunctionDescription %wZ\n", &FunctionDescriptor->FunctionDescription);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// now init hardware id
|
||||||
|
//
|
||||||
|
Index = swprintf(Buffer, L"USB\\VID_%04x&PID_%04x&Rev_%04x&MI_%02x", FDODeviceExtension->DeviceDescriptor->idVendor,
|
||||||
|
FDODeviceExtension->DeviceDescriptor->idProduct,
|
||||||
|
FDODeviceExtension->DeviceDescriptor->bcdDevice,
|
||||||
|
Descriptor->bFirstInterface) + 1;
|
||||||
|
Index = swprintf(&Buffer[Index], L"USB\\VID_%04x&PID_%04x&MI_%02x", FDODeviceExtension->DeviceDescriptor->idVendor,
|
||||||
|
FDODeviceExtension->DeviceDescriptor->idProduct,
|
||||||
|
Descriptor->bFirstInterface) + 1;
|
||||||
|
|
||||||
|
// allocate result buffer
|
||||||
|
DescriptionBuffer = AllocateItem(NonPagedPool, (Index + 1) * sizeof(WCHAR));
|
||||||
|
if (!DescriptionBuffer)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// failed to allocate memory
|
||||||
|
//
|
||||||
|
return STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
}
|
||||||
|
|
||||||
|
// copy description
|
||||||
|
RtlCopyMemory(DescriptionBuffer, Buffer, Index * sizeof(WCHAR));
|
||||||
|
RtlInitUnicodeString(&FunctionDescriptor->HardwareId, DescriptionBuffer);
|
||||||
|
|
||||||
|
//
|
||||||
|
// now init the compatible id
|
||||||
|
//
|
||||||
|
Index = swprintf(Buffer, L"USB\\Class_%02x&SubClass_%02x&Prot_%02x", Descriptor->bFunctionClass, Descriptor->bFunctionSubClass, Descriptor->bFunctionProtocol) + 1;
|
||||||
|
Index = swprintf(&Buffer[Index], L"USB\\Class_%04x&SubClass_%04x", Descriptor->bFunctionClass, Descriptor->bFunctionSubClass) + 1;
|
||||||
|
Index = swprintf(&Buffer[Index], L"USB\\Class_%04x", Descriptor->bFunctionClass) + 1;
|
||||||
|
|
||||||
|
// allocate result buffer
|
||||||
|
DescriptionBuffer = AllocateItem(NonPagedPool, (Index + 1) * sizeof(WCHAR));
|
||||||
|
if (!DescriptionBuffer)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// failed to allocate memory
|
||||||
|
//
|
||||||
|
return STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
}
|
||||||
|
|
||||||
|
// copy description
|
||||||
|
// copy description
|
||||||
|
RtlCopyMemory(DescriptionBuffer, Buffer, Index * sizeof(WCHAR));
|
||||||
|
RtlInitUnicodeString(&FunctionDescriptor->CompatibleId, DescriptionBuffer);
|
||||||
|
|
||||||
|
//
|
||||||
|
// done
|
||||||
|
//
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
USBCCGP_EnumWithAssociationDescriptor(
|
||||||
|
IN PDEVICE_OBJECT DeviceObject)
|
||||||
|
{
|
||||||
|
ULONG DescriptorCount, Index;
|
||||||
|
PFDO_DEVICE_EXTENSION FDODeviceExtension;
|
||||||
|
NTSTATUS Status = STATUS_SUCCESS;
|
||||||
|
|
||||||
|
//
|
||||||
|
// get device extension
|
||||||
|
//
|
||||||
|
FDODeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
||||||
|
ASSERT(FDODeviceExtension->Common.IsFDO);
|
||||||
|
|
||||||
|
//
|
||||||
|
// count association descriptors
|
||||||
|
//
|
||||||
|
DescriptorCount = USBCCGP_CountAssociationDescriptors(FDODeviceExtension->ConfigurationDescriptor);
|
||||||
|
if (!DescriptorCount)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// no descriptors found
|
||||||
|
//
|
||||||
|
return STATUS_NOT_SUPPORTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// allocate function descriptor array
|
||||||
|
//
|
||||||
|
FDODeviceExtension->FunctionDescriptor = AllocateItem(NonPagedPool, sizeof(USBC_FUNCTION_DESCRIPTOR) * DescriptorCount);
|
||||||
|
if (!FDODeviceExtension->FunctionDescriptorCount)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// no memory
|
||||||
|
//
|
||||||
|
DPRINT1("USBCCGP_EnumWithAssociationDescriptor failed to allocate function descriptor count %x\n", DescriptorCount);
|
||||||
|
return STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
}
|
||||||
|
|
||||||
|
for(Index = 0; Index < DescriptorCount; Index++)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// init function descriptors
|
||||||
|
//
|
||||||
|
Status = USBCCGP_InitFunctionDescriptor(FDODeviceExtension, Index, &FDODeviceExtension->FunctionDescriptor[Index]);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// failed
|
||||||
|
//
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// store function descriptor count
|
||||||
|
//
|
||||||
|
FDODeviceExtension->FunctionDescriptorCount = DescriptorCount;
|
||||||
|
|
||||||
|
//
|
||||||
|
// done
|
||||||
|
//
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
USBCCGP_EnumWithAudioLegacy(
|
||||||
|
IN PDEVICE_OBJECT DeviceObject)
|
||||||
|
{
|
||||||
|
UNIMPLEMENTED
|
||||||
|
return STATUS_NOT_IMPLEMENTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
USBCCGP_EnumWithUnionFunctionDescriptors(
|
||||||
|
IN PDEVICE_OBJECT DeviceObject)
|
||||||
|
{
|
||||||
|
UNIMPLEMENTED
|
||||||
|
return STATUS_NOT_IMPLEMENTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
USBCCGP_EnumerateFunctions(
|
||||||
|
IN PDEVICE_OBJECT DeviceObject)
|
||||||
|
{
|
||||||
|
NTSTATUS Status;
|
||||||
|
PFDO_DEVICE_EXTENSION FDODeviceExtension;
|
||||||
|
|
||||||
|
//
|
||||||
|
// get device extension
|
||||||
|
//
|
||||||
|
FDODeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
||||||
|
ASSERT(FDODeviceExtension->Common.IsFDO);
|
||||||
|
|
||||||
|
//
|
||||||
|
// first try with filter driver
|
||||||
|
//
|
||||||
|
Status = USBCCGP_CustomEnumWithInterface(DeviceObject);
|
||||||
|
if (NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// succeeded
|
||||||
|
//
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// enumerate functions with interface association descriptor
|
||||||
|
//
|
||||||
|
Status = USBCCGP_EnumWithAssociationDescriptor(DeviceObject);
|
||||||
|
if (NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// succeeded
|
||||||
|
//
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// try with union function descriptors
|
||||||
|
//
|
||||||
|
Status = USBCCGP_EnumWithUnionFunctionDescriptors(DeviceObject);
|
||||||
|
if (NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// succeeded
|
||||||
|
//
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// try with legacy audio methods
|
||||||
|
//
|
||||||
|
return USBCCGP_EnumWithAudioLegacy(DeviceObject);
|
||||||
|
}
|
197
drivers/usb/usbccgp/misc.c
Normal file
197
drivers/usb/usbccgp/misc.c
Normal file
|
@ -0,0 +1,197 @@
|
||||||
|
/*
|
||||||
|
* PROJECT: ReactOS Universal Serial Bus Bulk Enhanced Host Controller Interface
|
||||||
|
* LICENSE: GPL - See COPYING in the top level directory
|
||||||
|
* FILE: drivers/usb/usbccgp/misc.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
|
||||||
|
//
|
||||||
|
IO_COMPLETION_ROUTINE SyncForwardIrpCompletionRoutine;
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
|
USBSTOR_SyncForwardIrpCompletionRoutine(
|
||||||
|
PDEVICE_OBJECT DeviceObject,
|
||||||
|
PIRP Irp,
|
||||||
|
PVOID Context)
|
||||||
|
{
|
||||||
|
if (Irp->PendingReturned)
|
||||||
|
{
|
||||||
|
KeSetEvent((PKEVENT)Context, IO_NO_INCREMENT, FALSE);
|
||||||
|
}
|
||||||
|
return STATUS_MORE_PROCESSING_REQUIRED;
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
|
USBCCGP_SyncForwardIrp(
|
||||||
|
PDEVICE_OBJECT DeviceObject,
|
||||||
|
PIRP Irp)
|
||||||
|
{
|
||||||
|
KEVENT Event;
|
||||||
|
NTSTATUS Status;
|
||||||
|
|
||||||
|
//
|
||||||
|
// initialize event
|
||||||
|
//
|
||||||
|
KeInitializeEvent(&Event, NotificationEvent, FALSE);
|
||||||
|
|
||||||
|
//
|
||||||
|
// copy irp stack location
|
||||||
|
//
|
||||||
|
IoCopyCurrentIrpStackLocationToNext(Irp);
|
||||||
|
|
||||||
|
//
|
||||||
|
// set completion routine
|
||||||
|
//
|
||||||
|
IoSetCompletionRoutine(Irp, USBSTOR_SyncForwardIrpCompletionRoutine, &Event, TRUE, TRUE, TRUE);
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// call driver
|
||||||
|
//
|
||||||
|
Status = IoCallDriver(DeviceObject, Irp);
|
||||||
|
|
||||||
|
//
|
||||||
|
// check if pending
|
||||||
|
//
|
||||||
|
if (Status == STATUS_PENDING)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// wait for the request to finish
|
||||||
|
//
|
||||||
|
KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
|
||||||
|
|
||||||
|
//
|
||||||
|
// copy status code
|
||||||
|
//
|
||||||
|
Status = Irp->IoStatus.Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// done
|
||||||
|
//
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
USBCCGP_SyncUrbRequest(
|
||||||
|
IN PDEVICE_OBJECT DeviceObject,
|
||||||
|
OUT PURB UrbRequest)
|
||||||
|
{
|
||||||
|
PIRP Irp;
|
||||||
|
PIO_STACK_LOCATION IoStack;
|
||||||
|
KEVENT Event;
|
||||||
|
NTSTATUS Status;
|
||||||
|
|
||||||
|
//
|
||||||
|
// allocate irp
|
||||||
|
//
|
||||||
|
Irp = IoAllocateIrp(DeviceObject->StackSize, FALSE);
|
||||||
|
if (!Irp)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// no memory
|
||||||
|
//
|
||||||
|
return STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// initialize event
|
||||||
|
//
|
||||||
|
KeInitializeEvent(&Event, NotificationEvent, FALSE);
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// get next stack location
|
||||||
|
//
|
||||||
|
IoStack = IoGetNextIrpStackLocation(Irp);
|
||||||
|
|
||||||
|
//
|
||||||
|
// initialize stack location
|
||||||
|
//
|
||||||
|
IoStack->MajorFunction = IRP_MJ_INTERNAL_DEVICE_CONTROL;
|
||||||
|
IoStack->Parameters.DeviceIoControl.IoControlCode = IOCTL_INTERNAL_USB_SUBMIT_URB;
|
||||||
|
IoStack->Parameters.Others.Argument1 = (PVOID)UrbRequest;
|
||||||
|
IoStack->Parameters.DeviceIoControl.InputBufferLength = UrbRequest->UrbHeader.Length;
|
||||||
|
Irp->IoStatus.Status = STATUS_SUCCESS;
|
||||||
|
|
||||||
|
//
|
||||||
|
// setup completion routine
|
||||||
|
//
|
||||||
|
IoSetCompletionRoutine(Irp, USBSTOR_SyncForwardIrpCompletionRoutine, &Event, TRUE, TRUE, TRUE);
|
||||||
|
|
||||||
|
//
|
||||||
|
// call driver
|
||||||
|
//
|
||||||
|
Status = IoCallDriver(DeviceObject, Irp);
|
||||||
|
|
||||||
|
//
|
||||||
|
// check if request is pending
|
||||||
|
//
|
||||||
|
if (Status == STATUS_PENDING)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// wait for completion
|
||||||
|
//
|
||||||
|
KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
|
||||||
|
|
||||||
|
//
|
||||||
|
// update status
|
||||||
|
//
|
||||||
|
Status = Irp->IoStatus.Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// free irp
|
||||||
|
//
|
||||||
|
IoFreeIrp(Irp);
|
||||||
|
|
||||||
|
//
|
||||||
|
// done
|
||||||
|
//
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
PVOID
|
||||||
|
AllocateItem(
|
||||||
|
IN POOL_TYPE PoolType,
|
||||||
|
IN ULONG ItemSize)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// allocate item
|
||||||
|
//
|
||||||
|
PVOID Item = ExAllocatePoolWithTag(PoolType, ItemSize, USBCCPG_TAG);
|
||||||
|
|
||||||
|
if (Item)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// zero item
|
||||||
|
//
|
||||||
|
RtlZeroMemory(Item, ItemSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// return element
|
||||||
|
//
|
||||||
|
return Item;
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID
|
||||||
|
FreeItem(
|
||||||
|
IN PVOID Item)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// free item
|
||||||
|
//
|
||||||
|
ExFreePoolWithTag(Item, USBCCPG_TAG);
|
||||||
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* PROJECT: ReactOS Universal Serial Bus Bulk Enhanced Host Controller Interface
|
* PROJECT: ReactOS Universal Serial Bus Bulk Enhanced Host Controller Interface
|
||||||
* LICENSE: GPL - See COPYING in the top level directory
|
* LICENSE: GPL - See COPYING in the top level directory
|
||||||
* FILE: drivers/usb/usbccgp/fdo.c
|
* FILE: drivers/usb/usbccgp/pdo.c
|
||||||
* PURPOSE: USB device driver.
|
* PURPOSE: USB device driver.
|
||||||
* PROGRAMMERS:
|
* PROGRAMMERS:
|
||||||
* Michael Martin (michael.martin@reactos.org)
|
* Michael Martin (michael.martin@reactos.org)
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* PROJECT: ReactOS Universal Serial Bus Bulk Enhanced Host Controller Interface
|
* PROJECT: ReactOS Universal Serial Bus Bulk Enhanced Host Controller Interface
|
||||||
* LICENSE: GPL - See COPYING in the top level directory
|
* LICENSE: GPL - See COPYING in the top level directory
|
||||||
* FILE: drivers/usb/usbccgp/fdo.c
|
* FILE: drivers/usb/usbccgp/usbccgp.c
|
||||||
* PURPOSE: USB device driver.
|
* PURPOSE: USB device driver.
|
||||||
* PROGRAMMERS:
|
* PROGRAMMERS:
|
||||||
* Michael Martin (michael.martin@reactos.org)
|
* Michael Martin (michael.martin@reactos.org)
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
#include <ntddk.h>
|
#include <ntddk.h>
|
||||||
#define YDEBUG
|
#define YDEBUG
|
||||||
#include <debug.h>
|
#include <debug.h>
|
||||||
|
#include <initguid.h>
|
||||||
#include <hubbusif.h>
|
#include <hubbusif.h>
|
||||||
#include <usbbusif.h>
|
#include <usbbusif.h>
|
||||||
#include <usbioctl.h>
|
#include <usbioctl.h>
|
||||||
|
@ -34,6 +35,9 @@ typedef struct
|
||||||
PUSBD_INTERFACE_LIST_ENTRY InterfaceList; // interface list
|
PUSBD_INTERFACE_LIST_ENTRY InterfaceList; // interface list
|
||||||
ULONG InterfaceListCount; // interface list count
|
ULONG InterfaceListCount; // interface list count
|
||||||
USBD_CONFIGURATION_HANDLE ConfigurationHandle; // configuration handle
|
USBD_CONFIGURATION_HANDLE ConfigurationHandle; // configuration handle
|
||||||
|
USBC_DEVICE_CONFIGURATION_INTERFACE_V1 BusInterface; // bus custom enumeration interface
|
||||||
|
PUSBC_FUNCTION_DESCRIPTOR FunctionDescriptor; // usb function descriptor
|
||||||
|
ULONG FunctionDescriptorCount; // number of function descriptor
|
||||||
}FDO_DEVICE_EXTENSION, *PFDO_DEVICE_EXTENSION;
|
}FDO_DEVICE_EXTENSION, *PFDO_DEVICE_EXTENSION;
|
||||||
|
|
||||||
#define USBCCPG_TAG 'cbsu'
|
#define USBCCPG_TAG 'cbsu'
|
||||||
|
@ -55,6 +59,16 @@ USBCCGP_SelectConfiguration(
|
||||||
IN PDEVICE_OBJECT DeviceObject,
|
IN PDEVICE_OBJECT DeviceObject,
|
||||||
IN PFDO_DEVICE_EXTENSION DeviceExtension);
|
IN PFDO_DEVICE_EXTENSION DeviceExtension);
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
|
USBCCGP_GetDescriptor(
|
||||||
|
IN PDEVICE_OBJECT DeviceObject,
|
||||||
|
IN UCHAR DescriptorType,
|
||||||
|
IN ULONG DescriptorLength,
|
||||||
|
IN UCHAR DescriptorIndex,
|
||||||
|
IN LANGID LanguageId,
|
||||||
|
OUT PVOID *OutDescriptor);
|
||||||
|
|
||||||
/* misc.c */
|
/* misc.c */
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
|
@ -91,6 +105,15 @@ PDO_Dispatch(
|
||||||
PDEVICE_OBJECT DeviceObject,
|
PDEVICE_OBJECT DeviceObject,
|
||||||
PIRP Irp);
|
PIRP Irp);
|
||||||
|
|
||||||
|
/* function.c */
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
USBCCGP_QueryInterface(
|
||||||
|
IN PDEVICE_OBJECT DeviceObject,
|
||||||
|
OUT PUSBC_DEVICE_CONFIGURATION_INTERFACE_V1 BusInterface);
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
USBCCGP_EnumerateFunctions(
|
||||||
|
IN PDEVICE_OBJECT DeviceObject);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -4158,6 +4158,9 @@ IoTranslateBusAddress(
|
||||||
#endif /* (NTDDI_VERSION >= NTDDI_WS03SP1) */
|
#endif /* (NTDDI_VERSION >= NTDDI_WS03SP1) */
|
||||||
|
|
||||||
#if (NTDDI_VERSION >= NTDDI_VISTA)
|
#if (NTDDI_VERSION >= NTDDI_VISTA)
|
||||||
|
|
||||||
|
struct _DISK_GEOMETRY_EX;
|
||||||
|
|
||||||
NTKERNELAPI
|
NTKERNELAPI
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
NTAPI
|
NTAPI
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue