utdelete.c 19.6 KB
Newer Older
L
Linus Torvalds 已提交
1 2 3 4 5 6 7
/*******************************************************************************
 *
 * Module Name: utdelete - object deletion and reference count utilities
 *
 ******************************************************************************/

/*
8
 * Copyright (C) 2000 - 2013, Intel Corp.
L
Linus Torvalds 已提交
9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions, and the following disclaimer,
 *    without modification.
 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
 *    substantially similar to the "NO WARRANTY" disclaimer below
 *    ("Disclaimer") and any redistribution must be conditioned upon
 *    including a substantially similar Disclaimer requirement for further
 *    binary redistribution.
 * 3. Neither the names of the above-listed copyright holders nor the names
 *    of any contributors may be used to endorse or promote products derived
 *    from this software without specific prior written permission.
 *
 * Alternatively, this software may be distributed under the terms of the
 * GNU General Public License ("GPL") version 2 as published by the Free
 * Software Foundation.
 *
 * NO WARRANTY
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGES.
 */

#include <acpi/acpi.h>
L
Len Brown 已提交
45 46 47 48
#include "accommon.h"
#include "acinterp.h"
#include "acnamesp.h"
#include "acevents.h"
L
Linus Torvalds 已提交
49 50

#define _COMPONENT          ACPI_UTILITIES
L
Len Brown 已提交
51
ACPI_MODULE_NAME("utdelete")
L
Linus Torvalds 已提交
52

R
Robert Moore 已提交
53
/* Local prototypes */
L
Len Brown 已提交
54
static void acpi_ut_delete_internal_obj(union acpi_operand_object *object);
R
Robert Moore 已提交
55 56

static void
L
Len Brown 已提交
57
acpi_ut_update_ref_count(union acpi_operand_object *object, u32 action);
L
Linus Torvalds 已提交
58 59 60 61 62

/*******************************************************************************
 *
 * FUNCTION:    acpi_ut_delete_internal_obj
 *
63
 * PARAMETERS:  object         - Object to be deleted
L
Linus Torvalds 已提交
64 65 66 67 68 69 70 71
 *
 * RETURN:      None
 *
 * DESCRIPTION: Low level object deletion, after reference counts have been
 *              updated (All reference counts, including sub-objects!)
 *
 ******************************************************************************/

L
Len Brown 已提交
72
static void acpi_ut_delete_internal_obj(union acpi_operand_object *object)
L
Linus Torvalds 已提交
73
{
L
Len Brown 已提交
74 75 76 77
	void *obj_pointer = NULL;
	union acpi_operand_object *handler_desc;
	union acpi_operand_object *second_desc;
	union acpi_operand_object *next_desc;
78
	union acpi_operand_object **last_obj_ptr;
L
Linus Torvalds 已提交
79

B
Bob Moore 已提交
80
	ACPI_FUNCTION_TRACE_PTR(ut_delete_internal_obj, object);
L
Linus Torvalds 已提交
81 82 83 84 85 86 87 88 89

	if (!object) {
		return_VOID;
	}

	/*
	 * Must delete or free any pointers within the object that are not
	 * actual ACPI objects (for example, a raw buffer pointer).
	 */
90
	switch (object->common.type) {
L
Linus Torvalds 已提交
91 92
	case ACPI_TYPE_STRING:

L
Len Brown 已提交
93 94 95
		ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS,
				  "**** String %p, ptr %p\n", object,
				  object->string.pointer));
L
Linus Torvalds 已提交
96 97 98 99

		/* Free the actual string buffer */

		if (!(object->common.flags & AOPOBJ_STATIC_POINTER)) {
B
Bob Moore 已提交
100

L
Linus Torvalds 已提交
101 102 103 104 105 106 107 108
			/* But only if it is NOT a pointer into an ACPI table */

			obj_pointer = object->string.pointer;
		}
		break;

	case ACPI_TYPE_BUFFER:

L
Len Brown 已提交
109 110 111
		ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS,
				  "**** Buffer %p, ptr %p\n", object,
				  object->buffer.pointer));
L
Linus Torvalds 已提交
112 113 114 115

		/* Free the actual buffer */

		if (!(object->common.flags & AOPOBJ_STATIC_POINTER)) {
B
Bob Moore 已提交
116

L
Linus Torvalds 已提交
117 118 119 120 121 122 123 124
			/* But only if it is NOT a pointer into an ACPI table */

			obj_pointer = object->buffer.pointer;
		}
		break;

	case ACPI_TYPE_PACKAGE:

L
Len Brown 已提交
125 126 127
		ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS,
				  " **** Package of count %X\n",
				  object->package.count));
L
Linus Torvalds 已提交
128 129 130 131 132 133 134 135 136 137 138

		/*
		 * Elements of the package are not handled here, they are deleted
		 * separately
		 */

		/* Free the (variable length) element pointer array */

		obj_pointer = object->package.elements;
		break;

139 140 141 142
		/*
		 * These objects have a possible list of notify handlers.
		 * Device object also may have a GPE block.
		 */
L
Linus Torvalds 已提交
143 144 145
	case ACPI_TYPE_DEVICE:

		if (object->device.gpe_block) {
L
Len Brown 已提交
146 147
			(void)acpi_ev_delete_gpe_block(object->device.
						       gpe_block);
L
Linus Torvalds 已提交
148 149
		}

150 151 152 153 154
		/*lint -fallthrough */

	case ACPI_TYPE_PROCESSOR:
	case ACPI_TYPE_THERMAL:

155
		/* Walk the address handler list for this object */
L
Linus Torvalds 已提交
156

157
		handler_desc = object->common_notify.handler;
L
Linus Torvalds 已提交
158 159
		while (handler_desc) {
			next_desc = handler_desc->address_space.next;
L
Len Brown 已提交
160
			acpi_ut_remove_reference(handler_desc);
L
Linus Torvalds 已提交
161 162 163 164 165 166
			handler_desc = next_desc;
		}
		break;

	case ACPI_TYPE_MUTEX:

L
Len Brown 已提交
167
		ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS,
B
Bob Moore 已提交
168 169 170
				  "***** Mutex %p, OS Mutex %p\n",
				  object, object->mutex.os_mutex));

171
		if (object == acpi_gbl_global_lock_mutex) {
172 173

			/* Global Lock has extra semaphore */
B
Bob Moore 已提交
174 175 176 177 178

			(void)
			    acpi_os_delete_semaphore
			    (acpi_gbl_global_lock_semaphore);
			acpi_gbl_global_lock_semaphore = NULL;
179 180 181 182

			acpi_os_delete_mutex(object->mutex.os_mutex);
			acpi_gbl_global_lock_mutex = NULL;
		} else {
183
			acpi_ex_unlink_mutex(object);
184
			acpi_os_delete_mutex(object->mutex.os_mutex);
B
Bob Moore 已提交
185
		}
L
Linus Torvalds 已提交
186 187 188 189
		break;

	case ACPI_TYPE_EVENT:

L
Len Brown 已提交
190
		ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS,
B
Bob Moore 已提交
191 192
				  "***** Event %p, OS Semaphore %p\n",
				  object, object->event.os_semaphore));
L
Linus Torvalds 已提交
193

B
Bob Moore 已提交
194 195
		(void)acpi_os_delete_semaphore(object->event.os_semaphore);
		object->event.os_semaphore = NULL;
L
Linus Torvalds 已提交
196 197 198 199
		break;

	case ACPI_TYPE_METHOD:

L
Len Brown 已提交
200 201
		ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS,
				  "***** Method %p\n", object));
L
Linus Torvalds 已提交
202

B
Bob Moore 已提交
203
		/* Delete the method mutex if it exists */
L
Linus Torvalds 已提交
204

B
Bob Moore 已提交
205 206 207 208 209
		if (object->method.mutex) {
			acpi_os_delete_mutex(object->method.mutex->mutex.
					     os_mutex);
			acpi_ut_delete_object_desc(object->method.mutex);
			object->method.mutex = NULL;
L
Linus Torvalds 已提交
210 211 212 213 214
		}
		break;

	case ACPI_TYPE_REGION:

L
Len Brown 已提交
215 216
		ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS,
				  "***** Region %p\n", object));
L
Linus Torvalds 已提交
217

218 219 220 221 222 223 224 225
		/*
		 * Update address_range list. However, only permanent regions
		 * are installed in this list. (Not created within a method)
		 */
		if (!(object->region.node->flags & ANOBJ_TEMPORARY)) {
			acpi_ut_remove_address_range(object->region.space_id,
						     object->region.node);
		}
226

L
Len Brown 已提交
227
		second_desc = acpi_ns_get_secondary_object(object);
L
Linus Torvalds 已提交
228 229 230 231 232 233 234 235
		if (second_desc) {
			/*
			 * Free the region_context if and only if the handler is one of the
			 * default handlers -- and therefore, we created the context object
			 * locally, it was not created by an external caller.
			 */
			handler_desc = object->region.handler;
			if (handler_desc) {
236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255
				next_desc =
				    handler_desc->address_space.region_list;
				last_obj_ptr =
				    &handler_desc->address_space.region_list;

				/* Remove the region object from the handler's list */

				while (next_desc) {
					if (next_desc == object) {
						*last_obj_ptr =
						    next_desc->region.next;
						break;
					}

					/* Walk the linked list of handler */

					last_obj_ptr = &next_desc->region.next;
					next_desc = next_desc->region.next;
				}

B
Bob Moore 已提交
256
				if (handler_desc->address_space.handler_flags &
L
Len Brown 已提交
257
				    ACPI_ADDR_HANDLER_DEFAULT_INSTALLED) {
B
Bob Moore 已提交
258 259 260 261 262 263 264 265 266 267 268 269 270 271

					/* Deactivate region and free region context */

					if (handler_desc->address_space.setup) {
						(void)handler_desc->
						    address_space.setup(object,
									ACPI_REGION_DEACTIVATE,
									handler_desc->
									address_space.
									context,
									&second_desc->
									extra.
									region_context);
					}
L
Linus Torvalds 已提交
272 273
				}

L
Len Brown 已提交
274
				acpi_ut_remove_reference(handler_desc);
L
Linus Torvalds 已提交
275 276 277 278
			}

			/* Now we can free the Extra object */

L
Len Brown 已提交
279
			acpi_ut_delete_object_desc(second_desc);
L
Linus Torvalds 已提交
280 281 282 283 284
		}
		break;

	case ACPI_TYPE_BUFFER_FIELD:

L
Len Brown 已提交
285 286
		ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS,
				  "***** Buffer Field %p\n", object));
L
Linus Torvalds 已提交
287

L
Len Brown 已提交
288
		second_desc = acpi_ns_get_secondary_object(object);
L
Linus Torvalds 已提交
289
		if (second_desc) {
290 291 292 293 294 295 296 297 298 299 300
			acpi_ut_delete_object_desc(second_desc);
		}
		break;

	case ACPI_TYPE_LOCAL_BANK_FIELD:

		ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS,
				  "***** Bank Field %p\n", object));

		second_desc = acpi_ns_get_secondary_object(object);
		if (second_desc) {
L
Len Brown 已提交
301
			acpi_ut_delete_object_desc(second_desc);
L
Linus Torvalds 已提交
302 303 304 305
		}
		break;

	default:
306

L
Linus Torvalds 已提交
307 308 309 310 311 312
		break;
	}

	/* Free any allocated memory (pointer within the object) found above */

	if (obj_pointer) {
L
Len Brown 已提交
313 314
		ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS,
				  "Deleting Object Subptr %p\n", obj_pointer));
B
Bob Moore 已提交
315
		ACPI_FREE(obj_pointer);
L
Linus Torvalds 已提交
316 317 318 319
	}

	/* Now the object can be safely deleted */

L
Len Brown 已提交
320 321
	ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS, "Deleting Object %p [%s]\n",
			  object, acpi_ut_get_object_type_name(object)));
L
Linus Torvalds 已提交
322

L
Len Brown 已提交
323
	acpi_ut_delete_object_desc(object);
L
Linus Torvalds 已提交
324 325 326 327 328 329 330
	return_VOID;
}

/*******************************************************************************
 *
 * FUNCTION:    acpi_ut_delete_internal_object_list
 *
R
Robert Moore 已提交
331
 * PARAMETERS:  obj_list        - Pointer to the list to be deleted
L
Linus Torvalds 已提交
332 333 334 335 336 337 338 339
 *
 * RETURN:      None
 *
 * DESCRIPTION: This function deletes an internal object list, including both
 *              simple objects and package objects
 *
 ******************************************************************************/

L
Len Brown 已提交
340
void acpi_ut_delete_internal_object_list(union acpi_operand_object **obj_list)
L
Linus Torvalds 已提交
341
{
L
Len Brown 已提交
342
	union acpi_operand_object **internal_obj;
L
Linus Torvalds 已提交
343

344
	ACPI_FUNCTION_ENTRY();
L
Linus Torvalds 已提交
345 346 347 348

	/* Walk the null-terminated internal list */

	for (internal_obj = obj_list; *internal_obj; internal_obj++) {
L
Len Brown 已提交
349
		acpi_ut_remove_reference(*internal_obj);
L
Linus Torvalds 已提交
350 351 352 353
	}

	/* Free the combined parameter pointer list and object array */

B
Bob Moore 已提交
354
	ACPI_FREE(obj_list);
355
	return;
L
Linus Torvalds 已提交
356 357 358 359 360 361
}

/*******************************************************************************
 *
 * FUNCTION:    acpi_ut_update_ref_count
 *
362
 * PARAMETERS:  object          - Object whose ref count is to be updated
363
 *              action          - What to do (REF_INCREMENT or REF_DECREMENT)
L
Linus Torvalds 已提交
364
 *
365
 * RETURN:      None. Sets new reference count within the object
L
Linus Torvalds 已提交
366
 *
367
 * DESCRIPTION: Modify the reference count for an internal acpi object
L
Linus Torvalds 已提交
368 369 370 371
 *
 ******************************************************************************/

static void
L
Len Brown 已提交
372
acpi_ut_update_ref_count(union acpi_operand_object *object, u32 action)
L
Linus Torvalds 已提交
373
{
374 375 376
	u16 original_count;
	u16 new_count = 0;
	acpi_cpu_flags lock_flags;
L
Linus Torvalds 已提交
377

B
Bob Moore 已提交
378
	ACPI_FUNCTION_NAME(ut_update_ref_count);
L
Linus Torvalds 已提交
379 380 381 382 383 384

	if (!object) {
		return;
	}

	/*
385 386
	 * Always get the reference count lock. Note: Interpreter and/or
	 * Namespace is not always locked when this function is called.
L
Linus Torvalds 已提交
387
	 */
388 389 390 391 392
	lock_flags = acpi_os_acquire_lock(acpi_gbl_reference_count_lock);
	original_count = object->common.reference_count;

	/* Perform the reference count action (increment, decrement) */

L
Linus Torvalds 已提交
393 394 395
	switch (action) {
	case REF_INCREMENT:

396
		new_count = original_count + 1;
L
Linus Torvalds 已提交
397
		object->common.reference_count = new_count;
398 399 400 401 402 403 404 405 406
		acpi_os_release_lock(acpi_gbl_reference_count_lock, lock_flags);

		/* The current reference count should never be zero here */

		if (!original_count) {
			ACPI_WARNING((AE_INFO,
				      "Obj %p, Reference Count was zero before increment\n",
				      object));
		}
L
Linus Torvalds 已提交
407

L
Len Brown 已提交
408
		ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS,
409 410
				  "Obj %p Type %.2X Refs %.2X [Incremented]\n",
				  object, object->common.type, new_count));
L
Linus Torvalds 已提交
411 412 413 414
		break;

	case REF_DECREMENT:

415
		/* The current reference count must be non-zero */
L
Linus Torvalds 已提交
416

417 418 419
		if (original_count) {
			new_count = original_count - 1;
			object->common.reference_count = new_count;
L
Linus Torvalds 已提交
420 421
		}

422 423 424 425 426 427
		acpi_os_release_lock(acpi_gbl_reference_count_lock, lock_flags);

		if (!original_count) {
			ACPI_WARNING((AE_INFO,
				      "Obj %p, Reference Count is already zero, cannot decrement\n",
				      object));
L
Linus Torvalds 已提交
428 429
		}

430 431 432 433 434 435
		ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS,
				  "Obj %p Type %.2X Refs %.2X [Decremented]\n",
				  object, object->common.type, new_count));

		/* Actually delete the object on a reference count of zero */

L
Linus Torvalds 已提交
436
		if (new_count == 0) {
L
Len Brown 已提交
437
			acpi_ut_delete_internal_obj(object);
L
Linus Torvalds 已提交
438 439 440 441 442
		}
		break;

	default:

443 444 445 446
		acpi_os_release_lock(acpi_gbl_reference_count_lock, lock_flags);
		ACPI_ERROR((AE_INFO, "Unknown Reference Count action (0x%X)",
			    action));
		return;
L
Linus Torvalds 已提交
447 448 449 450 451 452
	}

	/*
	 * Sanity check the reference count, for debug purposes only.
	 * (A deleted object will have a huge reference count)
	 */
453
	if (new_count > ACPI_MAX_REFERENCE_COUNT) {
B
Bob Moore 已提交
454
		ACPI_WARNING((AE_INFO,
455 456
			      "Large Reference Count (0x%X) in object %p, Type=0x%.2X",
			      new_count, object, object->common.type));
L
Linus Torvalds 已提交
457 458 459 460 461 462 463
	}
}

/*******************************************************************************
 *
 * FUNCTION:    acpi_ut_update_object_reference
 *
464
 * PARAMETERS:  object              - Increment ref count for this object
L
Linus Torvalds 已提交
465
 *                                    and all sub-objects
466
 *              action              - Either REF_INCREMENT or REF_DECREMENT
L
Linus Torvalds 已提交
467 468 469 470 471 472 473 474 475 476 477 478 479 480 481
 *
 * RETURN:      Status
 *
 * DESCRIPTION: Increment the object reference count
 *
 * Object references are incremented when:
 * 1) An object is attached to a Node (namespace object)
 * 2) An object is copied (all subobjects must be incremented)
 *
 * Object references are decremented when:
 * 1) An object is detached from an Node
 *
 ******************************************************************************/

acpi_status
B
Bob Moore 已提交
482
acpi_ut_update_object_reference(union acpi_operand_object *object, u16 action)
L
Linus Torvalds 已提交
483
{
L
Len Brown 已提交
484 485 486
	acpi_status status = AE_OK;
	union acpi_generic_state *state_list = NULL;
	union acpi_operand_object *next_object = NULL;
487
	union acpi_operand_object *prev_object;
L
Len Brown 已提交
488
	union acpi_generic_state *state;
489
	u32 i;
L
Linus Torvalds 已提交
490

491
	ACPI_FUNCTION_NAME(ut_update_object_reference);
L
Linus Torvalds 已提交
492

493
	while (object) {
B
Bob Moore 已提交
494

495
		/* Make sure that this isn't a namespace handle */
L
Linus Torvalds 已提交
496

L
Len Brown 已提交
497 498 499
		if (ACPI_GET_DESCRIPTOR_TYPE(object) == ACPI_DESC_TYPE_NAMED) {
			ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS,
					  "Object %p is NS handle\n", object));
500
			return (AE_OK);
501
		}
L
Linus Torvalds 已提交
502 503 504 505 506

		/*
		 * All sub-objects must have their reference count incremented also.
		 * Different object types have different subobjects.
		 */
507
		switch (object->common.type) {
L
Linus Torvalds 已提交
508
		case ACPI_TYPE_DEVICE:
B
Bob Moore 已提交
509 510 511
		case ACPI_TYPE_PROCESSOR:
		case ACPI_TYPE_POWER:
		case ACPI_TYPE_THERMAL:
512 513 514 515 516 517 518 519 520 521 522 523 524 525 526
			/*
			 * Update the notify objects for these types (if present)
			 * Two lists, system and device notify handlers.
			 */
			for (i = 0; i < ACPI_NUM_NOTIFY_TYPES; i++) {
				prev_object =
				    object->common_notify.notify_list[i];
				while (prev_object) {
					next_object =
					    prev_object->notify.next[i];
					acpi_ut_update_ref_count(prev_object,
								 action);
					prev_object = next_object;
				}
			}
L
Linus Torvalds 已提交
527 528 529 530
			break;

		case ACPI_TYPE_PACKAGE:
			/*
531 532
			 * We must update all the sub-objects of the package,
			 * each of whom may have their own sub-objects.
L
Linus Torvalds 已提交
533 534 535
			 */
			for (i = 0; i < object->package.count; i++) {
				/*
536 537
				 * Null package elements are legal and can be simply
				 * ignored.
L
Linus Torvalds 已提交
538
				 */
539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568
				next_object = object->package.elements[i];
				if (!next_object) {
					continue;
				}

				switch (next_object->common.type) {
				case ACPI_TYPE_INTEGER:
				case ACPI_TYPE_STRING:
				case ACPI_TYPE_BUFFER:
					/*
					 * For these very simple sub-objects, we can just
					 * update the reference count here and continue.
					 * Greatly increases performance of this operation.
					 */
					acpi_ut_update_ref_count(next_object,
								 action);
					break;

				default:
					/*
					 * For complex sub-objects, push them onto the stack
					 * for later processing (this eliminates recursion.)
					 */
					status =
					    acpi_ut_create_update_state_and_push
					    (next_object, action, &state_list);
					if (ACPI_FAILURE(status)) {
						goto error_exit;
					}
					break;
L
Linus Torvalds 已提交
569 570
				}
			}
571
			next_object = NULL;
L
Linus Torvalds 已提交
572 573 574 575
			break;

		case ACPI_TYPE_BUFFER_FIELD:

576
			next_object = object->buffer_field.buffer_obj;
L
Linus Torvalds 已提交
577 578 579 580
			break;

		case ACPI_TYPE_LOCAL_REGION_FIELD:

581 582
			next_object = object->field.region_obj;
			break;
L
Linus Torvalds 已提交
583 584 585

		case ACPI_TYPE_LOCAL_BANK_FIELD:

586
			next_object = object->bank_field.bank_obj;
L
Len Brown 已提交
587 588 589 590 591 592 593
			status =
			    acpi_ut_create_update_state_and_push(object->
								 bank_field.
								 region_obj,
								 action,
								 &state_list);
			if (ACPI_FAILURE(status)) {
L
Linus Torvalds 已提交
594 595 596 597 598 599
				goto error_exit;
			}
			break;

		case ACPI_TYPE_LOCAL_INDEX_FIELD:

600
			next_object = object->index_field.index_obj;
L
Len Brown 已提交
601 602 603 604 605 606 607
			status =
			    acpi_ut_create_update_state_and_push(object->
								 index_field.
								 data_obj,
								 action,
								 &state_list);
			if (ACPI_FAILURE(status)) {
L
Linus Torvalds 已提交
608 609 610 611 612 613
				goto error_exit;
			}
			break;

		case ACPI_TYPE_LOCAL_REFERENCE:
			/*
614 615 616
			 * The target of an Index (a package, string, or buffer) or a named
			 * reference must track changes to the ref count of the index or
			 * target object.
L
Linus Torvalds 已提交
617
			 */
618 619
			if ((object->reference.class == ACPI_REFCLASS_INDEX) ||
			    (object->reference.class == ACPI_REFCLASS_NAME)) {
620
				next_object = object->reference.object;
L
Linus Torvalds 已提交
621 622 623 624 625
			}
			break;

		case ACPI_TYPE_REGION:
		default:
626

B
Bob Moore 已提交
627
			break;	/* No subobjects for all other types */
L
Linus Torvalds 已提交
628 629 630
		}

		/*
B
Bob Moore 已提交
631
		 * Now we can update the count in the main object. This can only
L
Linus Torvalds 已提交
632 633 634
		 * happen after we update the sub-objects in case this causes the
		 * main object to be deleted.
		 */
L
Len Brown 已提交
635
		acpi_ut_update_ref_count(object, action);
636
		object = NULL;
L
Linus Torvalds 已提交
637 638 639

		/* Move on to the next object to be updated */

640 641 642
		if (next_object) {
			object = next_object;
			next_object = NULL;
L
Len Brown 已提交
643 644
		} else if (state_list) {
			state = acpi_ut_pop_generic_state(&state_list);
645
			object = state->update.object;
L
Len Brown 已提交
646
			acpi_ut_delete_generic_state(state);
647
		}
L
Linus Torvalds 已提交
648 649
	}

650
	return (AE_OK);
L
Linus Torvalds 已提交
651

L
Len Brown 已提交
652
      error_exit:
L
Linus Torvalds 已提交
653

B
Bob Moore 已提交
654 655
	ACPI_EXCEPTION((AE_INFO, status,
			"Could not update object reference count"));
L
Linus Torvalds 已提交
656

657 658 659 660 661 662 663
	/* Free any stacked Update State objects */

	while (state_list) {
		state = acpi_ut_pop_generic_state(&state_list);
		acpi_ut_delete_generic_state(state);
	}

664
	return (status);
L
Linus Torvalds 已提交
665 666 667 668 669 670
}

/*******************************************************************************
 *
 * FUNCTION:    acpi_ut_add_reference
 *
671
 * PARAMETERS:  object          - Object whose reference count is to be
R
Robert Moore 已提交
672
 *                                incremented
L
Linus Torvalds 已提交
673 674 675 676 677 678 679
 *
 * RETURN:      None
 *
 * DESCRIPTION: Add one reference to an ACPI object
 *
 ******************************************************************************/

L
Len Brown 已提交
680
void acpi_ut_add_reference(union acpi_operand_object *object)
L
Linus Torvalds 已提交
681 682
{

683
	ACPI_FUNCTION_NAME(ut_add_reference);
L
Linus Torvalds 已提交
684 685 686

	/* Ensure that we have a valid object */

L
Len Brown 已提交
687
	if (!acpi_ut_valid_internal_object(object)) {
688
		return;
L
Linus Torvalds 已提交
689 690
	}

L
Len Brown 已提交
691 692 693
	ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS,
			  "Obj %p Current Refs=%X [To Be Incremented]\n",
			  object, object->common.reference_count));
L
Linus Torvalds 已提交
694 695 696

	/* Increment the reference count */

L
Len Brown 已提交
697
	(void)acpi_ut_update_object_reference(object, REF_INCREMENT);
698
	return;
L
Linus Torvalds 已提交
699 700 701 702 703 704
}

/*******************************************************************************
 *
 * FUNCTION:    acpi_ut_remove_reference
 *
705
 * PARAMETERS:  object         - Object whose ref count will be decremented
L
Linus Torvalds 已提交
706 707 708 709 710 711 712
 *
 * RETURN:      None
 *
 * DESCRIPTION: Decrement the reference count of an ACPI internal object
 *
 ******************************************************************************/

L
Len Brown 已提交
713
void acpi_ut_remove_reference(union acpi_operand_object *object)
L
Linus Torvalds 已提交
714 715
{

716
	ACPI_FUNCTION_NAME(ut_remove_reference);
L
Linus Torvalds 已提交
717 718

	/*
B
Bob Moore 已提交
719 720
	 * Allow a NULL pointer to be passed in, just ignore it. This saves
	 * each caller from having to check. Also, ignore NS nodes.
L
Linus Torvalds 已提交
721 722
	 */
	if (!object ||
L
Len Brown 已提交
723
	    (ACPI_GET_DESCRIPTOR_TYPE(object) == ACPI_DESC_TYPE_NAMED)) {
724
		return;
L
Linus Torvalds 已提交
725 726 727 728
	}

	/* Ensure that we have a valid object */

L
Len Brown 已提交
729
	if (!acpi_ut_valid_internal_object(object)) {
730
		return;
L
Linus Torvalds 已提交
731 732
	}

L
Len Brown 已提交
733 734 735
	ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS,
			  "Obj %p Current Refs=%X [To Be Decremented]\n",
			  object, object->common.reference_count));
L
Linus Torvalds 已提交
736 737 738

	/*
	 * Decrement the reference count, and only actually delete the object
B
Bob Moore 已提交
739
	 * if the reference count becomes 0. (Must also decrement the ref count
L
Linus Torvalds 已提交
740 741
	 * of all subobjects!)
	 */
L
Len Brown 已提交
742
	(void)acpi_ut_update_object_reference(object, REF_DECREMENT);
743
	return;
L
Linus Torvalds 已提交
744
}