Print this page
update to acpica-unix2-20140114
update to acpica-unix2-20131218
acpica-unix2-20130823
PANKOVs restructure
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/uts/intel/io/acpica/events/evgpeutil.c
+++ new/usr/src/common/acpica/components/events/evgpeutil.c
1 1 /******************************************************************************
2 2 *
3 3 * Module Name: evgpeutil - GPE utilities
4 4 *
5 5 *****************************************************************************/
6 6
7 7 /*
8 - * Copyright (C) 2000 - 2011, Intel Corp.
8 + * Copyright (C) 2000 - 2014, Intel Corp.
9 9 * All rights reserved.
10 10 *
11 11 * Redistribution and use in source and binary forms, with or without
12 12 * modification, are permitted provided that the following conditions
13 13 * are met:
14 14 * 1. Redistributions of source code must retain the above copyright
15 15 * notice, this list of conditions, and the following disclaimer,
16 16 * without modification.
17 17 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18 18 * substantially similar to the "NO WARRANTY" disclaimer below
19 19 * ("Disclaimer") and any redistribution must be conditioned upon
20 20 * including a substantially similar Disclaimer requirement for further
21 21 * binary redistribution.
22 22 * 3. Neither the names of the above-listed copyright holders nor the names
23 23 * of any contributors may be used to endorse or promote products derived
24 24 * from this software without specific prior written permission.
25 25 *
26 26 * Alternatively, this software may be distributed under the terms of the
27 27 * GNU General Public License ("GPL") version 2 as published by the Free
28 28 * Software Foundation.
29 29 *
30 30 * NO WARRANTY
31 31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32 32 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33 33 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
↓ open down ↓ |
15 lines elided |
↑ open up ↑ |
34 34 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35 35 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36 36 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37 37 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38 38 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39 39 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40 40 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41 41 * POSSIBILITY OF SUCH DAMAGES.
42 42 */
43 43
44 -
45 44 #include "acpi.h"
46 45 #include "accommon.h"
47 46 #include "acevents.h"
48 47
49 48 #define _COMPONENT ACPI_EVENTS
50 49 ACPI_MODULE_NAME ("evgpeutil")
51 50
52 51
52 +#if (!ACPI_REDUCED_HARDWARE) /* Entire module */
53 53 /*******************************************************************************
54 54 *
55 55 * FUNCTION: AcpiEvWalkGpeList
56 56 *
57 57 * PARAMETERS: GpeWalkCallback - Routine called for each GPE block
58 58 * Context - Value passed to callback
59 59 *
60 60 * RETURN: Status
61 61 *
62 62 * DESCRIPTION: Walk the GPE lists.
63 63 *
64 64 ******************************************************************************/
65 65
66 66 ACPI_STATUS
67 67 AcpiEvWalkGpeList (
68 68 ACPI_GPE_CALLBACK GpeWalkCallback,
69 69 void *Context)
70 70 {
71 71 ACPI_GPE_BLOCK_INFO *GpeBlock;
72 72 ACPI_GPE_XRUPT_INFO *GpeXruptInfo;
73 73 ACPI_STATUS Status = AE_OK;
74 74 ACPI_CPU_FLAGS Flags;
75 75
76 76
77 77 ACPI_FUNCTION_TRACE (EvWalkGpeList);
78 78
79 79
80 80 Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
81 81
82 82 /* Walk the interrupt level descriptor list */
83 83
84 84 GpeXruptInfo = AcpiGbl_GpeXruptListHead;
85 85 while (GpeXruptInfo)
86 86 {
87 87 /* Walk all Gpe Blocks attached to this interrupt level */
88 88
89 89 GpeBlock = GpeXruptInfo->GpeBlockListHead;
90 90 while (GpeBlock)
91 91 {
92 92 /* One callback per GPE block */
93 93
94 94 Status = GpeWalkCallback (GpeXruptInfo, GpeBlock, Context);
95 95 if (ACPI_FAILURE (Status))
96 96 {
97 97 if (Status == AE_CTRL_END) /* Callback abort */
98 98 {
99 99 Status = AE_OK;
100 100 }
101 101 goto UnlockAndExit;
102 102 }
103 103
104 104 GpeBlock = GpeBlock->Next;
105 105 }
106 106
107 107 GpeXruptInfo = GpeXruptInfo->Next;
108 108 }
109 109
110 110 UnlockAndExit:
111 111 AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
112 112 return_ACPI_STATUS (Status);
113 113 }
114 114
115 115
116 116 /*******************************************************************************
117 117 *
118 118 * FUNCTION: AcpiEvValidGpeEvent
119 119 *
120 120 * PARAMETERS: GpeEventInfo - Info for this GPE
121 121 *
122 122 * RETURN: TRUE if the GpeEvent is valid
123 123 *
124 124 * DESCRIPTION: Validate a GPE event. DO NOT CALL FROM INTERRUPT LEVEL.
125 125 * Should be called only when the GPE lists are semaphore locked
126 126 * and not subject to change.
127 127 *
128 128 ******************************************************************************/
129 129
130 130 BOOLEAN
131 131 AcpiEvValidGpeEvent (
132 132 ACPI_GPE_EVENT_INFO *GpeEventInfo)
133 133 {
134 134 ACPI_GPE_XRUPT_INFO *GpeXruptBlock;
135 135 ACPI_GPE_BLOCK_INFO *GpeBlock;
136 136
137 137
138 138 ACPI_FUNCTION_ENTRY ();
139 139
140 140
141 141 /* No need for spin lock since we are not changing any list elements */
142 142
143 143 /* Walk the GPE interrupt levels */
144 144
145 145 GpeXruptBlock = AcpiGbl_GpeXruptListHead;
146 146 while (GpeXruptBlock)
147 147 {
148 148 GpeBlock = GpeXruptBlock->GpeBlockListHead;
149 149
150 150 /* Walk the GPE blocks on this interrupt level */
151 151
152 152 while (GpeBlock)
153 153 {
154 154 if ((&GpeBlock->EventInfo[0] <= GpeEventInfo) &&
155 155 (&GpeBlock->EventInfo[GpeBlock->GpeCount] > GpeEventInfo))
156 156 {
157 157 return (TRUE);
158 158 }
159 159
160 160 GpeBlock = GpeBlock->Next;
161 161 }
162 162
163 163 GpeXruptBlock = GpeXruptBlock->Next;
164 164 }
165 165
166 166 return (FALSE);
167 167 }
168 168
169 169
170 170 /*******************************************************************************
171 171 *
172 172 * FUNCTION: AcpiEvGetGpeDevice
173 173 *
174 174 * PARAMETERS: GPE_WALK_CALLBACK
175 175 *
176 176 * RETURN: Status
177 177 *
178 178 * DESCRIPTION: Matches the input GPE index (0-CurrentGpeCount) with a GPE
179 179 * block device. NULL if the GPE is one of the FADT-defined GPEs.
180 180 *
181 181 ******************************************************************************/
182 182
183 183 ACPI_STATUS
184 184 AcpiEvGetGpeDevice (
185 185 ACPI_GPE_XRUPT_INFO *GpeXruptInfo,
186 186 ACPI_GPE_BLOCK_INFO *GpeBlock,
187 187 void *Context)
188 188 {
189 189 ACPI_GPE_DEVICE_INFO *Info = Context;
190 190
191 191
192 192 /* Increment Index by the number of GPEs in this block */
193 193
194 194 Info->NextBlockBaseIndex += GpeBlock->GpeCount;
195 195
196 196 if (Info->Index < Info->NextBlockBaseIndex)
197 197 {
198 198 /*
199 199 * The GPE index is within this block, get the node. Leave the node
200 200 * NULL for the FADT-defined GPEs
201 201 */
202 202 if ((GpeBlock->Node)->Type == ACPI_TYPE_DEVICE)
203 203 {
204 204 Info->GpeDevice = GpeBlock->Node;
205 205 }
206 206
207 207 Info->Status = AE_OK;
208 208 return (AE_CTRL_END);
↓ open down ↓ |
146 lines elided |
↑ open up ↑ |
209 209 }
210 210
211 211 return (AE_OK);
212 212 }
213 213
214 214
215 215 /*******************************************************************************
216 216 *
217 217 * FUNCTION: AcpiEvGetGpeXruptBlock
218 218 *
219 - * PARAMETERS: InterruptNumber - Interrupt for a GPE block
219 + * PARAMETERS: InterruptNumber - Interrupt for a GPE block
220 + * GpeXruptBlock - Where the block is returned
220 221 *
221 - * RETURN: A GPE interrupt block
222 + * RETURN: Status
222 223 *
223 224 * DESCRIPTION: Get or Create a GPE interrupt block. There is one interrupt
224 225 * block per unique interrupt level used for GPEs. Should be
225 226 * called only when the GPE lists are semaphore locked and not
226 227 * subject to change.
227 228 *
228 229 ******************************************************************************/
229 230
230 -ACPI_GPE_XRUPT_INFO *
231 +ACPI_STATUS
231 232 AcpiEvGetGpeXruptBlock (
232 - UINT32 InterruptNumber)
233 + UINT32 InterruptNumber,
234 + ACPI_GPE_XRUPT_INFO **GpeXruptBlock)
233 235 {
234 236 ACPI_GPE_XRUPT_INFO *NextGpeXrupt;
235 237 ACPI_GPE_XRUPT_INFO *GpeXrupt;
236 238 ACPI_STATUS Status;
237 239 ACPI_CPU_FLAGS Flags;
238 240
239 241
240 242 ACPI_FUNCTION_TRACE (EvGetGpeXruptBlock);
241 243
242 244
243 245 /* No need for lock since we are not changing any list elements here */
244 246
245 247 NextGpeXrupt = AcpiGbl_GpeXruptListHead;
246 248 while (NextGpeXrupt)
247 249 {
248 250 if (NextGpeXrupt->InterruptNumber == InterruptNumber)
249 251 {
250 - return_PTR (NextGpeXrupt);
252 + *GpeXruptBlock = NextGpeXrupt;
253 + return_ACPI_STATUS (AE_OK);
251 254 }
252 255
253 256 NextGpeXrupt = NextGpeXrupt->Next;
254 257 }
255 258
256 259 /* Not found, must allocate a new xrupt descriptor */
257 260
258 261 GpeXrupt = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_GPE_XRUPT_INFO));
259 262 if (!GpeXrupt)
260 263 {
261 - return_PTR (NULL);
264 + return_ACPI_STATUS (AE_NO_MEMORY);
262 265 }
263 266
264 267 GpeXrupt->InterruptNumber = InterruptNumber;
265 268
266 269 /* Install new interrupt descriptor with spin lock */
267 270
268 271 Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
269 272 if (AcpiGbl_GpeXruptListHead)
270 273 {
271 274 NextGpeXrupt = AcpiGbl_GpeXruptListHead;
272 275 while (NextGpeXrupt->Next)
273 276 {
↓ open down ↓ |
2 lines elided |
↑ open up ↑ |
274 277 NextGpeXrupt = NextGpeXrupt->Next;
275 278 }
276 279
277 280 NextGpeXrupt->Next = GpeXrupt;
278 281 GpeXrupt->Previous = NextGpeXrupt;
279 282 }
280 283 else
281 284 {
282 285 AcpiGbl_GpeXruptListHead = GpeXrupt;
283 286 }
287 +
284 288 AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
285 289
286 290 /* Install new interrupt handler if not SCI_INT */
287 291
288 292 if (InterruptNumber != AcpiGbl_FADT.SciInterrupt)
289 293 {
290 294 Status = AcpiOsInstallInterruptHandler (InterruptNumber,
291 295 AcpiEvGpeXruptHandler, GpeXrupt);
292 296 if (ACPI_FAILURE (Status))
293 297 {
294 - ACPI_ERROR ((AE_INFO,
298 + ACPI_EXCEPTION ((AE_INFO, Status,
295 299 "Could not install GPE interrupt handler at level 0x%X",
296 300 InterruptNumber));
297 - return_PTR (NULL);
301 + return_ACPI_STATUS (Status);
298 302 }
299 303 }
300 304
301 - return_PTR (GpeXrupt);
305 + *GpeXruptBlock = GpeXrupt;
306 + return_ACPI_STATUS (AE_OK);
302 307 }
303 308
304 309
305 310 /*******************************************************************************
306 311 *
307 312 * FUNCTION: AcpiEvDeleteGpeXrupt
308 313 *
309 314 * PARAMETERS: GpeXrupt - A GPE interrupt info block
310 315 *
311 316 * RETURN: Status
312 317 *
313 318 * DESCRIPTION: Remove and free a GpeXrupt block. Remove an associated
314 319 * interrupt handler if not the SCI interrupt.
315 320 *
316 321 ******************************************************************************/
317 322
318 323 ACPI_STATUS
319 324 AcpiEvDeleteGpeXrupt (
320 325 ACPI_GPE_XRUPT_INFO *GpeXrupt)
321 326 {
322 327 ACPI_STATUS Status;
323 328 ACPI_CPU_FLAGS Flags;
324 329
325 330
326 331 ACPI_FUNCTION_TRACE (EvDeleteGpeXrupt);
327 332
328 333
329 334 /* We never want to remove the SCI interrupt handler */
330 335
331 336 if (GpeXrupt->InterruptNumber == AcpiGbl_FADT.SciInterrupt)
332 337 {
333 338 GpeXrupt->GpeBlockListHead = NULL;
334 339 return_ACPI_STATUS (AE_OK);
335 340 }
336 341
337 342 /* Disable this interrupt */
338 343
339 344 Status = AcpiOsRemoveInterruptHandler (
340 345 GpeXrupt->InterruptNumber, AcpiEvGpeXruptHandler);
341 346 if (ACPI_FAILURE (Status))
342 347 {
343 348 return_ACPI_STATUS (Status);
344 349 }
345 350
346 351 /* Unlink the interrupt block with lock */
347 352
348 353 Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
349 354 if (GpeXrupt->Previous)
350 355 {
351 356 GpeXrupt->Previous->Next = GpeXrupt->Next;
352 357 }
353 358 else
354 359 {
355 360 /* No previous, update list head */
356 361
357 362 AcpiGbl_GpeXruptListHead = GpeXrupt->Next;
358 363 }
359 364
360 365 if (GpeXrupt->Next)
361 366 {
362 367 GpeXrupt->Next->Previous = GpeXrupt->Previous;
363 368 }
364 369 AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
365 370
366 371 /* Free the block */
367 372
368 373 ACPI_FREE (GpeXrupt);
369 374 return_ACPI_STATUS (AE_OK);
370 375 }
371 376
372 377
373 378 /*******************************************************************************
374 379 *
375 380 * FUNCTION: AcpiEvDeleteGpeHandlers
376 381 *
377 382 * PARAMETERS: GpeXruptInfo - GPE Interrupt info
378 383 * GpeBlock - Gpe Block info
379 384 *
380 385 * RETURN: Status
381 386 *
382 387 * DESCRIPTION: Delete all Handler objects found in the GPE data structs.
383 388 * Used only prior to termination.
↓ open down ↓ |
72 lines elided |
↑ open up ↑ |
384 389 *
385 390 ******************************************************************************/
386 391
387 392 ACPI_STATUS
388 393 AcpiEvDeleteGpeHandlers (
389 394 ACPI_GPE_XRUPT_INFO *GpeXruptInfo,
390 395 ACPI_GPE_BLOCK_INFO *GpeBlock,
391 396 void *Context)
392 397 {
393 398 ACPI_GPE_EVENT_INFO *GpeEventInfo;
399 + ACPI_GPE_NOTIFY_INFO *Notify;
400 + ACPI_GPE_NOTIFY_INFO *Next;
394 401 UINT32 i;
395 402 UINT32 j;
396 403
397 404
398 405 ACPI_FUNCTION_TRACE (EvDeleteGpeHandlers);
399 406
400 407
401 408 /* Examine each GPE Register within the block */
402 409
403 410 for (i = 0; i < GpeBlock->RegisterCount; i++)
404 411 {
↓ open down ↓ |
1 lines elided |
↑ open up ↑ |
405 412 /* Now look at the individual GPEs in this byte register */
406 413
407 414 for (j = 0; j < ACPI_GPE_REGISTER_WIDTH; j++)
408 415 {
409 416 GpeEventInfo = &GpeBlock->EventInfo[((ACPI_SIZE) i *
410 417 ACPI_GPE_REGISTER_WIDTH) + j];
411 418
412 419 if ((GpeEventInfo->Flags & ACPI_GPE_DISPATCH_MASK) ==
413 420 ACPI_GPE_DISPATCH_HANDLER)
414 421 {
422 + /* Delete an installed handler block */
423 +
415 424 ACPI_FREE (GpeEventInfo->Dispatch.Handler);
416 425 GpeEventInfo->Dispatch.Handler = NULL;
417 426 GpeEventInfo->Flags &= ~ACPI_GPE_DISPATCH_MASK;
418 427 }
428 + else if ((GpeEventInfo->Flags & ACPI_GPE_DISPATCH_MASK) ==
429 + ACPI_GPE_DISPATCH_NOTIFY)
430 + {
431 + /* Delete the implicit notification device list */
432 +
433 + Notify = GpeEventInfo->Dispatch.NotifyList;
434 + while (Notify)
435 + {
436 + Next = Notify->Next;
437 + ACPI_FREE (Notify);
438 + Notify = Next;
439 + }
440 + GpeEventInfo->Dispatch.NotifyList = NULL;
441 + GpeEventInfo->Flags &= ~ACPI_GPE_DISPATCH_MASK;
442 + }
419 443 }
420 444 }
421 445
422 446 return_ACPI_STATUS (AE_OK);
423 447 }
424 448
449 +#endif /* !ACPI_REDUCED_HARDWARE */
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX