PageRenderTime 76ms CodeModel.GetById 10ms app.highlight 59ms RepoModel.GetById 0ms app.codeStats 1ms

/drivers/acpi/namespace/nsutils.c

https://bitbucket.org/evzijst/gittest
C | 1069 lines | 475 code | 213 blank | 381 comment | 84 complexity | 25ba93e5d1fb29c70609e1277ba43eef MD5 | raw file
   1/******************************************************************************
   2 *
   3 * Module Name: nsutils - Utilities for accessing ACPI namespace, accessing
   4 *                        parents and siblings and Scope manipulation
   5 *
   6 *****************************************************************************/
   7
   8/*
   9 * Copyright (C) 2000 - 2005, 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 */
  44
  45
  46#include <acpi/acpi.h>
  47#include <acpi/acnamesp.h>
  48#include <acpi/amlcode.h>
  49#include <acpi/actables.h>
  50
  51#define _COMPONENT          ACPI_NAMESPACE
  52	 ACPI_MODULE_NAME    ("nsutils")
  53
  54
  55/*******************************************************************************
  56 *
  57 * FUNCTION:    acpi_ns_report_error
  58 *
  59 * PARAMETERS:  module_name         - Caller's module name (for error output)
  60 *              line_number         - Caller's line number (for error output)
  61 *              component_id        - Caller's component ID (for error output)
  62 *              Message             - Error message to use on failure
  63 *
  64 * RETURN:      None
  65 *
  66 * DESCRIPTION: Print warning message with full pathname
  67 *
  68 ******************************************************************************/
  69
  70void
  71acpi_ns_report_error (
  72	char                            *module_name,
  73	u32                             line_number,
  74	u32                             component_id,
  75	char                            *internal_name,
  76	acpi_status                     lookup_status)
  77{
  78	acpi_status                     status;
  79	char                            *name = NULL;
  80
  81
  82	acpi_os_printf ("%8s-%04d: *** Error: Looking up ",
  83		module_name, line_number);
  84
  85	if (lookup_status == AE_BAD_CHARACTER) {
  86		/* There is a non-ascii character in the name */
  87
  88		acpi_os_printf ("[0x%4.4X] (NON-ASCII)\n",
  89			*(ACPI_CAST_PTR (u32, internal_name)));
  90	}
  91	else {
  92		/* Convert path to external format */
  93
  94		status = acpi_ns_externalize_name (ACPI_UINT32_MAX,
  95				 internal_name, NULL, &name);
  96
  97		/* Print target name */
  98
  99		if (ACPI_SUCCESS (status)) {
 100			acpi_os_printf ("[%s]", name);
 101		}
 102		else {
 103			acpi_os_printf ("[COULD NOT EXTERNALIZE NAME]");
 104		}
 105
 106		if (name) {
 107			ACPI_MEM_FREE (name);
 108		}
 109	}
 110
 111	acpi_os_printf (" in namespace, %s\n",
 112		acpi_format_exception (lookup_status));
 113}
 114
 115
 116/*******************************************************************************
 117 *
 118 * FUNCTION:    acpi_ns_report_method_error
 119 *
 120 * PARAMETERS:  module_name         - Caller's module name (for error output)
 121 *              line_number         - Caller's line number (for error output)
 122 *              component_id        - Caller's component ID (for error output)
 123 *              Message             - Error message to use on failure
 124 *
 125 * RETURN:      None
 126 *
 127 * DESCRIPTION: Print warning message with full pathname
 128 *
 129 ******************************************************************************/
 130
 131void
 132acpi_ns_report_method_error (
 133	char                            *module_name,
 134	u32                             line_number,
 135	u32                             component_id,
 136	char                            *message,
 137	struct acpi_namespace_node      *prefix_node,
 138	char                            *path,
 139	acpi_status                     method_status)
 140{
 141	acpi_status                     status;
 142	struct acpi_namespace_node      *node = prefix_node;
 143
 144
 145	if (path) {
 146		status = acpi_ns_get_node_by_path (path, prefix_node,
 147				 ACPI_NS_NO_UPSEARCH, &node);
 148		if (ACPI_FAILURE (status)) {
 149			acpi_os_printf ("report_method_error: Could not get node\n");
 150			return;
 151		}
 152	}
 153
 154	acpi_os_printf ("%8s-%04d: *** Error: ", module_name, line_number);
 155	acpi_ns_print_node_pathname (node, message);
 156	acpi_os_printf (", %s\n", acpi_format_exception (method_status));
 157}
 158
 159
 160/*******************************************************************************
 161 *
 162 * FUNCTION:    acpi_ns_print_node_pathname
 163 *
 164 * PARAMETERS:  Node                - Object
 165 *              Msg                 - Prefix message
 166 *
 167 * DESCRIPTION: Print an object's full namespace pathname
 168 *              Manages allocation/freeing of a pathname buffer
 169 *
 170 ******************************************************************************/
 171
 172void
 173acpi_ns_print_node_pathname (
 174	struct acpi_namespace_node      *node,
 175	char                            *msg)
 176{
 177	struct acpi_buffer              buffer;
 178	acpi_status                     status;
 179
 180
 181	if (!node) {
 182		acpi_os_printf ("[NULL NAME]");
 183		return;
 184	}
 185
 186	/* Convert handle to full pathname and print it (with supplied message) */
 187
 188	buffer.length = ACPI_ALLOCATE_LOCAL_BUFFER;
 189
 190	status = acpi_ns_handle_to_pathname (node, &buffer);
 191	if (ACPI_SUCCESS (status)) {
 192		if (msg) {
 193			acpi_os_printf ("%s ", msg);
 194		}
 195
 196		acpi_os_printf ("[%s] (Node %p)", (char *) buffer.pointer, node);
 197		ACPI_MEM_FREE (buffer.pointer);
 198	}
 199}
 200
 201
 202/*******************************************************************************
 203 *
 204 * FUNCTION:    acpi_ns_valid_root_prefix
 205 *
 206 * PARAMETERS:  Prefix          - Character to be checked
 207 *
 208 * RETURN:      TRUE if a valid prefix
 209 *
 210 * DESCRIPTION: Check if a character is a valid ACPI Root prefix
 211 *
 212 ******************************************************************************/
 213
 214u8
 215acpi_ns_valid_root_prefix (
 216	char                            prefix)
 217{
 218
 219	return ((u8) (prefix == '\\'));
 220}
 221
 222
 223/*******************************************************************************
 224 *
 225 * FUNCTION:    acpi_ns_valid_path_separator
 226 *
 227 * PARAMETERS:  Sep              - Character to be checked
 228 *
 229 * RETURN:      TRUE if a valid path separator
 230 *
 231 * DESCRIPTION: Check if a character is a valid ACPI path separator
 232 *
 233 ******************************************************************************/
 234
 235u8
 236acpi_ns_valid_path_separator (
 237	char                            sep)
 238{
 239
 240	return ((u8) (sep == '.'));
 241}
 242
 243
 244/*******************************************************************************
 245 *
 246 * FUNCTION:    acpi_ns_get_type
 247 *
 248 * PARAMETERS:  Handle              - Parent Node to be examined
 249 *
 250 * RETURN:      Type field from Node whose handle is passed
 251 *
 252 ******************************************************************************/
 253
 254acpi_object_type
 255acpi_ns_get_type (
 256	struct acpi_namespace_node      *node)
 257{
 258	ACPI_FUNCTION_TRACE ("ns_get_type");
 259
 260
 261	if (!node) {
 262		ACPI_REPORT_WARNING (("ns_get_type: Null Node input pointer\n"));
 263		return_VALUE (ACPI_TYPE_ANY);
 264	}
 265
 266	return_VALUE ((acpi_object_type) node->type);
 267}
 268
 269
 270/*******************************************************************************
 271 *
 272 * FUNCTION:    acpi_ns_local
 273 *
 274 * PARAMETERS:  Type            - A namespace object type
 275 *
 276 * RETURN:      LOCAL if names must be found locally in objects of the
 277 *              passed type, 0 if enclosing scopes should be searched
 278 *
 279 ******************************************************************************/
 280
 281u32
 282acpi_ns_local (
 283	acpi_object_type                type)
 284{
 285	ACPI_FUNCTION_TRACE ("ns_local");
 286
 287
 288	if (!acpi_ut_valid_object_type (type)) {
 289		/* Type code out of range  */
 290
 291		ACPI_REPORT_WARNING (("ns_local: Invalid Object Type\n"));
 292		return_VALUE (ACPI_NS_NORMAL);
 293	}
 294
 295	return_VALUE ((u32) acpi_gbl_ns_properties[type] & ACPI_NS_LOCAL);
 296}
 297
 298
 299/*******************************************************************************
 300 *
 301 * FUNCTION:    acpi_ns_get_internal_name_length
 302 *
 303 * PARAMETERS:  Info            - Info struct initialized with the
 304 *                                external name pointer.
 305 *
 306 * RETURN:      Status
 307 *
 308 * DESCRIPTION: Calculate the length of the internal (AML) namestring
 309 *              corresponding to the external (ASL) namestring.
 310 *
 311 ******************************************************************************/
 312
 313void
 314acpi_ns_get_internal_name_length (
 315	struct acpi_namestring_info     *info)
 316{
 317	char                            *next_external_char;
 318	u32                             i;
 319
 320
 321	ACPI_FUNCTION_ENTRY ();
 322
 323
 324	next_external_char = info->external_name;
 325	info->num_carats = 0;
 326	info->num_segments = 0;
 327	info->fully_qualified = FALSE;
 328
 329	/*
 330	 * For the internal name, the required length is 4 bytes per segment, plus
 331	 * 1 each for root_prefix, multi_name_prefix_op, segment count, trailing null
 332	 * (which is not really needed, but no there's harm in putting it there)
 333	 *
 334	 * strlen() + 1 covers the first name_seg, which has no path separator
 335	 */
 336	if (acpi_ns_valid_root_prefix (next_external_char[0])) {
 337		info->fully_qualified = TRUE;
 338		next_external_char++;
 339	}
 340	else {
 341		/*
 342		 * Handle Carat prefixes
 343		 */
 344		while (*next_external_char == '^') {
 345			info->num_carats++;
 346			next_external_char++;
 347		}
 348	}
 349
 350	/*
 351	 * Determine the number of ACPI name "segments" by counting the number of
 352	 * path separators within the string. Start with one segment since the
 353	 * segment count is [(# separators) + 1], and zero separators is ok.
 354	 */
 355	if (*next_external_char) {
 356		info->num_segments = 1;
 357		for (i = 0; next_external_char[i]; i++) {
 358			if (acpi_ns_valid_path_separator (next_external_char[i])) {
 359				info->num_segments++;
 360			}
 361		}
 362	}
 363
 364	info->length = (ACPI_NAME_SIZE * info->num_segments) +
 365			  4 + info->num_carats;
 366
 367	info->next_external_char = next_external_char;
 368}
 369
 370
 371/*******************************************************************************
 372 *
 373 * FUNCTION:    acpi_ns_build_internal_name
 374 *
 375 * PARAMETERS:  Info            - Info struct fully initialized
 376 *
 377 * RETURN:      Status
 378 *
 379 * DESCRIPTION: Construct the internal (AML) namestring
 380 *              corresponding to the external (ASL) namestring.
 381 *
 382 ******************************************************************************/
 383
 384acpi_status
 385acpi_ns_build_internal_name (
 386	struct acpi_namestring_info     *info)
 387{
 388	u32                             num_segments = info->num_segments;
 389	char                            *internal_name = info->internal_name;
 390	char                            *external_name = info->next_external_char;
 391	char                            *result = NULL;
 392	acpi_native_uint                i;
 393
 394
 395	ACPI_FUNCTION_TRACE ("ns_build_internal_name");
 396
 397
 398	/* Setup the correct prefixes, counts, and pointers */
 399
 400	if (info->fully_qualified) {
 401		internal_name[0] = '\\';
 402
 403		if (num_segments <= 1) {
 404			result = &internal_name[1];
 405		}
 406		else if (num_segments == 2) {
 407			internal_name[1] = AML_DUAL_NAME_PREFIX;
 408			result = &internal_name[2];
 409		}
 410		else {
 411			internal_name[1] = AML_MULTI_NAME_PREFIX_OP;
 412			internal_name[2] = (char) num_segments;
 413			result = &internal_name[3];
 414		}
 415	}
 416	else {
 417		/*
 418		 * Not fully qualified.
 419		 * Handle Carats first, then append the name segments
 420		 */
 421		i = 0;
 422		if (info->num_carats) {
 423			for (i = 0; i < info->num_carats; i++) {
 424				internal_name[i] = '^';
 425			}
 426		}
 427
 428		if (num_segments <= 1) {
 429			result = &internal_name[i];
 430		}
 431		else if (num_segments == 2) {
 432			internal_name[i] = AML_DUAL_NAME_PREFIX;
 433			result = &internal_name[(acpi_native_uint) (i+1)];
 434		}
 435		else {
 436			internal_name[i] = AML_MULTI_NAME_PREFIX_OP;
 437			internal_name[(acpi_native_uint) (i+1)] = (char) num_segments;
 438			result = &internal_name[(acpi_native_uint) (i+2)];
 439		}
 440	}
 441
 442	/* Build the name (minus path separators) */
 443
 444	for (; num_segments; num_segments--) {
 445		for (i = 0; i < ACPI_NAME_SIZE; i++) {
 446			if (acpi_ns_valid_path_separator (*external_name) ||
 447			   (*external_name == 0)) {
 448				/* Pad the segment with underscore(s) if segment is short */
 449
 450				result[i] = '_';
 451			}
 452			else {
 453				/* Convert the character to uppercase and save it */
 454
 455				result[i] = (char) ACPI_TOUPPER ((int) *external_name);
 456				external_name++;
 457			}
 458		}
 459
 460		/* Now we must have a path separator, or the pathname is bad */
 461
 462		if (!acpi_ns_valid_path_separator (*external_name) &&
 463			(*external_name != 0)) {
 464			return_ACPI_STATUS (AE_BAD_PARAMETER);
 465		}
 466
 467		/* Move on the next segment */
 468
 469		external_name++;
 470		result += ACPI_NAME_SIZE;
 471	}
 472
 473	/* Terminate the string */
 474
 475	*result = 0;
 476
 477	if (info->fully_qualified) {
 478		ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Returning [%p] (abs) \"\\%s\"\n",
 479			internal_name, internal_name));
 480	}
 481	else {
 482		ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Returning [%p] (rel) \"%s\"\n",
 483			internal_name, internal_name));
 484	}
 485
 486	return_ACPI_STATUS (AE_OK);
 487}
 488
 489
 490/*******************************************************************************
 491 *
 492 * FUNCTION:    acpi_ns_internalize_name
 493 *
 494 * PARAMETERS:  *external_name          - External representation of name
 495 *              **Converted Name        - Where to return the resulting
 496 *                                        internal represention of the name
 497 *
 498 * RETURN:      Status
 499 *
 500 * DESCRIPTION: Convert an external representation (e.g. "\_PR_.CPU0")
 501 *              to internal form (e.g. 5c 2f 02 5f 50 52 5f 43 50 55 30)
 502 *
 503 *******************************************************************************/
 504
 505acpi_status
 506acpi_ns_internalize_name (
 507	char                            *external_name,
 508	char                            **converted_name)
 509{
 510	char                            *internal_name;
 511	struct acpi_namestring_info     info;
 512	acpi_status                     status;
 513
 514
 515	ACPI_FUNCTION_TRACE ("ns_internalize_name");
 516
 517
 518	if ((!external_name)     ||
 519		(*external_name == 0) ||
 520		(!converted_name)) {
 521		return_ACPI_STATUS (AE_BAD_PARAMETER);
 522	}
 523
 524	/* Get the length of the new internal name */
 525
 526	info.external_name = external_name;
 527	acpi_ns_get_internal_name_length (&info);
 528
 529	/* We need a segment to store the internal  name */
 530
 531	internal_name = ACPI_MEM_CALLOCATE (info.length);
 532	if (!internal_name) {
 533		return_ACPI_STATUS (AE_NO_MEMORY);
 534	}
 535
 536	/* Build the name */
 537
 538	info.internal_name = internal_name;
 539	status = acpi_ns_build_internal_name (&info);
 540	if (ACPI_FAILURE (status)) {
 541		ACPI_MEM_FREE (internal_name);
 542		return_ACPI_STATUS (status);
 543	}
 544
 545	*converted_name = internal_name;
 546	return_ACPI_STATUS (AE_OK);
 547}
 548
 549
 550/*******************************************************************************
 551 *
 552 * FUNCTION:    acpi_ns_externalize_name
 553 *
 554 * PARAMETERS:  *internal_name         - Internal representation of name
 555 *              **converted_name       - Where to return the resulting
 556 *                                       external representation of name
 557 *
 558 * RETURN:      Status
 559 *
 560 * DESCRIPTION: Convert internal name (e.g. 5c 2f 02 5f 50 52 5f 43 50 55 30)
 561 *              to its external form (e.g. "\_PR_.CPU0")
 562 *
 563 ******************************************************************************/
 564
 565acpi_status
 566acpi_ns_externalize_name (
 567	u32                             internal_name_length,
 568	char                            *internal_name,
 569	u32                             *converted_name_length,
 570	char                            **converted_name)
 571{
 572	acpi_native_uint                names_index = 0;
 573	acpi_native_uint                num_segments = 0;
 574	acpi_native_uint                required_length;
 575	acpi_native_uint                prefix_length = 0;
 576	acpi_native_uint                i = 0;
 577	acpi_native_uint                j = 0;
 578
 579
 580	ACPI_FUNCTION_TRACE ("ns_externalize_name");
 581
 582
 583	if (!internal_name_length   ||
 584		!internal_name          ||
 585		!converted_name) {
 586		return_ACPI_STATUS (AE_BAD_PARAMETER);
 587	}
 588
 589	/*
 590	 * Check for a prefix (one '\' | one or more '^').
 591	 */
 592	switch (internal_name[0]) {
 593	case '\\':
 594		prefix_length = 1;
 595		break;
 596
 597	case '^':
 598		for (i = 0; i < internal_name_length; i++) {
 599			if (internal_name[i] == '^') {
 600				prefix_length = i + 1;
 601			}
 602			else {
 603				break;
 604			}
 605		}
 606
 607		if (i == internal_name_length) {
 608			prefix_length = i;
 609		}
 610
 611		break;
 612
 613	default:
 614		break;
 615	}
 616
 617	/*
 618	 * Check for object names.  Note that there could be 0-255 of these
 619	 * 4-byte elements.
 620	 */
 621	if (prefix_length < internal_name_length) {
 622		switch (internal_name[prefix_length]) {
 623		case AML_MULTI_NAME_PREFIX_OP:
 624
 625			/* <count> 4-byte names */
 626
 627			names_index = prefix_length + 2;
 628			num_segments = (acpi_native_uint) (u8)
 629					   internal_name[(acpi_native_uint) (prefix_length + 1)];
 630			break;
 631
 632		case AML_DUAL_NAME_PREFIX:
 633
 634			/* Two 4-byte names */
 635
 636			names_index = prefix_length + 1;
 637			num_segments = 2;
 638			break;
 639
 640		case 0:
 641
 642			/* null_name */
 643
 644			names_index = 0;
 645			num_segments = 0;
 646			break;
 647
 648		default:
 649
 650			/* one 4-byte name */
 651
 652			names_index = prefix_length;
 653			num_segments = 1;
 654			break;
 655		}
 656	}
 657
 658	/*
 659	 * Calculate the length of converted_name, which equals the length
 660	 * of the prefix, length of all object names, length of any required
 661	 * punctuation ('.') between object names, plus the NULL terminator.
 662	 */
 663	required_length = prefix_length + (4 * num_segments) +
 664			   ((num_segments > 0) ? (num_segments - 1) : 0) + 1;
 665
 666	/*
 667	 * Check to see if we're still in bounds.  If not, there's a problem
 668	 * with internal_name (invalid format).
 669	 */
 670	if (required_length > internal_name_length) {
 671		ACPI_REPORT_ERROR (("ns_externalize_name: Invalid internal name\n"));
 672		return_ACPI_STATUS (AE_BAD_PATHNAME);
 673	}
 674
 675	/*
 676	 * Build converted_name
 677	 */
 678	*converted_name = ACPI_MEM_CALLOCATE (required_length);
 679	if (!(*converted_name)) {
 680		return_ACPI_STATUS (AE_NO_MEMORY);
 681	}
 682
 683	j = 0;
 684
 685	for (i = 0; i < prefix_length; i++) {
 686		(*converted_name)[j++] = internal_name[i];
 687	}
 688
 689	if (num_segments > 0) {
 690		for (i = 0; i < num_segments; i++) {
 691			if (i > 0) {
 692				(*converted_name)[j++] = '.';
 693			}
 694
 695			(*converted_name)[j++] = internal_name[names_index++];
 696			(*converted_name)[j++] = internal_name[names_index++];
 697			(*converted_name)[j++] = internal_name[names_index++];
 698			(*converted_name)[j++] = internal_name[names_index++];
 699		}
 700	}
 701
 702	if (converted_name_length) {
 703		*converted_name_length = (u32) required_length;
 704	}
 705
 706	return_ACPI_STATUS (AE_OK);
 707}
 708
 709
 710/*******************************************************************************
 711 *
 712 * FUNCTION:    acpi_ns_map_handle_to_node
 713 *
 714 * PARAMETERS:  Handle          - Handle to be converted to an Node
 715 *
 716 * RETURN:      A Name table entry pointer
 717 *
 718 * DESCRIPTION: Convert a namespace handle to a real Node
 719 *
 720 * Note: Real integer handles allow for more verification
 721 *       and keep all pointers within this subsystem.
 722 *
 723 ******************************************************************************/
 724
 725struct acpi_namespace_node *
 726acpi_ns_map_handle_to_node (
 727	acpi_handle                     handle)
 728{
 729
 730	ACPI_FUNCTION_ENTRY ();
 731
 732
 733	/*
 734	 * Simple implementation.
 735	 */
 736	if (!handle) {
 737		return (NULL);
 738	}
 739
 740	if (handle == ACPI_ROOT_OBJECT) {
 741		return (acpi_gbl_root_node);
 742	}
 743
 744	/* We can at least attempt to verify the handle */
 745
 746	if (ACPI_GET_DESCRIPTOR_TYPE (handle) != ACPI_DESC_TYPE_NAMED) {
 747		return (NULL);
 748	}
 749
 750	return ((struct acpi_namespace_node *) handle);
 751}
 752
 753
 754/*******************************************************************************
 755 *
 756 * FUNCTION:    acpi_ns_convert_entry_to_handle
 757 *
 758 * PARAMETERS:  Node          - Node to be converted to a Handle
 759 *
 760 * RETURN:      A user handle
 761 *
 762 * DESCRIPTION: Convert a real Node to a namespace handle
 763 *
 764 ******************************************************************************/
 765
 766acpi_handle
 767acpi_ns_convert_entry_to_handle (
 768	struct acpi_namespace_node          *node)
 769{
 770
 771
 772	/*
 773	 * Simple implementation for now;
 774	 */
 775	return ((acpi_handle) node);
 776
 777
 778/* ---------------------------------------------------
 779
 780	if (!Node)
 781	{
 782		return (NULL);
 783	}
 784
 785	if (Node == acpi_gbl_root_node)
 786	{
 787		return (ACPI_ROOT_OBJECT);
 788	}
 789
 790
 791	return ((acpi_handle) Node);
 792------------------------------------------------------*/
 793}
 794
 795
 796/*******************************************************************************
 797 *
 798 * FUNCTION:    acpi_ns_terminate
 799 *
 800 * PARAMETERS:  none
 801 *
 802 * RETURN:      none
 803 *
 804 * DESCRIPTION: free memory allocated for table storage.
 805 *
 806 ******************************************************************************/
 807
 808void
 809acpi_ns_terminate (void)
 810{
 811	union acpi_operand_object       *obj_desc;
 812
 813
 814	ACPI_FUNCTION_TRACE ("ns_terminate");
 815
 816
 817	/*
 818	 * 1) Free the entire namespace -- all nodes and objects
 819	 *
 820	 * Delete all object descriptors attached to namepsace nodes
 821	 */
 822	acpi_ns_delete_namespace_subtree (acpi_gbl_root_node);
 823
 824	/* Detach any objects attached to the root */
 825
 826	obj_desc = acpi_ns_get_attached_object (acpi_gbl_root_node);
 827	if (obj_desc) {
 828		acpi_ns_detach_object (acpi_gbl_root_node);
 829	}
 830
 831	ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Namespace freed\n"));
 832
 833	/*
 834	 * 2) Now we can delete the ACPI tables
 835	 */
 836	acpi_tb_delete_all_tables ();
 837	ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "ACPI Tables freed\n"));
 838
 839	return_VOID;
 840}
 841
 842
 843/*******************************************************************************
 844 *
 845 * FUNCTION:    acpi_ns_opens_scope
 846 *
 847 * PARAMETERS:  Type        - A valid namespace type
 848 *
 849 * RETURN:      NEWSCOPE if the passed type "opens a name scope" according
 850 *              to the ACPI specification, else 0
 851 *
 852 ******************************************************************************/
 853
 854u32
 855acpi_ns_opens_scope (
 856	acpi_object_type                type)
 857{
 858	ACPI_FUNCTION_TRACE_STR ("ns_opens_scope", acpi_ut_get_type_name (type));
 859
 860
 861	if (!acpi_ut_valid_object_type (type)) {
 862		/* type code out of range  */
 863
 864		ACPI_REPORT_WARNING (("ns_opens_scope: Invalid Object Type %X\n", type));
 865		return_VALUE (ACPI_NS_NORMAL);
 866	}
 867
 868	return_VALUE (((u32) acpi_gbl_ns_properties[type]) & ACPI_NS_NEWSCOPE);
 869}
 870
 871
 872/*******************************************************************************
 873 *
 874 * FUNCTION:    acpi_ns_get_node_by_path
 875 *
 876 * PARAMETERS:  *Pathname   - Name to be found, in external (ASL) format. The
 877 *                            \ (backslash) and ^ (carat) prefixes, and the
 878 *                            . (period) to separate segments are supported.
 879 *              start_node  - Root of subtree to be searched, or NS_ALL for the
 880 *                            root of the name space.  If Name is fully
 881 *                            qualified (first s8 is '\'), the passed value
 882 *                            of Scope will not be accessed.
 883 *              Flags       - Used to indicate whether to perform upsearch or
 884 *                            not.
 885 *              return_node - Where the Node is returned
 886 *
 887 * DESCRIPTION: Look up a name relative to a given scope and return the
 888 *              corresponding Node.  NOTE: Scope can be null.
 889 *
 890 * MUTEX:       Locks namespace
 891 *
 892 ******************************************************************************/
 893
 894acpi_status
 895acpi_ns_get_node_by_path (
 896	char                            *pathname,
 897	struct acpi_namespace_node      *start_node,
 898	u32                             flags,
 899	struct acpi_namespace_node      **return_node)
 900{
 901	union acpi_generic_state        scope_info;
 902	acpi_status                     status;
 903	char                            *internal_path = NULL;
 904
 905
 906	ACPI_FUNCTION_TRACE_PTR ("ns_get_node_by_path", pathname);
 907
 908
 909	if (pathname) {
 910		/* Convert path to internal representation */
 911
 912		status = acpi_ns_internalize_name (pathname, &internal_path);
 913		if (ACPI_FAILURE (status)) {
 914			return_ACPI_STATUS (status);
 915		}
 916	}
 917
 918	/* Must lock namespace during lookup */
 919
 920	status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE);
 921	if (ACPI_FAILURE (status)) {
 922		goto cleanup;
 923	}
 924
 925	/* Setup lookup scope (search starting point) */
 926
 927	scope_info.scope.node = start_node;
 928
 929	/* Lookup the name in the namespace */
 930
 931	status = acpi_ns_lookup (&scope_info, internal_path,
 932			 ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE,
 933			 (flags | ACPI_NS_DONT_OPEN_SCOPE),
 934			 NULL, return_node);
 935	if (ACPI_FAILURE (status)) {
 936		ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "%s, %s\n",
 937				internal_path, acpi_format_exception (status)));
 938	}
 939
 940	(void) acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
 941
 942cleanup:
 943	/* Cleanup */
 944	if (internal_path) {
 945		ACPI_MEM_FREE (internal_path);
 946	}
 947	return_ACPI_STATUS (status);
 948}
 949
 950
 951/*******************************************************************************
 952 *
 953 * FUNCTION:    acpi_ns_find_parent_name
 954 *
 955 * PARAMETERS:  *child_node            - Named Obj whose name is to be found
 956 *
 957 * RETURN:      The ACPI name
 958 *
 959 * DESCRIPTION: Search for the given obj in its parent scope and return the
 960 *              name segment, or "????" if the parent name can't be found
 961 *              (which "should not happen").
 962 *
 963 ******************************************************************************/
 964#ifdef ACPI_FUTURE_USAGE
 965acpi_name
 966acpi_ns_find_parent_name (
 967	struct acpi_namespace_node      *child_node)
 968{
 969	struct acpi_namespace_node      *parent_node;
 970
 971
 972	ACPI_FUNCTION_TRACE ("ns_find_parent_name");
 973
 974
 975	if (child_node) {
 976		/* Valid entry.  Get the parent Node */
 977
 978		parent_node = acpi_ns_get_parent_node (child_node);
 979		if (parent_node) {
 980			ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
 981				"Parent of %p [%4.4s] is %p [%4.4s]\n",
 982				child_node, acpi_ut_get_node_name (child_node),
 983				parent_node, acpi_ut_get_node_name (parent_node)));
 984
 985			if (parent_node->name.integer) {
 986				return_VALUE ((acpi_name) parent_node->name.integer);
 987			}
 988		}
 989
 990		ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
 991			"Unable to find parent of %p (%4.4s)\n",
 992			child_node, acpi_ut_get_node_name (child_node)));
 993	}
 994
 995	return_VALUE (ACPI_UNKNOWN_NAME);
 996}
 997#endif
 998
 999
1000/*******************************************************************************
1001 *
1002 * FUNCTION:    acpi_ns_get_parent_node
1003 *
1004 * PARAMETERS:  Node       - Current table entry
1005 *
1006 * RETURN:      Parent entry of the given entry
1007 *
1008 * DESCRIPTION: Obtain the parent entry for a given entry in the namespace.
1009 *
1010 ******************************************************************************/
1011
1012
1013struct acpi_namespace_node *
1014acpi_ns_get_parent_node (
1015	struct acpi_namespace_node      *node)
1016{
1017	ACPI_FUNCTION_ENTRY ();
1018
1019
1020	if (!node) {
1021		return (NULL);
1022	}
1023
1024	/*
1025	 * Walk to the end of this peer list. The last entry is marked with a flag
1026	 * and the peer pointer is really a pointer back to the parent. This saves
1027	 * putting a parent back pointer in each and every named object!
1028	 */
1029	while (!(node->flags & ANOBJ_END_OF_PEER_LIST)) {
1030		node = node->peer;
1031	}
1032
1033
1034	return (node->peer);
1035}
1036
1037
1038/*******************************************************************************
1039 *
1040 * FUNCTION:    acpi_ns_get_next_valid_node
1041 *
1042 * PARAMETERS:  Node       - Current table entry
1043 *
1044 * RETURN:      Next valid Node in the linked node list. NULL if no more valid
1045 *              nodes.
1046 *
1047 * DESCRIPTION: Find the next valid node within a name table.
1048 *              Useful for implementing NULL-end-of-list loops.
1049 *
1050 ******************************************************************************/
1051
1052
1053struct acpi_namespace_node *
1054acpi_ns_get_next_valid_node (
1055	struct acpi_namespace_node      *node)
1056{
1057
1058	/* If we are at the end of this peer list, return NULL */
1059
1060	if (node->flags & ANOBJ_END_OF_PEER_LIST) {
1061		return NULL;
1062	}
1063
1064	/* Otherwise just return the next peer */
1065
1066	return (node->peer);
1067}
1068
1069