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/CMa…
==============================================================================
--- 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/chi…
==============================================================================
--- 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/dis…
==============================================================================
--- 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/vid…
==============================================================================
--- 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/vid…
==============================================================================
--- 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