-ULONG STDCALL
-VideoPortInitialize(IN PVOID Context1,
- IN PVOID Context2,
- IN PVIDEO_HW_INITIALIZATION_DATA HwInitializationData,
- IN PVOID HwContext)
-{
- PUNICODE_STRING RegistryPath;
- UCHAR Again = FALSE;
- WCHAR DeviceBuffer[20];
- WCHAR SymlinkBuffer[20];
- WCHAR DeviceVideoBuffer[20];
- NTSTATUS Status;
- PDRIVER_OBJECT MPDriverObject = (PDRIVER_OBJECT) Context1;
- PDEVICE_OBJECT MPDeviceObject;
- VIDEO_PORT_CONFIG_INFO ConfigInfo;
- PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension;
- ULONG DisplayNumber;
- UNICODE_STRING DeviceName;
- UNICODE_STRING SymlinkName;
- ULONG MaxBus;
- ULONG MaxLen;
- KIRQL IRQL;
- KAFFINITY Affinity;
- ULONG InterruptVector;
- OBJECT_ATTRIBUTES Obj;
- HANDLE ObjHandle;
-
- DPRINT("VideoPortInitialize\n");
-
- RegistryPath = (PUNICODE_STRING) Context2;
-
- /* Build Dispatch table from passed data */
- MPDriverObject->DriverStartIo = (PDRIVER_STARTIO) HwInitializationData->HwStartIO;
-
- /* Find the first free device number */
- for (DisplayNumber = 0;;)
- {
- swprintf(SymlinkBuffer, L"\\??\\DISPLAY%lu", DisplayNumber + 1);
- RtlInitUnicodeString(&SymlinkName, SymlinkBuffer);
- InitializeObjectAttributes(&Obj, &SymlinkName, 0, NULL, NULL);
- Status = ZwOpenSymbolicLinkObject(&ObjHandle, GENERIC_READ, &Obj);
- if (NT_SUCCESS(Status))
- {
- ZwClose(ObjHandle);
- DisplayNumber++;
- continue;
- }
- else if (Status == STATUS_NOT_FOUND || Status == STATUS_UNSUCCESSFUL)
- {
- break;
- }
- else
- {
- return Status;
- }
- }
-
- DPRINT("- DisplayNumber: %d\n", DisplayNumber);
-
- Again = FALSE;
-
- do
- {
- /* Create a unicode device name. */
- swprintf(DeviceBuffer, L"\\Device\\Video%lu", DisplayNumber);
- RtlInitUnicodeString(&DeviceName, DeviceBuffer);
-
- /* Create the device. */
- Status = IoCreateDevice(
- MPDriverObject,
- HwInitializationData->HwDeviceExtensionSize +
- sizeof(VIDEO_PORT_DEVICE_EXTENSION),
- &DeviceName,
- FILE_DEVICE_VIDEO,
- 0,
- TRUE,
- &MPDeviceObject);
- if (!NT_SUCCESS(Status))
- {
- DPRINT("IoCreateDevice call failed with status 0x%08x\n", Status);
- return Status;
- }
-
- MPDriverObject->DeviceObject = MPDeviceObject;
-
- /* Initialize the miniport drivers dispatch table */
- MPDriverObject->MajorFunction[IRP_MJ_CREATE] = VidDispatchOpen;
- MPDriverObject->MajorFunction[IRP_MJ_CLOSE] = VidDispatchClose;
- MPDriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = VidDispatchDeviceControl;
-
- /* Initialize our device extension */
- DeviceExtension =
- (PVIDEO_PORT_DEVICE_EXTENSION) MPDeviceObject->DeviceExtension;
- DeviceExtension->DeviceObject = MPDeviceObject;
- DeviceExtension->HwInitialize = HwInitializationData->HwInitialize;
- DeviceExtension->HwResetHw = HwInitializationData->HwResetHw;
- DeviceExtension->AdapterInterfaceType = HwInitializationData->AdapterInterfaceType;
- DeviceExtension->SystemIoBusNumber = 0;
- MaxLen = (wcslen(RegistryPath->Buffer) + 10) * sizeof(WCHAR);
- DeviceExtension->RegistryPath.MaximumLength = MaxLen;
- DeviceExtension->RegistryPath.Buffer = ExAllocatePoolWithTag(PagedPool,
- MaxLen,
- TAG_VIDEO_PORT);
- swprintf(DeviceExtension->RegistryPath.Buffer, L"%s\\Device0",
- RegistryPath->Buffer);
- DeviceExtension->RegistryPath.Length = wcslen(DeviceExtension->RegistryPath.Buffer) *
- sizeof(WCHAR);
-
- MaxBus = (DeviceExtension->AdapterInterfaceType == PCIBus) ? 8 : 1;
- DPRINT("MaxBus: %lu\n", MaxBus);
- InitializeListHead(&DeviceExtension->AddressMappingListHead);
-
- /* Set the buffering strategy here... */
- /* If you change this, remember to change VidDispatchDeviceControl too */
- MPDeviceObject->Flags |= DO_BUFFERED_IO;
-
- do
- {
- RtlZeroMemory(&DeviceExtension->MiniPortDeviceExtension,
- HwInitializationData->HwDeviceExtensionSize);
- DPRINT("Searching on bus %d\n", DeviceExtension->SystemIoBusNumber);
- /* Setup configuration info */
- RtlZeroMemory(&ConfigInfo, sizeof(VIDEO_PORT_CONFIG_INFO));
- ConfigInfo.Length = sizeof(VIDEO_PORT_CONFIG_INFO);
- ConfigInfo.AdapterInterfaceType = DeviceExtension->AdapterInterfaceType;
- ConfigInfo.SystemIoBusNumber = DeviceExtension->SystemIoBusNumber;
- ConfigInfo.InterruptMode = (PCIBus == DeviceExtension->AdapterInterfaceType) ?
- LevelSensitive : Latched;
-
- /* Call HwFindAdapter entry point */
- /* FIXME: Need to figure out what string to pass as param 3 */
- Status = HwInitializationData->HwFindAdapter(&DeviceExtension->MiniPortDeviceExtension,
- Context2,
- NULL,
- &ConfigInfo,
- &Again);
- if (NO_ERROR != Status)
- {
- DPRINT("HwFindAdapter call failed with error %d\n", Status);
- DeviceExtension->SystemIoBusNumber++;
- }
- }
- while (NO_ERROR != Status && DeviceExtension->SystemIoBusNumber < MaxBus);
-
- if (NO_ERROR != Status)
- {
- RtlFreeUnicodeString(&DeviceExtension->RegistryPath);
- IoDeleteDevice(MPDeviceObject);
-
- return Status;
- }
- DPRINT("Found adapter\n");
-
- /* create symbolic link "\??\DISPLAYx" */
- swprintf(SymlinkBuffer, L"\\??\\DISPLAY%lu", DisplayNumber + 1);
- RtlInitUnicodeString (&SymlinkName,
- SymlinkBuffer);
- IoCreateSymbolicLink (&SymlinkName,
- &DeviceName);
-
- /* Add entry to DEVICEMAP\VIDEO key in registry */
- swprintf(DeviceVideoBuffer, L"\\Device\\Video%d", DisplayNumber);
- RtlWriteRegistryValue(RTL_REGISTRY_DEVICEMAP,
- L"VIDEO",
- DeviceVideoBuffer,
- REG_SZ,
- DeviceExtension->RegistryPath.Buffer,
- DeviceExtension->RegistryPath.Length + sizeof(WCHAR));
-
- /* FIXME: Allocate hardware resources for device */
-
- /* Allocate interrupt for device */
- DeviceExtension->HwInterrupt = HwInitializationData->HwInterrupt;
- if (0 == ConfigInfo.BusInterruptVector)
- {
- ConfigInfo.BusInterruptVector = DeviceExtension->InterruptVector;
- }
- if (0 == ConfigInfo.BusInterruptLevel)
- {
- ConfigInfo.BusInterruptLevel = DeviceExtension->InterruptLevel;
- }
- if (NULL != HwInitializationData->HwInterrupt)
- {
- InterruptVector =
- HalGetInterruptVector(ConfigInfo.AdapterInterfaceType,
- ConfigInfo.SystemIoBusNumber,
- ConfigInfo.BusInterruptLevel,
- ConfigInfo.BusInterruptVector,
- &IRQL,
- &Affinity);
- if (0 == InterruptVector)
- {
- DPRINT1("HalGetInterruptVector failed\n");
- IoDeleteDevice(MPDeviceObject);
-
- return STATUS_INSUFFICIENT_RESOURCES;
- }
- KeInitializeSpinLock(&DeviceExtension->InterruptSpinLock);
- Status = IoConnectInterrupt(&DeviceExtension->InterruptObject,
- VPInterruptRoutine,
- DeviceExtension,
- &DeviceExtension->InterruptSpinLock,
- InterruptVector,
- IRQL,
- IRQL,
- ConfigInfo.InterruptMode,
- FALSE,
- Affinity,
- FALSE);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("IoConnectInterrupt failed with status 0x%08x\n", Status);
- IoDeleteDevice(MPDeviceObject);
-
- return Status;
- }
- }
- DisplayNumber++;
- }
- while (Again);
-
- DeviceExtension->HwTimer = HwInitializationData->HwTimer;
- if (HwInitializationData->HwTimer != NULL)
- {
- DPRINT("Initializing timer\n");
- Status = IoInitializeTimer(MPDeviceObject,
- VPTimerRoutine,
- DeviceExtension);
- if (!NT_SUCCESS(Status))
- {
- DPRINT("IoInitializeTimer failed with status 0x%08x\n", Status);
-
- if (HwInitializationData->HwInterrupt != NULL)
- {
- IoDisconnectInterrupt(DeviceExtension->InterruptObject);
- }
- IoDeleteDevice(MPDeviceObject);
-
- return Status;
- }
- }
-
- return STATUS_SUCCESS;
-}