Author: cgutman Date: Mon Mar 12 03:29:36 2012 New Revision: 56128
URL: http://svn.reactos.org/svn/reactos?rev=56128&view=rev Log: [VIDEOPRT] - Fix broken VIDEO_PORT_GET_DEVICE_EXTENSION macro - Add support for child devices (monitors only for now) - Monitors now show up in device manager ("Plug and Play Monitor" shows up if EDID data is reported, otherwise "Default Monitor" is displayed)
Added: trunk/reactos/drivers/video/videoprt/child.c (with props) Modified: trunk/reactos/drivers/video/videoprt/CMakeLists.txt trunk/reactos/drivers/video/videoprt/dispatch.c trunk/reactos/drivers/video/videoprt/videoprt.c trunk/reactos/drivers/video/videoprt/videoprt.h
Modified: trunk/reactos/drivers/video/videoprt/CMakeLists.txt URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/video/videoprt/CMak... ============================================================================== --- trunk/reactos/drivers/video/videoprt/CMakeLists.txt [iso-8859-1] (original) +++ trunk/reactos/drivers/video/videoprt/CMakeLists.txt [iso-8859-1] Mon Mar 12 03:29:36 2012 @@ -7,6 +7,7 @@
list(APPEND SOURCE agp.c + child.c ddc.c dispatch.c dma.c
Added: trunk/reactos/drivers/video/videoprt/child.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/video/videoprt/chil... ============================================================================== --- trunk/reactos/drivers/video/videoprt/child.c (added) +++ trunk/reactos/drivers/video/videoprt/child.c [iso-8859-1] Mon Mar 12 03:29:36 2012 @@ -1,0 +1,396 @@ +/* + * VideoPort driver + * + * Copyright (C) 2012 ReactOS Team + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#include "videoprt.h" + +/* PRIVATE FUNCTIONS **********************************************************/ + +BOOLEAN +NTAPI +IntVideoPortGetMonitorId( + IN PVIDEO_PORT_CHILD_EXTENSION ChildExtension, + IN OUT PWCHAR Buffer) +{ + USHORT Manufacturer, Model; + UNICODE_STRING UnicodeModelStr; + + /* This must be valid to call this function */ + ASSERT(ChildExtension->EdidValid); + + /* 3 letters 5-bit ANSI manufacturer code (big endian) */ + Manufacturer = *(PUSHORT)(&ChildExtension->ChildDescriptor[8]); + + /* Letters encoded as A=1 to Z=26 */ + Buffer[0] = (WCHAR)((Manufacturer & 0x7C00) + 'A' - 1); + Buffer[1] = (WCHAR)((Manufacturer & 0x03E0) + 'A' - 1); + Buffer[2] = (WCHAR)((Manufacturer & 0x001F) + 'A' - 1); + + /* Model number (16-bit little endian) */ + Model = *(PUSHORT)(&ChildExtension->ChildDescriptor[10]); + + /* Use Rtl helper for conversion */ + UnicodeModelStr.Buffer = &Buffer[3]; + UnicodeModelStr.Length = 0; + UnicodeModelStr.MaximumLength = 4 * sizeof(WCHAR); + RtlIntegerToUnicodeString(Model, 16, &UnicodeModelStr); + + /* Terminate it */ + Buffer[7] = UNICODE_NULL; + + /* And we're done */ + return TRUE; +} + +NTSTATUS NTAPI +IntVideoPortChildQueryId( + IN PVIDEO_PORT_CHILD_EXTENSION ChildExtension, + IN PIRP Irp, + IN PIO_STACK_LOCATION IrpSp) +{ + PWCHAR Buffer = NULL, StaticBuffer; + UNICODE_STRING UnicodeStr; + ULONG Length; + + switch (IrpSp->Parameters.QueryId.IdType) + { + case BusQueryDeviceID: + switch (ChildExtension->ChildType) + { + case Monitor: + if (ChildExtension->EdidValid) + { + StaticBuffer = L"DISPLAY\"; + Length = 8 * sizeof(WCHAR); + Buffer = ExAllocatePool(PagedPool, (wcslen(StaticBuffer) + 8) * sizeof(WCHAR)); + if (!Buffer) return STATUS_NO_MEMORY; + + /* Write the static portion */ + RtlCopyMemory(Buffer, StaticBuffer, wcslen(StaticBuffer) * sizeof(WCHAR)); + + /* Add the dynamic portion */ + IntVideoPortGetMonitorId(ChildExtension, + &Buffer[wcslen(StaticBuffer)]); + } + else + { + StaticBuffer = L"DISPLAY\Default_Monitor"; + Length = wcslen(StaticBuffer) * sizeof(WCHAR); + Buffer = ExAllocatePool(PagedPool, (wcslen(StaticBuffer) + 1) * sizeof(WCHAR)); + if (!Buffer) return STATUS_NO_MEMORY; + + /* Copy the default id */ + RtlCopyMemory(Buffer, StaticBuffer, (wcslen(StaticBuffer) + 1) * sizeof(WCHAR)); + } + break; + default: + ASSERT(FALSE); + break; + } + break; + case BusQueryInstanceID: + Buffer = ExAllocatePool(PagedPool, 5 * sizeof(WCHAR)); + if (!Buffer) return STATUS_NO_MEMORY; + + UnicodeStr.Buffer = Buffer; + UnicodeStr.Length = 0; + UnicodeStr.MaximumLength = 4 * sizeof(WCHAR); + RtlIntegerToUnicodeString(ChildExtension->ChildId, 16, &UnicodeStr); + break; + case BusQueryHardwareIDs: + switch (ChildExtension->ChildType) + { + case Monitor: + if (ChildExtension->EdidValid) + { + StaticBuffer = L"MONITOR\"; + Length = 8 * sizeof(WCHAR); + Buffer = ExAllocatePool(PagedPool, (wcslen(StaticBuffer) + 9) * sizeof(WCHAR)); + if (!Buffer) return STATUS_NO_MEMORY; + + /* Write the static portion */ + RtlCopyMemory(Buffer, StaticBuffer, wcslen(StaticBuffer) * sizeof(WCHAR)); + + /* Add the dynamic portion */ + IntVideoPortGetMonitorId(ChildExtension, + &Buffer[wcslen(StaticBuffer)]); + + /* Add the second null termination char */ + Buffer[wcslen(StaticBuffer) + 8] = UNICODE_NULL; + } + else + { + StaticBuffer = L"MONITOR\Default_Monitor"; + Length = wcslen(StaticBuffer) * sizeof(WCHAR); + Buffer = ExAllocatePool(PagedPool, (wcslen(StaticBuffer) + 2) * sizeof(WCHAR)); + if (!Buffer) return STATUS_NO_MEMORY; + + /* Copy the default id */ + RtlCopyMemory(Buffer, StaticBuffer, (wcslen(StaticBuffer) + 1) * sizeof(WCHAR)); + + /* Add the second null terminator */ + Buffer[wcslen(StaticBuffer) + 1] = UNICODE_NULL; + } + break; + default: + ASSERT(FALSE); + break; + } + break; + case BusQueryCompatibleIDs: + switch (ChildExtension->ChildType) + { + case Monitor: + if (ChildExtension->EdidValid) + { + StaticBuffer = L"*PNP09FF"; + Buffer = ExAllocatePool(PagedPool, (wcslen(StaticBuffer) + 2) * sizeof(WCHAR)); + if (!Buffer) return STATUS_NO_MEMORY; + + RtlCopyMemory(Buffer, StaticBuffer, (wcslen(StaticBuffer) + 1) * sizeof(WCHAR)); + + Buffer[wcslen(StaticBuffer)+1] = UNICODE_NULL; + } + else + { + /* No PNP ID for non-PnP monitors */ + return Irp->IoStatus.Status; + } + break; + default: + ASSERT(FALSE); + break; + } + break; + default: + return Irp->IoStatus.Status; + } + + INFO_(VIDEOPRT, "Reporting ID: %S\n", Buffer); + Irp->IoStatus.Information = (ULONG_PTR)Buffer; + + return STATUS_SUCCESS; +} + +NTSTATUS NTAPI +IntVideoPortChildQueryText( + IN PVIDEO_PORT_CHILD_EXTENSION ChildExtension, + IN PIRP Irp, + IN PIO_STACK_LOCATION IrpSp) +{ + PWCHAR Buffer, StaticBuffer; + + if (IrpSp->Parameters.QueryDeviceText.DeviceTextType != DeviceTextDescription) + return Irp->IoStatus.Status; + + switch (ChildExtension->ChildType) + { + case Monitor: + /* FIXME: We can return a better description I think */ + StaticBuffer = L"Monitor"; + break; + + case VideoChip: + /* FIXME: No idea what we return here */ + StaticBuffer = L"Video chip"; + break; + + default: /* Other */ + StaticBuffer = L"Other device"; + break; + } + + Buffer = ExAllocatePool(PagedPool, (wcslen(StaticBuffer) + 1) * sizeof(WCHAR)); + if (!Buffer) return STATUS_NO_MEMORY; + + RtlCopyMemory(Buffer, StaticBuffer, (wcslen(StaticBuffer) + 1) * sizeof(WCHAR)); + + INFO_(VIDEOPRT, "Reporting description: %S\n", Buffer); + Irp->IoStatus.Information = (ULONG_PTR)Buffer; + + return STATUS_SUCCESS; +} + +NTSTATUS NTAPI +IntVideoPortChildQueryRelations( + IN PVIDEO_PORT_CHILD_EXTENSION ChildExtension, + IN PIRP Irp, + IN PIO_STACK_LOCATION IrpSp) +{ + PDEVICE_RELATIONS DeviceRelations; + + if (IrpSp->Parameters.QueryDeviceRelations.Type != TargetDeviceRelation) + { + WARN_(VIDEOPRT, "Unsupported device relations type\n"); + return Irp->IoStatus.Status; + } + + DeviceRelations = ExAllocatePool(NonPagedPool, sizeof(DEVICE_RELATIONS)); + if (!DeviceRelations) return STATUS_NO_MEMORY; + + DeviceRelations->Count = 1; + DeviceRelations->Objects[0] = ChildExtension->PhysicalDeviceObject; + + ObReferenceObject(DeviceRelations->Objects[0]); + + Irp->IoStatus.Information = (ULONG_PTR)DeviceRelations; + + return STATUS_SUCCESS; +} + +NTSTATUS NTAPI +IntVideoPortChildQueryCapabilities( + IN PVIDEO_PORT_CHILD_EXTENSION ChildExtension, + IN PIRP Irp, + IN PIO_STACK_LOCATION IrpSp) +{ + PDEVICE_CAPABILITIES DeviceCaps = IrpSp->Parameters.DeviceCapabilities.Capabilities; + ULONG i; + + /* Set some values */ + DeviceCaps->LockSupported = FALSE; + DeviceCaps->EjectSupported = FALSE; + DeviceCaps->DockDevice = FALSE; + DeviceCaps->UniqueID = FALSE; + DeviceCaps->RawDeviceOK = FALSE; + DeviceCaps->WakeFromD0 = FALSE; + DeviceCaps->WakeFromD1 = FALSE; + DeviceCaps->WakeFromD2 = FALSE; + DeviceCaps->WakeFromD3 = FALSE; + DeviceCaps->HardwareDisabled = FALSE; + DeviceCaps->NoDisplayInUI = FALSE; + + /* Address and UI number are set by default */ + + DeviceCaps->DeviceState[PowerSystemWorking] = PowerDeviceD0; + for (i = 1; i < POWER_SYSTEM_MAXIMUM; i++) + { + DeviceCaps->DeviceState[i] = PowerDeviceD3; + } + + DeviceCaps->SystemWake = PowerSystemUnspecified; + DeviceCaps->DeviceWake = PowerDeviceUnspecified; + + /* FIXME: Device power states */ + DeviceCaps->DeviceD1 = FALSE; + DeviceCaps->DeviceD2 = FALSE; + DeviceCaps->D1Latency = 0; + DeviceCaps->D2Latency = 0; + DeviceCaps->D3Latency = 0; + + switch (ChildExtension->ChildType) + { + case VideoChip: + /* FIXME: Copy capabilities from parent */ + ASSERT(FALSE); + break; + + case NonPrimaryChip: /* Reserved */ + ASSERT(FALSE); + break; + + case Monitor: + DeviceCaps->SilentInstall = TRUE; + DeviceCaps->Removable = TRUE; + DeviceCaps->SurpriseRemovalOK = TRUE; + break; + + default: /* Other */ + DeviceCaps->SilentInstall = FALSE; + DeviceCaps->Removable = FALSE; + DeviceCaps->SurpriseRemovalOK = FALSE; + break; + } + + return STATUS_SUCCESS; +} + +NTSTATUS NTAPI +IntVideoPortDispatchPdoPnp( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + PIO_STACK_LOCATION IrpSp; + NTSTATUS Status = Irp->IoStatus.Status; + + IrpSp = IoGetCurrentIrpStackLocation(Irp); + + switch (IrpSp->MinorFunction) + { + case IRP_MN_START_DEVICE: + case IRP_MN_STOP_DEVICE: + /* Nothing to do */ + Status = STATUS_SUCCESS; + break; + + case IRP_MN_QUERY_RESOURCES: + case IRP_MN_QUERY_RESOURCE_REQUIREMENTS: + /* None (keep old status) */ + break; + + case IRP_MN_QUERY_ID: + /* Call our helper */ + Status = IntVideoPortChildQueryId(DeviceObject->DeviceExtension, + Irp, + IrpSp); + break; + + case IRP_MN_QUERY_CAPABILITIES: + /* Call our helper */ + Status = IntVideoPortChildQueryCapabilities(DeviceObject->DeviceExtension, + Irp, + IrpSp); + break; + + case IRP_MN_SURPRISE_REMOVAL: + case IRP_MN_QUERY_REMOVE_DEVICE: + Status = STATUS_SUCCESS; + break; + + case IRP_MN_REMOVE_DEVICE: + Irp->IoStatus.Status = STATUS_SUCCESS; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + IoDeleteDevice(DeviceObject); + return STATUS_SUCCESS; + + case IRP_MN_QUERY_DEVICE_RELATIONS: + /* Call our helper */ + Status = IntVideoPortChildQueryRelations(DeviceObject->DeviceExtension, + Irp, + IrpSp); + break; + + case IRP_MN_QUERY_DEVICE_TEXT: + /* Call our helper */ + Status = IntVideoPortChildQueryText(DeviceObject->DeviceExtension, + Irp, + IrpSp); + break; + + default: + break; + } + + Irp->IoStatus.Status = Status; + + IoCompleteRequest(Irp, IO_NO_INCREMENT); + + return Status; +}
Propchange: trunk/reactos/drivers/video/videoprt/child.c ------------------------------------------------------------------------------ svn:eol-style = native
Modified: trunk/reactos/drivers/video/videoprt/dispatch.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/video/videoprt/disp... ============================================================================== --- trunk/reactos/drivers/video/videoprt/dispatch.c [iso-8859-1] (original) +++ trunk/reactos/drivers/video/videoprt/dispatch.c [iso-8859-1] Mon Mar 12 03:29:36 2012 @@ -410,6 +410,51 @@ return STATUS_MORE_PROCESSING_REQUIRED; }
+NTSTATUS +NTAPI +IntVideoPortQueryBusRelations(PDEVICE_OBJECT DeviceObject, PIRP Irp) +{ + PDEVICE_RELATIONS DeviceRelations; + PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension = DeviceObject->DeviceExtension; + PVIDEO_PORT_CHILD_EXTENSION ChildExtension; + ULONG i; + PLIST_ENTRY CurrentEntry; + + /* Count the children */ + i = 0; + CurrentEntry = DeviceExtension->ChildDeviceList.Flink; + while (CurrentEntry != &DeviceExtension->ChildDeviceList) + { + i++; + CurrentEntry = CurrentEntry->Flink; + } + + if (i == 0) + return Irp->IoStatus.Status; + + DeviceRelations = ExAllocatePool(PagedPool, sizeof(DEVICE_RELATIONS) + ((i - 1) * sizeof(PVOID))); + if (!DeviceRelations) return STATUS_NO_MEMORY; + + DeviceRelations->Count = i; + + /* Add the children */ + i = 0; + CurrentEntry = DeviceExtension->ChildDeviceList.Flink; + while (CurrentEntry != &DeviceExtension->ChildDeviceList) + { + ChildExtension = CONTAINING_RECORD(CurrentEntry, VIDEO_PORT_CHILD_EXTENSION, ListEntry); + + DeviceRelations->Objects[i] = ChildExtension->PhysicalDeviceObject; + + i++; + CurrentEntry = CurrentEntry->Flink; + } + + INFO_(VIDEOPRT, "Reported %d PDOs\n", i); + Irp->IoStatus.Information = (ULONG_PTR)DeviceRelations; + + return STATUS_SUCCESS; +}
NTSTATUS NTAPI @@ -433,14 +478,14 @@ return Status; }
- -NTSTATUS NTAPI -IntVideoPortDispatchPnp( +NTSTATUS NTAPI +IntVideoPortDispatchFdoPnp( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) { PIO_STACK_LOCATION IrpSp; NTSTATUS Status; + PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension = DeviceObject->DeviceExtension;
IrpSp = IoGetCurrentIrpStackLocation(Irp);
@@ -464,6 +509,20 @@ IoCompleteRequest(Irp, IO_NO_INCREMENT); break;
+ case IRP_MN_QUERY_DEVICE_RELATIONS: + if (IrpSp->Parameters.QueryDeviceRelations.Type != BusRelations) + { + IoSkipCurrentIrpStackLocation(Irp); + Status = IoCallDriver(DeviceExtension->NextDeviceObject, Irp); + } + else + { + Status = IntVideoPortQueryBusRelations(DeviceObject, Irp); + Irp->IoStatus.Status = Status; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + } + break; + case IRP_MN_REMOVE_DEVICE: case IRP_MN_QUERY_REMOVE_DEVICE: case IRP_MN_CANCEL_REMOVE_DEVICE: @@ -496,6 +555,19 @@ }
NTSTATUS NTAPI +IntVideoPortDispatchPnp( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + PVIDEO_PORT_COMMON_EXTENSION CommonExtension = DeviceObject->DeviceExtension; + + if (CommonExtension->Fdo) + return IntVideoPortDispatchFdoPnp(DeviceObject, Irp); + else + return IntVideoPortDispatchPdoPnp(DeviceObject, Irp); +} + +NTSTATUS NTAPI IntVideoPortDispatchCleanup( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Modified: trunk/reactos/drivers/video/videoprt/videoprt.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/video/videoprt/vide... ============================================================================== --- trunk/reactos/drivers/video/videoprt/videoprt.c [iso-8859-1] (original) +++ trunk/reactos/drivers/video/videoprt/videoprt.c [iso-8859-1] Mon Mar 12 03:29:36 2012 @@ -250,11 +250,14 @@ */
DeviceExtension = (PVIDEO_PORT_DEVICE_EXTENSION)((*DeviceObject)->DeviceExtension); + DeviceExtension->Common.Fdo = TRUE; DeviceExtension->DeviceNumber = DeviceNumber; DeviceExtension->DriverObject = DriverObject; DeviceExtension->PhysicalDeviceObject = PhysicalDeviceObject; DeviceExtension->FunctionalDeviceObject = *DeviceObject; DeviceExtension->DriverExtension = DriverExtension; + + InitializeListHead(&DeviceExtension->ChildDeviceList);
/* * Get the registry path associated with this driver. @@ -1097,14 +1100,14 @@ PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension; ULONG Status; VIDEO_CHILD_ENUM_INFO ChildEnumInfo; - VIDEO_CHILD_TYPE ChildType; BOOLEAN bHaveLastMonitorID = FALSE; UCHAR LastMonitorID[10]; - UCHAR ChildDescriptor[256]; - ULONG ChildId; ULONG Unused; UINT i; - + PDEVICE_OBJECT ChildDeviceObject; + PVIDEO_PORT_CHILD_EXTENSION ChildExtension; + + INFO_(VIDEOPRT, "Starting child device probe\n"); DeviceExtension = VIDEO_PORT_GET_DEVICE_EXTENSION(HwDeviceExtension); if (DeviceExtension->DriverExtension->InitializationData.HwGetVideoChildDescriptor == NULL) { @@ -1112,95 +1115,144 @@ return NO_ERROR; }
- /* Setup the ChildEnumInfo */ - ChildEnumInfo.Size = sizeof (ChildEnumInfo); - ChildEnumInfo.ChildDescriptorSize = sizeof (ChildDescriptor); - ChildEnumInfo.ACPIHwId = 0; - ChildEnumInfo.ChildHwDeviceExtension = NULL; /* FIXME: must be set to - ChildHwDeviceExtension... */ + if (!IsListEmpty(&DeviceExtension->ChildDeviceList)) + { + ERR_(VIDEOPRT, "FIXME: Support calling VideoPortEnumerateChildren again!\n"); + return NO_ERROR; + }
/* Enumerate the children */ for (i = 1; ; i++) { - ChildEnumInfo.ChildIndex = i; - RtlZeroMemory(ChildDescriptor, sizeof(ChildDescriptor)); + Status = IoCreateDevice(DeviceExtension->DriverObject, + sizeof(VIDEO_PORT_CHILD_EXTENSION) + + DeviceExtension->DriverExtension->InitializationData.HwChildDeviceExtensionSize, + NULL, + FILE_DEVICE_CONTROLLER, + FILE_DEVICE_SECURE_OPEN, + FALSE, + &ChildDeviceObject); + if (!NT_SUCCESS(Status)) + return Status; + + ChildExtension = ChildDeviceObject->DeviceExtension; + + RtlZeroMemory(ChildExtension, sizeof(VIDEO_PORT_CHILD_EXTENSION) + + DeviceExtension->DriverExtension->InitializationData.HwChildDeviceExtensionSize); + + ChildExtension->Common.Fdo = FALSE; + ChildExtension->ChildId = i; + ChildExtension->PhysicalDeviceObject = ChildDeviceObject; + ChildExtension->DriverObject = DeviceExtension->DriverObject; + + /* Setup the ChildEnumInfo */ + ChildEnumInfo.Size = sizeof(ChildEnumInfo); + ChildEnumInfo.ChildDescriptorSize = sizeof(ChildExtension->ChildDescriptor); + ChildEnumInfo.ACPIHwId = 0; + + if (DeviceExtension->DriverExtension->InitializationData.HwChildDeviceExtensionSize) + ChildEnumInfo.ChildHwDeviceExtension = VIDEO_PORT_GET_CHILD_EXTENSION(ChildExtension); + else + ChildEnumInfo.ChildHwDeviceExtension = NULL; + + ChildEnumInfo.ChildIndex = ChildExtension->ChildId; + + INFO_(VIDEOPRT, "Probing child: %d\n", ChildEnumInfo.ChildIndex); Status = DeviceExtension->DriverExtension->InitializationData.HwGetVideoChildDescriptor( HwDeviceExtension, &ChildEnumInfo, - &ChildType, - ChildDescriptor, - &ChildId, + &ChildExtension->ChildType, + ChildExtension->ChildDescriptor, + &ChildExtension->ChildId, &Unused); if (Status == VIDEO_ENUM_MORE_DEVICES) { - if (ChildType == Monitor) + if (ChildExtension->ChildType == Monitor) { // Check if the EDID is valid - if (ChildDescriptor[0] == 0x00 && - ChildDescriptor[1] == 0xFF && - ChildDescriptor[2] == 0xFF && - ChildDescriptor[3] == 0xFF && - ChildDescriptor[4] == 0xFF && - ChildDescriptor[5] == 0xFF && - ChildDescriptor[6] == 0xFF && - ChildDescriptor[7] == 0x00) + if (ChildExtension->ChildDescriptor[0] == 0x00 && + ChildExtension->ChildDescriptor[1] == 0xFF && + ChildExtension->ChildDescriptor[2] == 0xFF && + ChildExtension->ChildDescriptor[3] == 0xFF && + ChildExtension->ChildDescriptor[4] == 0xFF && + ChildExtension->ChildDescriptor[5] == 0xFF && + ChildExtension->ChildDescriptor[6] == 0xFF && + ChildExtension->ChildDescriptor[7] == 0x00) { if (bHaveLastMonitorID) { // Compare the previous monitor ID with the current one, break the loop if they are identical - if (RtlCompareMemory(LastMonitorID, &ChildDescriptor[8], sizeof(LastMonitorID)) == sizeof(LastMonitorID)) + if (RtlCompareMemory(LastMonitorID, &ChildExtension->ChildDescriptor[8], sizeof(LastMonitorID)) == sizeof(LastMonitorID)) { INFO_(VIDEOPRT, "Found identical Monitor ID two times, stopping enumeration\n"); + IoDeleteDevice(ChildDeviceObject); break; } }
// Copy 10 bytes from the EDID, which can be used to uniquely identify the monitor - RtlCopyMemory(LastMonitorID, &ChildDescriptor[8], sizeof(LastMonitorID)); + RtlCopyMemory(LastMonitorID, &ChildExtension->ChildDescriptor[8], sizeof(LastMonitorID)); bHaveLastMonitorID = TRUE; + + /* Mark it valid */ + ChildExtension->EdidValid = TRUE; + } + else + { + /* Mark it invalid */ + ChildExtension->EdidValid = FALSE; } } } else if (Status == VIDEO_ENUM_INVALID_DEVICE) { WARN_(VIDEOPRT, "Child device %d is invalid!\n", ChildEnumInfo.ChildIndex); + IoDeleteDevice(ChildDeviceObject); continue; } else if (Status == VIDEO_ENUM_NO_MORE_DEVICES) { INFO_(VIDEOPRT, "End of child enumeration! (%d children enumerated)\n", i - 1); + IoDeleteDevice(ChildDeviceObject); break; } else { WARN_(VIDEOPRT, "HwGetVideoChildDescriptor returned unknown status code 0x%x!\n", Status); + IoDeleteDevice(ChildDeviceObject); break; }
-#ifndef NDEBUG - if (ChildType == Monitor) + if (ChildExtension->ChildType == Monitor) { UINT j; - PUCHAR p = ChildDescriptor; - INFO_(VIDEOPRT, "Monitor device enumerated! (ChildId = 0x%x)\n", ChildId); - for (j = 0; j < sizeof (ChildDescriptor); j += 8) + PUCHAR p = ChildExtension->ChildDescriptor; + INFO_(VIDEOPRT, "Monitor device enumerated! (ChildId = 0x%x)\n", ChildExtension->ChildId); + for (j = 0; j < sizeof (ChildExtension->ChildDescriptor); j += 8) { INFO_(VIDEOPRT, "%02x %02x %02x %02x %02x %02x %02x %02x\n", p[j+0], p[j+1], p[j+2], p[j+3], p[j+4], p[j+5], p[j+6], p[j+7]); } } - else if (ChildType == Other) - { - INFO_(VIDEOPRT, ""Other" device enumerated: DeviceId = %S\n", (PWSTR)ChildDescriptor); + else if (ChildExtension->ChildType == Other) + { + INFO_(VIDEOPRT, ""Other" device enumerated: DeviceId = %S\n", (PWSTR)ChildExtension->ChildDescriptor); } else { - WARN_(VIDEOPRT, "HwGetVideoChildDescriptor returned unsupported type: %d\n", ChildType); - } -#endif /* NDEBUG */ - - } + ERR_(VIDEOPRT, "HwGetVideoChildDescriptor returned unsupported type: %d\n", ChildExtension->ChildType); + } + + /* Clear the init flag */ + ChildDeviceObject->Flags &= ~DO_DEVICE_INITIALIZING; + + InsertTailList(&DeviceExtension->ChildDeviceList, + &ChildExtension->ListEntry); + } + + /* Trigger reenumeration by the PnP manager */ + IoInvalidateDeviceRelations(DeviceExtension->PhysicalDeviceObject, BusRelations);
return NO_ERROR; }
Modified: trunk/reactos/drivers/video/videoprt/videoprt.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/video/videoprt/vide... ============================================================================== --- trunk/reactos/drivers/video/videoprt/videoprt.h [iso-8859-1] (original) +++ trunk/reactos/drivers/video/videoprt/videoprt.h [iso-8859-1] Mon Mar 12 03:29:36 2012 @@ -78,8 +78,14 @@ UNICODE_STRING RegistryPath; } VIDEO_PORT_DRIVER_EXTENSION, *PVIDEO_PORT_DRIVER_EXTENSION;
+typedef struct _VIDEO_PORT_COMMON_EXTENSION +{ + BOOLEAN Fdo; +} VIDEO_PORT_COMMON_EXTENSION, *PVIDEO_PORT_COMMON_EXTENSION; + typedef struct _VIDEO_PORT_DEVICE_EXTENSTION { + VIDEO_PORT_COMMON_EXTENSION Common; ULONG DeviceNumber; PDRIVER_OBJECT DriverObject; PDEVICE_OBJECT PhysicalDeviceObject; @@ -101,13 +107,37 @@ ULONG DeviceOpened; AGP_BUS_INTERFACE_STANDARD AgpInterface; KMUTEX DeviceLock; - LIST_ENTRY DmaAdapterList; + LIST_ENTRY DmaAdapterList, ChildDeviceList; CHAR MiniPortDeviceExtension[1]; } VIDEO_PORT_DEVICE_EXTENSION, *PVIDEO_PORT_DEVICE_EXTENSION;
+typedef struct _VIDEO_PORT_CHILD_EXTENSION +{ + VIDEO_PORT_COMMON_EXTENSION Common; + + ULONG ChildId; + VIDEO_CHILD_TYPE ChildType; + UCHAR ChildDescriptor[256]; + + BOOLEAN EdidValid; + + PDRIVER_OBJECT DriverObject; + PDEVICE_OBJECT PhysicalDeviceObject; + + LIST_ENTRY ListEntry; + + CHAR ChildDeviceExtension[1]; +} VIDEO_PORT_CHILD_EXTENSION, *PVIDEO_PORT_CHILD_EXTENSION; + +#define VIDEO_PORT_GET_CHILD_EXTENSION(MiniportExtension) \ + CONTAINING_RECORD( \ + MiniportExtension, \ + VIDEO_PORT_CHILD_EXTENSION, \ + ChildDeviceExtension) + #define VIDEO_PORT_GET_DEVICE_EXTENSION(MiniportExtension) \ CONTAINING_RECORD( \ - HwDeviceExtension, \ + MiniportExtension, \ VIDEO_PORT_DEVICE_EXTENSION, \ MiniPortDeviceExtension)
@@ -130,6 +160,13 @@ IN PVOID HwDeviceExtension, IN OUT PINTERFACE Interface);
+/* child.c */ + +NTSTATUS NTAPI +IntVideoPortDispatchPdoPnp( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp); + /* dispatch.c */
NTSTATUS NTAPI