ReactOS 0.4.15-dev-7788-g1ad9096
evgpeutil.c
Go to the documentation of this file.
1/******************************************************************************
2 *
3 * Module Name: evgpeutil - GPE utilities
4 *
5 *****************************************************************************/
6
7/*
8 * Copyright (C) 2000 - 2022, Intel Corp.
9 * All rights reserved.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions, and the following disclaimer,
16 * without modification.
17 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18 * substantially similar to the "NO WARRANTY" disclaimer below
19 * ("Disclaimer") and any redistribution must be conditioned upon
20 * including a substantially similar Disclaimer requirement for further
21 * binary redistribution.
22 * 3. Neither the names of the above-listed copyright holders nor the names
23 * of any contributors may be used to endorse or promote products derived
24 * from this software without specific prior written permission.
25 *
26 * Alternatively, this software may be distributed under the terms of the
27 * GNU General Public License ("GPL") version 2 as published by the Free
28 * Software Foundation.
29 *
30 * NO WARRANTY
31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
34 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41 * POSSIBILITY OF SUCH DAMAGES.
42 */
43
44#include "acpi.h"
45#include "accommon.h"
46#include "acevents.h"
47
48#define _COMPONENT ACPI_EVENTS
49 ACPI_MODULE_NAME ("evgpeutil")
50
51
52#if (!ACPI_REDUCED_HARDWARE) /* Entire module */
53/*******************************************************************************
54 *
55 * FUNCTION: AcpiEvWalkGpeList
56 *
57 * PARAMETERS: GpeWalkCallback - Routine called for each GPE block
58 * Context - Value passed to callback
59 *
60 * RETURN: Status
61 *
62 * DESCRIPTION: Walk the GPE lists.
63 *
64 ******************************************************************************/
65
68 ACPI_GPE_CALLBACK GpeWalkCallback,
69 void *Context)
70{
71 ACPI_GPE_BLOCK_INFO *GpeBlock;
72 ACPI_GPE_XRUPT_INFO *GpeXruptInfo;
75
76
77 ACPI_FUNCTION_TRACE (EvWalkGpeList);
78
79
80 Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
81
82 /* Walk the interrupt level descriptor list */
83
84 GpeXruptInfo = AcpiGbl_GpeXruptListHead;
85 while (GpeXruptInfo)
86 {
87 /* Walk all Gpe Blocks attached to this interrupt level */
88
89 GpeBlock = GpeXruptInfo->GpeBlockListHead;
90 while (GpeBlock)
91 {
92 /* One callback per GPE block */
93
94 Status = GpeWalkCallback (GpeXruptInfo, GpeBlock, Context);
95 if (ACPI_FAILURE (Status))
96 {
97 if (Status == AE_CTRL_END) /* Callback abort */
98 {
99 Status = AE_OK;
100 }
101 goto UnlockAndExit;
102 }
103
104 GpeBlock = GpeBlock->Next;
105 }
106
107 GpeXruptInfo = GpeXruptInfo->Next;
108 }
109
110UnlockAndExit:
111 AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
113}
114
115
116/*******************************************************************************
117 *
118 * FUNCTION: AcpiEvGetGpeDevice
119 *
120 * PARAMETERS: GPE_WALK_CALLBACK
121 *
122 * RETURN: Status
123 *
124 * DESCRIPTION: Matches the input GPE index (0-CurrentGpeCount) with a GPE
125 * block device. NULL if the GPE is one of the FADT-defined GPEs.
126 *
127 ******************************************************************************/
128
131 ACPI_GPE_XRUPT_INFO *GpeXruptInfo,
132 ACPI_GPE_BLOCK_INFO *GpeBlock,
133 void *Context)
134{
136
137
138 /* Increment Index by the number of GPEs in this block */
139
140 Info->NextBlockBaseIndex += GpeBlock->GpeCount;
141
142 if (Info->Index < Info->NextBlockBaseIndex)
143 {
144 /*
145 * The GPE index is within this block, get the node. Leave the node
146 * NULL for the FADT-defined GPEs
147 */
148 if ((GpeBlock->Node)->Type == ACPI_TYPE_DEVICE)
149 {
150 Info->GpeDevice = GpeBlock->Node;
151 }
152
153 Info->Status = AE_OK;
154 return (AE_CTRL_END);
155 }
156
157 return (AE_OK);
158}
159
160
161/*******************************************************************************
162 *
163 * FUNCTION: AcpiEvGetGpeXruptBlock
164 *
165 * PARAMETERS: InterruptNumber - Interrupt for a GPE block
166 * GpeXruptBlock - Where the block is returned
167 *
168 * RETURN: Status
169 *
170 * DESCRIPTION: Get or Create a GPE interrupt block. There is one interrupt
171 * block per unique interrupt level used for GPEs. Should be
172 * called only when the GPE lists are semaphore locked and not
173 * subject to change.
174 *
175 ******************************************************************************/
176
179 UINT32 InterruptNumber,
180 ACPI_GPE_XRUPT_INFO **GpeXruptBlock)
181{
182 ACPI_GPE_XRUPT_INFO *NextGpeXrupt;
183 ACPI_GPE_XRUPT_INFO *GpeXrupt;
186
187
188 ACPI_FUNCTION_TRACE (EvGetGpeXruptBlock);
189
190
191 /* No need for lock since we are not changing any list elements here */
192
193 NextGpeXrupt = AcpiGbl_GpeXruptListHead;
194 while (NextGpeXrupt)
195 {
196 if (NextGpeXrupt->InterruptNumber == InterruptNumber)
197 {
198 *GpeXruptBlock = NextGpeXrupt;
200 }
201
202 NextGpeXrupt = NextGpeXrupt->Next;
203 }
204
205 /* Not found, must allocate a new xrupt descriptor */
206
207 GpeXrupt = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_GPE_XRUPT_INFO));
208 if (!GpeXrupt)
209 {
211 }
212
213 GpeXrupt->InterruptNumber = InterruptNumber;
214
215 /* Install new interrupt descriptor with spin lock */
216
217 Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
218 if (AcpiGbl_GpeXruptListHead)
219 {
220 NextGpeXrupt = AcpiGbl_GpeXruptListHead;
221 while (NextGpeXrupt->Next)
222 {
223 NextGpeXrupt = NextGpeXrupt->Next;
224 }
225
226 NextGpeXrupt->Next = GpeXrupt;
227 GpeXrupt->Previous = NextGpeXrupt;
228 }
229 else
230 {
231 AcpiGbl_GpeXruptListHead = GpeXrupt;
232 }
233
234 AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
235
236 /* Install new interrupt handler if not SCI_INT */
237
238 if (InterruptNumber != AcpiGbl_FADT.SciInterrupt)
239 {
240 Status = AcpiOsInstallInterruptHandler (InterruptNumber,
241 AcpiEvGpeXruptHandler, GpeXrupt);
242 if (ACPI_FAILURE (Status))
243 {
245 "Could not install GPE interrupt handler at level 0x%X",
246 InterruptNumber));
248 }
249 }
250
251 *GpeXruptBlock = GpeXrupt;
253}
254
255
256/*******************************************************************************
257 *
258 * FUNCTION: AcpiEvDeleteGpeXrupt
259 *
260 * PARAMETERS: GpeXrupt - A GPE interrupt info block
261 *
262 * RETURN: Status
263 *
264 * DESCRIPTION: Remove and free a GpeXrupt block. Remove an associated
265 * interrupt handler if not the SCI interrupt.
266 *
267 ******************************************************************************/
268
271 ACPI_GPE_XRUPT_INFO *GpeXrupt)
272{
275
276
277 ACPI_FUNCTION_TRACE (EvDeleteGpeXrupt);
278
279
280 /* We never want to remove the SCI interrupt handler */
281
282 if (GpeXrupt->InterruptNumber == AcpiGbl_FADT.SciInterrupt)
283 {
284 GpeXrupt->GpeBlockListHead = NULL;
286 }
287
288 /* Disable this interrupt */
289
292 if (ACPI_FAILURE (Status))
293 {
295 }
296
297 /* Unlink the interrupt block with lock */
298
299 Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
300 if (GpeXrupt->Previous)
301 {
302 GpeXrupt->Previous->Next = GpeXrupt->Next;
303 }
304 else
305 {
306 /* No previous, update list head */
307
308 AcpiGbl_GpeXruptListHead = GpeXrupt->Next;
309 }
310
311 if (GpeXrupt->Next)
312 {
313 GpeXrupt->Next->Previous = GpeXrupt->Previous;
314 }
315 AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
316
317 /* Free the block */
318
319 ACPI_FREE (GpeXrupt);
321}
322
323
324/*******************************************************************************
325 *
326 * FUNCTION: AcpiEvDeleteGpeHandlers
327 *
328 * PARAMETERS: GpeXruptInfo - GPE Interrupt info
329 * GpeBlock - Gpe Block info
330 *
331 * RETURN: Status
332 *
333 * DESCRIPTION: Delete all Handler objects found in the GPE data structs.
334 * Used only prior to termination.
335 *
336 ******************************************************************************/
337
340 ACPI_GPE_XRUPT_INFO *GpeXruptInfo,
341 ACPI_GPE_BLOCK_INFO *GpeBlock,
342 void *Context)
343{
347 UINT32 i;
348 UINT32 j;
349
350
351 ACPI_FUNCTION_TRACE (EvDeleteGpeHandlers);
352
353
354 /* Examine each GPE Register within the block */
355
356 for (i = 0; i < GpeBlock->RegisterCount; i++)
357 {
358 /* Now look at the individual GPEs in this byte register */
359
360 for (j = 0; j < ACPI_GPE_REGISTER_WIDTH; j++)
361 {
362 GpeEventInfo = &GpeBlock->EventInfo[((ACPI_SIZE) i *
364
369 {
370 /* Delete an installed handler block */
371
374 GpeEventInfo->Flags &= ~ACPI_GPE_DISPATCH_MASK;
375 }
378 {
379 /* Delete the implicit notification device list */
380
382 while (Notify)
383 {
384 Next = Notify->Next;
386 Notify = Next;
387 }
388
390 GpeEventInfo->Flags &= ~ACPI_GPE_DISPATCH_MASK;
391 }
392 }
393 }
394
396}
397
398#endif /* !ACPI_REDUCED_HARDWARE */
unsigned int UINT32
ACPI_GPE_EVENT_INFO * GpeEventInfo
Definition: acevents.h:195
#define ACPI_FAILURE(a)
Definition: acexcep.h:95
#define AE_CTRL_END
Definition: acexcep.h:230
#define AE_NO_MEMORY
Definition: acexcep.h:112
#define AE_OK
Definition: acexcep.h:97
ACPI_STATUS(* ACPI_GPE_CALLBACK)(ACPI_GPE_XRUPT_INFO *GpeXruptInfo, ACPI_GPE_BLOCK_INFO *GpeBlock, void *Context)
Definition: aclocal.h:628
#define ACPI_EXCEPTION(plist)
Definition: acoutput.h:239
#define ACPI_MODULE_NAME(Name)
Definition: acoutput.h:216
#define return_ACPI_STATUS(s)
Definition: acoutput.h:496
#define ACPI_FUNCTION_TRACE(a)
Definition: acoutput.h:480
#define AE_INFO
Definition: acoutput.h:230
ACPI_STATUS AcpiOsRemoveInterruptHandler(UINT32 InterruptNumber, ACPI_OSD_HANDLER ServiceRoutine)
Definition: osl.c:606
void AcpiOsReleaseLock(ACPI_SPINLOCK Handle, ACPI_CPU_FLAGS Flags)
Definition: osl.c:516
ACPI_CPU_FLAGS AcpiOsAcquireLock(ACPI_SPINLOCK Handle)
Definition: osl.c:498
ACPI_STATUS AcpiOsInstallInterruptHandler(UINT32 InterruptNumber, ACPI_OSD_HANDLER ServiceRoutine, void *Context)
Definition: osl.c:548
#define ACPI_CPU_FLAGS
Definition: actypes.h:252
#define ACPI_FREE(a)
Definition: actypes.h:386
UINT32 ACPI_STATUS
Definition: actypes.h:460
#define ACPI_GPE_DISPATCH_TYPE(flags)
Definition: actypes.h:825
#define ACPI_GPE_DISPATCH_NOTIFY
Definition: actypes.h:822
#define ACPI_TYPE_DEVICE
Definition: actypes.h:693
#define ACPI_GPE_DISPATCH_RAW_HANDLER
Definition: actypes.h:823
#define ACPI_ALLOCATE_ZEROED(a)
Definition: actypes.h:385
#define ACPI_GPE_REGISTER_WIDTH
Definition: actypes.h:407
#define ACPI_GPE_DISPATCH_HANDLER
Definition: actypes.h:821
#define NULL
Definition: types.h:112
BOOL WINAPI SHIM_OBJ_NAME() Notify(DWORD fdwReason, PVOID ptr)
ACPI_STATUS AcpiEvDeleteGpeXrupt(ACPI_GPE_XRUPT_INFO *GpeXrupt)
Definition: evgpeutil.c:270
ACPI_STATUS AcpiEvDeleteGpeHandlers(ACPI_GPE_XRUPT_INFO *GpeXruptInfo, ACPI_GPE_BLOCK_INFO *GpeBlock, void *Context)
Definition: evgpeutil.c:339
ACPI_STATUS AcpiEvWalkGpeList(ACPI_GPE_CALLBACK GpeWalkCallback, void *Context)
Definition: evgpeutil.c:67
ACPI_STATUS AcpiEvGetGpeDevice(ACPI_GPE_XRUPT_INFO *GpeXruptInfo, ACPI_GPE_BLOCK_INFO *GpeBlock, void *Context)
Definition: evgpeutil.c:130
ACPI_STATUS AcpiEvGetGpeXruptBlock(UINT32 InterruptNumber, ACPI_GPE_XRUPT_INFO **GpeXruptBlock)
Definition: evgpeutil.c:178
UINT32 ACPI_SYSTEM_XFACE AcpiEvGpeXruptHandler(void *Context)
Definition: evsci.c:176
Status
Definition: gdiplustypes.h:25
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint GLint GLint j
Definition: glfuncs.h:250
HRESULT Next([in] ULONG celt, [out, size_is(celt), length_is(*pceltFetched)] STATPROPSETSTG *rgelt, [out] ULONG *pceltFetched)
UINT32 RegisterCount
Definition: aclocal.h:590
struct acpi_gpe_block_info * Next
Definition: aclocal.h:585
ACPI_NAMESPACE_NODE * Node
Definition: aclocal.h:583
ACPI_GPE_EVENT_INFO * EventInfo
Definition: aclocal.h:588
union acpi_gpe_dispatch_info Dispatch
Definition: aclocal.h:554
UINT32 InterruptNumber
Definition: aclocal.h:605
struct acpi_gpe_xrupt_info * Previous
Definition: aclocal.h:602
struct acpi_gpe_xrupt_info * Next
Definition: aclocal.h:603
ACPI_GPE_BLOCK_INFO * GpeBlockListHead
Definition: aclocal.h:604
ACPI_GPE_HANDLER_INFO * Handler
Definition: aclocal.h:543
ACPI_GPE_NOTIFY_INFO * NotifyList
Definition: aclocal.h:544
_Must_inspect_result_ _In_ WDFCHILDLIST _In_ PWDF_CHILD_LIST_ITERATOR _Out_ WDFDEVICE _Inout_opt_ PWDF_CHILD_RETRIEVE_INFO Info
Definition: wdfchildlist.h:690
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170