Author: janderwald
Date: Thu Jan 26 19:11:44 2012
New Revision: 55219
URL:
http://svn.reactos.org/svn/reactos?rev=55219&view=rev
Log:
[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
Modified:
branches/usb-bringup-trunk/drivers/usb/usbccgp/fdo.c
branches/usb-bringup-trunk/drivers/usb/usbccgp/pdo.c
branches/usb-bringup-trunk/drivers/usb/usbccgp/usbccgp.h
Modified: branches/usb-bringup-trunk/drivers/usb/usbccgp/fdo.c
URL:
http://svn.reactos.org/svn/reactos/branches/usb-bringup-trunk/drivers/usb/u…
==============================================================================
--- branches/usb-bringup-trunk/drivers/usb/usbccgp/fdo.c [iso-8859-1] (original)
+++ branches/usb-bringup-trunk/drivers/usb/usbccgp/fdo.c [iso-8859-1] Thu Jan 26 19:11:44
2012
@@ -127,9 +127,181 @@
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,12 +378,29 @@
ASSERT(FDODeviceExtension->FunctionDescriptor);
//
- // FIXME:create PDO for each function
- //
- ASSERT(FALSE);
+ // now create the pdo
+ //
+ 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(
@@ -234,11 +423,17 @@
{
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 @@
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return Status;
}
-}
-
-
+
+}
+
+
Modified: branches/usb-bringup-trunk/drivers/usb/usbccgp/pdo.c
URL:
http://svn.reactos.org/svn/reactos/branches/usb-bringup-trunk/drivers/usb/u…
==============================================================================
--- branches/usb-bringup-trunk/drivers/usb/usbccgp/pdo.c [iso-8859-1] (original)
+++ branches/usb-bringup-trunk/drivers/usb/usbccgp/pdo.c [iso-8859-1] Thu Jan 26 19:11:44
2012
@@ -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 @@
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;
+ }
+
+}
Modified: branches/usb-bringup-trunk/drivers/usb/usbccgp/usbccgp.h
URL:
http://svn.reactos.org/svn/reactos/branches/usb-bringup-trunk/drivers/usb/u…
==============================================================================
--- branches/usb-bringup-trunk/drivers/usb/usbccgp/usbccgp.h [iso-8859-1] (original)
+++ branches/usb-bringup-trunk/drivers/usb/usbccgp/usbccgp.h [iso-8859-1] Thu Jan 26
19:11:44 2012
@@ -38,6 +38,7 @@
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
{
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 */