ia64/linux-2.6.18-xen.hg

view drivers/acpi/namespace/nsutils.c @ 897:329ea0ccb344

balloon: try harder to balloon up under memory pressure.

Currently if the balloon driver is unable to increase the guest's
reservation it assumes the failure was due to reaching its full
allocation, gives up on the ballooning operation and records the limit
it reached as the "hard limit". The driver will not try again until
the target is set again (even to the same value).

However it is possible that ballooning has in fact failed due to
memory pressure in the host and therefore it is desirable to keep
attempting to reach the target in case memory becomes available. The
most likely scenario is that some guests are ballooning down while
others are ballooning up and therefore there is temporary memory
pressure while things stabilise. You would not expect a well behaved
toolstack to ask a domain to balloon to more than its allocation nor
would you expect it to deliberately over-commit memory by setting
balloon targets which exceed the total host memory.

This patch drops the concept of a hard limit and causes the balloon
driver to retry increasing the reservation on a timer in the same
manner as when decreasing the reservation.

Also if we partially succeed in increasing the reservation
(i.e. receive less pages than we asked for) then we may as well keep
those pages rather than returning them to Xen.

Signed-off-by: Ian Campbell <ian.campbell@citrix.com>
author Keir Fraser <keir.fraser@citrix.com>
date Fri Jun 05 14:01:20 2009 +0100 (2009-06-05)
parents 831230e53067
children
line source
1 /******************************************************************************
2 *
3 * Module Name: nsutils - Utilities for accessing ACPI namespace, accessing
4 * parents and siblings and Scope manipulation
5 *
6 *****************************************************************************/
8 /*
9 * Copyright (C) 2000 - 2006, R. Byron Moore
10 * All rights reserved.
11 *
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions
14 * are met:
15 * 1. Redistributions of source code must retain the above copyright
16 * notice, this list of conditions, and the following disclaimer,
17 * without modification.
18 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
19 * substantially similar to the "NO WARRANTY" disclaimer below
20 * ("Disclaimer") and any redistribution must be conditioned upon
21 * including a substantially similar Disclaimer requirement for further
22 * binary redistribution.
23 * 3. Neither the names of the above-listed copyright holders nor the names
24 * of any contributors may be used to endorse or promote products derived
25 * from this software without specific prior written permission.
26 *
27 * Alternatively, this software may be distributed under the terms of the
28 * GNU General Public License ("GPL") version 2 as published by the Free
29 * Software Foundation.
30 *
31 * NO WARRANTY
32 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
33 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
34 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
35 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
36 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
37 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
38 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
39 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
40 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
41 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
42 * POSSIBILITY OF SUCH DAMAGES.
43 */
45 #include <acpi/acpi.h>
46 #include <acpi/acnamesp.h>
47 #include <acpi/amlcode.h>
48 #include <acpi/actables.h>
50 #define _COMPONENT ACPI_NAMESPACE
51 ACPI_MODULE_NAME("nsutils")
53 /* Local prototypes */
54 static u8 acpi_ns_valid_path_separator(char sep);
56 #ifdef ACPI_OBSOLETE_FUNCTIONS
57 acpi_name acpi_ns_find_parent_name(struct acpi_namespace_node *node_to_search);
58 #endif
60 /*******************************************************************************
61 *
62 * FUNCTION: acpi_ns_report_error
63 *
64 * PARAMETERS: module_name - Caller's module name (for error output)
65 * line_number - Caller's line number (for error output)
66 * internal_name - Name or path of the namespace node
67 * lookup_status - Exception code from NS lookup
68 *
69 * RETURN: None
70 *
71 * DESCRIPTION: Print warning message with full pathname
72 *
73 ******************************************************************************/
75 void
76 acpi_ns_report_error(char *module_name,
77 u32 line_number,
78 char *internal_name, acpi_status lookup_status)
79 {
80 acpi_status status;
81 u32 bad_name;
82 char *name = NULL;
84 acpi_os_printf("ACPI Error (%s-%04d): ", module_name, line_number);
86 if (lookup_status == AE_BAD_CHARACTER) {
88 /* There is a non-ascii character in the name */
90 ACPI_MOVE_32_TO_32(&bad_name, internal_name);
91 acpi_os_printf("[0x%4.4X] (NON-ASCII)", bad_name);
92 } else {
93 /* Convert path to external format */
95 status = acpi_ns_externalize_name(ACPI_UINT32_MAX,
96 internal_name, NULL, &name);
98 /* Print target name */
100 if (ACPI_SUCCESS(status)) {
101 acpi_os_printf("[%s]", name);
102 } else {
103 acpi_os_printf("[COULD NOT EXTERNALIZE NAME]");
104 }
106 if (name) {
107 ACPI_FREE(name);
108 }
109 }
111 acpi_os_printf(" Namespace lookup failure, %s\n",
112 acpi_format_exception(lookup_status));
113 }
115 /*******************************************************************************
116 *
117 * FUNCTION: acpi_ns_report_method_error
118 *
119 * PARAMETERS: module_name - Caller's module name (for error output)
120 * line_number - Caller's line number (for error output)
121 * Message - Error message to use on failure
122 * prefix_node - Prefix relative to the path
123 * Path - Path to the node (optional)
124 * method_status - Execution status
125 *
126 * RETURN: None
127 *
128 * DESCRIPTION: Print warning message with full pathname
129 *
130 ******************************************************************************/
132 void
133 acpi_ns_report_method_error(char *module_name,
134 u32 line_number,
135 char *message,
136 struct acpi_namespace_node *prefix_node,
137 char *path, acpi_status method_status)
138 {
139 acpi_status status;
140 struct acpi_namespace_node *node = prefix_node;
142 acpi_os_printf("ACPI Error (%s-%04d): ", module_name, line_number);
144 if (path) {
145 status =
146 acpi_ns_get_node(prefix_node, path, ACPI_NS_NO_UPSEARCH,
147 &node);
148 if (ACPI_FAILURE(status)) {
149 acpi_os_printf("[Could not get node by pathname]");
150 }
151 }
153 acpi_ns_print_node_pathname(node, message);
154 acpi_os_printf(", %s\n", acpi_format_exception(method_status));
155 }
157 /*******************************************************************************
158 *
159 * FUNCTION: acpi_ns_print_node_pathname
160 *
161 * PARAMETERS: Node - Object
162 * Message - Prefix message
163 *
164 * DESCRIPTION: Print an object's full namespace pathname
165 * Manages allocation/freeing of a pathname buffer
166 *
167 ******************************************************************************/
169 void
170 acpi_ns_print_node_pathname(struct acpi_namespace_node *node, char *message)
171 {
172 struct acpi_buffer buffer;
173 acpi_status status;
175 if (!node) {
176 acpi_os_printf("[NULL NAME]");
177 return;
178 }
180 /* Convert handle to full pathname and print it (with supplied message) */
182 buffer.length = ACPI_ALLOCATE_LOCAL_BUFFER;
184 status = acpi_ns_handle_to_pathname(node, &buffer);
185 if (ACPI_SUCCESS(status)) {
186 if (message) {
187 acpi_os_printf("%s ", message);
188 }
190 acpi_os_printf("[%s] (Node %p)", (char *)buffer.pointer, node);
191 ACPI_FREE(buffer.pointer);
192 }
193 }
195 /*******************************************************************************
196 *
197 * FUNCTION: acpi_ns_valid_root_prefix
198 *
199 * PARAMETERS: Prefix - Character to be checked
200 *
201 * RETURN: TRUE if a valid prefix
202 *
203 * DESCRIPTION: Check if a character is a valid ACPI Root prefix
204 *
205 ******************************************************************************/
207 u8 acpi_ns_valid_root_prefix(char prefix)
208 {
210 return ((u8) (prefix == '\\'));
211 }
213 /*******************************************************************************
214 *
215 * FUNCTION: acpi_ns_valid_path_separator
216 *
217 * PARAMETERS: Sep - Character to be checked
218 *
219 * RETURN: TRUE if a valid path separator
220 *
221 * DESCRIPTION: Check if a character is a valid ACPI path separator
222 *
223 ******************************************************************************/
225 static u8 acpi_ns_valid_path_separator(char sep)
226 {
228 return ((u8) (sep == '.'));
229 }
231 /*******************************************************************************
232 *
233 * FUNCTION: acpi_ns_get_type
234 *
235 * PARAMETERS: Node - Parent Node to be examined
236 *
237 * RETURN: Type field from Node whose handle is passed
238 *
239 * DESCRIPTION: Return the type of a Namespace node
240 *
241 ******************************************************************************/
243 acpi_object_type acpi_ns_get_type(struct acpi_namespace_node * node)
244 {
245 ACPI_FUNCTION_TRACE(ns_get_type);
247 if (!node) {
248 ACPI_WARNING((AE_INFO, "Null Node parameter"));
249 return_UINT32(ACPI_TYPE_ANY);
250 }
252 return_UINT32((acpi_object_type) node->type);
253 }
255 /*******************************************************************************
256 *
257 * FUNCTION: acpi_ns_local
258 *
259 * PARAMETERS: Type - A namespace object type
260 *
261 * RETURN: LOCAL if names must be found locally in objects of the
262 * passed type, 0 if enclosing scopes should be searched
263 *
264 * DESCRIPTION: Returns scope rule for the given object type.
265 *
266 ******************************************************************************/
268 u32 acpi_ns_local(acpi_object_type type)
269 {
270 ACPI_FUNCTION_TRACE(ns_local);
272 if (!acpi_ut_valid_object_type(type)) {
274 /* Type code out of range */
276 ACPI_WARNING((AE_INFO, "Invalid Object Type %X", type));
277 return_UINT32(ACPI_NS_NORMAL);
278 }
280 return_UINT32((u32) acpi_gbl_ns_properties[type] & ACPI_NS_LOCAL);
281 }
283 /*******************************************************************************
284 *
285 * FUNCTION: acpi_ns_get_internal_name_length
286 *
287 * PARAMETERS: Info - Info struct initialized with the
288 * external name pointer.
289 *
290 * RETURN: None
291 *
292 * DESCRIPTION: Calculate the length of the internal (AML) namestring
293 * corresponding to the external (ASL) namestring.
294 *
295 ******************************************************************************/
297 void acpi_ns_get_internal_name_length(struct acpi_namestring_info *info)
298 {
299 char *next_external_char;
300 u32 i;
302 ACPI_FUNCTION_ENTRY();
304 next_external_char = info->external_name;
305 info->num_carats = 0;
306 info->num_segments = 0;
307 info->fully_qualified = FALSE;
309 /*
310 * For the internal name, the required length is 4 bytes per segment, plus
311 * 1 each for root_prefix, multi_name_prefix_op, segment count, trailing null
312 * (which is not really needed, but no there's harm in putting it there)
313 *
314 * strlen() + 1 covers the first name_seg, which has no path separator
315 */
316 if (acpi_ns_valid_root_prefix(next_external_char[0])) {
317 info->fully_qualified = TRUE;
318 next_external_char++;
319 } else {
320 /*
321 * Handle Carat prefixes
322 */
323 while (*next_external_char == '^') {
324 info->num_carats++;
325 next_external_char++;
326 }
327 }
329 /*
330 * Determine the number of ACPI name "segments" by counting the number of
331 * path separators within the string. Start with one segment since the
332 * segment count is [(# separators) + 1], and zero separators is ok.
333 */
334 if (*next_external_char) {
335 info->num_segments = 1;
336 for (i = 0; next_external_char[i]; i++) {
337 if (acpi_ns_valid_path_separator(next_external_char[i])) {
338 info->num_segments++;
339 }
340 }
341 }
343 info->length = (ACPI_NAME_SIZE * info->num_segments) +
344 4 + info->num_carats;
346 info->next_external_char = next_external_char;
347 }
349 /*******************************************************************************
350 *
351 * FUNCTION: acpi_ns_build_internal_name
352 *
353 * PARAMETERS: Info - Info struct fully initialized
354 *
355 * RETURN: Status
356 *
357 * DESCRIPTION: Construct the internal (AML) namestring
358 * corresponding to the external (ASL) namestring.
359 *
360 ******************************************************************************/
362 acpi_status acpi_ns_build_internal_name(struct acpi_namestring_info *info)
363 {
364 u32 num_segments = info->num_segments;
365 char *internal_name = info->internal_name;
366 char *external_name = info->next_external_char;
367 char *result = NULL;
368 acpi_native_uint i;
370 ACPI_FUNCTION_TRACE(ns_build_internal_name);
372 /* Setup the correct prefixes, counts, and pointers */
374 if (info->fully_qualified) {
375 internal_name[0] = '\\';
377 if (num_segments <= 1) {
378 result = &internal_name[1];
379 } else if (num_segments == 2) {
380 internal_name[1] = AML_DUAL_NAME_PREFIX;
381 result = &internal_name[2];
382 } else {
383 internal_name[1] = AML_MULTI_NAME_PREFIX_OP;
384 internal_name[2] = (char)num_segments;
385 result = &internal_name[3];
386 }
387 } else {
388 /*
389 * Not fully qualified.
390 * Handle Carats first, then append the name segments
391 */
392 i = 0;
393 if (info->num_carats) {
394 for (i = 0; i < info->num_carats; i++) {
395 internal_name[i] = '^';
396 }
397 }
399 if (num_segments <= 1) {
400 result = &internal_name[i];
401 } else if (num_segments == 2) {
402 internal_name[i] = AML_DUAL_NAME_PREFIX;
403 result = &internal_name[(acpi_native_uint) (i + 1)];
404 } else {
405 internal_name[i] = AML_MULTI_NAME_PREFIX_OP;
406 internal_name[(acpi_native_uint) (i + 1)] =
407 (char)num_segments;
408 result = &internal_name[(acpi_native_uint) (i + 2)];
409 }
410 }
412 /* Build the name (minus path separators) */
414 for (; num_segments; num_segments--) {
415 for (i = 0; i < ACPI_NAME_SIZE; i++) {
416 if (acpi_ns_valid_path_separator(*external_name) ||
417 (*external_name == 0)) {
419 /* Pad the segment with underscore(s) if segment is short */
421 result[i] = '_';
422 } else {
423 /* Convert the character to uppercase and save it */
425 result[i] =
426 (char)ACPI_TOUPPER((int)*external_name);
427 external_name++;
428 }
429 }
431 /* Now we must have a path separator, or the pathname is bad */
433 if (!acpi_ns_valid_path_separator(*external_name) &&
434 (*external_name != 0)) {
435 return_ACPI_STATUS(AE_BAD_PARAMETER);
436 }
438 /* Move on the next segment */
440 external_name++;
441 result += ACPI_NAME_SIZE;
442 }
444 /* Terminate the string */
446 *result = 0;
448 if (info->fully_qualified) {
449 ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
450 "Returning [%p] (abs) \"\\%s\"\n",
451 internal_name, internal_name));
452 } else {
453 ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Returning [%p] (rel) \"%s\"\n",
454 internal_name, internal_name));
455 }
457 return_ACPI_STATUS(AE_OK);
458 }
460 /*******************************************************************************
461 *
462 * FUNCTION: acpi_ns_internalize_name
463 *
464 * PARAMETERS: *external_name - External representation of name
465 * **Converted Name - Where to return the resulting
466 * internal represention of the name
467 *
468 * RETURN: Status
469 *
470 * DESCRIPTION: Convert an external representation (e.g. "\_PR_.CPU0")
471 * to internal form (e.g. 5c 2f 02 5f 50 52 5f 43 50 55 30)
472 *
473 *******************************************************************************/
475 acpi_status acpi_ns_internalize_name(char *external_name, char **converted_name)
476 {
477 char *internal_name;
478 struct acpi_namestring_info info;
479 acpi_status status;
481 ACPI_FUNCTION_TRACE(ns_internalize_name);
483 if ((!external_name) || (*external_name == 0) || (!converted_name)) {
484 return_ACPI_STATUS(AE_BAD_PARAMETER);
485 }
487 /* Get the length of the new internal name */
489 info.external_name = external_name;
490 acpi_ns_get_internal_name_length(&info);
492 /* We need a segment to store the internal name */
494 internal_name = ACPI_ALLOCATE_ZEROED(info.length);
495 if (!internal_name) {
496 return_ACPI_STATUS(AE_NO_MEMORY);
497 }
499 /* Build the name */
501 info.internal_name = internal_name;
502 status = acpi_ns_build_internal_name(&info);
503 if (ACPI_FAILURE(status)) {
504 ACPI_FREE(internal_name);
505 return_ACPI_STATUS(status);
506 }
508 *converted_name = internal_name;
509 return_ACPI_STATUS(AE_OK);
510 }
512 /*******************************************************************************
513 *
514 * FUNCTION: acpi_ns_externalize_name
515 *
516 * PARAMETERS: internal_name_length - Lenth of the internal name below
517 * internal_name - Internal representation of name
518 * converted_name_length - Where the length is returned
519 * converted_name - Where the resulting external name
520 * is returned
521 *
522 * RETURN: Status
523 *
524 * DESCRIPTION: Convert internal name (e.g. 5c 2f 02 5f 50 52 5f 43 50 55 30)
525 * to its external (printable) form (e.g. "\_PR_.CPU0")
526 *
527 ******************************************************************************/
529 acpi_status
530 acpi_ns_externalize_name(u32 internal_name_length,
531 char *internal_name,
532 u32 * converted_name_length, char **converted_name)
533 {
534 acpi_native_uint names_index = 0;
535 acpi_native_uint num_segments = 0;
536 acpi_native_uint required_length;
537 acpi_native_uint prefix_length = 0;
538 acpi_native_uint i = 0;
539 acpi_native_uint j = 0;
541 ACPI_FUNCTION_TRACE(ns_externalize_name);
543 if (!internal_name_length || !internal_name || !converted_name) {
544 return_ACPI_STATUS(AE_BAD_PARAMETER);
545 }
547 /*
548 * Check for a prefix (one '\' | one or more '^').
549 */
550 switch (internal_name[0]) {
551 case '\\':
552 prefix_length = 1;
553 break;
555 case '^':
556 for (i = 0; i < internal_name_length; i++) {
557 if (internal_name[i] == '^') {
558 prefix_length = i + 1;
559 } else {
560 break;
561 }
562 }
564 if (i == internal_name_length) {
565 prefix_length = i;
566 }
568 break;
570 default:
571 break;
572 }
574 /*
575 * Check for object names. Note that there could be 0-255 of these
576 * 4-byte elements.
577 */
578 if (prefix_length < internal_name_length) {
579 switch (internal_name[prefix_length]) {
580 case AML_MULTI_NAME_PREFIX_OP:
582 /* <count> 4-byte names */
584 names_index = prefix_length + 2;
585 num_segments = (acpi_native_uint) (u8)
586 internal_name[(acpi_native_uint)
587 (prefix_length + 1)];
588 break;
590 case AML_DUAL_NAME_PREFIX:
592 /* Two 4-byte names */
594 names_index = prefix_length + 1;
595 num_segments = 2;
596 break;
598 case 0:
600 /* null_name */
602 names_index = 0;
603 num_segments = 0;
604 break;
606 default:
608 /* one 4-byte name */
610 names_index = prefix_length;
611 num_segments = 1;
612 break;
613 }
614 }
616 /*
617 * Calculate the length of converted_name, which equals the length
618 * of the prefix, length of all object names, length of any required
619 * punctuation ('.') between object names, plus the NULL terminator.
620 */
621 required_length = prefix_length + (4 * num_segments) +
622 ((num_segments > 0) ? (num_segments - 1) : 0) + 1;
624 /*
625 * Check to see if we're still in bounds. If not, there's a problem
626 * with internal_name (invalid format).
627 */
628 if (required_length > internal_name_length) {
629 ACPI_ERROR((AE_INFO, "Invalid internal name"));
630 return_ACPI_STATUS(AE_BAD_PATHNAME);
631 }
633 /*
634 * Build converted_name
635 */
636 *converted_name = ACPI_ALLOCATE_ZEROED(required_length);
637 if (!(*converted_name)) {
638 return_ACPI_STATUS(AE_NO_MEMORY);
639 }
641 j = 0;
643 for (i = 0; i < prefix_length; i++) {
644 (*converted_name)[j++] = internal_name[i];
645 }
647 if (num_segments > 0) {
648 for (i = 0; i < num_segments; i++) {
649 if (i > 0) {
650 (*converted_name)[j++] = '.';
651 }
653 (*converted_name)[j++] = internal_name[names_index++];
654 (*converted_name)[j++] = internal_name[names_index++];
655 (*converted_name)[j++] = internal_name[names_index++];
656 (*converted_name)[j++] = internal_name[names_index++];
657 }
658 }
660 if (converted_name_length) {
661 *converted_name_length = (u32) required_length;
662 }
664 return_ACPI_STATUS(AE_OK);
665 }
667 /*******************************************************************************
668 *
669 * FUNCTION: acpi_ns_map_handle_to_node
670 *
671 * PARAMETERS: Handle - Handle to be converted to an Node
672 *
673 * RETURN: A Name table entry pointer
674 *
675 * DESCRIPTION: Convert a namespace handle to a real Node
676 *
677 * Note: Real integer handles would allow for more verification
678 * and keep all pointers within this subsystem - however this introduces
679 * more (and perhaps unnecessary) overhead.
680 *
681 ******************************************************************************/
683 struct acpi_namespace_node *acpi_ns_map_handle_to_node(acpi_handle handle)
684 {
686 ACPI_FUNCTION_ENTRY();
688 /*
689 * Simple implementation
690 */
691 if ((!handle) || (handle == ACPI_ROOT_OBJECT)) {
692 return (acpi_gbl_root_node);
693 }
695 /* We can at least attempt to verify the handle */
697 if (ACPI_GET_DESCRIPTOR_TYPE(handle) != ACPI_DESC_TYPE_NAMED) {
698 return (NULL);
699 }
701 return (ACPI_CAST_PTR(struct acpi_namespace_node, handle));
702 }
704 /*******************************************************************************
705 *
706 * FUNCTION: acpi_ns_convert_entry_to_handle
707 *
708 * PARAMETERS: Node - Node to be converted to a Handle
709 *
710 * RETURN: A user handle
711 *
712 * DESCRIPTION: Convert a real Node to a namespace handle
713 *
714 ******************************************************************************/
716 acpi_handle acpi_ns_convert_entry_to_handle(struct acpi_namespace_node *node)
717 {
719 /*
720 * Simple implementation for now;
721 */
722 return ((acpi_handle) node);
724 /* Example future implementation ---------------------
726 if (!Node)
727 {
728 return (NULL);
729 }
731 if (Node == acpi_gbl_root_node)
732 {
733 return (ACPI_ROOT_OBJECT);
734 }
736 return ((acpi_handle) Node);
737 ------------------------------------------------------*/
738 }
740 /*******************************************************************************
741 *
742 * FUNCTION: acpi_ns_terminate
743 *
744 * PARAMETERS: none
745 *
746 * RETURN: none
747 *
748 * DESCRIPTION: free memory allocated for namespace and ACPI table storage.
749 *
750 ******************************************************************************/
752 void acpi_ns_terminate(void)
753 {
754 union acpi_operand_object *obj_desc;
756 ACPI_FUNCTION_TRACE(ns_terminate);
758 /*
759 * 1) Free the entire namespace -- all nodes and objects
760 *
761 * Delete all object descriptors attached to namepsace nodes
762 */
763 acpi_ns_delete_namespace_subtree(acpi_gbl_root_node);
765 /* Detach any objects attached to the root */
767 obj_desc = acpi_ns_get_attached_object(acpi_gbl_root_node);
768 if (obj_desc) {
769 acpi_ns_detach_object(acpi_gbl_root_node);
770 }
772 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Namespace freed\n"));
774 /*
775 * 2) Now we can delete the ACPI tables
776 */
777 acpi_tb_delete_all_tables();
778 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "ACPI Tables freed\n"));
780 return_VOID;
781 }
783 /*******************************************************************************
784 *
785 * FUNCTION: acpi_ns_opens_scope
786 *
787 * PARAMETERS: Type - A valid namespace type
788 *
789 * RETURN: NEWSCOPE if the passed type "opens a name scope" according
790 * to the ACPI specification, else 0
791 *
792 ******************************************************************************/
794 u32 acpi_ns_opens_scope(acpi_object_type type)
795 {
796 ACPI_FUNCTION_TRACE_STR(ns_opens_scope, acpi_ut_get_type_name(type));
798 if (!acpi_ut_valid_object_type(type)) {
800 /* type code out of range */
802 ACPI_WARNING((AE_INFO, "Invalid Object Type %X", type));
803 return_UINT32(ACPI_NS_NORMAL);
804 }
806 return_UINT32(((u32) acpi_gbl_ns_properties[type]) & ACPI_NS_NEWSCOPE);
807 }
809 /*******************************************************************************
810 *
811 * FUNCTION: acpi_ns_get_node
812 *
813 * PARAMETERS: *Pathname - Name to be found, in external (ASL) format. The
814 * \ (backslash) and ^ (carat) prefixes, and the
815 * . (period) to separate segments are supported.
816 * prefix_node - Root of subtree to be searched, or NS_ALL for the
817 * root of the name space. If Name is fully
818 * qualified (first s8 is '\'), the passed value
819 * of Scope will not be accessed.
820 * Flags - Used to indicate whether to perform upsearch or
821 * not.
822 * return_node - Where the Node is returned
823 *
824 * DESCRIPTION: Look up a name relative to a given scope and return the
825 * corresponding Node. NOTE: Scope can be null.
826 *
827 * MUTEX: Locks namespace
828 *
829 ******************************************************************************/
831 acpi_status
832 acpi_ns_get_node(struct acpi_namespace_node *prefix_node,
833 char *pathname,
834 u32 flags, struct acpi_namespace_node **return_node)
835 {
836 union acpi_generic_state scope_info;
837 acpi_status status;
838 char *internal_path;
840 ACPI_FUNCTION_TRACE_PTR(ns_get_node, pathname);
842 if (!pathname) {
843 *return_node = prefix_node;
844 if (!prefix_node) {
845 *return_node = acpi_gbl_root_node;
846 }
847 return_ACPI_STATUS(AE_OK);
848 }
850 /* Convert path to internal representation */
852 status = acpi_ns_internalize_name(pathname, &internal_path);
853 if (ACPI_FAILURE(status)) {
854 return_ACPI_STATUS(status);
855 }
857 /* Must lock namespace during lookup */
859 status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
860 if (ACPI_FAILURE(status)) {
861 goto cleanup;
862 }
864 /* Setup lookup scope (search starting point) */
866 scope_info.scope.node = prefix_node;
868 /* Lookup the name in the namespace */
870 status = acpi_ns_lookup(&scope_info, internal_path, ACPI_TYPE_ANY,
871 ACPI_IMODE_EXECUTE,
872 (flags | ACPI_NS_DONT_OPEN_SCOPE), NULL,
873 return_node);
874 if (ACPI_FAILURE(status)) {
875 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "%s, %s\n",
876 pathname, acpi_format_exception(status)));
877 }
879 (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
881 cleanup:
882 ACPI_FREE(internal_path);
883 return_ACPI_STATUS(status);
884 }
886 /*******************************************************************************
887 *
888 * FUNCTION: acpi_ns_get_parent_node
889 *
890 * PARAMETERS: Node - Current table entry
891 *
892 * RETURN: Parent entry of the given entry
893 *
894 * DESCRIPTION: Obtain the parent entry for a given entry in the namespace.
895 *
896 ******************************************************************************/
898 struct acpi_namespace_node *acpi_ns_get_parent_node(struct acpi_namespace_node
899 *node)
900 {
901 ACPI_FUNCTION_ENTRY();
903 if (!node) {
904 return (NULL);
905 }
907 /*
908 * Walk to the end of this peer list. The last entry is marked with a flag
909 * and the peer pointer is really a pointer back to the parent. This saves
910 * putting a parent back pointer in each and every named object!
911 */
912 while (!(node->flags & ANOBJ_END_OF_PEER_LIST)) {
913 node = node->peer;
914 }
916 return (node->peer);
917 }
919 /*******************************************************************************
920 *
921 * FUNCTION: acpi_ns_get_next_valid_node
922 *
923 * PARAMETERS: Node - Current table entry
924 *
925 * RETURN: Next valid Node in the linked node list. NULL if no more valid
926 * nodes.
927 *
928 * DESCRIPTION: Find the next valid node within a name table.
929 * Useful for implementing NULL-end-of-list loops.
930 *
931 ******************************************************************************/
933 struct acpi_namespace_node *acpi_ns_get_next_valid_node(struct
934 acpi_namespace_node
935 *node)
936 {
938 /* If we are at the end of this peer list, return NULL */
940 if (node->flags & ANOBJ_END_OF_PEER_LIST) {
941 return NULL;
942 }
944 /* Otherwise just return the next peer */
946 return (node->peer);
947 }
949 #ifdef ACPI_OBSOLETE_FUNCTIONS
950 /*******************************************************************************
951 *
952 * FUNCTION: acpi_ns_find_parent_name
953 *
954 * PARAMETERS: *child_node - Named Obj whose name is to be found
955 *
956 * RETURN: The ACPI name
957 *
958 * DESCRIPTION: Search for the given obj in its parent scope and return the
959 * name segment, or "????" if the parent name can't be found
960 * (which "should not happen").
961 *
962 ******************************************************************************/
964 acpi_name acpi_ns_find_parent_name(struct acpi_namespace_node * child_node)
965 {
966 struct acpi_namespace_node *parent_node;
968 ACPI_FUNCTION_TRACE(ns_find_parent_name);
970 if (child_node) {
972 /* Valid entry. Get the parent Node */
974 parent_node = acpi_ns_get_parent_node(child_node);
975 if (parent_node) {
976 ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
977 "Parent of %p [%4.4s] is %p [%4.4s]\n",
978 child_node,
979 acpi_ut_get_node_name(child_node),
980 parent_node,
981 acpi_ut_get_node_name(parent_node)));
983 if (parent_node->name.integer) {
984 return_VALUE((acpi_name) parent_node->name.
985 integer);
986 }
987 }
989 ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
990 "Unable to find parent of %p (%4.4s)\n",
991 child_node,
992 acpi_ut_get_node_name(child_node)));
993 }
995 return_VALUE(ACPI_UNKNOWN_NAME);
996 }
997 #endif