Sync with trunk (r48123)
[reactos.git] / drivers / video / 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 /* PRIVATE FUNCTIONS **********************************************************/
25
26 BOOLEAN NTAPI
27 IntVideoPortInterruptRoutine(
28 IN struct _KINTERRUPT *Interrupt,
29 IN PVOID ServiceContext)
30 {
31 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension = ServiceContext;
32
33 ASSERT(DeviceExtension->DriverExtension->InitializationData.HwInterrupt != NULL);
34
35 return DeviceExtension->DriverExtension->InitializationData.HwInterrupt(
36 &DeviceExtension->MiniPortDeviceExtension);
37 }
38
39 BOOLEAN NTAPI
40 IntVideoPortSetupInterrupt(
41 IN PDEVICE_OBJECT DeviceObject,
42 IN PVIDEO_PORT_DRIVER_EXTENSION DriverExtension,
43 IN PVIDEO_PORT_CONFIG_INFO ConfigInfo)
44 {
45 NTSTATUS Status;
46 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension;
47
48 DeviceExtension = (PVIDEO_PORT_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
49
50 /*
51 * MSDN documentation for VIDEO_PORT_CONFIG_INFO states: "If a miniport driver's
52 * HwVidFindAdapter function finds that the video adapter does not generate
53 * interrupts or that it cannot determine a valid interrupt vector/level for
54 * the adapter, HwVidFindAdapter should set both BusInterruptVector and
55 * BusInterruptLevel to zero.
56 */
57
58 if (DriverExtension->InitializationData.HwInterrupt != NULL &&
59 (ConfigInfo->BusInterruptLevel != 0 ||
60 ConfigInfo->BusInterruptVector != 0))
61 {
62 ULONG InterruptVector;
63 KIRQL Irql;
64 KAFFINITY Affinity;
65
66 InterruptVector = HalGetInterruptVector(
67 ConfigInfo->AdapterInterfaceType,
68 ConfigInfo->SystemIoBusNumber,
69 ConfigInfo->BusInterruptLevel,
70 ConfigInfo->BusInterruptVector,
71 &Irql,
72 &Affinity);
73
74 if (InterruptVector == 0)
75 {
76 WARN_(VIDEOPRT, "HalGetInterruptVector failed\n");
77 return FALSE;
78 }
79
80 KeInitializeSpinLock(&DeviceExtension->InterruptSpinLock);
81 Status = IoConnectInterrupt(
82 &DeviceExtension->InterruptObject,
83 IntVideoPortInterruptRoutine,
84 DeviceExtension,
85 &DeviceExtension->InterruptSpinLock,
86 InterruptVector,
87 Irql,
88 Irql,
89 ConfigInfo->InterruptMode,
90 DeviceExtension->InterruptShared,
91 Affinity,
92 FALSE);
93
94 if (!NT_SUCCESS(Status))
95 {
96 WARN_(VIDEOPRT, "IoConnectInterrupt failed with status 0x%08x\n", Status);
97 return FALSE;
98 }
99 }
100
101 return TRUE;
102 }
103
104 /* PUBLIC FUNCTIONS ***********************************************************/
105
106 /*
107 * @implemented
108 */
109 VP_STATUS
110 NTAPI
111 VideoPortEnableInterrupt(IN PVOID HwDeviceExtension)
112 {
113 #ifndef _M_AMD64
114 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension;
115 BOOLEAN InterruptValid;
116
117 /* Get the device extension */
118 DeviceExtension = VIDEO_PORT_GET_DEVICE_EXTENSION(HwDeviceExtension);
119
120 /* Fail if the driver didn't register an ISR */
121 if (!DeviceExtension->DriverExtension->InitializationData.HwInterrupt)
122 {
123 /* No ISR, no interrupts */
124 return ERROR_INVALID_FUNCTION;
125 }
126
127 /* Re-enable the interrupt and return */
128 InterruptValid = HalEnableSystemInterrupt(DeviceExtension->InterruptVector,
129 0,
130 DeviceExtension->InterruptLevel);
131
132 /* Make sure the interrupt was valid */
133 ASSERT(InterruptValid == TRUE);
134
135 /* Return to caller */
136 return NO_ERROR;
137 #else
138 /* FIXME: Function still present? If so what to use instead of HalEnableSystemInterrupt? */
139 UNIMPLEMENTED;
140 return ERROR_INVALID_FUNCTION;
141 #endif
142 }
143
144 /*
145 * @implemented
146 */
147 VP_STATUS
148 NTAPI
149 VideoPortDisableInterrupt(IN PVOID HwDeviceExtension)
150 {
151 #ifndef _M_AMD64
152 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension;
153
154 /* Get the device extension */
155 DeviceExtension = VIDEO_PORT_GET_DEVICE_EXTENSION(HwDeviceExtension);
156
157 /* Fail if the driver didn't register an ISR */
158 if (!DeviceExtension->DriverExtension->InitializationData.HwInterrupt)
159 {
160 /* No ISR, no interrupts */
161 return ERROR_INVALID_FUNCTION;
162 }
163
164 /* Disable the interrupt and return */
165 HalDisableSystemInterrupt(DeviceExtension->InterruptVector,
166 0);
167 return NO_ERROR;
168 #else
169 /* FIXME: Function still present? If so what to use instead of HalDisableSystemInterrupt? */
170 UNIMPLEMENTED;
171 return ERROR_INVALID_FUNCTION;
172 #endif
173 }