mirror of
https://github.com/reactos/reactos.git
synced 2025-04-02 19:53:19 +00:00
[USBCCGP]
- Implement querying device relations for FDO - Implement creating device objects for each discovered function - Invalidate device relations after the child pdo have been created - Implement PDO device relations, most of query id, query device capabilities, start device - USBCCGP should now initialize and create the child pdos - Next is device control handling - WIP, untested svn path=/branches/usb-bringup-trunk/; revision=55219
This commit is contained in:
parent
a565eb2d37
commit
8f792f3587
3 changed files with 525 additions and 10 deletions
|
@ -127,9 +127,181 @@ FDO_DeviceRelations(
|
|||
PDEVICE_OBJECT DeviceObject,
|
||||
PIRP Irp)
|
||||
{
|
||||
UNIMPLEMENTED
|
||||
ASSERT(FALSE);
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
ULONG DeviceCount = 0;
|
||||
ULONG Index;
|
||||
PDEVICE_RELATIONS DeviceRelations;
|
||||
PIO_STACK_LOCATION IoStack;
|
||||
PFDO_DEVICE_EXTENSION FDODeviceExtension;
|
||||
|
||||
//
|
||||
// get device extension
|
||||
//
|
||||
FDODeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
||||
|
||||
|
||||
//
|
||||
// get current irp stack location
|
||||
//
|
||||
IoStack = IoGetCurrentIrpStackLocation(Irp);
|
||||
|
||||
//
|
||||
// check if relation type is BusRelations
|
||||
//
|
||||
if (IoStack->Parameters.QueryDeviceRelations.Type != BusRelations)
|
||||
{
|
||||
//
|
||||
// FDO always only handles bus relations
|
||||
//
|
||||
return USBCCGP_SyncForwardIrp(FDODeviceExtension->NextDeviceObject, Irp);
|
||||
}
|
||||
|
||||
//
|
||||
// go through array and count device objects
|
||||
//
|
||||
for(Index = 0; Index < FDODeviceExtension->FunctionDescriptorCount; Index++)
|
||||
{
|
||||
if (FDODeviceExtension->ChildPDO[Index])
|
||||
{
|
||||
//
|
||||
// child pdo
|
||||
//
|
||||
DeviceCount++;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// allocate device relations
|
||||
//
|
||||
DeviceRelations = (PDEVICE_RELATIONS)AllocateItem(PagedPool, sizeof(DEVICE_RELATIONS) + (DeviceCount > 1 ? (DeviceCount-1) * sizeof(PDEVICE_OBJECT) : 0));
|
||||
if (!DeviceRelations)
|
||||
{
|
||||
//
|
||||
// no memory
|
||||
//
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
|
||||
//
|
||||
// add device objects
|
||||
//
|
||||
for(Index = 0; Index < FDODeviceExtension->FunctionDescriptorCount; Index++)
|
||||
{
|
||||
if (FDODeviceExtension->ChildPDO[Index])
|
||||
{
|
||||
//
|
||||
// store child pdo
|
||||
//
|
||||
DeviceRelations->Objects[DeviceRelations->Count] = FDODeviceExtension->ChildPDO[Index];
|
||||
|
||||
//
|
||||
// add reference
|
||||
//
|
||||
ObReferenceObject(FDODeviceExtension->ChildPDO[Index]);
|
||||
|
||||
//
|
||||
// increment count
|
||||
//
|
||||
DeviceRelations->Count++;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// store result
|
||||
//
|
||||
Irp->IoStatus.Information = (ULONG_PTR)DeviceRelations;
|
||||
|
||||
//
|
||||
// request completed successfully
|
||||
//
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
FDO_CreateChildPdo(
|
||||
IN PDEVICE_OBJECT DeviceObject)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
PDEVICE_OBJECT PDODeviceObject;
|
||||
PPDO_DEVICE_EXTENSION PDODeviceExtension;
|
||||
PFDO_DEVICE_EXTENSION FDODeviceExtension;
|
||||
ULONG Index;
|
||||
|
||||
//
|
||||
// get device extension
|
||||
//
|
||||
FDODeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
||||
ASSERT(FDODeviceExtension->Common.IsFDO);
|
||||
|
||||
//
|
||||
// lets create array for the child PDO
|
||||
//
|
||||
FDODeviceExtension->ChildPDO = AllocateItem(NonPagedPool, sizeof(PDEVICE_OBJECT) * FDODeviceExtension->FunctionDescriptorCount);
|
||||
if (!FDODeviceExtension->ChildPDO)
|
||||
{
|
||||
//
|
||||
// no memory
|
||||
//
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
|
||||
//
|
||||
// create pdo for each function
|
||||
//
|
||||
for(Index = 0; Index < FDODeviceExtension->FunctionDescriptorCount; Index++)
|
||||
{
|
||||
//
|
||||
// create the PDO
|
||||
//
|
||||
Status = IoCreateDevice(FDODeviceExtension->DriverObject, sizeof(PDO_DEVICE_EXTENSION), NULL, FILE_DEVICE_USB, FILE_AUTOGENERATED_DEVICE_NAME, FALSE, &PDODeviceObject);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
//
|
||||
// failed to create device object
|
||||
//
|
||||
DPRINT1("IoCreateDevice failed with %x\n", Status);
|
||||
return Status;
|
||||
}
|
||||
|
||||
//
|
||||
// store in array
|
||||
//
|
||||
FDODeviceExtension->ChildPDO[Index] = PDODeviceObject;
|
||||
|
||||
//
|
||||
// get device extension
|
||||
//
|
||||
PDODeviceExtension = (PPDO_DEVICE_EXTENSION)PDODeviceObject->DeviceExtension;
|
||||
RtlZeroMemory(PDODeviceExtension, sizeof(PDO_DEVICE_EXTENSION));
|
||||
|
||||
//
|
||||
// init device extension
|
||||
//
|
||||
PDODeviceExtension->Common.IsFDO = FALSE;
|
||||
PDODeviceExtension->FunctionDescriptor = &FDODeviceExtension->FunctionDescriptor[Index];
|
||||
PDODeviceExtension->NextDeviceObject = DeviceObject;
|
||||
PDODeviceExtension->FunctionIndex = Index;
|
||||
RtlCopyMemory(&PDODeviceExtension->Capabilities, &FDODeviceExtension->Capabilities, sizeof(DEVICE_CAPABILITIES));
|
||||
|
||||
//
|
||||
// patch the stack size
|
||||
//
|
||||
PDODeviceObject->StackSize = DeviceObject->StackSize + 1;
|
||||
|
||||
//
|
||||
// set device flags
|
||||
//
|
||||
PDODeviceObject->Flags |= DO_DIRECT_IO | DO_MAP_IO_BUFFER;
|
||||
|
||||
//
|
||||
// device is initialized
|
||||
//
|
||||
PDODeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
|
||||
}
|
||||
|
||||
//
|
||||
// done
|
||||
//
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
|
@ -206,13 +378,30 @@ FDO_StartDevice(
|
|||
ASSERT(FDODeviceExtension->FunctionDescriptor);
|
||||
|
||||
//
|
||||
// FIXME:create PDO for each function
|
||||
// now create the pdo
|
||||
//
|
||||
ASSERT(FALSE);
|
||||
Status = FDO_CreateChildPdo(DeviceObject);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
//
|
||||
// failed
|
||||
//
|
||||
DPRINT1("FDO_CreateChildPdo failed with %x\n", Status);
|
||||
return Status;
|
||||
}
|
||||
|
||||
//
|
||||
// inform pnp manager of new device objects
|
||||
//
|
||||
IoInvalidateDeviceRelations(FDODeviceExtension->PhysicalDeviceObject, BusRelations);
|
||||
|
||||
//
|
||||
// done
|
||||
//
|
||||
DPRINT1("[USBCCGP] FDO initialized successfully\n");
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS
|
||||
FDO_HandlePnp(
|
||||
PDEVICE_OBJECT DeviceObject,
|
||||
|
@ -234,11 +423,17 @@ FDO_HandlePnp(
|
|||
{
|
||||
case IRP_MN_START_DEVICE:
|
||||
{
|
||||
//
|
||||
// start the device
|
||||
//
|
||||
Status = FDO_StartDevice(DeviceObject, Irp);
|
||||
break;
|
||||
}
|
||||
case IRP_MN_QUERY_DEVICE_RELATIONS:
|
||||
{
|
||||
//
|
||||
// handle device relations
|
||||
//
|
||||
Status = FDO_DeviceRelations(DeviceObject, Irp);
|
||||
break;
|
||||
}
|
||||
|
@ -301,6 +496,7 @@ FDO_Dispatch(
|
|||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
return Status;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -11,6 +11,306 @@
|
|||
|
||||
#include "usbccgp.h"
|
||||
|
||||
NTSTATUS
|
||||
USBCCGP_PdoHandleQueryDeviceText(
|
||||
IN PDEVICE_OBJECT DeviceObject,
|
||||
IN OUT PIRP Irp)
|
||||
{
|
||||
LPWSTR Buffer;
|
||||
PPDO_DEVICE_EXTENSION PDODeviceExtension;
|
||||
|
||||
//
|
||||
// get device extension
|
||||
//
|
||||
PDODeviceExtension = (PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
||||
|
||||
//
|
||||
// is there a device description
|
||||
//
|
||||
if (PDODeviceExtension->FunctionDescriptor->FunctionDescription.Length)
|
||||
{
|
||||
//
|
||||
// allocate buffer
|
||||
//
|
||||
Buffer = AllocateItem(NonPagedPool, PDODeviceExtension->FunctionDescriptor->FunctionDescription.Length + sizeof(WCHAR));
|
||||
if (!Buffer)
|
||||
{
|
||||
//
|
||||
// no memory
|
||||
//
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
|
||||
//
|
||||
// copy buffer
|
||||
//
|
||||
Irp->IoStatus.Information = (ULONG_PTR)Buffer;
|
||||
RtlCopyMemory(Buffer, PDODeviceExtension->FunctionDescriptor->FunctionDescription.Buffer, PDODeviceExtension->FunctionDescriptor->FunctionDescription.Length);
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
//
|
||||
// FIXME use GenericCompositeUSBDeviceString
|
||||
//
|
||||
UNIMPLEMENTED
|
||||
return Irp->IoStatus.Status;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
USBCCGP_PdoHandleDeviceRelations(
|
||||
IN PDEVICE_OBJECT DeviceObject,
|
||||
IN OUT PIRP Irp)
|
||||
{
|
||||
PDEVICE_RELATIONS DeviceRelations;
|
||||
PIO_STACK_LOCATION IoStack;
|
||||
|
||||
DPRINT1("USBCCGP_PdoHandleDeviceRelations\n");
|
||||
|
||||
//
|
||||
// get current irp stack location
|
||||
//
|
||||
IoStack = IoGetCurrentIrpStackLocation(Irp);
|
||||
|
||||
//
|
||||
// check if relation type is BusRelations
|
||||
//
|
||||
if (IoStack->Parameters.QueryDeviceRelations.Type != TargetDeviceRelation)
|
||||
{
|
||||
//
|
||||
// PDO handles only target device relation
|
||||
//
|
||||
return Irp->IoStatus.Status;
|
||||
}
|
||||
|
||||
//
|
||||
// allocate device relations
|
||||
//
|
||||
DeviceRelations = (PDEVICE_RELATIONS)AllocateItem(PagedPool, sizeof(DEVICE_RELATIONS));
|
||||
if (!DeviceRelations)
|
||||
{
|
||||
//
|
||||
// no memory
|
||||
//
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
|
||||
//
|
||||
// initialize device relations
|
||||
//
|
||||
DeviceRelations->Count = 1;
|
||||
DeviceRelations->Objects[0] = DeviceObject;
|
||||
ObReferenceObject(DeviceObject);
|
||||
|
||||
//
|
||||
// store result
|
||||
//
|
||||
Irp->IoStatus.Information = (ULONG_PTR)DeviceRelations;
|
||||
|
||||
//
|
||||
// completed successfully
|
||||
//
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
USBCCGP_PdoHandleQueryId(
|
||||
PDEVICE_OBJECT DeviceObject,
|
||||
PIRP Irp)
|
||||
{
|
||||
PIO_STACK_LOCATION IoStack;
|
||||
PUNICODE_STRING DeviceString = NULL;
|
||||
UNICODE_STRING TempString;
|
||||
PPDO_DEVICE_EXTENSION PDODeviceExtension;
|
||||
NTSTATUS Status;
|
||||
LPWSTR Buffer;
|
||||
|
||||
//
|
||||
// get current irp stack location
|
||||
//
|
||||
IoStack = IoGetCurrentIrpStackLocation(Irp);
|
||||
|
||||
//
|
||||
// get device extension
|
||||
//
|
||||
PDODeviceExtension = (PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
||||
|
||||
|
||||
if (IoStack->Parameters.QueryId.IdType == BusQueryDeviceID)
|
||||
{
|
||||
//
|
||||
// handle query device id
|
||||
//
|
||||
Status = USBCCGP_SyncForwardIrp(PDODeviceExtension->NextDeviceObject, Irp);
|
||||
|
||||
//
|
||||
// FIXME append interface id
|
||||
//
|
||||
ASSERT(FALSE);
|
||||
return Status;
|
||||
}
|
||||
else if (IoStack->Parameters.QueryId.IdType == BusQueryHardwareIDs)
|
||||
{
|
||||
//
|
||||
// handle instance id
|
||||
//
|
||||
DeviceString = &PDODeviceExtension->FunctionDescriptor->HardwareId;
|
||||
}
|
||||
else if (IoStack->Parameters.QueryId.IdType == BusQueryInstanceID)
|
||||
{
|
||||
//
|
||||
// handle instance id
|
||||
//
|
||||
RtlInitUnicodeString(&TempString, L"0000");
|
||||
DeviceString = &TempString;
|
||||
}
|
||||
else if (IoStack->Parameters.QueryId.IdType == BusQueryCompatibleIDs)
|
||||
{
|
||||
//
|
||||
// handle instance id
|
||||
//
|
||||
DeviceString = &PDODeviceExtension->FunctionDescriptor->CompatibleId;
|
||||
}
|
||||
|
||||
//
|
||||
// sanity check
|
||||
//
|
||||
ASSERT(DeviceString != NULL);
|
||||
|
||||
//
|
||||
// allocate buffer
|
||||
//
|
||||
Buffer = AllocateItem(NonPagedPool, DeviceString->Length + sizeof(WCHAR));
|
||||
if (!Buffer)
|
||||
{
|
||||
//
|
||||
// no memory
|
||||
//
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
|
||||
//
|
||||
// copy buffer
|
||||
//
|
||||
Irp->IoStatus.Information = (ULONG_PTR)Buffer;
|
||||
RtlCopyMemory(Buffer, DeviceString->Buffer, DeviceString->Length);
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
PDO_HandlePnp(
|
||||
PDEVICE_OBJECT DeviceObject,
|
||||
PIRP Irp)
|
||||
{
|
||||
PIO_STACK_LOCATION IoStack;
|
||||
PPDO_DEVICE_EXTENSION PDODeviceExtension;
|
||||
NTSTATUS Status;
|
||||
|
||||
//
|
||||
// get current stack location
|
||||
//
|
||||
IoStack = IoGetCurrentIrpStackLocation(Irp);
|
||||
|
||||
//
|
||||
// get device extension
|
||||
//
|
||||
PDODeviceExtension = (PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
||||
|
||||
//
|
||||
// sanity check
|
||||
//
|
||||
ASSERT(PDODeviceExtension->Common.IsFDO == FALSE);
|
||||
|
||||
switch(IoStack->MinorFunction)
|
||||
{
|
||||
case IRP_MN_QUERY_DEVICE_RELATIONS:
|
||||
{
|
||||
//
|
||||
// handle device relations
|
||||
//
|
||||
Status = USBCCGP_PdoHandleDeviceRelations(DeviceObject, Irp);
|
||||
break;
|
||||
}
|
||||
case IRP_MN_QUERY_DEVICE_TEXT:
|
||||
{
|
||||
//
|
||||
// handle query device text
|
||||
//
|
||||
Status = USBCCGP_PdoHandleQueryDeviceText(DeviceObject, Irp);
|
||||
break;
|
||||
}
|
||||
case IRP_MN_QUERY_ID:
|
||||
{
|
||||
//
|
||||
// handle request
|
||||
//
|
||||
Status = USBCCGP_PdoHandleQueryId(DeviceObject, Irp);
|
||||
break;
|
||||
}
|
||||
case IRP_MN_REMOVE_DEVICE:
|
||||
{
|
||||
DPRINT1("IRP_MN_REMOVE_DEVICE\n");
|
||||
|
||||
/* Complete the IRP */
|
||||
Irp->IoStatus.Status = STATUS_SUCCESS;
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
|
||||
/* Delete the device object */
|
||||
IoDeleteDevice(DeviceObject);
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
case IRP_MN_QUERY_CAPABILITIES:
|
||||
{
|
||||
//
|
||||
// copy device capabilities
|
||||
//
|
||||
RtlCopyMemory(IoStack->Parameters.DeviceCapabilities.Capabilities, &PDODeviceExtension->Capabilities, sizeof(DEVICE_CAPABILITIES));
|
||||
|
||||
/* Complete the IRP */
|
||||
Irp->IoStatus.Status = STATUS_SUCCESS;
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
case IRP_MN_START_DEVICE:
|
||||
{
|
||||
//
|
||||
// no-op for PDO
|
||||
//
|
||||
DPRINT1("[USBCCGP] PDO IRP_MN_START\n");
|
||||
Status = STATUS_SUCCESS;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
//
|
||||
// do nothing
|
||||
//
|
||||
Status = Irp->IoStatus.Status;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// complete request
|
||||
//
|
||||
if (Status != STATUS_PENDING)
|
||||
{
|
||||
//
|
||||
// store result
|
||||
//
|
||||
Irp->IoStatus.Status = Status;
|
||||
|
||||
//
|
||||
// complete request
|
||||
//
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
}
|
||||
|
||||
//
|
||||
// done processing
|
||||
//
|
||||
return Status;
|
||||
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS
|
||||
|
@ -18,7 +318,22 @@ PDO_Dispatch(
|
|||
PDEVICE_OBJECT DeviceObject,
|
||||
PIRP Irp)
|
||||
{
|
||||
UNIMPLEMENTED
|
||||
ASSERT(FALSE);
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
PIO_STACK_LOCATION IoStack;
|
||||
NTSTATUS Status;
|
||||
|
||||
/* get stack location */
|
||||
IoStack = IoGetCurrentIrpStackLocation(Irp);
|
||||
|
||||
switch(IoStack->MajorFunction)
|
||||
{
|
||||
case IRP_MJ_PNP:
|
||||
return PDO_HandlePnp(DeviceObject, Irp);
|
||||
default:
|
||||
DPRINT1("PDO_Dispatch Function %x not implemented\n", IoStack->MajorFunction);
|
||||
ASSERT(FALSE);
|
||||
Status = Irp->IoStatus.Status;
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
return Status;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -38,6 +38,7 @@ typedef struct
|
|||
USBC_DEVICE_CONFIGURATION_INTERFACE_V1 BusInterface; // bus custom enumeration interface
|
||||
PUSBC_FUNCTION_DESCRIPTOR FunctionDescriptor; // usb function descriptor
|
||||
ULONG FunctionDescriptorCount; // number of function descriptor
|
||||
PDEVICE_OBJECT * ChildPDO; // child pdos
|
||||
}FDO_DEVICE_EXTENSION, *PFDO_DEVICE_EXTENSION;
|
||||
|
||||
#define USBCCPG_TAG 'cbsu'
|
||||
|
@ -45,7 +46,10 @@ typedef struct
|
|||
typedef struct
|
||||
{
|
||||
COMMON_DEVICE_EXTENSION Common; // shared with FDO
|
||||
|
||||
PUSBC_FUNCTION_DESCRIPTOR FunctionDescriptor; // function descriptor
|
||||
PDEVICE_OBJECT NextDeviceObject; // next device object
|
||||
DEVICE_CAPABILITIES Capabilities; // device capabilities
|
||||
ULONG FunctionIndex; // function index
|
||||
}PDO_DEVICE_EXTENSION, *PPDO_DEVICE_EXTENSION;
|
||||
|
||||
/* descriptor.c */
|
||||
|
|
Loading…
Reference in a new issue