ReactOS  0.4.13-dev-927-ge85664a
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 - 2019, 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 MERCHANTIBILITY 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 
110 UnlockAndExit:
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 {
346  ACPI_GPE_NOTIFY_INFO *Next;
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 
375  }
378  {
379  /* Delete the implicit notification device list */
380 
382  while (Notify)
383  {
384  Next = Notify->Next;
385  ACPI_FREE (Notify);
386  Notify = Next;
387  }
388 
391  }
392  }
393  }
394 
396 }
397 
398 #endif /* !ACPI_REDUCED_HARDWARE */
#define ACPI_EXCEPTION(plist)
Definition: acoutput.h:239
struct acpi_gpe_block_info * Next
Definition: aclocal.h:585
BOOL WINAPI SHIM_OBJ_NAME() Notify(DWORD fdwReason, PVOID ptr)
ACPI_GPE_NOTIFY_INFO * NotifyList
Definition: aclocal.h:544
#define ACPI_FREE(a)
Definition: actypes.h:386
#define AE_CTRL_END
Definition: acexcep.h:230
#define ACPI_ALLOCATE_ZEROED(a)
Definition: actypes.h:385
ACPI_CPU_FLAGS AcpiOsAcquireLock(ACPI_SPINLOCK Handle)
Definition: osl.c:498
ACPI_STATUS AcpiEvGetGpeDevice(ACPI_GPE_XRUPT_INFO *GpeXruptInfo, ACPI_GPE_BLOCK_INFO *GpeBlock, void *Context)
Definition: evgpeutil.c:130
#define AE_NO_MEMORY
Definition: acexcep.h:112
ACPI_STATUS(* ACPI_GPE_CALLBACK)(ACPI_GPE_XRUPT_INFO *GpeXruptInfo, ACPI_GPE_BLOCK_INFO *GpeBlock, void *Context)
Definition: aclocal.h:628
#define ACPI_GPE_DISPATCH_TYPE(flags)
Definition: actypes.h:815
ACPI_STATUS AcpiOsRemoveInterruptHandler(UINT32 InterruptNumber, ACPI_OSD_HANDLER ServiceRoutine)
Definition: osl.c:606
struct acpi_gpe_xrupt_info * Next
Definition: aclocal.h:603
ACPI_GPE_EVENT_INFO * GpeEventInfo
Definition: acevents.h:195
#define ACPI_CPU_FLAGS
Definition: actypes.h:252
UINT32 ACPI_STATUS
Definition: actypes.h:460
#define ACPI_GPE_DISPATCH_RAW_HANDLER
Definition: actypes.h:813
ACPI_GPE_HANDLER_INFO * Handler
Definition: aclocal.h:543
struct TraceInfo Info
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
#define ACPI_FAILURE(a)
Definition: acexcep.h:95
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
#define ACPI_GPE_DISPATCH_NOTIFY
Definition: actypes.h:812
unsigned int UINT32
union acpi_gpe_dispatch_info Dispatch
Definition: aclocal.h:554
#define ACPI_GPE_DISPATCH_HANDLER
Definition: actypes.h:811
ACPI_STATUS AcpiEvDeleteGpeHandlers(ACPI_GPE_XRUPT_INFO *GpeXruptInfo, ACPI_GPE_BLOCK_INFO *GpeBlock, void *Context)
Definition: evgpeutil.c:339
UINT32 ACPI_SYSTEM_XFACE AcpiEvGpeXruptHandler(void *Context)
Definition: evsci.c:176
#define ACPI_MODULE_NAME(Name)
Definition: acoutput.h:216
smooth NULL
Definition: ftsmooth.c:416
#define AE_INFO
Definition: acoutput.h:230
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
ACPI_STATUS AcpiEvGetGpeXruptBlock(UINT32 InterruptNumber, ACPI_GPE_XRUPT_INFO **GpeXruptBlock)
Definition: evgpeutil.c:178
ACPI_STATUS AcpiOsInstallInterruptHandler(UINT32 InterruptNumber, ACPI_OSD_HANDLER ServiceRoutine, void *Context)
Definition: osl.c:548
HRESULT Next([in] ULONG celt, [out, size_is(celt), length_is(*pceltFetched)] STATPROPSETSTG *rgelt, [out] ULONG *pceltFetched)
ACPI_GPE_BLOCK_INFO * GpeBlockListHead
Definition: aclocal.h:604
#define ACPI_TYPE_DEVICE
Definition: actypes.h:684
#define ACPI_GPE_DISPATCH_MASK
Definition: actypes.h:814
UINT32 RegisterCount
Definition: aclocal.h:590
Status
Definition: gdiplustypes.h:24
ACPI_STATUS AcpiEvDeleteGpeXrupt(ACPI_GPE_XRUPT_INFO *GpeXrupt)
Definition: evgpeutil.c:270
#define return_ACPI_STATUS(s)
Definition: acoutput.h:496
#define ACPI_FUNCTION_TRACE(a)
Definition: acoutput.h:480
ACPI_STATUS AcpiEvWalkGpeList(ACPI_GPE_CALLBACK GpeWalkCallback, void *Context)
Definition: evgpeutil.c:67
void AcpiOsReleaseLock(ACPI_SPINLOCK Handle, ACPI_CPU_FLAGS Flags)
Definition: osl.c:516
struct tagContext Context
Definition: acpixf.h:1012
UINT32 InterruptNumber
Definition: aclocal.h:605
struct acpi_gpe_xrupt_info * Previous
Definition: aclocal.h:602
#define ACPI_GPE_REGISTER_WIDTH
Definition: actypes.h:407
#define AE_OK
Definition: acexcep.h:97
ACPI_GPE_EVENT_INFO * EventInfo
Definition: aclocal.h:588
ACPI_NAMESPACE_NODE * Node
Definition: aclocal.h:583