Sync to trunk revision 63857.
[reactos.git] / win32ss / drivers / videoprt / interrupt.c
1 /*
2 * VideoPort driver
3 *
4 * Copyright (C) 2002, 2003, 2004 ReactOS Team
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
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 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 *
20 */
21
22 #include "videoprt.h"
23
24 #include <ndk/halfuncs.h>
25
26 #define NDEBUG
27 #include <debug.h>
28
29 /* PRIVATE FUNCTIONS **********************************************************/
30
31 BOOLEAN NTAPI
32 IntVideoPortInterruptRoutine(
33 IN struct _KINTERRUPT *Interrupt,
34 IN PVOID ServiceContext)
35 {
36 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension = ServiceContext;
37
38 ASSERT(DeviceExtension->DriverExtension->InitializationData.HwInterrupt != NULL);
39
40 return DeviceExtension->DriverExtension->InitializationData.HwInterrupt(
41 &DeviceExtension->MiniPortDeviceExtension);
42 }
43
44 BOOLEAN NTAPI
45 IntVideoPortSetupInterrupt(
46 IN PDEVICE_OBJECT DeviceObject,
47 IN PVIDEO_PORT_DRIVER_EXTENSION DriverExtension,
48 IN PVIDEO_PORT_CONFIG_INFO ConfigInfo)
49 {
50 NTSTATUS Status;
51 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension;
52
53 DeviceExtension = (PVIDEO_PORT_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
54
55 /*
56 * MSDN documentation for VIDEO_PORT_CONFIG_INFO states: "If a miniport driver's
57 * HwVidFindAdapter function finds that the video adapter does not generate
58 * interrupts or that it cannot determine a valid interrupt vector/level for
59 * the adapter, HwVidFindAdapter should set both BusInterruptVector and
60 * BusInterruptLevel to zero.
61 */
62
63 if (DriverExtension->InitializationData.HwInterrupt != NULL &&
64 (ConfigInfo->BusInterruptLevel != 0 ||
65 ConfigInfo->BusInterruptVector != 0))
66 {
67 ULONG InterruptVector;
68 KIRQL Irql;
69 KAFFINITY Affinity;
70
71 InterruptVector = HalGetInterruptVector(
72 ConfigInfo->AdapterInterfaceType,
73 ConfigInfo->SystemIoBusNumber,
74 ConfigInfo->BusInterruptLevel,
75 ConfigInfo->BusInterruptVector,
76 &Irql,
77 &Affinity);
78
79 if (InterruptVector == 0)
80 {
81 WARN_(VIDEOPRT, "HalGetInterruptVector failed\n");
82 return FALSE;
83 }
84
85 KeInitializeSpinLock(&DeviceExtension->InterruptSpinLock);
86 Status = IoConnectInterrupt(
87 &DeviceExtension->InterruptObject,
88 IntVideoPortInterruptRoutine,
89 DeviceExtension,
90 &DeviceExtension->InterruptSpinLock,
91 InterruptVector,
92 Irql,
93 Irql,
94 ConfigInfo->InterruptMode,
95 DeviceExtension->InterruptShared,
96 Affinity,
97 FALSE);
98
99 if (!NT_SUCCESS(Status))
100 {
101 WARN_(VIDEOPRT, "IoConnectInterrupt failed with status 0x%08x\n", Status);
102 return FALSE;
103 }
104 }
105
106 return TRUE;
107 }
108
109 /* PUBLIC FUNCTIONS ***********************************************************/
110
111 /*
112 * @implemented
113 */
114 VP_STATUS
115 NTAPI
116 VideoPortEnableInterrupt(IN PVOID HwDeviceExtension)
117 {
118 #ifndef _M_AMD64
119 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension;
120 BOOLEAN InterruptValid;
121
122 /* Get the device extension */
123 DeviceExtension = VIDEO_PORT_GET_DEVICE_EXTENSION(HwDeviceExtension);
124
125 /* Fail if the driver didn't register an ISR */
126 if (!DeviceExtension->DriverExtension->InitializationData.HwInterrupt)
127 {
128 /* No ISR, no interrupts */
129 return ERROR_INVALID_FUNCTION;
130 }
131
132 /* Re-enable the interrupt and return */
133 InterruptValid = HalEnableSystemInterrupt(DeviceExtension->InterruptVector,
134 0,
135 DeviceExtension->InterruptLevel);
136
137 /* Make sure the interrupt was valid */
138 ASSERT(InterruptValid == TRUE);
139
140 /* Return to caller */
141 return NO_ERROR;
142 #else
143 /* FIXME: Function still present? If so what to use instead of HalEnableSystemInterrupt? */
144 UNIMPLEMENTED;
145 return ERROR_INVALID_FUNCTION;
146 #endif
147 }
148
149 /*
150 * @implemented
151 */
152 VP_STATUS
153 NTAPI
154 VideoPortDisableInterrupt(IN PVOID HwDeviceExtension)
155 {
156 #ifndef _M_AMD64
157 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension;
158
159 /* Get the device extension */
160 DeviceExtension = VIDEO_PORT_GET_DEVICE_EXTENSION(HwDeviceExtension);
161
162 /* Fail if the driver didn't register an ISR */
163 if (!DeviceExtension->DriverExtension->InitializationData.HwInterrupt)
164 {
165 /* No ISR, no interrupts */
166 return ERROR_INVALID_FUNCTION;
167 }
168
169 /* Disable the interrupt and return */
170 HalDisableSystemInterrupt(DeviceExtension->InterruptVector, 0);
171 return NO_ERROR;
172 #else
173 /* FIXME: Function still present? If so what to use instead of HalDisableSystemInterrupt? */
174 UNIMPLEMENTED;
175 return ERROR_INVALID_FUNCTION;
176 #endif
177 }