1 /*******************************************************************************
2  *
3  * Module Name: utdelete - object deletion and reference count utilities
4  *
5  ******************************************************************************/
6 
7 /*
8  * Copyright (C) 2000 - 2004, R. Byron Moore
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 
45 #include <acpi/acpi.h>
46 #include <acpi/acinterp.h>
47 #include <acpi/acnamesp.h>
48 #include <acpi/acevents.h>
49 
50 #define _COMPONENT          ACPI_UTILITIES
51 	 ACPI_MODULE_NAME    ("utdelete")
52 
53 
54 /*******************************************************************************
55  *
56  * FUNCTION:    acpi_ut_delete_internal_obj
57  *
58  * PARAMETERS:  *Object        - Pointer to the list to be deleted
59  *
60  * RETURN:      None
61  *
62  * DESCRIPTION: Low level object deletion, after reference counts have been
63  *              updated (All reference counts, including sub-objects!)
64  *
65  ******************************************************************************/
66 
67 void
acpi_ut_delete_internal_obj(union acpi_operand_object * object)68 acpi_ut_delete_internal_obj (
69 	union acpi_operand_object       *object)
70 {
71 	void                            *obj_pointer = NULL;
72 	union acpi_operand_object       *handler_desc;
73 	union acpi_operand_object       *second_desc;
74 	union acpi_operand_object       *next_desc;
75 
76 
77 	ACPI_FUNCTION_TRACE_PTR ("ut_delete_internal_obj", object);
78 
79 
80 	if (!object) {
81 		return_VOID;
82 	}
83 
84 	/*
85 	 * Must delete or free any pointers within the object that are not
86 	 * actual ACPI objects (for example, a raw buffer pointer).
87 	 */
88 	switch (ACPI_GET_OBJECT_TYPE (object)) {
89 	case ACPI_TYPE_STRING:
90 
91 		ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "**** String %p, ptr %p\n",
92 			object, object->string.pointer));
93 
94 		/* Free the actual string buffer */
95 
96 		if (!(object->common.flags & AOPOBJ_STATIC_POINTER)) {
97 			/* But only if it is NOT a pointer into an ACPI table */
98 
99 			obj_pointer = object->string.pointer;
100 		}
101 		break;
102 
103 
104 	case ACPI_TYPE_BUFFER:
105 
106 		ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "**** Buffer %p, ptr %p\n",
107 			object, object->buffer.pointer));
108 
109 		/* Free the actual buffer */
110 
111 		if (!(object->common.flags & AOPOBJ_STATIC_POINTER)) {
112 			/* But only if it is NOT a pointer into an ACPI table */
113 
114 			obj_pointer = object->buffer.pointer;
115 		}
116 		break;
117 
118 
119 	case ACPI_TYPE_PACKAGE:
120 
121 		ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, " **** Package of count %X\n",
122 			object->package.count));
123 
124 		/*
125 		 * Elements of the package are not handled here, they are deleted
126 		 * separately
127 		 */
128 
129 		/* Free the (variable length) element pointer array */
130 
131 		obj_pointer = object->package.elements;
132 		break;
133 
134 
135 	case ACPI_TYPE_DEVICE:
136 
137 		if (object->device.gpe_block) {
138 			(void) acpi_ev_delete_gpe_block (object->device.gpe_block);
139 		}
140 
141 		/* Walk the handler list for this device */
142 
143 		handler_desc = object->device.handler;
144 		while (handler_desc) {
145 			next_desc = handler_desc->address_space.next;
146 			acpi_ut_remove_reference (handler_desc);
147 			handler_desc = next_desc;
148 		}
149 		break;
150 
151 
152 	case ACPI_TYPE_MUTEX:
153 
154 		ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "***** Mutex %p, Semaphore %p\n",
155 			object, object->mutex.semaphore));
156 
157 		acpi_ex_unlink_mutex (object);
158 		(void) acpi_os_delete_semaphore (object->mutex.semaphore);
159 		break;
160 
161 
162 	case ACPI_TYPE_EVENT:
163 
164 		ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "***** Event %p, Semaphore %p\n",
165 			object, object->event.semaphore));
166 
167 		(void) acpi_os_delete_semaphore (object->event.semaphore);
168 		object->event.semaphore = NULL;
169 		break;
170 
171 
172 	case ACPI_TYPE_METHOD:
173 
174 		ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "***** Method %p\n", object));
175 
176 		/* Delete the method semaphore if it exists */
177 
178 		if (object->method.semaphore) {
179 			(void) acpi_os_delete_semaphore (object->method.semaphore);
180 			object->method.semaphore = NULL;
181 		}
182 		break;
183 
184 
185 	case ACPI_TYPE_REGION:
186 
187 		ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "***** Region %p\n", object));
188 
189 		second_desc = acpi_ns_get_secondary_object (object);
190 		if (second_desc) {
191 			/*
192 			 * Free the region_context if and only if the handler is one of the
193 			 * default handlers -- and therefore, we created the context object
194 			 * locally, it was not created by an external caller.
195 			 */
196 			handler_desc = object->region.handler;
197 			if (handler_desc) {
198 				if (handler_desc->address_space.hflags & ACPI_ADDR_HANDLER_DEFAULT_INSTALLED) {
199 					obj_pointer = second_desc->extra.region_context;
200 				}
201 
202 				acpi_ut_remove_reference (handler_desc);
203 			}
204 
205 			/* Now we can free the Extra object */
206 
207 			acpi_ut_delete_object_desc (second_desc);
208 		}
209 		break;
210 
211 
212 	case ACPI_TYPE_BUFFER_FIELD:
213 
214 		ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "***** Buffer Field %p\n", object));
215 
216 		second_desc = acpi_ns_get_secondary_object (object);
217 		if (second_desc) {
218 			acpi_ut_delete_object_desc (second_desc);
219 		}
220 		break;
221 
222 
223 	default:
224 		break;
225 	}
226 
227 	/* Free any allocated memory (pointer within the object) found above */
228 
229 	if (obj_pointer) {
230 		ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "Deleting Object Subptr %p\n",
231 				obj_pointer));
232 		ACPI_MEM_FREE (obj_pointer);
233 	}
234 
235 	/* Now the object can be safely deleted */
236 
237 	ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "Deleting Object %p [%s]\n",
238 			object, acpi_ut_get_object_type_name (object)));
239 
240 	acpi_ut_delete_object_desc (object);
241 	return_VOID;
242 }
243 
244 
245 /*******************************************************************************
246  *
247  * FUNCTION:    acpi_ut_delete_internal_object_list
248  *
249  * PARAMETERS:  *obj_list       - Pointer to the list to be deleted
250  *
251  * RETURN:      None
252  *
253  * DESCRIPTION: This function deletes an internal object list, including both
254  *              simple objects and package objects
255  *
256  ******************************************************************************/
257 
258 void
acpi_ut_delete_internal_object_list(union acpi_operand_object ** obj_list)259 acpi_ut_delete_internal_object_list (
260 	union acpi_operand_object       **obj_list)
261 {
262 	union acpi_operand_object       **internal_obj;
263 
264 
265 	ACPI_FUNCTION_TRACE ("ut_delete_internal_object_list");
266 
267 
268 	/* Walk the null-terminated internal list */
269 
270 	for (internal_obj = obj_list; *internal_obj; internal_obj++) {
271 		acpi_ut_remove_reference (*internal_obj);
272 	}
273 
274 	/* Free the combined parameter pointer list and object array */
275 
276 	ACPI_MEM_FREE (obj_list);
277 	return_VOID;
278 }
279 
280 
281 /*******************************************************************************
282  *
283  * FUNCTION:    acpi_ut_update_ref_count
284  *
285  * PARAMETERS:  *Object         - Object whose ref count is to be updated
286  *              Action          - What to do
287  *
288  * RETURN:      New ref count
289  *
290  * DESCRIPTION: Modify the ref count and return it.
291  *
292  ******************************************************************************/
293 
294 static void
acpi_ut_update_ref_count(union acpi_operand_object * object,u32 action)295 acpi_ut_update_ref_count (
296 	union acpi_operand_object       *object,
297 	u32                             action)
298 {
299 	u16                             count;
300 	u16                             new_count;
301 
302 
303 	ACPI_FUNCTION_NAME ("ut_update_ref_count");
304 
305 
306 	if (!object) {
307 		return;
308 	}
309 
310 	count = object->common.reference_count;
311 	new_count = count;
312 
313 	/*
314 	 * Perform the reference count action (increment, decrement, or force delete)
315 	 */
316 	switch (action) {
317 
318 	case REF_INCREMENT:
319 
320 		new_count++;
321 		object->common.reference_count = new_count;
322 
323 		ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "Obj %p Refs=%X, [Incremented]\n",
324 			object, new_count));
325 		break;
326 
327 
328 	case REF_DECREMENT:
329 
330 		if (count < 1) {
331 			ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "Obj %p Refs=%X, can't decrement! (Set to 0)\n",
332 				object, new_count));
333 
334 			new_count = 0;
335 		}
336 		else {
337 			new_count--;
338 
339 			ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "Obj %p Refs=%X, [Decremented]\n",
340 				object, new_count));
341 		}
342 
343 		if (ACPI_GET_OBJECT_TYPE (object) == ACPI_TYPE_METHOD) {
344 			ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "Method Obj %p Refs=%X, [Decremented]\n",
345 				object, new_count));
346 		}
347 
348 		object->common.reference_count = new_count;
349 		if (new_count == 0) {
350 			acpi_ut_delete_internal_obj (object);
351 		}
352 
353 		break;
354 
355 
356 	case REF_FORCE_DELETE:
357 
358 		ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "Obj %p Refs=%X, Force delete! (Set to 0)\n",
359 			object, count));
360 
361 		new_count = 0;
362 		object->common.reference_count = new_count;
363 		acpi_ut_delete_internal_obj (object);
364 		break;
365 
366 
367 	default:
368 
369 		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unknown action (%X)\n", action));
370 		break;
371 	}
372 
373 	/*
374 	 * Sanity check the reference count, for debug purposes only.
375 	 * (A deleted object will have a huge reference count)
376 	 */
377 	if (count > ACPI_MAX_REFERENCE_COUNT) {
378 
379 		ACPI_DEBUG_PRINT ((ACPI_DB_WARN,
380 			"**** Warning **** Large Reference Count (%X) in object %p\n\n",
381 			count, object));
382 	}
383 
384 	return;
385 }
386 
387 
388 /*******************************************************************************
389  *
390  * FUNCTION:    acpi_ut_update_object_reference
391  *
392  * PARAMETERS:  *Object             - Increment ref count for this object
393  *                                    and all sub-objects
394  *              Action              - Either REF_INCREMENT or REF_DECREMENT or
395  *                                    REF_FORCE_DELETE
396  *
397  * RETURN:      Status
398  *
399  * DESCRIPTION: Increment the object reference count
400  *
401  * Object references are incremented when:
402  * 1) An object is attached to a Node (namespace object)
403  * 2) An object is copied (all subobjects must be incremented)
404  *
405  * Object references are decremented when:
406  * 1) An object is detached from an Node
407  *
408  ******************************************************************************/
409 
410 acpi_status
acpi_ut_update_object_reference(union acpi_operand_object * object,u16 action)411 acpi_ut_update_object_reference (
412 	union acpi_operand_object       *object,
413 	u16                             action)
414 {
415 	acpi_status                     status;
416 	u32                             i;
417 	union acpi_generic_state         *state_list = NULL;
418 	union acpi_generic_state         *state;
419 	union acpi_operand_object        *tmp;
420 
421 	ACPI_FUNCTION_TRACE_PTR ("ut_update_object_reference", object);
422 
423 
424 	/* Ignore a null object ptr */
425 
426 	if (!object) {
427 		return_ACPI_STATUS (AE_OK);
428 	}
429 
430 	/* Make sure that this isn't a namespace handle */
431 
432 	if (ACPI_GET_DESCRIPTOR_TYPE (object) == ACPI_DESC_TYPE_NAMED) {
433 		ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "Object %p is NS handle\n", object));
434 		return_ACPI_STATUS (AE_OK);
435 	}
436 
437 	state = acpi_ut_create_update_state (object, action);
438 
439 	while (state) {
440 		object = state->update.object;
441 		action = state->update.value;
442 		acpi_ut_delete_generic_state (state);
443 
444 		/*
445 		 * All sub-objects must have their reference count incremented also.
446 		 * Different object types have different subobjects.
447 		 */
448 		switch (ACPI_GET_OBJECT_TYPE (object)) {
449 		case ACPI_TYPE_DEVICE:
450 
451 			tmp = object->device.system_notify;
452 			if (tmp && (tmp->common.reference_count <= 1) && action == REF_DECREMENT)
453 				object->device.system_notify = NULL;
454 			acpi_ut_update_ref_count (tmp, action);
455 
456 			tmp = object->device.device_notify;
457 			if (tmp && (tmp->common.reference_count <= 1) && action == REF_DECREMENT)
458 				object->device.device_notify = NULL;
459 			acpi_ut_update_ref_count (tmp, action);
460 
461 			break;
462 
463 
464 		case ACPI_TYPE_PACKAGE:
465 
466 			/*
467 			 * We must update all the sub-objects of the package
468 			 * (Each of whom may have their own sub-objects, etc.
469 			 */
470 			for (i = 0; i < object->package.count; i++) {
471 				/*
472 				 * Push each element onto the stack for later processing.
473 				 * Note: There can be null elements within the package,
474 				 * these are simply ignored
475 				 */
476 				status = acpi_ut_create_update_state_and_push (
477 						 object->package.elements[i], action, &state_list);
478 				if (ACPI_FAILURE (status)) {
479 					goto error_exit;
480 				}
481 
482 				tmp = object->package.elements[i];
483 				if (tmp && (tmp->common.reference_count <= 1)  && action == REF_DECREMENT)
484 					object->package.elements[i] = NULL;
485 			}
486 			break;
487 
488 
489 		case ACPI_TYPE_BUFFER_FIELD:
490 
491 			status = acpi_ut_create_update_state_and_push (
492 					 object->buffer_field.buffer_obj, action, &state_list);
493 			if (ACPI_FAILURE (status)) {
494 				goto error_exit;
495 			}
496 
497 			tmp = object->buffer_field.buffer_obj;
498 			if ( tmp && (tmp->common.reference_count <= 1)  && action == REF_DECREMENT)
499 				object->buffer_field.buffer_obj = NULL;
500 			break;
501 
502 
503 		case ACPI_TYPE_LOCAL_REGION_FIELD:
504 
505 			status = acpi_ut_create_update_state_and_push (
506 					 object->field.region_obj, action, &state_list);
507 			if (ACPI_FAILURE (status)) {
508 				goto error_exit;
509 			}
510 
511 			tmp = object->field.region_obj;
512 			if ( tmp && (tmp->common.reference_count <= 1)  && action == REF_DECREMENT)
513 				object->field.region_obj = NULL;
514 		   break;
515 
516 
517 		case ACPI_TYPE_LOCAL_BANK_FIELD:
518 
519 			status = acpi_ut_create_update_state_and_push (
520 					 object->bank_field.bank_obj, action, &state_list);
521 			if (ACPI_FAILURE (status)) {
522 				goto error_exit;
523 			}
524 
525 			tmp = object->bank_field.bank_obj;
526 			if ( tmp && (tmp->common.reference_count <= 1)  && action == REF_DECREMENT)
527 				object->bank_field.bank_obj = NULL;
528 
529 			status = acpi_ut_create_update_state_and_push (
530 					 object->bank_field.region_obj, action, &state_list);
531 			if (ACPI_FAILURE (status)) {
532 				goto error_exit;
533 			}
534 
535 			tmp = object->bank_field.region_obj;
536 			if ( tmp && (tmp->common.reference_count <= 1)  && action == REF_DECREMENT)
537 				object->bank_field.region_obj = NULL;
538 			break;
539 
540 
541 		case ACPI_TYPE_LOCAL_INDEX_FIELD:
542 
543 			status = acpi_ut_create_update_state_and_push (
544 					 object->index_field.index_obj, action, &state_list);
545 			if (ACPI_FAILURE (status)) {
546 				goto error_exit;
547 			}
548 
549 			tmp = object->index_field.index_obj;
550 			if ( tmp && (tmp->common.reference_count <= 1)  && action == REF_DECREMENT)
551 				object->index_field.index_obj = NULL;
552 
553 			status = acpi_ut_create_update_state_and_push (
554 					 object->index_field.data_obj, action, &state_list);
555 			if (ACPI_FAILURE (status)) {
556 				goto error_exit;
557 			}
558 
559 			tmp = object->index_field.data_obj;
560 			if ( tmp && (tmp->common.reference_count <= 1)  && action == REF_DECREMENT)
561 				object->index_field.data_obj = NULL;
562 			break;
563 
564 
565 		case ACPI_TYPE_REGION:
566 		case ACPI_TYPE_LOCAL_REFERENCE:
567 		default:
568 
569 			/* No subobjects */
570 			break;
571 		}
572 
573 		/*
574 		 * Now we can update the count in the main object.  This can only
575 		 * happen after we update the sub-objects in case this causes the
576 		 * main object to be deleted.
577 		 */
578 		acpi_ut_update_ref_count (object, action);
579 
580 		/* Move on to the next object to be updated */
581 
582 		state = acpi_ut_pop_generic_state (&state_list);
583 	}
584 
585 	return_ACPI_STATUS (AE_OK);
586 
587 
588 error_exit:
589 
590 	ACPI_REPORT_ERROR (("Could not update object reference count, %s\n",
591 		acpi_format_exception (status)));
592 
593 	return_ACPI_STATUS (status);
594 }
595 
596 
597 /*******************************************************************************
598  *
599  * FUNCTION:    acpi_ut_add_reference
600  *
601  * PARAMETERS:  *Object        - Object whose reference count is to be
602  *                                  incremented
603  *
604  * RETURN:      None
605  *
606  * DESCRIPTION: Add one reference to an ACPI object
607  *
608  ******************************************************************************/
609 
610 void
acpi_ut_add_reference(union acpi_operand_object * object)611 acpi_ut_add_reference (
612 	union acpi_operand_object       *object)
613 {
614 
615 	ACPI_FUNCTION_TRACE_PTR ("ut_add_reference", object);
616 
617 
618 	/* Ensure that we have a valid object */
619 
620 	if (!acpi_ut_valid_internal_object (object)) {
621 		return_VOID;
622 	}
623 
624 	/* Increment the reference count */
625 
626 	(void) acpi_ut_update_object_reference (object, REF_INCREMENT);
627 	return_VOID;
628 }
629 
630 
631 /*******************************************************************************
632  *
633  * FUNCTION:    acpi_ut_remove_reference
634  *
635  * PARAMETERS:  *Object        - Object whose ref count will be decremented
636  *
637  * RETURN:      None
638  *
639  * DESCRIPTION: Decrement the reference count of an ACPI internal object
640  *
641  ******************************************************************************/
642 
643 void
acpi_ut_remove_reference(union acpi_operand_object * object)644 acpi_ut_remove_reference (
645 	union acpi_operand_object       *object)
646 {
647 
648 	ACPI_FUNCTION_TRACE_PTR ("ut_remove_reference", object);
649 
650 
651 	/*
652 	 * Allow a NULL pointer to be passed in, just ignore it.  This saves
653 	 * each caller from having to check.  Also, ignore NS nodes.
654 	 *
655 	 */
656 	if (!object ||
657 		(ACPI_GET_DESCRIPTOR_TYPE (object) == ACPI_DESC_TYPE_NAMED)) {
658 		return_VOID;
659 	}
660 
661 	/* Ensure that we have a valid object */
662 
663 	if (!acpi_ut_valid_internal_object (object)) {
664 		return_VOID;
665 	}
666 
667 	ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "Obj %p Refs=%X\n",
668 			object, object->common.reference_count));
669 
670 	/*
671 	 * Decrement the reference count, and only actually delete the object
672 	 * if the reference count becomes 0.  (Must also decrement the ref count
673 	 * of all subobjects!)
674 	 */
675 	(void) acpi_ut_update_object_reference (object, REF_DECREMENT);
676 	return_VOID;
677 }
678 
679 
680