utmisc.c 27.7 KB
Newer Older
L
Linus Torvalds 已提交
1 2 3 4 5 6 7
/*******************************************************************************
 *
 * Module Name: utmisc - common utility procedures
 *
 ******************************************************************************/

/*
8
 * Copyright (C) 2000 - 2012, 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
#include "accommon.h"
#include "acnamesp.h"
L
Linus Torvalds 已提交
47 48

#define _COMPONENT          ACPI_UTILITIES
L
Len Brown 已提交
49
ACPI_MODULE_NAME("utmisc")
R
Robert Moore 已提交
50

51
#if defined ACPI_ASL_COMPILER || defined ACPI_EXEC_APP
52 53 54 55
/*******************************************************************************
 *
 * FUNCTION:    ut_convert_backslashes
 *
56
 * PARAMETERS:  pathname        - File pathname string to be converted
57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78
 *
 * RETURN:      Modifies the input Pathname
 *
 * DESCRIPTION: Convert all backslashes (0x5C) to forward slashes (0x2F) within
 *              the entire input file pathname string.
 *
 ******************************************************************************/
void ut_convert_backslashes(char *pathname)
{

	if (!pathname) {
		return;
	}

	while (*pathname) {
		if (*pathname == '\\') {
			*pathname = '/';
		}

		pathname++;
	}
}
79
#endif
80

81 82 83 84
/*******************************************************************************
 *
 * FUNCTION:    acpi_ut_is_pci_root_bridge
 *
85
 * PARAMETERS:  id              - The HID/CID in string format
86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108
 *
 * RETURN:      TRUE if the Id is a match for a PCI/PCI-Express Root Bridge
 *
 * DESCRIPTION: Determine if the input ID is a PCI Root Bridge ID.
 *
 ******************************************************************************/

u8 acpi_ut_is_pci_root_bridge(char *id)
{

	/*
	 * Check if this is a PCI root bridge.
	 * ACPI 3.0+: check for a PCI Express root also.
	 */
	if (!(ACPI_STRCMP(id,
			  PCI_ROOT_HID_STRING)) ||
	    !(ACPI_STRCMP(id, PCI_EXPRESS_ROOT_HID_STRING))) {
		return (TRUE);
	}

	return (FALSE);
}

B
Bob Moore 已提交
109 110 111 112
/*******************************************************************************
 *
 * FUNCTION:    acpi_ut_is_aml_table
 *
113
 * PARAMETERS:  table               - An ACPI table
B
Bob Moore 已提交
114 115 116 117 118 119 120 121
 *
 * RETURN:      TRUE if table contains executable AML; FALSE otherwise
 *
 * DESCRIPTION: Check ACPI Signature for a table that contains AML code.
 *              Currently, these are DSDT,SSDT,PSDT. All other table types are
 *              data tables that do not contain AML code.
 *
 ******************************************************************************/
122

B
Bob Moore 已提交
123 124 125
u8 acpi_ut_is_aml_table(struct acpi_table_header *table)
{

B
Bob Moore 已提交
126
	/* These are the only tables that contain executable AML */
B
Bob Moore 已提交
127

128 129 130
	if (ACPI_COMPARE_NAME(table->signature, ACPI_SIG_DSDT) ||
	    ACPI_COMPARE_NAME(table->signature, ACPI_SIG_PSDT) ||
	    ACPI_COMPARE_NAME(table->signature, ACPI_SIG_SSDT)) {
B
Bob Moore 已提交
131 132 133 134 135 136
		return (TRUE);
	}

	return (FALSE);
}

137 138 139 140 141 142
/*******************************************************************************
 *
 * FUNCTION:    acpi_ut_allocate_owner_id
 *
 * PARAMETERS:  owner_id        - Where the new owner ID is returned
 *
143 144 145 146 147
 * RETURN:      Status
 *
 * DESCRIPTION: Allocate a table or method owner ID. The owner ID is used to
 *              track objects created by the table or method, to be deleted
 *              when the method exits or the table is unloaded.
148 149
 *
 ******************************************************************************/
B
Bob Moore 已提交
150

L
Len Brown 已提交
151
acpi_status acpi_ut_allocate_owner_id(acpi_owner_id * owner_id)
152
{
153 154 155
	u32 i;
	u32 j;
	u32 k;
L
Len Brown 已提交
156
	acpi_status status;
157

B
Bob Moore 已提交
158
	ACPI_FUNCTION_TRACE(ut_allocate_owner_id);
159

R
Robert Moore 已提交
160 161 162
	/* Guard against multiple allocations of ID to the same location */

	if (*owner_id) {
163
		ACPI_ERROR((AE_INFO, "Owner ID [0x%2.2X] already exists",
B
Bob Moore 已提交
164
			    *owner_id));
R
Robert Moore 已提交
165 166 167
		return_ACPI_STATUS(AE_ALREADY_EXISTS);
	}

168 169
	/* Mutex for the global ID mask */

L
Len Brown 已提交
170 171 172
	status = acpi_ut_acquire_mutex(ACPI_MTX_CACHES);
	if (ACPI_FAILURE(status)) {
		return_ACPI_STATUS(status);
173 174
	}

B
Bob Moore 已提交
175 176
	/*
	 * Find a free owner ID, cycle through all possible IDs on repeated
B
Bob Moore 已提交
177 178
	 * allocations. (ACPI_NUM_OWNERID_MASKS + 1) because first index may have
	 * to be scanned twice.
B
Bob Moore 已提交
179
	 */
B
Bob Moore 已提交
180 181 182 183
	for (i = 0, j = acpi_gbl_last_owner_id_index;
	     i < (ACPI_NUM_OWNERID_MASKS + 1); i++, j++) {
		if (j >= ACPI_NUM_OWNERID_MASKS) {
			j = 0;	/* Wraparound to start of mask array */
B
Bob Moore 已提交
184 185
		}

B
Bob Moore 已提交
186 187
		for (k = acpi_gbl_next_owner_id_offset; k < 32; k++) {
			if (acpi_gbl_owner_id_mask[j] == ACPI_UINT32_MAX) {
B
Bob Moore 已提交
188

B
Bob Moore 已提交
189 190 191 192 193 194 195 196 197 198 199 200 201
				/* There are no free IDs in this mask */

				break;
			}

			if (!(acpi_gbl_owner_id_mask[j] & (1 << k))) {
				/*
				 * Found a free ID. The actual ID is the bit index plus one,
				 * making zero an invalid Owner ID. Save this as the last ID
				 * allocated and update the global ID mask.
				 */
				acpi_gbl_owner_id_mask[j] |= (1 << k);

202 203
				acpi_gbl_last_owner_id_index = (u8)j;
				acpi_gbl_next_owner_id_offset = (u8)(k + 1);
B
Bob Moore 已提交
204 205 206 207 208 209 210 211 212 213 214

				/*
				 * Construct encoded ID from the index and bit position
				 *
				 * Note: Last [j].k (bit 255) is never used and is marked
				 * permanently allocated (prevents +1 overflow)
				 */
				*owner_id =
				    (acpi_owner_id) ((k + 1) + ACPI_MUL_32(j));

				ACPI_DEBUG_PRINT((ACPI_DB_VALUES,
B
Bob Moore 已提交
215
						  "Allocated OwnerId: %2.2X\n",
B
Bob Moore 已提交
216 217 218
						  (unsigned int)*owner_id));
				goto exit;
			}
219
		}
B
Bob Moore 已提交
220 221

		acpi_gbl_next_owner_id_offset = 0;
222 223 224
	}

	/*
B
Bob Moore 已提交
225
	 * All owner_ids have been allocated. This typically should
226 227 228 229
	 * not happen since the IDs are reused after deallocation. The IDs are
	 * allocated upon table load (one per table) and method execution, and
	 * they are released when a table is unloaded or a method completes
	 * execution.
B
Bob Moore 已提交
230 231 232
	 *
	 * If this error happens, there may be very deep nesting of invoked control
	 * methods, or there may be a bug where the IDs are not released.
233 234
	 */
	status = AE_OWNER_ID_LIMIT;
B
Bob Moore 已提交
235
	ACPI_ERROR((AE_INFO,
B
Bob Moore 已提交
236
		    "Could not allocate new OwnerId (255 max), AE_OWNER_ID_LIMIT"));
237

L
Len Brown 已提交
238 239 240
      exit:
	(void)acpi_ut_release_mutex(ACPI_MTX_CACHES);
	return_ACPI_STATUS(status);
241 242 243 244 245 246
}

/*******************************************************************************
 *
 * FUNCTION:    acpi_ut_release_owner_id
 *
247
 * PARAMETERS:  owner_id_ptr        - Pointer to a previously allocated owner_ID
248
 *
249 250 251 252
 * RETURN:      None. No error is returned because we are either exiting a
 *              control method or unloading a table. Either way, we would
 *              ignore any error anyway.
 *
B
Bob Moore 已提交
253
 * DESCRIPTION: Release a table or method owner ID.  Valid IDs are 1 - 255
254 255 256
 *
 ******************************************************************************/

L
Len Brown 已提交
257
void acpi_ut_release_owner_id(acpi_owner_id * owner_id_ptr)
258
{
L
Len Brown 已提交
259 260
	acpi_owner_id owner_id = *owner_id_ptr;
	acpi_status status;
261
	u32 index;
B
Bob Moore 已提交
262
	u32 bit;
263

B
Bob Moore 已提交
264
	ACPI_FUNCTION_TRACE_U32(ut_release_owner_id, owner_id);
265

266 267 268 269
	/* Always clear the input owner_id (zero is an invalid ID) */

	*owner_id_ptr = 0;

270
	/* Zero is not a valid owner_ID */
271

B
Bob Moore 已提交
272
	if (owner_id == 0) {
273
		ACPI_ERROR((AE_INFO, "Invalid OwnerId: 0x%2.2X", owner_id));
274 275 276 277 278
		return_VOID;
	}

	/* Mutex for the global ID mask */

L
Len Brown 已提交
279 280
	status = acpi_ut_acquire_mutex(ACPI_MTX_CACHES);
	if (ACPI_FAILURE(status)) {
281
		return_VOID;
282 283
	}

R
Robert Moore 已提交
284 285 286
	/* Normalize the ID to zero */

	owner_id--;
287

B
Bob Moore 已提交
288 289 290 291 292
	/* Decode ID to index/offset pair */

	index = ACPI_DIV_32(owner_id);
	bit = 1 << ACPI_MOD_32(owner_id);

293
	/* Free the owner ID only if it is valid */
294

B
Bob Moore 已提交
295 296 297
	if (acpi_gbl_owner_id_mask[index] & bit) {
		acpi_gbl_owner_id_mask[index] ^= bit;
	} else {
B
Bob Moore 已提交
298
		ACPI_ERROR((AE_INFO,
299
			    "Release of non-allocated OwnerId: 0x%2.2X",
B
Bob Moore 已提交
300
			    owner_id + 1));
301 302
	}

L
Len Brown 已提交
303
	(void)acpi_ut_release_mutex(ACPI_MTX_CACHES);
304
	return_VOID;
305 306
}

R
Robert Moore 已提交
307 308 309 310 311 312
/*******************************************************************************
 *
 * FUNCTION:    acpi_ut_strupr (strupr)
 *
 * PARAMETERS:  src_string      - The source string to convert
 *
313
 * RETURN:      None
R
Robert Moore 已提交
314 315 316 317 318 319 320
 *
 * DESCRIPTION: Convert string to uppercase
 *
 * NOTE: This is not a POSIX function, so it appears here, not in utclib.c
 *
 ******************************************************************************/

L
Len Brown 已提交
321
void acpi_ut_strupr(char *src_string)
R
Robert Moore 已提交
322
{
L
Len Brown 已提交
323
	char *string;
R
Robert Moore 已提交
324

L
Len Brown 已提交
325
	ACPI_FUNCTION_ENTRY();
R
Robert Moore 已提交
326

327
	if (!src_string) {
328
		return;
329 330
	}

R
Robert Moore 已提交
331 332 333
	/* Walk entire string, uppercasing the letters */

	for (string = src_string; *string; string++) {
L
Len Brown 已提交
334
		*string = (char)ACPI_TOUPPER(*string);
R
Robert Moore 已提交
335 336
	}

337
	return;
R
Robert Moore 已提交
338 339
}

340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406
#ifdef ACPI_ASL_COMPILER
/*******************************************************************************
 *
 * FUNCTION:    acpi_ut_strlwr (strlwr)
 *
 * PARAMETERS:  src_string      - The source string to convert
 *
 * RETURN:      None
 *
 * DESCRIPTION: Convert string to lowercase
 *
 * NOTE: This is not a POSIX function, so it appears here, not in utclib.c
 *
 ******************************************************************************/

void acpi_ut_strlwr(char *src_string)
{
	char *string;

	ACPI_FUNCTION_ENTRY();

	if (!src_string) {
		return;
	}

	/* Walk entire string, lowercasing the letters */

	for (string = src_string; *string; string++) {
		*string = (char)ACPI_TOLOWER(*string);
	}

	return;
}

/******************************************************************************
 *
 * FUNCTION:    acpi_ut_stricmp
 *
 * PARAMETERS:  string1             - first string to compare
 *              string2             - second string to compare
 *
 * RETURN:      int that signifies string relationship. Zero means strings
 *              are equal.
 *
 * DESCRIPTION: Implementation of the non-ANSI stricmp function (compare
 *              strings with no case sensitivity)
 *
 ******************************************************************************/

int acpi_ut_stricmp(char *string1, char *string2)
{
	int c1;
	int c2;

	do {
		c1 = tolower((int)*string1);
		c2 = tolower((int)*string2);

		string1++;
		string2++;
	}
	while ((c1 == c2) && (c1));

	return (c1 - c2);
}
#endif

L
Linus Torvalds 已提交
407 408 409 410
/*******************************************************************************
 *
 * FUNCTION:    acpi_ut_print_string
 *
411
 * PARAMETERS:  string          - Null terminated ASCII string
R
Robert Moore 已提交
412
 *              max_length      - Maximum output length
L
Linus Torvalds 已提交
413 414 415 416 417 418 419 420
 *
 * RETURN:      None
 *
 * DESCRIPTION: Dump an ASCII string with support for ACPI-defined escape
 *              sequences.
 *
 ******************************************************************************/

L
Len Brown 已提交
421
void acpi_ut_print_string(char *string, u8 max_length)
L
Linus Torvalds 已提交
422
{
L
Len Brown 已提交
423
	u32 i;
L
Linus Torvalds 已提交
424 425

	if (!string) {
L
Len Brown 已提交
426
		acpi_os_printf("<\"NULL STRING PTR\">");
L
Linus Torvalds 已提交
427 428 429
		return;
	}

L
Len Brown 已提交
430
	acpi_os_printf("\"");
L
Linus Torvalds 已提交
431
	for (i = 0; string[i] && (i < max_length); i++) {
B
Bob Moore 已提交
432

L
Linus Torvalds 已提交
433 434 435 436
		/* Escape sequences */

		switch (string[i]) {
		case 0x07:
L
Len Brown 已提交
437
			acpi_os_printf("\\a");	/* BELL */
L
Linus Torvalds 已提交
438 439 440
			break;

		case 0x08:
L
Len Brown 已提交
441
			acpi_os_printf("\\b");	/* BACKSPACE */
L
Linus Torvalds 已提交
442 443 444
			break;

		case 0x0C:
L
Len Brown 已提交
445
			acpi_os_printf("\\f");	/* FORMFEED */
L
Linus Torvalds 已提交
446 447 448
			break;

		case 0x0A:
L
Len Brown 已提交
449
			acpi_os_printf("\\n");	/* LINEFEED */
L
Linus Torvalds 已提交
450 451 452
			break;

		case 0x0D:
L
Len Brown 已提交
453
			acpi_os_printf("\\r");	/* CARRIAGE RETURN */
L
Linus Torvalds 已提交
454 455 456
			break;

		case 0x09:
L
Len Brown 已提交
457
			acpi_os_printf("\\t");	/* HORIZONTAL TAB */
L
Linus Torvalds 已提交
458 459 460
			break;

		case 0x0B:
L
Len Brown 已提交
461
			acpi_os_printf("\\v");	/* VERTICAL TAB */
L
Linus Torvalds 已提交
462 463
			break;

L
Len Brown 已提交
464 465 466 467
		case '\'':	/* Single Quote */
		case '\"':	/* Double Quote */
		case '\\':	/* Backslash */
			acpi_os_printf("\\%c", (int)string[i]);
L
Linus Torvalds 已提交
468 469 470 471 472 473
			break;

		default:

			/* Check for printable character or hex escape */

L
Len Brown 已提交
474
			if (ACPI_IS_PRINT(string[i])) {
L
Linus Torvalds 已提交
475 476
				/* This is a normal character */

L
Len Brown 已提交
477 478
				acpi_os_printf("%c", (int)string[i]);
			} else {
L
Linus Torvalds 已提交
479 480
				/* All others will be Hex escapes */

L
Len Brown 已提交
481
				acpi_os_printf("\\x%2.2X", (s32) string[i]);
L
Linus Torvalds 已提交
482 483 484 485
			}
			break;
		}
	}
L
Len Brown 已提交
486
	acpi_os_printf("\"");
L
Linus Torvalds 已提交
487 488

	if (i == max_length && string[i]) {
L
Len Brown 已提交
489
		acpi_os_printf("...");
L
Linus Torvalds 已提交
490 491 492 493 494 495 496
	}
}

/*******************************************************************************
 *
 * FUNCTION:    acpi_ut_dword_byte_swap
 *
497
 * PARAMETERS:  value           - Value to be converted
L
Linus Torvalds 已提交
498
 *
R
Robert Moore 已提交
499 500
 * RETURN:      u32 integer with bytes swapped
 *
L
Linus Torvalds 已提交
501 502 503 504
 * DESCRIPTION: Convert a 32-bit value to big-endian (swap the bytes)
 *
 ******************************************************************************/

L
Len Brown 已提交
505
u32 acpi_ut_dword_byte_swap(u32 value)
L
Linus Torvalds 已提交
506 507
{
	union {
L
Len Brown 已提交
508 509
		u32 value;
		u8 bytes[4];
L
Linus Torvalds 已提交
510 511
	} out;
	union {
L
Len Brown 已提交
512 513
		u32 value;
		u8 bytes[4];
L
Linus Torvalds 已提交
514 515
	} in;

L
Len Brown 已提交
516
	ACPI_FUNCTION_ENTRY();
L
Linus Torvalds 已提交
517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542

	in.value = value;

	out.bytes[0] = in.bytes[3];
	out.bytes[1] = in.bytes[2];
	out.bytes[2] = in.bytes[1];
	out.bytes[3] = in.bytes[0];

	return (out.value);
}

/*******************************************************************************
 *
 * FUNCTION:    acpi_ut_set_integer_width
 *
 * PARAMETERS:  Revision            From DSDT header
 *
 * RETURN:      None
 *
 * DESCRIPTION: Set the global integer bit width based upon the revision
 *              of the DSDT.  For Revision 1 and 0, Integers are 32 bits.
 *              For Revision 2 and above, Integers are 64 bits.  Yes, this
 *              makes a difference.
 *
 ******************************************************************************/

L
Len Brown 已提交
543
void acpi_ut_set_integer_width(u8 revision)
L
Linus Torvalds 已提交
544 545
{

546
	if (revision < 2) {
B
Bob Moore 已提交
547 548 549

		/* 32-bit case */

L
Linus Torvalds 已提交
550 551 552
		acpi_gbl_integer_bit_width = 32;
		acpi_gbl_integer_nybble_width = 8;
		acpi_gbl_integer_byte_width = 4;
L
Len Brown 已提交
553
	} else {
B
Bob Moore 已提交
554 555
		/* 64-bit case (ACPI 2.0+) */

L
Linus Torvalds 已提交
556 557 558 559 560 561 562 563 564 565 566
		acpi_gbl_integer_bit_width = 64;
		acpi_gbl_integer_nybble_width = 16;
		acpi_gbl_integer_byte_width = 8;
	}
}

#ifdef ACPI_DEBUG_OUTPUT
/*******************************************************************************
 *
 * FUNCTION:    acpi_ut_display_init_pathname
 *
567
 * PARAMETERS:  type                - Object type of the node
R
Robert Moore 已提交
568
 *              obj_handle          - Handle whose pathname will be displayed
569
 *              path                - Additional path string to be appended.
L
Linus Torvalds 已提交
570 571 572 573 574 575 576 577 578
 *                                      (NULL if no extra path)
 *
 * RETURN:      acpi_status
 *
 * DESCRIPTION: Display full pathname of an object, DEBUG ONLY
 *
 ******************************************************************************/

void
L
Len Brown 已提交
579 580 581
acpi_ut_display_init_pathname(u8 type,
			      struct acpi_namespace_node *obj_handle,
			      char *path)
L
Linus Torvalds 已提交
582
{
L
Len Brown 已提交
583 584
	acpi_status status;
	struct acpi_buffer buffer;
L
Linus Torvalds 已提交
585

L
Len Brown 已提交
586
	ACPI_FUNCTION_ENTRY();
L
Linus Torvalds 已提交
587 588 589 590 591 592 593 594 595 596

	/* Only print the path if the appropriate debug level is enabled */

	if (!(acpi_dbg_level & ACPI_LV_INIT_NAMES)) {
		return;
	}

	/* Get the full pathname to the node */

	buffer.length = ACPI_ALLOCATE_LOCAL_BUFFER;
L
Len Brown 已提交
597 598
	status = acpi_ns_handle_to_pathname(obj_handle, &buffer);
	if (ACPI_FAILURE(status)) {
L
Linus Torvalds 已提交
599 600 601 602 603 604 605
		return;
	}

	/* Print what we're doing */

	switch (type) {
	case ACPI_TYPE_METHOD:
L
Len Brown 已提交
606
		acpi_os_printf("Executing  ");
L
Linus Torvalds 已提交
607 608 609
		break;

	default:
L
Len Brown 已提交
610
		acpi_os_printf("Initializing ");
L
Linus Torvalds 已提交
611 612 613 614 615
		break;
	}

	/* Print the object type and pathname */

L
Len Brown 已提交
616 617
	acpi_os_printf("%-12s %s",
		       acpi_ut_get_type_name(type), (char *)buffer.pointer);
L
Linus Torvalds 已提交
618 619 620 621

	/* Extra path is used to append names like _STA, _INI, etc. */

	if (path) {
L
Len Brown 已提交
622
		acpi_os_printf(".%s", path);
L
Linus Torvalds 已提交
623
	}
L
Len Brown 已提交
624
	acpi_os_printf("\n");
L
Linus Torvalds 已提交
625

B
Bob Moore 已提交
626
	ACPI_FREE(buffer.pointer);
L
Linus Torvalds 已提交
627 628 629
}
#endif

B
Bob Moore 已提交
630 631 632 633
/*******************************************************************************
 *
 * FUNCTION:    acpi_ut_valid_acpi_char
 *
634 635
 * PARAMETERS:  char            - The character to be examined
 *              position        - Byte position (0-3)
B
Bob Moore 已提交
636 637 638 639 640 641 642 643 644 645 646 647
 *
 * RETURN:      TRUE if the character is valid, FALSE otherwise
 *
 * DESCRIPTION: Check for a valid ACPI character. Must be one of:
 *              1) Upper case alpha
 *              2) numeric
 *              3) underscore
 *
 *              We allow a '!' as the last character because of the ASF! table
 *
 ******************************************************************************/

648
u8 acpi_ut_valid_acpi_char(char character, u32 position)
B
Bob Moore 已提交
649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665
{

	if (!((character >= 'A' && character <= 'Z') ||
	      (character >= '0' && character <= '9') || (character == '_'))) {

		/* Allow a '!' in the last position */

		if (character == '!' && position == 3) {
			return (TRUE);
		}

		return (FALSE);
	}

	return (TRUE);
}

L
Linus Torvalds 已提交
666 667 668 669
/*******************************************************************************
 *
 * FUNCTION:    acpi_ut_valid_acpi_name
 *
670
 * PARAMETERS:  name            - The name to be examined
L
Linus Torvalds 已提交
671
 *
R
Robert Moore 已提交
672
 * RETURN:      TRUE if the name is valid, FALSE otherwise
L
Linus Torvalds 已提交
673 674 675 676 677 678 679 680
 *
 * DESCRIPTION: Check for a valid ACPI name.  Each character must be one of:
 *              1) Upper case alpha
 *              2) numeric
 *              3) underscore
 *
 ******************************************************************************/

L
Len Brown 已提交
681
u8 acpi_ut_valid_acpi_name(u32 name)
L
Linus Torvalds 已提交
682
{
683
	u32 i;
L
Linus Torvalds 已提交
684

L
Len Brown 已提交
685
	ACPI_FUNCTION_ENTRY();
L
Linus Torvalds 已提交
686 687

	for (i = 0; i < ACPI_NAME_SIZE; i++) {
B
Bob Moore 已提交
688 689
		if (!acpi_ut_valid_acpi_char
		    ((ACPI_CAST_PTR(char, &name))[i], i)) {
L
Linus Torvalds 已提交
690 691 692 693 694 695 696 697 698
			return (FALSE);
		}
	}

	return (TRUE);
}

/*******************************************************************************
 *
B
Bob Moore 已提交
699
 * FUNCTION:    acpi_ut_repair_name
L
Linus Torvalds 已提交
700
 *
701
 * PARAMETERS:  name            - The ACPI name to be repaired
L
Linus Torvalds 已提交
702
 *
B
Bob Moore 已提交
703
 * RETURN:      Repaired version of the name
L
Linus Torvalds 已提交
704
 *
B
Bob Moore 已提交
705
 * DESCRIPTION: Repair an ACPI name: Change invalid characters to '*' and
706 707 708 709 710 711 712 713 714 715
 *              return the new name. NOTE: the Name parameter must reside in
 *              read/write memory, cannot be a const.
 *
 * An ACPI Name must consist of valid ACPI characters. We will repair the name
 * if necessary because we don't want to abort because of this, but we want
 * all namespace names to be printable. A warning message is appropriate.
 *
 * This issue came up because there are in fact machines that exhibit
 * this problem, and we want to be able to enable ACPI support for them,
 * even though there are a few bad names.
L
Linus Torvalds 已提交
716 717 718
 *
 ******************************************************************************/

719
void acpi_ut_repair_name(char *name)
L
Linus Torvalds 已提交
720
{
721 722 723 724 725 726
	u32 i;
	u8 found_bad_char = FALSE;

	ACPI_FUNCTION_NAME(ut_repair_name);

	/* Check each character in the name */
L
Linus Torvalds 已提交
727

B
Bob Moore 已提交
728
	for (i = 0; i < ACPI_NAME_SIZE; i++) {
729 730 731
		if (acpi_ut_valid_acpi_char(name[i], i)) {
			continue;
		}
B
Bob Moore 已提交
732 733 734 735 736 737

		/*
		 * Replace a bad character with something printable, yet technically
		 * still invalid. This prevents any collisions with existing "good"
		 * names in the namespace.
		 */
738 739
		name[i] = '*';
		found_bad_char = TRUE;
B
Bob Moore 已提交
740
	}
L
Linus Torvalds 已提交
741

742 743 744 745 746 747 748 749 750 751 752 753 754 755
	if (found_bad_char) {

		/* Report warning only if in strict mode or debug mode */

		if (!acpi_gbl_enable_interpreter_slack) {
			ACPI_WARNING((AE_INFO,
				      "Found bad character(s) in name, repaired: [%4.4s]\n",
				      name));
		} else {
			ACPI_DEBUG_PRINT((ACPI_DB_INFO,
					  "Found bad character(s) in name, repaired: [%4.4s]\n",
					  name));
		}
	}
L
Linus Torvalds 已提交
756 757 758 759 760 761
}

/*******************************************************************************
 *
 * FUNCTION:    acpi_ut_strtoul64
 *
762 763
 * PARAMETERS:  string          - Null terminated string
 *              base            - Radix of the string: 16 or ACPI_ANY_BASE;
B
Bob Moore 已提交
764
 *                                ACPI_ANY_BASE means 'in behalf of to_integer'
L
Linus Torvalds 已提交
765 766 767 768
 *              ret_integer     - Where the converted integer is returned
 *
 * RETURN:      Status and Converted value
 *
B
Bob Moore 已提交
769 770 771
 * DESCRIPTION: Convert a string into an unsigned value. Performs either a
 *              32-bit or 64-bit conversion, depending on the current mode
 *              of the interpreter.
L
Linus Torvalds 已提交
772 773 774 775
 *              NOTE: Does not support Octal strings, not needed.
 *
 ******************************************************************************/

776
acpi_status acpi_ut_strtoul64(char *string, u32 base, u64 *ret_integer)
L
Linus Torvalds 已提交
777
{
L
Len Brown 已提交
778
	u32 this_digit = 0;
779 780 781
	u64 return_value = 0;
	u64 quotient;
	u64 dividend;
B
Bob Moore 已提交
782 783 784 785 786
	u32 to_integer_op = (base == ACPI_ANY_BASE);
	u32 mode32 = (acpi_gbl_integer_byte_width == 4);
	u8 valid_digits = 0;
	u8 sign_of0x = 0;
	u8 term = 0;
L
Linus Torvalds 已提交
787

B
Bob Moore 已提交
788
	ACPI_FUNCTION_TRACE_STR(ut_stroul64, string);
L
Linus Torvalds 已提交
789 790 791 792 793 794 795 796

	switch (base) {
	case ACPI_ANY_BASE:
	case 16:
		break;

	default:
		/* Invalid Base */
L
Len Brown 已提交
797
		return_ACPI_STATUS(AE_BAD_PARAMETER);
L
Linus Torvalds 已提交
798 799
	}

B
Bob Moore 已提交
800 801 802 803
	if (!string) {
		goto error_exit;
	}

L
Linus Torvalds 已提交
804 805
	/* Skip over any white space in the buffer */

B
Bob Moore 已提交
806
	while ((*string) && (ACPI_IS_SPACE(*string) || *string == '\t')) {
L
Linus Torvalds 已提交
807 808 809
		string++;
	}

B
Bob Moore 已提交
810 811
	if (to_integer_op) {
		/*
812
		 * Base equal to ACPI_ANY_BASE means 'ToInteger operation case'.
B
Bob Moore 已提交
813 814
		 * We need to determine if it is decimal or hexadecimal.
		 */
L
Len Brown 已提交
815
		if ((*string == '0') && (ACPI_TOLOWER(*(string + 1)) == 'x')) {
B
Bob Moore 已提交
816
			sign_of0x = 1;
L
Linus Torvalds 已提交
817
			base = 16;
B
Bob Moore 已提交
818 819

			/* Skip over the leading '0x' */
L
Linus Torvalds 已提交
820
			string += 2;
L
Len Brown 已提交
821
		} else {
L
Linus Torvalds 已提交
822 823 824 825
			base = 10;
		}
	}

B
Bob Moore 已提交
826 827 828 829 830 831 832 833
	/* Any string left? Check that '0x' is not followed by white space. */

	if (!(*string) || ACPI_IS_SPACE(*string) || *string == '\t') {
		if (to_integer_op) {
			goto error_exit;
		} else {
			goto all_done;
		}
L
Linus Torvalds 已提交
834 835
	}

B
Bob Moore 已提交
836 837 838 839
	/*
	 * Perform a 32-bit or 64-bit conversion, depending upon the current
	 * execution mode of the interpreter
	 */
B
Bob Moore 已提交
840
	dividend = (mode32) ? ACPI_UINT32_MAX : ACPI_UINT64_MAX;
L
Linus Torvalds 已提交
841

B
Bob Moore 已提交
842
	/* Main loop: convert the string to a 32- or 64-bit integer */
L
Linus Torvalds 已提交
843 844

	while (*string) {
L
Len Brown 已提交
845
		if (ACPI_IS_DIGIT(*string)) {
B
Bob Moore 已提交
846

L
Linus Torvalds 已提交
847 848
			/* Convert ASCII 0-9 to Decimal value */

849
			this_digit = ((u8)*string) - '0';
B
Bob Moore 已提交
850
		} else if (base == 10) {
L
Linus Torvalds 已提交
851

B
Bob Moore 已提交
852
			/* Digit is out of range; possible in to_integer case only */
L
Linus Torvalds 已提交
853

B
Bob Moore 已提交
854 855
			term = 1;
		} else {
856
			this_digit = (u8)ACPI_TOUPPER(*string);
L
Len Brown 已提交
857
			if (ACPI_IS_XDIGIT((char)this_digit)) {
B
Bob Moore 已提交
858

L
Linus Torvalds 已提交
859 860 861
				/* Convert ASCII Hex char to value */

				this_digit = this_digit - 'A' + 10;
L
Len Brown 已提交
862
			} else {
B
Bob Moore 已提交
863 864 865 866 867 868 869 870
				term = 1;
			}
		}

		if (term) {
			if (to_integer_op) {
				goto error_exit;
			} else {
L
Linus Torvalds 已提交
871 872
				break;
			}
B
Bob Moore 已提交
873 874 875 876 877 878 879 880 881 882
		} else if ((valid_digits == 0) && (this_digit == 0)
			   && !sign_of0x) {

			/* Skip zeros */
			string++;
			continue;
		}

		valid_digits++;

883 884 885
		if (sign_of0x
		    && ((valid_digits > 16)
			|| ((valid_digits > 8) && mode32))) {
B
Bob Moore 已提交
886 887 888 889 890 891
			/*
			 * This is to_integer operation case.
			 * No any restrictions for string-to-integer conversion,
			 * see ACPI spec.
			 */
			goto error_exit;
L
Linus Torvalds 已提交
892 893 894 895
		}

		/* Divide the digit into the correct position */

896
		(void)acpi_ut_short_divide((dividend - (u64)this_digit),
897
					   base, &quotient, NULL);
B
Bob Moore 已提交
898

L
Linus Torvalds 已提交
899
		if (return_value > quotient) {
B
Bob Moore 已提交
900 901 902 903 904
			if (to_integer_op) {
				goto error_exit;
			} else {
				break;
			}
L
Linus Torvalds 已提交
905 906 907 908 909 910 911 912 913
		}

		return_value *= base;
		return_value += this_digit;
		string++;
	}

	/* All done, normal exit */

B
Bob Moore 已提交
914 915
      all_done:

B
Bob Moore 已提交
916 917 918
	ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Converted value: %8.8X%8.8X\n",
			  ACPI_FORMAT_UINT64(return_value)));

L
Linus Torvalds 已提交
919
	*ret_integer = return_value;
L
Len Brown 已提交
920
	return_ACPI_STATUS(AE_OK);
L
Linus Torvalds 已提交
921

L
Len Brown 已提交
922
      error_exit:
L
Linus Torvalds 已提交
923 924 925
	/* Base was set/validated above */

	if (base == 10) {
L
Len Brown 已提交
926 927 928
		return_ACPI_STATUS(AE_BAD_DECIMAL_CONSTANT);
	} else {
		return_ACPI_STATUS(AE_BAD_HEX_CONSTANT);
L
Linus Torvalds 已提交
929 930 931 932 933 934 935
	}
}

/*******************************************************************************
 *
 * FUNCTION:    acpi_ut_create_update_state_and_push
 *
936 937
 * PARAMETERS:  object          - Object to be added to the new state
 *              action          - Increment/Decrement
L
Linus Torvalds 已提交
938 939
 *              state_list      - List the state will be added to
 *
R
Robert Moore 已提交
940
 * RETURN:      Status
L
Linus Torvalds 已提交
941 942 943 944 945 946
 *
 * DESCRIPTION: Create a new state and push it
 *
 ******************************************************************************/

acpi_status
L
Len Brown 已提交
947 948 949
acpi_ut_create_update_state_and_push(union acpi_operand_object *object,
				     u16 action,
				     union acpi_generic_state **state_list)
L
Linus Torvalds 已提交
950
{
L
Len Brown 已提交
951
	union acpi_generic_state *state;
L
Linus Torvalds 已提交
952

L
Len Brown 已提交
953
	ACPI_FUNCTION_ENTRY();
L
Linus Torvalds 已提交
954 955 956 957 958 959 960

	/* Ignore null objects; these are expected */

	if (!object) {
		return (AE_OK);
	}

L
Len Brown 已提交
961
	state = acpi_ut_create_update_state(object, action);
L
Linus Torvalds 已提交
962 963 964 965
	if (!state) {
		return (AE_NO_MEMORY);
	}

L
Len Brown 已提交
966
	acpi_ut_push_generic_state(state_list, state);
L
Linus Torvalds 已提交
967 968 969 970 971 972 973
	return (AE_OK);
}

/*******************************************************************************
 *
 * FUNCTION:    acpi_ut_walk_package_tree
 *
R
Robert Moore 已提交
974 975 976
 * PARAMETERS:  source_object       - The package to walk
 *              target_object       - Target object (if package is being copied)
 *              walk_callback       - Called once for each package element
977
 *              context             - Passed to the callback function
L
Linus Torvalds 已提交
978 979 980 981 982 983 984 985
 *
 * RETURN:      Status
 *
 * DESCRIPTION: Walk through a package
 *
 ******************************************************************************/

acpi_status
986
acpi_ut_walk_package_tree(union acpi_operand_object *source_object,
L
Len Brown 已提交
987 988
			  void *target_object,
			  acpi_pkg_callback walk_callback, void *context)
L
Linus Torvalds 已提交
989
{
L
Len Brown 已提交
990 991 992 993 994
	acpi_status status = AE_OK;
	union acpi_generic_state *state_list = NULL;
	union acpi_generic_state *state;
	u32 this_index;
	union acpi_operand_object *this_source_obj;
L
Linus Torvalds 已提交
995

B
Bob Moore 已提交
996
	ACPI_FUNCTION_TRACE(ut_walk_package_tree);
L
Linus Torvalds 已提交
997

L
Len Brown 已提交
998
	state = acpi_ut_create_pkg_state(source_object, target_object, 0);
L
Linus Torvalds 已提交
999
	if (!state) {
L
Len Brown 已提交
1000
		return_ACPI_STATUS(AE_NO_MEMORY);
L
Linus Torvalds 已提交
1001 1002 1003
	}

	while (state) {
B
Bob Moore 已提交
1004

L
Linus Torvalds 已提交
1005 1006
		/* Get one element of the package */

L
Len Brown 已提交
1007
		this_index = state->pkg.index;
L
Linus Torvalds 已提交
1008
		this_source_obj = (union acpi_operand_object *)
L
Len Brown 已提交
1009
		    state->pkg.source_object->package.elements[this_index];
L
Linus Torvalds 已提交
1010 1011 1012 1013 1014 1015 1016 1017 1018 1019

		/*
		 * Check for:
		 * 1) An uninitialized package element.  It is completely
		 *    legal to declare a package and leave it uninitialized
		 * 2) Not an internal object - can be a namespace node instead
		 * 3) Any type other than a package.  Packages are handled in else
		 *    case below.
		 */
		if ((!this_source_obj) ||
L
Len Brown 已提交
1020 1021
		    (ACPI_GET_DESCRIPTOR_TYPE(this_source_obj) !=
		     ACPI_DESC_TYPE_OPERAND)
1022
		    || (this_source_obj->common.type != ACPI_TYPE_PACKAGE)) {
L
Len Brown 已提交
1023 1024 1025 1026 1027
			status =
			    walk_callback(ACPI_COPY_TYPE_SIMPLE,
					  this_source_obj, state, context);
			if (ACPI_FAILURE(status)) {
				return_ACPI_STATUS(status);
L
Linus Torvalds 已提交
1028 1029 1030
			}

			state->pkg.index++;
L
Len Brown 已提交
1031 1032
			while (state->pkg.index >=
			       state->pkg.source_object->package.count) {
L
Linus Torvalds 已提交
1033 1034 1035 1036 1037 1038 1039
				/*
				 * We've handled all of the objects at this level,  This means
				 * that we have just completed a package.  That package may
				 * have contained one or more packages itself.
				 *
				 * Delete this state and pop the previous state (package).
				 */
L
Len Brown 已提交
1040 1041
				acpi_ut_delete_generic_state(state);
				state = acpi_ut_pop_generic_state(&state_list);
L
Linus Torvalds 已提交
1042 1043 1044 1045 1046 1047 1048 1049 1050

				/* Finished when there are no more states */

				if (!state) {
					/*
					 * We have handled all of the objects in the top level
					 * package just add the length of the package objects
					 * and exit
					 */
L
Len Brown 已提交
1051
					return_ACPI_STATUS(AE_OK);
L
Linus Torvalds 已提交
1052 1053 1054 1055 1056 1057 1058 1059
				}

				/*
				 * Go back up a level and move the index past the just
				 * completed package object.
				 */
				state->pkg.index++;
			}
L
Len Brown 已提交
1060
		} else {
L
Linus Torvalds 已提交
1061 1062
			/* This is a subobject of type package */

L
Len Brown 已提交
1063 1064 1065 1066 1067
			status =
			    walk_callback(ACPI_COPY_TYPE_PACKAGE,
					  this_source_obj, state, context);
			if (ACPI_FAILURE(status)) {
				return_ACPI_STATUS(status);
L
Linus Torvalds 已提交
1068 1069 1070 1071 1072 1073
			}

			/*
			 * Push the current state and create a new one
			 * The callback above returned a new target package object.
			 */
L
Len Brown 已提交
1074 1075 1076 1077
			acpi_ut_push_generic_state(&state_list, state);
			state = acpi_ut_create_pkg_state(this_source_obj,
							 state->pkg.
							 this_target_obj, 0);
L
Linus Torvalds 已提交
1078
			if (!state) {
1079 1080 1081 1082 1083 1084 1085 1086 1087

				/* Free any stacked Update State objects */

				while (state_list) {
					state =
					    acpi_ut_pop_generic_state
					    (&state_list);
					acpi_ut_delete_generic_state(state);
				}
L
Len Brown 已提交
1088
				return_ACPI_STATUS(AE_NO_MEMORY);
L
Linus Torvalds 已提交
1089 1090 1091 1092 1093 1094
			}
		}
	}

	/* We should never get here */

L
Len Brown 已提交
1095
	return_ACPI_STATUS(AE_AML_INTERNAL);
L
Linus Torvalds 已提交
1096
}