Print this page
update to acpica-unix2-20140114
acpica-unix2-20130823
PANKOVs restructure
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/uts/intel/io/acpica/utilities/utdelete.c
+++ new/usr/src/common/acpica/components/utilities/utdelete.c
1 1 /*******************************************************************************
2 2 *
3 3 * Module Name: utdelete - object deletion and reference count 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
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 44 #define __UTDELETE_C__
45 45
46 46 #include "acpi.h"
47 47 #include "accommon.h"
48 48 #include "acinterp.h"
49 49 #include "acnamesp.h"
50 50 #include "acevents.h"
51 51
52 52
53 53 #define _COMPONENT ACPI_UTILITIES
54 54 ACPI_MODULE_NAME ("utdelete")
55 55
56 56 /* Local prototypes */
57 57
58 58 static void
59 59 AcpiUtDeleteInternalObj (
60 60 ACPI_OPERAND_OBJECT *Object);
61 61
62 62 static void
63 63 AcpiUtUpdateRefCount (
64 64 ACPI_OPERAND_OBJECT *Object,
65 65 UINT32 Action);
66 66
67 67
68 68 /*******************************************************************************
69 69 *
70 70 * FUNCTION: AcpiUtDeleteInternalObj
71 71 *
72 72 * PARAMETERS: Object - Object to be deleted
73 73 *
74 74 * RETURN: None
75 75 *
76 76 * DESCRIPTION: Low level object deletion, after reference counts have been
77 77 * updated (All reference counts, including sub-objects!)
78 78 *
79 79 ******************************************************************************/
80 80
81 81 static void
82 82 AcpiUtDeleteInternalObj (
83 83 ACPI_OPERAND_OBJECT *Object)
84 84 {
85 85 void *ObjPointer = NULL;
86 86 ACPI_OPERAND_OBJECT *HandlerDesc;
87 87 ACPI_OPERAND_OBJECT *SecondDesc;
88 88 ACPI_OPERAND_OBJECT *NextDesc;
89 89 ACPI_OPERAND_OBJECT **LastObjPtr;
90 90
91 91
92 92 ACPI_FUNCTION_TRACE_PTR (UtDeleteInternalObj, Object);
93 93
94 94
95 95 if (!Object)
96 96 {
97 97 return_VOID;
98 98 }
99 99
100 100 /*
101 101 * Must delete or free any pointers within the object that are not
102 102 * actual ACPI objects (for example, a raw buffer pointer).
103 103 */
104 104 switch (Object->Common.Type)
105 105 {
106 106 case ACPI_TYPE_STRING:
107 107
108 108 ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "**** String %p, ptr %p\n",
109 109 Object, Object->String.Pointer));
110 110
↓ open down ↓ |
92 lines elided |
↑ open up ↑ |
111 111 /* Free the actual string buffer */
112 112
113 113 if (!(Object->Common.Flags & AOPOBJ_STATIC_POINTER))
114 114 {
115 115 /* But only if it is NOT a pointer into an ACPI table */
116 116
117 117 ObjPointer = Object->String.Pointer;
118 118 }
119 119 break;
120 120
121 -
122 121 case ACPI_TYPE_BUFFER:
123 122
124 123 ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "**** Buffer %p, ptr %p\n",
125 124 Object, Object->Buffer.Pointer));
126 125
127 126 /* Free the actual buffer */
128 127
129 128 if (!(Object->Common.Flags & AOPOBJ_STATIC_POINTER))
130 129 {
131 130 /* But only if it is NOT a pointer into an ACPI table */
132 131
133 132 ObjPointer = Object->Buffer.Pointer;
134 133 }
135 134 break;
136 135
137 -
138 136 case ACPI_TYPE_PACKAGE:
139 137
140 138 ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, " **** Package of count %X\n",
141 139 Object->Package.Count));
142 140
143 141 /*
144 142 * Elements of the package are not handled here, they are deleted
145 143 * separately
146 144 */
147 145
148 146 /* Free the (variable length) element pointer array */
149 147
150 148 ObjPointer = Object->Package.Elements;
151 149 break;
152 150
153 -
154 151 /*
155 152 * These objects have a possible list of notify handlers.
156 153 * Device object also may have a GPE block.
157 154 */
158 155 case ACPI_TYPE_DEVICE:
159 156
160 157 if (Object->Device.GpeBlock)
161 158 {
162 159 (void) AcpiEvDeleteGpeBlock (Object->Device.GpeBlock);
163 160 }
164 161
165 162 /*lint -fallthrough */
166 163
167 164 case ACPI_TYPE_PROCESSOR:
168 165 case ACPI_TYPE_THERMAL:
169 166
170 - /* Walk the notify handler list for this object */
167 + /* Walk the address handler list for this object */
171 168
172 169 HandlerDesc = Object->CommonNotify.Handler;
173 170 while (HandlerDesc)
174 171 {
175 172 NextDesc = HandlerDesc->AddressSpace.Next;
176 173 AcpiUtRemoveReference (HandlerDesc);
177 174 HandlerDesc = NextDesc;
178 175 }
179 176 break;
180 177
181 -
182 178 case ACPI_TYPE_MUTEX:
183 179
184 180 ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS,
185 181 "***** Mutex %p, OS Mutex %p\n",
186 182 Object, Object->Mutex.OsMutex));
187 183
188 184 if (Object == AcpiGbl_GlobalLockMutex)
189 185 {
190 186 /* Global Lock has extra semaphore */
191 187
192 188 (void) AcpiOsDeleteSemaphore (AcpiGbl_GlobalLockSemaphore);
193 189 AcpiGbl_GlobalLockSemaphore = NULL;
194 190
↓ open down ↓ |
3 lines elided |
↑ open up ↑ |
195 191 AcpiOsDeleteMutex (Object->Mutex.OsMutex);
196 192 AcpiGbl_GlobalLockMutex = NULL;
197 193 }
198 194 else
199 195 {
200 196 AcpiExUnlinkMutex (Object);
201 197 AcpiOsDeleteMutex (Object->Mutex.OsMutex);
202 198 }
203 199 break;
204 200
205 -
206 201 case ACPI_TYPE_EVENT:
207 202
208 203 ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS,
209 204 "***** Event %p, OS Semaphore %p\n",
210 205 Object, Object->Event.OsSemaphore));
211 206
212 207 (void) AcpiOsDeleteSemaphore (Object->Event.OsSemaphore);
213 208 Object->Event.OsSemaphore = NULL;
214 209 break;
215 210
216 -
217 211 case ACPI_TYPE_METHOD:
218 212
219 213 ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS,
220 214 "***** Method %p\n", Object));
221 215
222 216 /* Delete the method mutex if it exists */
223 217
224 218 if (Object->Method.Mutex)
225 219 {
226 220 AcpiOsDeleteMutex (Object->Method.Mutex->Mutex.OsMutex);
227 221 AcpiUtDeleteObjectDesc (Object->Method.Mutex);
228 222 Object->Method.Mutex = NULL;
229 223 }
230 224 break;
231 225
232 -
233 226 case ACPI_TYPE_REGION:
234 227
235 228 ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS,
236 229 "***** Region %p\n", Object));
237 230
231 + /*
232 + * Update AddressRange list. However, only permanent regions
233 + * are installed in this list. (Not created within a method)
234 + */
235 + if (!(Object->Region.Node->Flags & ANOBJ_TEMPORARY))
236 + {
237 + AcpiUtRemoveAddressRange (Object->Region.SpaceId,
238 + Object->Region.Node);
239 + }
240 +
238 241 SecondDesc = AcpiNsGetSecondaryObject (Object);
239 242 if (SecondDesc)
240 243 {
241 244 /*
242 245 * Free the RegionContext if and only if the handler is one of the
243 246 * default handlers -- and therefore, we created the context object
244 247 * locally, it was not created by an external caller.
245 248 */
246 249 HandlerDesc = Object->Region.Handler;
247 250 if (HandlerDesc)
248 251 {
249 252 NextDesc = HandlerDesc->AddressSpace.RegionList;
250 253 LastObjPtr = &HandlerDesc->AddressSpace.RegionList;
251 254
252 255 /* Remove the region object from the handler's list */
253 256
254 257 while (NextDesc)
255 258 {
256 259 if (NextDesc == Object)
257 260 {
258 261 *LastObjPtr = NextDesc->Region.Next;
259 262 break;
260 263 }
261 264
262 265 /* Walk the linked list of handler */
263 266
264 267 LastObjPtr = &NextDesc->Region.Next;
265 268 NextDesc = NextDesc->Region.Next;
266 269 }
267 270
268 271 if (HandlerDesc->AddressSpace.HandlerFlags &
269 272 ACPI_ADDR_HANDLER_DEFAULT_INSTALLED)
270 273 {
271 274 /* Deactivate region and free region context */
272 275
273 276 if (HandlerDesc->AddressSpace.Setup)
274 277 {
275 278 (void) HandlerDesc->AddressSpace.Setup (Object,
276 279 ACPI_REGION_DEACTIVATE,
277 280 HandlerDesc->AddressSpace.Context,
278 281 &SecondDesc->Extra.RegionContext);
279 282 }
280 283 }
↓ open down ↓ |
33 lines elided |
↑ open up ↑ |
281 284
282 285 AcpiUtRemoveReference (HandlerDesc);
283 286 }
284 287
285 288 /* Now we can free the Extra object */
286 289
287 290 AcpiUtDeleteObjectDesc (SecondDesc);
288 291 }
289 292 break;
290 293
291 -
292 294 case ACPI_TYPE_BUFFER_FIELD:
293 295
294 296 ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS,
295 297 "***** Buffer Field %p\n", Object));
296 298
297 299 SecondDesc = AcpiNsGetSecondaryObject (Object);
298 300 if (SecondDesc)
299 301 {
300 302 AcpiUtDeleteObjectDesc (SecondDesc);
301 303 }
302 304 break;
303 305
304 -
305 306 case ACPI_TYPE_LOCAL_BANK_FIELD:
306 307
307 308 ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS,
308 309 "***** Bank Field %p\n", Object));
309 310
310 311 SecondDesc = AcpiNsGetSecondaryObject (Object);
311 312 if (SecondDesc)
312 313 {
313 314 AcpiUtDeleteObjectDesc (SecondDesc);
314 315 }
315 316 break;
316 317
317 -
318 318 default:
319 +
319 320 break;
320 321 }
321 322
322 323 /* Free any allocated memory (pointer within the object) found above */
323 324
324 325 if (ObjPointer)
325 326 {
326 327 ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "Deleting Object Subptr %p\n",
327 328 ObjPointer));
328 329 ACPI_FREE (ObjPointer);
329 330 }
330 331
331 332 /* Now the object can be safely deleted */
332 333
333 334 ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "Deleting Object %p [%s]\n",
334 335 Object, AcpiUtGetObjectTypeName (Object)));
335 336
336 337 AcpiUtDeleteObjectDesc (Object);
337 338 return_VOID;
338 339 }
339 340
340 341
341 342 /*******************************************************************************
342 343 *
343 344 * FUNCTION: AcpiUtDeleteInternalObjectList
344 345 *
345 346 * PARAMETERS: ObjList - Pointer to the list to be deleted
346 347 *
347 348 * RETURN: None
348 349 *
349 350 * DESCRIPTION: This function deletes an internal object list, including both
350 351 * simple objects and package objects
↓ open down ↓ |
22 lines elided |
↑ open up ↑ |
351 352 *
352 353 ******************************************************************************/
353 354
354 355 void
355 356 AcpiUtDeleteInternalObjectList (
356 357 ACPI_OPERAND_OBJECT **ObjList)
357 358 {
358 359 ACPI_OPERAND_OBJECT **InternalObj;
359 360
360 361
361 - ACPI_FUNCTION_TRACE (UtDeleteInternalObjectList);
362 + ACPI_FUNCTION_ENTRY ();
362 363
363 364
364 365 /* Walk the null-terminated internal list */
365 366
366 367 for (InternalObj = ObjList; *InternalObj; InternalObj++)
367 368 {
368 369 AcpiUtRemoveReference (*InternalObj);
369 370 }
370 371
371 372 /* Free the combined parameter pointer list and object array */
372 373
373 374 ACPI_FREE (ObjList);
374 - return_VOID;
375 + return;
375 376 }
376 377
377 378
378 379 /*******************************************************************************
379 380 *
380 381 * FUNCTION: AcpiUtUpdateRefCount
381 382 *
382 383 * PARAMETERS: Object - Object whose ref count is to be updated
383 - * Action - What to do
384 + * Action - What to do (REF_INCREMENT or REF_DECREMENT)
384 385 *
385 - * RETURN: New ref count
386 + * RETURN: None. Sets new reference count within the object
386 387 *
387 - * DESCRIPTION: Modify the ref count and return it.
388 + * DESCRIPTION: Modify the reference count for an internal acpi object
388 389 *
389 390 ******************************************************************************/
390 391
391 392 static void
392 393 AcpiUtUpdateRefCount (
393 394 ACPI_OPERAND_OBJECT *Object,
394 395 UINT32 Action)
395 396 {
396 - UINT16 Count;
397 - UINT16 NewCount;
397 + UINT16 OriginalCount;
398 + UINT16 NewCount = 0;
399 + ACPI_CPU_FLAGS LockFlags;
398 400
399 401
400 402 ACPI_FUNCTION_NAME (UtUpdateRefCount);
401 403
402 404
403 405 if (!Object)
404 406 {
405 407 return;
406 408 }
407 409
408 - Count = Object->Common.ReferenceCount;
409 - NewCount = Count;
410 -
411 410 /*
412 - * Perform the reference count action (increment, decrement, force delete)
411 + * Always get the reference count lock. Note: Interpreter and/or
412 + * Namespace is not always locked when this function is called.
413 413 */
414 + LockFlags = AcpiOsAcquireLock (AcpiGbl_ReferenceCountLock);
415 + OriginalCount = Object->Common.ReferenceCount;
416 +
417 + /* Perform the reference count action (increment, decrement) */
418 +
414 419 switch (Action)
415 420 {
416 421 case REF_INCREMENT:
417 422
418 - NewCount++;
423 + NewCount = OriginalCount + 1;
419 424 Object->Common.ReferenceCount = NewCount;
425 + AcpiOsReleaseLock (AcpiGbl_ReferenceCountLock, LockFlags);
420 426
427 + /* The current reference count should never be zero here */
428 +
429 + if (!OriginalCount)
430 + {
431 + ACPI_WARNING ((AE_INFO,
432 + "Obj %p, Reference Count was zero before increment\n",
433 + Object));
434 + }
435 +
421 436 ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS,
422 - "Obj %p Refs=%X, [Incremented]\n",
423 - Object, NewCount));
437 + "Obj %p Type %.2X Refs %.2X [Incremented]\n",
438 + Object, Object->Common.Type, NewCount));
424 439 break;
425 440
426 441 case REF_DECREMENT:
427 442
428 - if (Count < 1)
429 - {
430 - ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS,
431 - "Obj %p Refs=%X, can't decrement! (Set to 0)\n",
432 - Object, NewCount));
443 + /* The current reference count must be non-zero */
433 444
434 - NewCount = 0;
435 - }
436 - else
445 + if (OriginalCount)
437 446 {
438 - NewCount--;
439 -
440 - ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS,
441 - "Obj %p Refs=%X, [Decremented]\n",
442 - Object, NewCount));
447 + NewCount = OriginalCount - 1;
448 + Object->Common.ReferenceCount = NewCount;
443 449 }
444 450
445 - if (Object->Common.Type == ACPI_TYPE_METHOD)
451 + AcpiOsReleaseLock (AcpiGbl_ReferenceCountLock, LockFlags);
452 +
453 + if (!OriginalCount)
446 454 {
447 - ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS,
448 - "Method Obj %p Refs=%X, [Decremented]\n", Object, NewCount));
455 + ACPI_WARNING ((AE_INFO,
456 + "Obj %p, Reference Count is already zero, cannot decrement\n",
457 + Object));
449 458 }
450 459
451 - Object->Common.ReferenceCount = NewCount;
460 + ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS,
461 + "Obj %p Type %.2X Refs %.2X [Decremented]\n",
462 + Object, Object->Common.Type, NewCount));
463 +
464 + /* Actually delete the object on a reference count of zero */
465 +
452 466 if (NewCount == 0)
453 467 {
454 468 AcpiUtDeleteInternalObj (Object);
455 469 }
456 470 break;
457 471
458 - case REF_FORCE_DELETE:
459 -
460 - ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS,
461 - "Obj %p Refs=%X, Force delete! (Set to 0)\n", Object, Count));
462 -
463 - NewCount = 0;
464 - Object->Common.ReferenceCount = NewCount;
465 - AcpiUtDeleteInternalObj (Object);
466 - break;
467 -
468 472 default:
469 473
470 - ACPI_ERROR ((AE_INFO, "Unknown action (0x%X)", Action));
471 - break;
474 + AcpiOsReleaseLock (AcpiGbl_ReferenceCountLock, LockFlags);
475 + ACPI_ERROR ((AE_INFO, "Unknown Reference Count action (0x%X)",
476 + Action));
477 + return;
472 478 }
473 479
474 480 /*
475 481 * Sanity check the reference count, for debug purposes only.
476 482 * (A deleted object will have a huge reference count)
477 483 */
478 - if (Count > ACPI_MAX_REFERENCE_COUNT)
484 + if (NewCount > ACPI_MAX_REFERENCE_COUNT)
479 485 {
480 486 ACPI_WARNING ((AE_INFO,
481 - "Large Reference Count (0x%X) in object %p", Count, Object));
487 + "Large Reference Count (0x%X) in object %p, Type=0x%.2X",
488 + NewCount, Object, Object->Common.Type));
482 489 }
483 490 }
484 491
485 492
486 493 /*******************************************************************************
487 494 *
488 495 * FUNCTION: AcpiUtUpdateObjectReference
489 496 *
490 497 * PARAMETERS: Object - Increment ref count for this object
491 498 * and all sub-objects
492 - * Action - Either REF_INCREMENT or REF_DECREMENT or
493 - * REF_FORCE_DELETE
499 + * Action - Either REF_INCREMENT or REF_DECREMENT
494 500 *
495 501 * RETURN: Status
496 502 *
497 503 * DESCRIPTION: Increment the object reference count
498 504 *
499 505 * Object references are incremented when:
500 506 * 1) An object is attached to a Node (namespace object)
501 507 * 2) An object is copied (all subobjects must be incremented)
502 508 *
503 509 * Object references are decremented when:
504 510 * 1) An object is detached from an Node
505 511 *
↓ open down ↓ |
2 lines elided |
↑ open up ↑ |
506 512 ******************************************************************************/
507 513
508 514 ACPI_STATUS
509 515 AcpiUtUpdateObjectReference (
510 516 ACPI_OPERAND_OBJECT *Object,
511 517 UINT16 Action)
512 518 {
513 519 ACPI_STATUS Status = AE_OK;
514 520 ACPI_GENERIC_STATE *StateList = NULL;
515 521 ACPI_OPERAND_OBJECT *NextObject = NULL;
522 + ACPI_OPERAND_OBJECT *PrevObject;
516 523 ACPI_GENERIC_STATE *State;
517 524 UINT32 i;
518 525
519 526
520 - ACPI_FUNCTION_TRACE_PTR (UtUpdateObjectReference, Object);
527 + ACPI_FUNCTION_NAME (UtUpdateObjectReference);
521 528
522 529
523 530 while (Object)
524 531 {
525 532 /* Make sure that this isn't a namespace handle */
526 533
527 534 if (ACPI_GET_DESCRIPTOR_TYPE (Object) == ACPI_DESC_TYPE_NAMED)
528 535 {
529 536 ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS,
530 537 "Object %p is NS handle\n", Object));
531 - return_ACPI_STATUS (AE_OK);
538 + return (AE_OK);
532 539 }
533 540
534 541 /*
535 542 * All sub-objects must have their reference count incremented also.
536 543 * Different object types have different subobjects.
537 544 */
538 545 switch (Object->Common.Type)
539 546 {
540 547 case ACPI_TYPE_DEVICE:
541 548 case ACPI_TYPE_PROCESSOR:
542 549 case ACPI_TYPE_POWER:
543 550 case ACPI_TYPE_THERMAL:
544 -
545 - /* Update the notify objects for these types (if present) */
546 -
547 - AcpiUtUpdateRefCount (Object->CommonNotify.SystemNotify, Action);
548 - AcpiUtUpdateRefCount (Object->CommonNotify.DeviceNotify, Action);
551 + /*
552 + * Update the notify objects for these types (if present)
553 + * Two lists, system and device notify handlers.
554 + */
555 + for (i = 0; i < ACPI_NUM_NOTIFY_TYPES; i++)
556 + {
557 + PrevObject = Object->CommonNotify.NotifyList[i];
558 + while (PrevObject)
559 + {
560 + NextObject = PrevObject->Notify.Next[i];
561 + AcpiUtUpdateRefCount (PrevObject, Action);
562 + PrevObject = NextObject;
563 + }
564 + }
549 565 break;
550 566
551 567 case ACPI_TYPE_PACKAGE:
552 568 /*
553 569 * We must update all the sub-objects of the package,
554 570 * each of whom may have their own sub-objects.
555 571 */
556 572 for (i = 0; i < Object->Package.Count; i++)
557 573 {
558 574 /*
559 - * Push each element onto the stack for later processing.
560 - * Note: There can be null elements within the package,
561 - * these are simply ignored
575 + * Null package elements are legal and can be simply
576 + * ignored.
562 577 */
563 - Status = AcpiUtCreateUpdateStateAndPush (
564 - Object->Package.Elements[i], Action, &StateList);
565 - if (ACPI_FAILURE (Status))
578 + NextObject = Object->Package.Elements[i];
579 + if (!NextObject)
566 580 {
567 - goto ErrorExit;
581 + continue;
568 582 }
583 +
584 + switch (NextObject->Common.Type)
585 + {
586 + case ACPI_TYPE_INTEGER:
587 + case ACPI_TYPE_STRING:
588 + case ACPI_TYPE_BUFFER:
589 + /*
590 + * For these very simple sub-objects, we can just
591 + * update the reference count here and continue.
592 + * Greatly increases performance of this operation.
593 + */
594 + AcpiUtUpdateRefCount (NextObject, Action);
595 + break;
596 +
597 + default:
598 + /*
599 + * For complex sub-objects, push them onto the stack
600 + * for later processing (this eliminates recursion.)
601 + */
602 + Status = AcpiUtCreateUpdateStateAndPush (
603 + NextObject, Action, &StateList);
604 + if (ACPI_FAILURE (Status))
605 + {
606 + goto ErrorExit;
607 + }
608 + break;
609 + }
569 610 }
611 + NextObject = NULL;
570 612 break;
571 613
572 614 case ACPI_TYPE_BUFFER_FIELD:
573 615
574 616 NextObject = Object->BufferField.BufferObj;
575 617 break;
576 618
577 619 case ACPI_TYPE_LOCAL_REGION_FIELD:
578 620
579 621 NextObject = Object->Field.RegionObj;
580 622 break;
581 623
582 624 case ACPI_TYPE_LOCAL_BANK_FIELD:
583 625
584 626 NextObject = Object->BankField.BankObj;
585 627 Status = AcpiUtCreateUpdateStateAndPush (
586 628 Object->BankField.RegionObj, Action, &StateList);
587 629 if (ACPI_FAILURE (Status))
588 630 {
589 631 goto ErrorExit;
590 632 }
591 633 break;
592 634
593 635 case ACPI_TYPE_LOCAL_INDEX_FIELD:
594 636
595 637 NextObject = Object->IndexField.IndexObj;
596 638 Status = AcpiUtCreateUpdateStateAndPush (
597 639 Object->IndexField.DataObj, Action, &StateList);
598 640 if (ACPI_FAILURE (Status))
599 641 {
600 642 goto ErrorExit;
601 643 }
602 644 break;
603 645
604 646 case ACPI_TYPE_LOCAL_REFERENCE:
605 647 /*
606 648 * The target of an Index (a package, string, or buffer) or a named
607 649 * reference must track changes to the ref count of the index or
608 650 * target object.
↓ open down ↓ |
29 lines elided |
↑ open up ↑ |
609 651 */
610 652 if ((Object->Reference.Class == ACPI_REFCLASS_INDEX) ||
611 653 (Object->Reference.Class== ACPI_REFCLASS_NAME))
612 654 {
613 655 NextObject = Object->Reference.Object;
614 656 }
615 657 break;
616 658
617 659 case ACPI_TYPE_REGION:
618 660 default:
661 +
619 662 break; /* No subobjects for all other types */
620 663 }
621 664
622 665 /*
623 666 * Now we can update the count in the main object. This can only
624 667 * happen after we update the sub-objects in case this causes the
625 668 * main object to be deleted.
626 669 */
627 670 AcpiUtUpdateRefCount (Object, Action);
628 671 Object = NULL;
629 672
630 673 /* Move on to the next object to be updated */
631 674
632 675 if (NextObject)
633 676 {
634 677 Object = NextObject;
↓ open down ↓ |
6 lines elided |
↑ open up ↑ |
635 678 NextObject = NULL;
636 679 }
637 680 else if (StateList)
638 681 {
639 682 State = AcpiUtPopGenericState (&StateList);
640 683 Object = State->Update.Object;
641 684 AcpiUtDeleteGenericState (State);
642 685 }
643 686 }
644 687
645 - return_ACPI_STATUS (AE_OK);
688 + return (AE_OK);
646 689
647 690
648 691 ErrorExit:
649 692
650 693 ACPI_EXCEPTION ((AE_INFO, Status,
651 694 "Could not update object reference count"));
652 695
653 696 /* Free any stacked Update State objects */
654 697
655 698 while (StateList)
656 699 {
657 700 State = AcpiUtPopGenericState (&StateList);
658 701 AcpiUtDeleteGenericState (State);
659 702 }
660 703
661 - return_ACPI_STATUS (Status);
704 + return (Status);
662 705 }
663 706
664 707
665 708 /*******************************************************************************
666 709 *
667 710 * FUNCTION: AcpiUtAddReference
668 711 *
669 712 * PARAMETERS: Object - Object whose reference count is to be
670 713 * incremented
671 714 *
672 715 * RETURN: None
↓ open down ↓ |
1 lines elided |
↑ open up ↑ |
673 716 *
674 717 * DESCRIPTION: Add one reference to an ACPI object
675 718 *
676 719 ******************************************************************************/
677 720
678 721 void
679 722 AcpiUtAddReference (
680 723 ACPI_OPERAND_OBJECT *Object)
681 724 {
682 725
683 - ACPI_FUNCTION_TRACE_PTR (UtAddReference, Object);
726 + ACPI_FUNCTION_NAME (UtAddReference);
684 727
685 728
686 729 /* Ensure that we have a valid object */
687 730
688 731 if (!AcpiUtValidInternalObject (Object))
689 732 {
690 - return_VOID;
733 + return;
691 734 }
692 735
693 736 ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS,
694 737 "Obj %p Current Refs=%X [To Be Incremented]\n",
695 738 Object, Object->Common.ReferenceCount));
696 739
697 740 /* Increment the reference count */
698 741
699 742 (void) AcpiUtUpdateObjectReference (Object, REF_INCREMENT);
700 - return_VOID;
743 + return;
701 744 }
702 745
703 746
704 747 /*******************************************************************************
705 748 *
706 749 * FUNCTION: AcpiUtRemoveReference
707 750 *
708 751 * PARAMETERS: Object - Object whose ref count will be decremented
709 752 *
710 753 * RETURN: None
711 754 *
712 755 * DESCRIPTION: Decrement the reference count of an ACPI internal object
713 756 *
714 757 ******************************************************************************/
715 758
716 759 void
717 760 AcpiUtRemoveReference (
718 761 ACPI_OPERAND_OBJECT *Object)
719 762 {
720 763
721 - ACPI_FUNCTION_TRACE_PTR (UtRemoveReference, Object);
764 + ACPI_FUNCTION_NAME (UtRemoveReference);
722 765
723 766
724 767 /*
725 768 * Allow a NULL pointer to be passed in, just ignore it. This saves
726 769 * each caller from having to check. Also, ignore NS nodes.
727 - *
728 770 */
729 771 if (!Object ||
730 772 (ACPI_GET_DESCRIPTOR_TYPE (Object) == ACPI_DESC_TYPE_NAMED))
731 773
732 774 {
733 - return_VOID;
775 + return;
734 776 }
735 777
736 778 /* Ensure that we have a valid object */
737 779
738 780 if (!AcpiUtValidInternalObject (Object))
739 781 {
740 - return_VOID;
782 + return;
741 783 }
742 784
743 785 ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS,
744 786 "Obj %p Current Refs=%X [To Be Decremented]\n",
745 787 Object, Object->Common.ReferenceCount));
746 788
747 789 /*
748 790 * Decrement the reference count, and only actually delete the object
749 791 * if the reference count becomes 0. (Must also decrement the ref count
750 792 * of all subobjects!)
751 793 */
752 794 (void) AcpiUtUpdateObjectReference (Object, REF_DECREMENT);
753 - return_VOID;
795 + return;
754 796 }
755 -
756 -
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX