4 * Copyright (C) 2002, 2003, 2004 ReactOS Team
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
16 * You should have received a copy of the GNU Library General Public
17 * License along with this library; see the file COPYING.LIB.
18 * If not, write to the Free Software Foundation,
19 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
26 /* EXTERNAL FUNCTIONS *********************************************************/
28 typedef PVOID PHAL_RESET_DISPLAY_PARAMETERS
;
29 VOID STDCALL
HalAcquireDisplayOwnership(IN PHAL_RESET_DISPLAY_PARAMETERS ResetDisplayParameters
);
30 VOID STDCALL
HalReleaseDisplayOwnership();
32 /* GLOBAL VARIABLES ***********************************************************/
34 PVIDEO_PORT_DEVICE_EXTENSION ResetDisplayParametersDeviceExtension
= NULL
;
36 /* PRIVATE FUNCTIONS **********************************************************/
39 * Reset display to blue screen
43 IntVideoPortResetDisplayParameters(ULONG Columns
, ULONG Rows
)
45 PVIDEO_PORT_DRIVER_EXTENSION DriverExtension
;
47 if (ResetDisplayParametersDeviceExtension
== NULL
)
50 DriverExtension
= ResetDisplayParametersDeviceExtension
->DriverExtension
;
52 if (DriverExtension
->InitializationData
.HwResetHw
!= NULL
)
54 if (DriverExtension
->InitializationData
.HwResetHw(
55 &ResetDisplayParametersDeviceExtension
->MiniPortDeviceExtension
,
58 ResetDisplayParametersDeviceExtension
= NULL
;
63 ResetDisplayParametersDeviceExtension
= NULL
;
68 IntVideoPortAddDevice(
69 IN PDRIVER_OBJECT DriverObject
,
70 IN PDEVICE_OBJECT PhysicalDeviceObject
)
72 PVIDEO_PORT_DRIVER_EXTENSION DriverExtension
;
75 * Get the initialization data we saved in VideoPortInitialize.
78 DriverExtension
= IoGetDriverObjectExtension(DriverObject
, DriverObject
);
81 * Create adapter device object.
84 return IntVideoPortCreateAdapterDeviceObject(
92 * IntVideoPortDispatchOpen
94 * Answer requests for Open calls.
101 IntVideoPortDispatchOpen(
102 IN PDEVICE_OBJECT DeviceObject
,
105 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension
;
106 PVIDEO_PORT_DRIVER_EXTENSION DriverExtension
;
108 DPRINT("IntVideoPortDispatchOpen\n");
110 if (CsrssInitialized
== FALSE
)
113 * We know the first open call will be from the CSRSS process
114 * to let us know its handle.
117 DPRINT("Referencing CSRSS\n");
118 Csrss
= PsGetCurrentProcess();
119 DPRINT("Csrss %p\n", Csrss
);
121 CsrssInitialized
= TRUE
;
123 Irp
->IoStatus
.Information
= FILE_OPENED
;
124 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
126 return STATUS_SUCCESS
;
129 DeviceExtension
= (PVIDEO_PORT_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
130 DriverExtension
= DeviceExtension
->DriverExtension
;
132 if (DriverExtension
->InitializationData
.HwInitialize(&DeviceExtension
->MiniPortDeviceExtension
))
134 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
136 InterlockedIncrement((PLONG
)&DeviceExtension
->DeviceOpened
);
139 * Storing the device extension pointer in a static variable is an
140 * ugly hack. Unfortunately, we need it in VideoPortResetDisplayParameters
141 * and HalAcquireDisplayOwnership doesn't allow us to pass a userdata
142 * parameter. On the bright side, the DISPLAY device is opened
143 * exclusively, so there can be only one device extension active at
147 ResetDisplayParametersDeviceExtension
= DeviceExtension
;
148 HalAcquireDisplayOwnership(IntVideoPortResetDisplayParameters
);
152 Irp
->IoStatus
.Status
= STATUS_UNSUCCESSFUL
;
155 Irp
->IoStatus
.Information
= FILE_OPENED
;
156 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
158 return STATUS_SUCCESS
;
162 * IntVideoPortDispatchClose
164 * Answer requests for Close calls.
171 IntVideoPortDispatchClose(
172 IN PDEVICE_OBJECT DeviceObject
,
175 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension
;
177 DPRINT("IntVideoPortDispatchClose\n");
179 DeviceExtension
= (PVIDEO_PORT_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
180 if (DeviceExtension
->DeviceOpened
>= 1 &&
181 InterlockedDecrement((PLONG
)&DeviceExtension
->DeviceOpened
) == 0)
183 ResetDisplayParametersDeviceExtension
= DeviceExtension
;
184 HalReleaseDisplayOwnership();
187 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
188 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
190 return STATUS_SUCCESS
;
194 * IntVideoPortDispatchDeviceControl
196 * Answer requests for device control calls.
203 IntVideoPortDispatchDeviceControl(
204 IN PDEVICE_OBJECT DeviceObject
,
207 PIO_STACK_LOCATION IrpStack
;
208 PVIDEO_PORT_DRIVER_EXTENSION DriverExtension
;
209 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension
;
210 PVIDEO_REQUEST_PACKET vrp
;
213 DPRINT("IntVideoPortDispatchDeviceControl\n");
215 IrpStack
= IoGetCurrentIrpStackLocation(Irp
);
216 DeviceExtension
= DeviceObject
->DeviceExtension
;
217 DriverExtension
= DeviceExtension
->DriverExtension
;
219 /* Translate the IRP to a VRP */
220 vrp
= ExAllocatePool(NonPagedPool
, sizeof(VIDEO_REQUEST_PACKET
));
223 return STATUS_NO_MEMORY
;
226 vrp
->StatusBlock
= (PSTATUS_BLOCK
)&(Irp
->IoStatus
);
227 vrp
->IoControlCode
= IrpStack
->Parameters
.DeviceIoControl
.IoControlCode
;
229 DPRINT("- IoControlCode: %x\n", vrp
->IoControlCode
);
231 /* We're assuming METHOD_BUFFERED */
232 vrp
->InputBuffer
= Irp
->AssociatedIrp
.SystemBuffer
;
233 vrp
->InputBufferLength
= IrpStack
->Parameters
.DeviceIoControl
.InputBufferLength
;
234 vrp
->OutputBuffer
= Irp
->AssociatedIrp
.SystemBuffer
;
235 vrp
->OutputBufferLength
= IrpStack
->Parameters
.DeviceIoControl
.OutputBufferLength
;
237 /* Call the Miniport Driver with the VRP */
238 DriverExtension
->InitializationData
.HwStartIO(
239 &DeviceExtension
->MiniPortDeviceExtension
,
245 DPRINT("- Returned status: %x\n", Irp
->IoStatus
.Status
);
247 if (Irp
->IoStatus
.Status
!= STATUS_SUCCESS
)
249 /* Map from win32 error codes to NT status values. */
250 switch (Irp
->IoStatus
.Status
)
252 case ERROR_NOT_ENOUGH_MEMORY
: Irp
->IoStatus
.Status
= STATUS_INSUFFICIENT_RESOURCES
; break;
253 case ERROR_MORE_DATA
: Irp
->IoStatus
.Status
= STATUS_BUFFER_OVERFLOW
; break;
254 case ERROR_INVALID_FUNCTION
: Irp
->IoStatus
.Status
= STATUS_NOT_IMPLEMENTED
; break;
255 case ERROR_INVALID_PARAMETER
: Irp
->IoStatus
.Status
= STATUS_INVALID_PARAMETER
; break;
256 case ERROR_INSUFFICIENT_BUFFER
: Irp
->IoStatus
.Status
= STATUS_BUFFER_TOO_SMALL
; break;
257 case ERROR_DEV_NOT_EXIST
: Irp
->IoStatus
.Status
= STATUS_DEVICE_DOES_NOT_EXIST
; break;
258 case ERROR_IO_PENDING
: Irp
->IoStatus
.Status
= STATUS_PENDING
; break;
262 Status
= Irp
->IoStatus
.Status
;
263 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
269 IntVideoPortPnPStartDevice(
270 IN PDEVICE_OBJECT DeviceObject
,
273 PIO_STACK_LOCATION Stack
= IoGetCurrentIrpStackLocation(Irp
);
274 PDRIVER_OBJECT DriverObject
;
275 PVIDEO_PORT_DRIVER_EXTENSION DriverExtension
;
276 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension
;
277 PCM_RESOURCE_LIST AllocatedResources
;
280 * Get the initialization data we saved in VideoPortInitialize.
283 DriverObject
= DeviceObject
->DriverObject
;
284 DriverExtension
= IoGetDriverObjectExtension(DriverObject
, DriverObject
);
285 DeviceExtension
= (PVIDEO_PORT_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
288 * Store some resources in the DeviceExtension.
291 AllocatedResources
= Stack
->Parameters
.StartDevice
.AllocatedResources
;
292 if (AllocatedResources
!= NULL
)
294 CM_FULL_RESOURCE_DESCRIPTOR
*FullList
;
295 CM_PARTIAL_RESOURCE_DESCRIPTOR
*Descriptor
;
297 ULONG ResourceListSize
;
299 /* Save the resource list */
300 ResourceCount
= AllocatedResources
->List
[0].PartialResourceList
.Count
;
302 FIELD_OFFSET(CM_RESOURCE_LIST
, List
[0].PartialResourceList
.
303 PartialDescriptors
[ResourceCount
]);
304 DeviceExtension
->AllocatedResources
= ExAllocatePool(PagedPool
, ResourceListSize
);
305 if (DeviceExtension
->AllocatedResources
== NULL
)
307 return STATUS_INSUFFICIENT_RESOURCES
;
310 RtlCopyMemory(DeviceExtension
->AllocatedResources
,
314 /* Get the interrupt level/vector - needed by HwFindAdapter sometimes */
315 for (FullList
= AllocatedResources
->List
;
316 FullList
< AllocatedResources
->List
+ AllocatedResources
->Count
;
319 /* FIXME: Is this ASSERT ok for resources from the PNP manager? */
320 ASSERT(FullList
->InterfaceType
== PCIBus
&&
321 FullList
->BusNumber
== DeviceExtension
->SystemIoBusNumber
&&
322 1 == FullList
->PartialResourceList
.Version
&&
323 1 == FullList
->PartialResourceList
.Revision
);
324 for (Descriptor
= FullList
->PartialResourceList
.PartialDescriptors
;
325 Descriptor
< FullList
->PartialResourceList
.PartialDescriptors
+ FullList
->PartialResourceList
.Count
;
328 if (Descriptor
->Type
== CmResourceTypeInterrupt
)
330 DeviceExtension
->InterruptLevel
= Descriptor
->u
.Interrupt
.Level
;
331 DeviceExtension
->InterruptVector
= Descriptor
->u
.Interrupt
.Vector
;
336 DPRINT("Interrupt level: 0x%x Interrupt Vector: 0x%x\n",
337 DeviceExtension
->InterruptLevel
,
338 DeviceExtension
->InterruptVector
);
341 * Create adapter device object.
344 return IntVideoPortFindAdapter(
353 IntVideoPortForwardIrpAndWaitCompletionRoutine(
358 PKEVENT Event
= Context
;
360 if (Irp
->PendingReturned
)
361 KeSetEvent(Event
, IO_NO_INCREMENT
, FALSE
);
363 return STATUS_MORE_PROCESSING_REQUIRED
;
369 IntVideoPortForwardIrpAndWait(PDEVICE_OBJECT DeviceObject
, PIRP Irp
)
373 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension
=
374 (PVIDEO_PORT_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
376 KeInitializeEvent(&Event
, NotificationEvent
, FALSE
);
377 IoCopyCurrentIrpStackLocationToNext(Irp
);
378 IoSetCompletionRoutine(Irp
, IntVideoPortForwardIrpAndWaitCompletionRoutine
,
379 &Event
, TRUE
, TRUE
, TRUE
);
380 Status
= IoCallDriver(DeviceExtension
->NextDeviceObject
, Irp
);
381 if (Status
== STATUS_PENDING
)
383 KeWaitForSingleObject(&Event
, Executive
, KernelMode
, FALSE
, NULL
);
384 Status
= Irp
->IoStatus
.Status
;
391 IntVideoPortDispatchPnp(
392 IN PDEVICE_OBJECT DeviceObject
,
395 PIO_STACK_LOCATION IrpSp
;
398 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
400 switch (IrpSp
->MinorFunction
)
402 case IRP_MN_START_DEVICE
:
403 Status
= IntVideoPortForwardIrpAndWait(DeviceObject
, Irp
);
404 if (NT_SUCCESS(Status
) && NT_SUCCESS(Irp
->IoStatus
.Status
))
405 Status
= IntVideoPortPnPStartDevice(DeviceObject
, Irp
);
406 Irp
->IoStatus
.Status
= Status
;
407 Irp
->IoStatus
.Information
= 0;
408 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
412 case IRP_MN_REMOVE_DEVICE
:
413 case IRP_MN_QUERY_REMOVE_DEVICE
:
414 case IRP_MN_CANCEL_REMOVE_DEVICE
:
415 case IRP_MN_SURPRISE_REMOVAL
:
417 case IRP_MN_STOP_DEVICE
:
418 Status
= IntVideoPortForwardIrpAndWait(DeviceObject
, Irp
);
419 if (NT_SUCCESS(Status
) && NT_SUCCESS(Irp
->IoStatus
.Status
))
420 Status
= STATUS_SUCCESS
;
421 Irp
->IoStatus
.Status
= Status
;
422 Irp
->IoStatus
.Information
= 0;
423 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
426 case IRP_MN_QUERY_STOP_DEVICE
:
427 case IRP_MN_CANCEL_STOP_DEVICE
:
428 Status
= STATUS_SUCCESS
;
429 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
430 Irp
->IoStatus
.Information
= 0;
431 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
435 return STATUS_NOT_IMPLEMENTED
;
443 IntVideoPortDispatchCleanup(
444 IN PDEVICE_OBJECT DeviceObject
,
447 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension
;
449 DeviceExtension
= DeviceObject
->DeviceExtension
;
450 RtlFreeUnicodeString(&DeviceExtension
->RegistryPath
);
452 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
453 Irp
->IoStatus
.Information
= 0;
454 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
456 return STATUS_SUCCESS
;
460 IntVideoPortDispatchPower(
461 IN PDEVICE_OBJECT DeviceObject
,
464 return STATUS_NOT_IMPLEMENTED
;
468 IntVideoPortUnload(PDRIVER_OBJECT DriverObject
)