ia64/linux-2.6.18-xen.hg

annotate drivers/acpi/utilities/utmisc.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
rev   line source
ian@0 1 /*******************************************************************************
ian@0 2 *
ian@0 3 * Module Name: utmisc - common utility procedures
ian@0 4 *
ian@0 5 ******************************************************************************/
ian@0 6
ian@0 7 /*
ian@0 8 * Copyright (C) 2000 - 2006, R. Byron Moore
ian@0 9 * All rights reserved.
ian@0 10 *
ian@0 11 * Redistribution and use in source and binary forms, with or without
ian@0 12 * modification, are permitted provided that the following conditions
ian@0 13 * are met:
ian@0 14 * 1. Redistributions of source code must retain the above copyright
ian@0 15 * notice, this list of conditions, and the following disclaimer,
ian@0 16 * without modification.
ian@0 17 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
ian@0 18 * substantially similar to the "NO WARRANTY" disclaimer below
ian@0 19 * ("Disclaimer") and any redistribution must be conditioned upon
ian@0 20 * including a substantially similar Disclaimer requirement for further
ian@0 21 * binary redistribution.
ian@0 22 * 3. Neither the names of the above-listed copyright holders nor the names
ian@0 23 * of any contributors may be used to endorse or promote products derived
ian@0 24 * from this software without specific prior written permission.
ian@0 25 *
ian@0 26 * Alternatively, this software may be distributed under the terms of the
ian@0 27 * GNU General Public License ("GPL") version 2 as published by the Free
ian@0 28 * Software Foundation.
ian@0 29 *
ian@0 30 * NO WARRANTY
ian@0 31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
ian@0 32 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
ian@0 33 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
ian@0 34 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
ian@0 35 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
ian@0 36 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
ian@0 37 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
ian@0 38 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
ian@0 39 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
ian@0 40 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
ian@0 41 * POSSIBILITY OF SUCH DAMAGES.
ian@0 42 */
ian@0 43
ian@0 44 #include <linux/module.h>
ian@0 45
ian@0 46 #include <acpi/acpi.h>
ian@0 47 #include <acpi/acnamesp.h>
ian@0 48
ian@0 49 #define _COMPONENT ACPI_UTILITIES
ian@0 50 ACPI_MODULE_NAME("utmisc")
ian@0 51
ian@0 52 /*******************************************************************************
ian@0 53 *
ian@0 54 * FUNCTION: acpi_ut_is_aml_table
ian@0 55 *
ian@0 56 * PARAMETERS: Table - An ACPI table
ian@0 57 *
ian@0 58 * RETURN: TRUE if table contains executable AML; FALSE otherwise
ian@0 59 *
ian@0 60 * DESCRIPTION: Check ACPI Signature for a table that contains AML code.
ian@0 61 * Currently, these are DSDT,SSDT,PSDT. All other table types are
ian@0 62 * data tables that do not contain AML code.
ian@0 63 *
ian@0 64 ******************************************************************************/
ian@0 65 u8 acpi_ut_is_aml_table(struct acpi_table_header *table)
ian@0 66 {
ian@0 67
ian@0 68 /* These are the only tables that contain executable AML */
ian@0 69
ian@0 70 if (ACPI_COMPARE_NAME(table->signature, DSDT_SIG) ||
ian@0 71 ACPI_COMPARE_NAME(table->signature, PSDT_SIG) ||
ian@0 72 ACPI_COMPARE_NAME(table->signature, SSDT_SIG)) {
ian@0 73 return (TRUE);
ian@0 74 }
ian@0 75
ian@0 76 return (FALSE);
ian@0 77 }
ian@0 78
ian@0 79 /*******************************************************************************
ian@0 80 *
ian@0 81 * FUNCTION: acpi_ut_allocate_owner_id
ian@0 82 *
ian@0 83 * PARAMETERS: owner_id - Where the new owner ID is returned
ian@0 84 *
ian@0 85 * RETURN: Status
ian@0 86 *
ian@0 87 * DESCRIPTION: Allocate a table or method owner ID. The owner ID is used to
ian@0 88 * track objects created by the table or method, to be deleted
ian@0 89 * when the method exits or the table is unloaded.
ian@0 90 *
ian@0 91 ******************************************************************************/
ian@0 92
ian@0 93 acpi_status acpi_ut_allocate_owner_id(acpi_owner_id * owner_id)
ian@0 94 {
ian@0 95 acpi_native_uint i;
ian@0 96 acpi_native_uint j;
ian@0 97 acpi_native_uint k;
ian@0 98 acpi_status status;
ian@0 99
ian@0 100 ACPI_FUNCTION_TRACE(ut_allocate_owner_id);
ian@0 101
ian@0 102 /* Guard against multiple allocations of ID to the same location */
ian@0 103
ian@0 104 if (*owner_id) {
ian@0 105 ACPI_ERROR((AE_INFO, "Owner ID [%2.2X] already exists",
ian@0 106 *owner_id));
ian@0 107 return_ACPI_STATUS(AE_ALREADY_EXISTS);
ian@0 108 }
ian@0 109
ian@0 110 /* Mutex for the global ID mask */
ian@0 111
ian@0 112 status = acpi_ut_acquire_mutex(ACPI_MTX_CACHES);
ian@0 113 if (ACPI_FAILURE(status)) {
ian@0 114 return_ACPI_STATUS(status);
ian@0 115 }
ian@0 116
ian@0 117 /*
ian@0 118 * Find a free owner ID, cycle through all possible IDs on repeated
ian@0 119 * allocations. (ACPI_NUM_OWNERID_MASKS + 1) because first index may have
ian@0 120 * to be scanned twice.
ian@0 121 */
ian@0 122 for (i = 0, j = acpi_gbl_last_owner_id_index;
ian@0 123 i < (ACPI_NUM_OWNERID_MASKS + 1); i++, j++) {
ian@0 124 if (j >= ACPI_NUM_OWNERID_MASKS) {
ian@0 125 j = 0; /* Wraparound to start of mask array */
ian@0 126 }
ian@0 127
ian@0 128 for (k = acpi_gbl_next_owner_id_offset; k < 32; k++) {
ian@0 129 if (acpi_gbl_owner_id_mask[j] == ACPI_UINT32_MAX) {
ian@0 130
ian@0 131 /* There are no free IDs in this mask */
ian@0 132
ian@0 133 break;
ian@0 134 }
ian@0 135
ian@0 136 if (!(acpi_gbl_owner_id_mask[j] & (1 << k))) {
ian@0 137 /*
ian@0 138 * Found a free ID. The actual ID is the bit index plus one,
ian@0 139 * making zero an invalid Owner ID. Save this as the last ID
ian@0 140 * allocated and update the global ID mask.
ian@0 141 */
ian@0 142 acpi_gbl_owner_id_mask[j] |= (1 << k);
ian@0 143
ian@0 144 acpi_gbl_last_owner_id_index = (u8) j;
ian@0 145 acpi_gbl_next_owner_id_offset = (u8) (k + 1);
ian@0 146
ian@0 147 /*
ian@0 148 * Construct encoded ID from the index and bit position
ian@0 149 *
ian@0 150 * Note: Last [j].k (bit 255) is never used and is marked
ian@0 151 * permanently allocated (prevents +1 overflow)
ian@0 152 */
ian@0 153 *owner_id =
ian@0 154 (acpi_owner_id) ((k + 1) + ACPI_MUL_32(j));
ian@0 155
ian@0 156 ACPI_DEBUG_PRINT((ACPI_DB_VALUES,
ian@0 157 "Allocated OwnerId: %2.2X\n",
ian@0 158 (unsigned int)*owner_id));
ian@0 159 goto exit;
ian@0 160 }
ian@0 161 }
ian@0 162
ian@0 163 acpi_gbl_next_owner_id_offset = 0;
ian@0 164 }
ian@0 165
ian@0 166 /*
ian@0 167 * All owner_ids have been allocated. This typically should
ian@0 168 * not happen since the IDs are reused after deallocation. The IDs are
ian@0 169 * allocated upon table load (one per table) and method execution, and
ian@0 170 * they are released when a table is unloaded or a method completes
ian@0 171 * execution.
ian@0 172 *
ian@0 173 * If this error happens, there may be very deep nesting of invoked control
ian@0 174 * methods, or there may be a bug where the IDs are not released.
ian@0 175 */
ian@0 176 status = AE_OWNER_ID_LIMIT;
ian@0 177 ACPI_ERROR((AE_INFO,
ian@0 178 "Could not allocate new OwnerId (255 max), AE_OWNER_ID_LIMIT"));
ian@0 179
ian@0 180 exit:
ian@0 181 (void)acpi_ut_release_mutex(ACPI_MTX_CACHES);
ian@0 182 return_ACPI_STATUS(status);
ian@0 183 }
ian@0 184
ian@0 185 /*******************************************************************************
ian@0 186 *
ian@0 187 * FUNCTION: acpi_ut_release_owner_id
ian@0 188 *
ian@0 189 * PARAMETERS: owner_id_ptr - Pointer to a previously allocated owner_iD
ian@0 190 *
ian@0 191 * RETURN: None. No error is returned because we are either exiting a
ian@0 192 * control method or unloading a table. Either way, we would
ian@0 193 * ignore any error anyway.
ian@0 194 *
ian@0 195 * DESCRIPTION: Release a table or method owner ID. Valid IDs are 1 - 255
ian@0 196 *
ian@0 197 ******************************************************************************/
ian@0 198
ian@0 199 void acpi_ut_release_owner_id(acpi_owner_id * owner_id_ptr)
ian@0 200 {
ian@0 201 acpi_owner_id owner_id = *owner_id_ptr;
ian@0 202 acpi_status status;
ian@0 203 acpi_native_uint index;
ian@0 204 u32 bit;
ian@0 205
ian@0 206 ACPI_FUNCTION_TRACE_U32(ut_release_owner_id, owner_id);
ian@0 207
ian@0 208 /* Always clear the input owner_id (zero is an invalid ID) */
ian@0 209
ian@0 210 *owner_id_ptr = 0;
ian@0 211
ian@0 212 /* Zero is not a valid owner_iD */
ian@0 213
ian@0 214 if (owner_id == 0) {
ian@0 215 ACPI_ERROR((AE_INFO, "Invalid OwnerId: %2.2X", owner_id));
ian@0 216 return_VOID;
ian@0 217 }
ian@0 218
ian@0 219 /* Mutex for the global ID mask */
ian@0 220
ian@0 221 status = acpi_ut_acquire_mutex(ACPI_MTX_CACHES);
ian@0 222 if (ACPI_FAILURE(status)) {
ian@0 223 return_VOID;
ian@0 224 }
ian@0 225
ian@0 226 /* Normalize the ID to zero */
ian@0 227
ian@0 228 owner_id--;
ian@0 229
ian@0 230 /* Decode ID to index/offset pair */
ian@0 231
ian@0 232 index = ACPI_DIV_32(owner_id);
ian@0 233 bit = 1 << ACPI_MOD_32(owner_id);
ian@0 234
ian@0 235 /* Free the owner ID only if it is valid */
ian@0 236
ian@0 237 if (acpi_gbl_owner_id_mask[index] & bit) {
ian@0 238 acpi_gbl_owner_id_mask[index] ^= bit;
ian@0 239 } else {
ian@0 240 ACPI_ERROR((AE_INFO,
ian@0 241 "Release of non-allocated OwnerId: %2.2X",
ian@0 242 owner_id + 1));
ian@0 243 }
ian@0 244
ian@0 245 (void)acpi_ut_release_mutex(ACPI_MTX_CACHES);
ian@0 246 return_VOID;
ian@0 247 }
ian@0 248
ian@0 249 /*******************************************************************************
ian@0 250 *
ian@0 251 * FUNCTION: acpi_ut_strupr (strupr)
ian@0 252 *
ian@0 253 * PARAMETERS: src_string - The source string to convert
ian@0 254 *
ian@0 255 * RETURN: None
ian@0 256 *
ian@0 257 * DESCRIPTION: Convert string to uppercase
ian@0 258 *
ian@0 259 * NOTE: This is not a POSIX function, so it appears here, not in utclib.c
ian@0 260 *
ian@0 261 ******************************************************************************/
ian@0 262
ian@0 263 void acpi_ut_strupr(char *src_string)
ian@0 264 {
ian@0 265 char *string;
ian@0 266
ian@0 267 ACPI_FUNCTION_ENTRY();
ian@0 268
ian@0 269 if (!src_string) {
ian@0 270 return;
ian@0 271 }
ian@0 272
ian@0 273 /* Walk entire string, uppercasing the letters */
ian@0 274
ian@0 275 for (string = src_string; *string; string++) {
ian@0 276 *string = (char)ACPI_TOUPPER(*string);
ian@0 277 }
ian@0 278
ian@0 279 return;
ian@0 280 }
ian@0 281
ian@0 282 /*******************************************************************************
ian@0 283 *
ian@0 284 * FUNCTION: acpi_ut_print_string
ian@0 285 *
ian@0 286 * PARAMETERS: String - Null terminated ASCII string
ian@0 287 * max_length - Maximum output length
ian@0 288 *
ian@0 289 * RETURN: None
ian@0 290 *
ian@0 291 * DESCRIPTION: Dump an ASCII string with support for ACPI-defined escape
ian@0 292 * sequences.
ian@0 293 *
ian@0 294 ******************************************************************************/
ian@0 295
ian@0 296 void acpi_ut_print_string(char *string, u8 max_length)
ian@0 297 {
ian@0 298 u32 i;
ian@0 299
ian@0 300 if (!string) {
ian@0 301 acpi_os_printf("<\"NULL STRING PTR\">");
ian@0 302 return;
ian@0 303 }
ian@0 304
ian@0 305 acpi_os_printf("\"");
ian@0 306 for (i = 0; string[i] && (i < max_length); i++) {
ian@0 307
ian@0 308 /* Escape sequences */
ian@0 309
ian@0 310 switch (string[i]) {
ian@0 311 case 0x07:
ian@0 312 acpi_os_printf("\\a"); /* BELL */
ian@0 313 break;
ian@0 314
ian@0 315 case 0x08:
ian@0 316 acpi_os_printf("\\b"); /* BACKSPACE */
ian@0 317 break;
ian@0 318
ian@0 319 case 0x0C:
ian@0 320 acpi_os_printf("\\f"); /* FORMFEED */
ian@0 321 break;
ian@0 322
ian@0 323 case 0x0A:
ian@0 324 acpi_os_printf("\\n"); /* LINEFEED */
ian@0 325 break;
ian@0 326
ian@0 327 case 0x0D:
ian@0 328 acpi_os_printf("\\r"); /* CARRIAGE RETURN */
ian@0 329 break;
ian@0 330
ian@0 331 case 0x09:
ian@0 332 acpi_os_printf("\\t"); /* HORIZONTAL TAB */
ian@0 333 break;
ian@0 334
ian@0 335 case 0x0B:
ian@0 336 acpi_os_printf("\\v"); /* VERTICAL TAB */
ian@0 337 break;
ian@0 338
ian@0 339 case '\'': /* Single Quote */
ian@0 340 case '\"': /* Double Quote */
ian@0 341 case '\\': /* Backslash */
ian@0 342 acpi_os_printf("\\%c", (int)string[i]);
ian@0 343 break;
ian@0 344
ian@0 345 default:
ian@0 346
ian@0 347 /* Check for printable character or hex escape */
ian@0 348
ian@0 349 if (ACPI_IS_PRINT(string[i])) {
ian@0 350 /* This is a normal character */
ian@0 351
ian@0 352 acpi_os_printf("%c", (int)string[i]);
ian@0 353 } else {
ian@0 354 /* All others will be Hex escapes */
ian@0 355
ian@0 356 acpi_os_printf("\\x%2.2X", (s32) string[i]);
ian@0 357 }
ian@0 358 break;
ian@0 359 }
ian@0 360 }
ian@0 361 acpi_os_printf("\"");
ian@0 362
ian@0 363 if (i == max_length && string[i]) {
ian@0 364 acpi_os_printf("...");
ian@0 365 }
ian@0 366 }
ian@0 367
ian@0 368 /*******************************************************************************
ian@0 369 *
ian@0 370 * FUNCTION: acpi_ut_dword_byte_swap
ian@0 371 *
ian@0 372 * PARAMETERS: Value - Value to be converted
ian@0 373 *
ian@0 374 * RETURN: u32 integer with bytes swapped
ian@0 375 *
ian@0 376 * DESCRIPTION: Convert a 32-bit value to big-endian (swap the bytes)
ian@0 377 *
ian@0 378 ******************************************************************************/
ian@0 379
ian@0 380 u32 acpi_ut_dword_byte_swap(u32 value)
ian@0 381 {
ian@0 382 union {
ian@0 383 u32 value;
ian@0 384 u8 bytes[4];
ian@0 385 } out;
ian@0 386 union {
ian@0 387 u32 value;
ian@0 388 u8 bytes[4];
ian@0 389 } in;
ian@0 390
ian@0 391 ACPI_FUNCTION_ENTRY();
ian@0 392
ian@0 393 in.value = value;
ian@0 394
ian@0 395 out.bytes[0] = in.bytes[3];
ian@0 396 out.bytes[1] = in.bytes[2];
ian@0 397 out.bytes[2] = in.bytes[1];
ian@0 398 out.bytes[3] = in.bytes[0];
ian@0 399
ian@0 400 return (out.value);
ian@0 401 }
ian@0 402
ian@0 403 /*******************************************************************************
ian@0 404 *
ian@0 405 * FUNCTION: acpi_ut_set_integer_width
ian@0 406 *
ian@0 407 * PARAMETERS: Revision From DSDT header
ian@0 408 *
ian@0 409 * RETURN: None
ian@0 410 *
ian@0 411 * DESCRIPTION: Set the global integer bit width based upon the revision
ian@0 412 * of the DSDT. For Revision 1 and 0, Integers are 32 bits.
ian@0 413 * For Revision 2 and above, Integers are 64 bits. Yes, this
ian@0 414 * makes a difference.
ian@0 415 *
ian@0 416 ******************************************************************************/
ian@0 417
ian@0 418 void acpi_ut_set_integer_width(u8 revision)
ian@0 419 {
ian@0 420
ian@0 421 if (revision <= 1) {
ian@0 422
ian@0 423 /* 32-bit case */
ian@0 424
ian@0 425 acpi_gbl_integer_bit_width = 32;
ian@0 426 acpi_gbl_integer_nybble_width = 8;
ian@0 427 acpi_gbl_integer_byte_width = 4;
ian@0 428 } else {
ian@0 429 /* 64-bit case (ACPI 2.0+) */
ian@0 430
ian@0 431 acpi_gbl_integer_bit_width = 64;
ian@0 432 acpi_gbl_integer_nybble_width = 16;
ian@0 433 acpi_gbl_integer_byte_width = 8;
ian@0 434 }
ian@0 435 }
ian@0 436
ian@0 437 #ifdef ACPI_DEBUG_OUTPUT
ian@0 438 /*******************************************************************************
ian@0 439 *
ian@0 440 * FUNCTION: acpi_ut_display_init_pathname
ian@0 441 *
ian@0 442 * PARAMETERS: Type - Object type of the node
ian@0 443 * obj_handle - Handle whose pathname will be displayed
ian@0 444 * Path - Additional path string to be appended.
ian@0 445 * (NULL if no extra path)
ian@0 446 *
ian@0 447 * RETURN: acpi_status
ian@0 448 *
ian@0 449 * DESCRIPTION: Display full pathname of an object, DEBUG ONLY
ian@0 450 *
ian@0 451 ******************************************************************************/
ian@0 452
ian@0 453 void
ian@0 454 acpi_ut_display_init_pathname(u8 type,
ian@0 455 struct acpi_namespace_node *obj_handle,
ian@0 456 char *path)
ian@0 457 {
ian@0 458 acpi_status status;
ian@0 459 struct acpi_buffer buffer;
ian@0 460
ian@0 461 ACPI_FUNCTION_ENTRY();
ian@0 462
ian@0 463 /* Only print the path if the appropriate debug level is enabled */
ian@0 464
ian@0 465 if (!(acpi_dbg_level & ACPI_LV_INIT_NAMES)) {
ian@0 466 return;
ian@0 467 }
ian@0 468
ian@0 469 /* Get the full pathname to the node */
ian@0 470
ian@0 471 buffer.length = ACPI_ALLOCATE_LOCAL_BUFFER;
ian@0 472 status = acpi_ns_handle_to_pathname(obj_handle, &buffer);
ian@0 473 if (ACPI_FAILURE(status)) {
ian@0 474 return;
ian@0 475 }
ian@0 476
ian@0 477 /* Print what we're doing */
ian@0 478
ian@0 479 switch (type) {
ian@0 480 case ACPI_TYPE_METHOD:
ian@0 481 acpi_os_printf("Executing ");
ian@0 482 break;
ian@0 483
ian@0 484 default:
ian@0 485 acpi_os_printf("Initializing ");
ian@0 486 break;
ian@0 487 }
ian@0 488
ian@0 489 /* Print the object type and pathname */
ian@0 490
ian@0 491 acpi_os_printf("%-12s %s",
ian@0 492 acpi_ut_get_type_name(type), (char *)buffer.pointer);
ian@0 493
ian@0 494 /* Extra path is used to append names like _STA, _INI, etc. */
ian@0 495
ian@0 496 if (path) {
ian@0 497 acpi_os_printf(".%s", path);
ian@0 498 }
ian@0 499 acpi_os_printf("\n");
ian@0 500
ian@0 501 ACPI_FREE(buffer.pointer);
ian@0 502 }
ian@0 503 #endif
ian@0 504
ian@0 505 /*******************************************************************************
ian@0 506 *
ian@0 507 * FUNCTION: acpi_ut_valid_acpi_char
ian@0 508 *
ian@0 509 * PARAMETERS: Char - The character to be examined
ian@0 510 * Position - Byte position (0-3)
ian@0 511 *
ian@0 512 * RETURN: TRUE if the character is valid, FALSE otherwise
ian@0 513 *
ian@0 514 * DESCRIPTION: Check for a valid ACPI character. Must be one of:
ian@0 515 * 1) Upper case alpha
ian@0 516 * 2) numeric
ian@0 517 * 3) underscore
ian@0 518 *
ian@0 519 * We allow a '!' as the last character because of the ASF! table
ian@0 520 *
ian@0 521 ******************************************************************************/
ian@0 522
ian@0 523 u8 acpi_ut_valid_acpi_char(char character, acpi_native_uint position)
ian@0 524 {
ian@0 525
ian@0 526 if (!((character >= 'A' && character <= 'Z') ||
ian@0 527 (character >= '0' && character <= '9') || (character == '_'))) {
ian@0 528
ian@0 529 /* Allow a '!' in the last position */
ian@0 530
ian@0 531 if (character == '!' && position == 3) {
ian@0 532 return (TRUE);
ian@0 533 }
ian@0 534
ian@0 535 return (FALSE);
ian@0 536 }
ian@0 537
ian@0 538 return (TRUE);
ian@0 539 }
ian@0 540
ian@0 541 /*******************************************************************************
ian@0 542 *
ian@0 543 * FUNCTION: acpi_ut_valid_acpi_name
ian@0 544 *
ian@0 545 * PARAMETERS: Name - The name to be examined
ian@0 546 *
ian@0 547 * RETURN: TRUE if the name is valid, FALSE otherwise
ian@0 548 *
ian@0 549 * DESCRIPTION: Check for a valid ACPI name. Each character must be one of:
ian@0 550 * 1) Upper case alpha
ian@0 551 * 2) numeric
ian@0 552 * 3) underscore
ian@0 553 *
ian@0 554 ******************************************************************************/
ian@0 555
ian@0 556 u8 acpi_ut_valid_acpi_name(u32 name)
ian@0 557 {
ian@0 558 acpi_native_uint i;
ian@0 559
ian@0 560 ACPI_FUNCTION_ENTRY();
ian@0 561
ian@0 562 for (i = 0; i < ACPI_NAME_SIZE; i++) {
ian@0 563 if (!acpi_ut_valid_acpi_char
ian@0 564 ((ACPI_CAST_PTR(char, &name))[i], i)) {
ian@0 565 return (FALSE);
ian@0 566 }
ian@0 567 }
ian@0 568
ian@0 569 return (TRUE);
ian@0 570 }
ian@0 571
ian@0 572 /*******************************************************************************
ian@0 573 *
ian@0 574 * FUNCTION: acpi_ut_repair_name
ian@0 575 *
ian@0 576 * PARAMETERS: Name - The ACPI name to be repaired
ian@0 577 *
ian@0 578 * RETURN: Repaired version of the name
ian@0 579 *
ian@0 580 * DESCRIPTION: Repair an ACPI name: Change invalid characters to '*' and
ian@0 581 * return the new name.
ian@0 582 *
ian@0 583 ******************************************************************************/
ian@0 584
ian@0 585 acpi_name acpi_ut_repair_name(acpi_name name)
ian@0 586 {
ian@0 587 char *name_ptr = ACPI_CAST_PTR(char, &name);
ian@0 588 char new_name[ACPI_NAME_SIZE];
ian@0 589 acpi_native_uint i;
ian@0 590
ian@0 591 for (i = 0; i < ACPI_NAME_SIZE; i++) {
ian@0 592 new_name[i] = name_ptr[i];
ian@0 593
ian@0 594 /*
ian@0 595 * Replace a bad character with something printable, yet technically
ian@0 596 * still invalid. This prevents any collisions with existing "good"
ian@0 597 * names in the namespace.
ian@0 598 */
ian@0 599 if (!acpi_ut_valid_acpi_char(name_ptr[i], i)) {
ian@0 600 new_name[i] = '*';
ian@0 601 }
ian@0 602 }
ian@0 603
ian@0 604 return (*ACPI_CAST_PTR(u32, new_name));
ian@0 605 }
ian@0 606
ian@0 607 /*******************************************************************************
ian@0 608 *
ian@0 609 * FUNCTION: acpi_ut_strtoul64
ian@0 610 *
ian@0 611 * PARAMETERS: String - Null terminated string
ian@0 612 * Base - Radix of the string: 16 or ACPI_ANY_BASE;
ian@0 613 * ACPI_ANY_BASE means 'in behalf of to_integer'
ian@0 614 * ret_integer - Where the converted integer is returned
ian@0 615 *
ian@0 616 * RETURN: Status and Converted value
ian@0 617 *
ian@0 618 * DESCRIPTION: Convert a string into an unsigned value. Performs either a
ian@0 619 * 32-bit or 64-bit conversion, depending on the current mode
ian@0 620 * of the interpreter.
ian@0 621 * NOTE: Does not support Octal strings, not needed.
ian@0 622 *
ian@0 623 ******************************************************************************/
ian@0 624
ian@0 625 acpi_status
ian@0 626 acpi_ut_strtoul64(char *string, u32 base, acpi_integer * ret_integer)
ian@0 627 {
ian@0 628 u32 this_digit = 0;
ian@0 629 acpi_integer return_value = 0;
ian@0 630 acpi_integer quotient;
ian@0 631 acpi_integer dividend;
ian@0 632 u32 to_integer_op = (base == ACPI_ANY_BASE);
ian@0 633 u32 mode32 = (acpi_gbl_integer_byte_width == 4);
ian@0 634 u8 valid_digits = 0;
ian@0 635 u8 sign_of0x = 0;
ian@0 636 u8 term = 0;
ian@0 637
ian@0 638 ACPI_FUNCTION_TRACE_STR(ut_stroul64, string);
ian@0 639
ian@0 640 switch (base) {
ian@0 641 case ACPI_ANY_BASE:
ian@0 642 case 16:
ian@0 643 break;
ian@0 644
ian@0 645 default:
ian@0 646 /* Invalid Base */
ian@0 647 return_ACPI_STATUS(AE_BAD_PARAMETER);
ian@0 648 }
ian@0 649
ian@0 650 if (!string) {
ian@0 651 goto error_exit;
ian@0 652 }
ian@0 653
ian@0 654 /* Skip over any white space in the buffer */
ian@0 655
ian@0 656 while ((*string) && (ACPI_IS_SPACE(*string) || *string == '\t')) {
ian@0 657 string++;
ian@0 658 }
ian@0 659
ian@0 660 if (to_integer_op) {
ian@0 661 /*
ian@0 662 * Base equal to ACPI_ANY_BASE means 'to_integer operation case'.
ian@0 663 * We need to determine if it is decimal or hexadecimal.
ian@0 664 */
ian@0 665 if ((*string == '0') && (ACPI_TOLOWER(*(string + 1)) == 'x')) {
ian@0 666 sign_of0x = 1;
ian@0 667 base = 16;
ian@0 668
ian@0 669 /* Skip over the leading '0x' */
ian@0 670 string += 2;
ian@0 671 } else {
ian@0 672 base = 10;
ian@0 673 }
ian@0 674 }
ian@0 675
ian@0 676 /* Any string left? Check that '0x' is not followed by white space. */
ian@0 677
ian@0 678 if (!(*string) || ACPI_IS_SPACE(*string) || *string == '\t') {
ian@0 679 if (to_integer_op) {
ian@0 680 goto error_exit;
ian@0 681 } else {
ian@0 682 goto all_done;
ian@0 683 }
ian@0 684 }
ian@0 685
ian@0 686 /*
ian@0 687 * Perform a 32-bit or 64-bit conversion, depending upon the current
ian@0 688 * execution mode of the interpreter
ian@0 689 */
ian@0 690 dividend = (mode32) ? ACPI_UINT32_MAX : ACPI_UINT64_MAX;
ian@0 691
ian@0 692 /* Main loop: convert the string to a 32- or 64-bit integer */
ian@0 693
ian@0 694 while (*string) {
ian@0 695 if (ACPI_IS_DIGIT(*string)) {
ian@0 696
ian@0 697 /* Convert ASCII 0-9 to Decimal value */
ian@0 698
ian@0 699 this_digit = ((u8) * string) - '0';
ian@0 700 } else if (base == 10) {
ian@0 701
ian@0 702 /* Digit is out of range; possible in to_integer case only */
ian@0 703
ian@0 704 term = 1;
ian@0 705 } else {
ian@0 706 this_digit = (u8) ACPI_TOUPPER(*string);
ian@0 707 if (ACPI_IS_XDIGIT((char)this_digit)) {
ian@0 708
ian@0 709 /* Convert ASCII Hex char to value */
ian@0 710
ian@0 711 this_digit = this_digit - 'A' + 10;
ian@0 712 } else {
ian@0 713 term = 1;
ian@0 714 }
ian@0 715 }
ian@0 716
ian@0 717 if (term) {
ian@0 718 if (to_integer_op) {
ian@0 719 goto error_exit;
ian@0 720 } else {
ian@0 721 break;
ian@0 722 }
ian@0 723 } else if ((valid_digits == 0) && (this_digit == 0)
ian@0 724 && !sign_of0x) {
ian@0 725
ian@0 726 /* Skip zeros */
ian@0 727 string++;
ian@0 728 continue;
ian@0 729 }
ian@0 730
ian@0 731 valid_digits++;
ian@0 732
ian@0 733 if (sign_of0x
ian@0 734 && ((valid_digits > 16)
ian@0 735 || ((valid_digits > 8) && mode32))) {
ian@0 736 /*
ian@0 737 * This is to_integer operation case.
ian@0 738 * No any restrictions for string-to-integer conversion,
ian@0 739 * see ACPI spec.
ian@0 740 */
ian@0 741 goto error_exit;
ian@0 742 }
ian@0 743
ian@0 744 /* Divide the digit into the correct position */
ian@0 745
ian@0 746 (void)
ian@0 747 acpi_ut_short_divide((dividend - (acpi_integer) this_digit),
ian@0 748 base, &quotient, NULL);
ian@0 749
ian@0 750 if (return_value > quotient) {
ian@0 751 if (to_integer_op) {
ian@0 752 goto error_exit;
ian@0 753 } else {
ian@0 754 break;
ian@0 755 }
ian@0 756 }
ian@0 757
ian@0 758 return_value *= base;
ian@0 759 return_value += this_digit;
ian@0 760 string++;
ian@0 761 }
ian@0 762
ian@0 763 /* All done, normal exit */
ian@0 764
ian@0 765 all_done:
ian@0 766
ian@0 767 ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Converted value: %8.8X%8.8X\n",
ian@0 768 ACPI_FORMAT_UINT64(return_value)));
ian@0 769
ian@0 770 *ret_integer = return_value;
ian@0 771 return_ACPI_STATUS(AE_OK);
ian@0 772
ian@0 773 error_exit:
ian@0 774 /* Base was set/validated above */
ian@0 775
ian@0 776 if (base == 10) {
ian@0 777 return_ACPI_STATUS(AE_BAD_DECIMAL_CONSTANT);
ian@0 778 } else {
ian@0 779 return_ACPI_STATUS(AE_BAD_HEX_CONSTANT);
ian@0 780 }
ian@0 781 }
ian@0 782
ian@0 783 /*******************************************************************************
ian@0 784 *
ian@0 785 * FUNCTION: acpi_ut_create_update_state_and_push
ian@0 786 *
ian@0 787 * PARAMETERS: Object - Object to be added to the new state
ian@0 788 * Action - Increment/Decrement
ian@0 789 * state_list - List the state will be added to
ian@0 790 *
ian@0 791 * RETURN: Status
ian@0 792 *
ian@0 793 * DESCRIPTION: Create a new state and push it
ian@0 794 *
ian@0 795 ******************************************************************************/
ian@0 796
ian@0 797 acpi_status
ian@0 798 acpi_ut_create_update_state_and_push(union acpi_operand_object *object,
ian@0 799 u16 action,
ian@0 800 union acpi_generic_state **state_list)
ian@0 801 {
ian@0 802 union acpi_generic_state *state;
ian@0 803
ian@0 804 ACPI_FUNCTION_ENTRY();
ian@0 805
ian@0 806 /* Ignore null objects; these are expected */
ian@0 807
ian@0 808 if (!object) {
ian@0 809 return (AE_OK);
ian@0 810 }
ian@0 811
ian@0 812 state = acpi_ut_create_update_state(object, action);
ian@0 813 if (!state) {
ian@0 814 return (AE_NO_MEMORY);
ian@0 815 }
ian@0 816
ian@0 817 acpi_ut_push_generic_state(state_list, state);
ian@0 818 return (AE_OK);
ian@0 819 }
ian@0 820
ian@0 821 /*******************************************************************************
ian@0 822 *
ian@0 823 * FUNCTION: acpi_ut_walk_package_tree
ian@0 824 *
ian@0 825 * PARAMETERS: source_object - The package to walk
ian@0 826 * target_object - Target object (if package is being copied)
ian@0 827 * walk_callback - Called once for each package element
ian@0 828 * Context - Passed to the callback function
ian@0 829 *
ian@0 830 * RETURN: Status
ian@0 831 *
ian@0 832 * DESCRIPTION: Walk through a package
ian@0 833 *
ian@0 834 ******************************************************************************/
ian@0 835
ian@0 836 acpi_status
ian@0 837 acpi_ut_walk_package_tree(union acpi_operand_object * source_object,
ian@0 838 void *target_object,
ian@0 839 acpi_pkg_callback walk_callback, void *context)
ian@0 840 {
ian@0 841 acpi_status status = AE_OK;
ian@0 842 union acpi_generic_state *state_list = NULL;
ian@0 843 union acpi_generic_state *state;
ian@0 844 u32 this_index;
ian@0 845 union acpi_operand_object *this_source_obj;
ian@0 846
ian@0 847 ACPI_FUNCTION_TRACE(ut_walk_package_tree);
ian@0 848
ian@0 849 state = acpi_ut_create_pkg_state(source_object, target_object, 0);
ian@0 850 if (!state) {
ian@0 851 return_ACPI_STATUS(AE_NO_MEMORY);
ian@0 852 }
ian@0 853
ian@0 854 while (state) {
ian@0 855
ian@0 856 /* Get one element of the package */
ian@0 857
ian@0 858 this_index = state->pkg.index;
ian@0 859 this_source_obj = (union acpi_operand_object *)
ian@0 860 state->pkg.source_object->package.elements[this_index];
ian@0 861
ian@0 862 /*
ian@0 863 * Check for:
ian@0 864 * 1) An uninitialized package element. It is completely
ian@0 865 * legal to declare a package and leave it uninitialized
ian@0 866 * 2) Not an internal object - can be a namespace node instead
ian@0 867 * 3) Any type other than a package. Packages are handled in else
ian@0 868 * case below.
ian@0 869 */
ian@0 870 if ((!this_source_obj) ||
ian@0 871 (ACPI_GET_DESCRIPTOR_TYPE(this_source_obj) !=
ian@0 872 ACPI_DESC_TYPE_OPERAND)
ian@0 873 || (ACPI_GET_OBJECT_TYPE(this_source_obj) !=
ian@0 874 ACPI_TYPE_PACKAGE)) {
ian@0 875 status =
ian@0 876 walk_callback(ACPI_COPY_TYPE_SIMPLE,
ian@0 877 this_source_obj, state, context);
ian@0 878 if (ACPI_FAILURE(status)) {
ian@0 879 return_ACPI_STATUS(status);
ian@0 880 }
ian@0 881
ian@0 882 state->pkg.index++;
ian@0 883 while (state->pkg.index >=
ian@0 884 state->pkg.source_object->package.count) {
ian@0 885 /*
ian@0 886 * We've handled all of the objects at this level, This means
ian@0 887 * that we have just completed a package. That package may
ian@0 888 * have contained one or more packages itself.
ian@0 889 *
ian@0 890 * Delete this state and pop the previous state (package).
ian@0 891 */
ian@0 892 acpi_ut_delete_generic_state(state);
ian@0 893 state = acpi_ut_pop_generic_state(&state_list);
ian@0 894
ian@0 895 /* Finished when there are no more states */
ian@0 896
ian@0 897 if (!state) {
ian@0 898 /*
ian@0 899 * We have handled all of the objects in the top level
ian@0 900 * package just add the length of the package objects
ian@0 901 * and exit
ian@0 902 */
ian@0 903 return_ACPI_STATUS(AE_OK);
ian@0 904 }
ian@0 905
ian@0 906 /*
ian@0 907 * Go back up a level and move the index past the just
ian@0 908 * completed package object.
ian@0 909 */
ian@0 910 state->pkg.index++;
ian@0 911 }
ian@0 912 } else {
ian@0 913 /* This is a subobject of type package */
ian@0 914
ian@0 915 status =
ian@0 916 walk_callback(ACPI_COPY_TYPE_PACKAGE,
ian@0 917 this_source_obj, state, context);
ian@0 918 if (ACPI_FAILURE(status)) {
ian@0 919 return_ACPI_STATUS(status);
ian@0 920 }
ian@0 921
ian@0 922 /*
ian@0 923 * Push the current state and create a new one
ian@0 924 * The callback above returned a new target package object.
ian@0 925 */
ian@0 926 acpi_ut_push_generic_state(&state_list, state);
ian@0 927 state = acpi_ut_create_pkg_state(this_source_obj,
ian@0 928 state->pkg.
ian@0 929 this_target_obj, 0);
ian@0 930 if (!state) {
ian@0 931 return_ACPI_STATUS(AE_NO_MEMORY);
ian@0 932 }
ian@0 933 }
ian@0 934 }
ian@0 935
ian@0 936 /* We should never get here */
ian@0 937
ian@0 938 return_ACPI_STATUS(AE_AML_INTERNAL);
ian@0 939 }
ian@0 940
ian@0 941 /*******************************************************************************
ian@0 942 *
ian@0 943 * FUNCTION: acpi_ut_error, acpi_ut_warning, acpi_ut_info
ian@0 944 *
ian@0 945 * PARAMETERS: module_name - Caller's module name (for error output)
ian@0 946 * line_number - Caller's line number (for error output)
ian@0 947 * Format - Printf format string + additional args
ian@0 948 *
ian@0 949 * RETURN: None
ian@0 950 *
ian@0 951 * DESCRIPTION: Print message with module/line/version info
ian@0 952 *
ian@0 953 ******************************************************************************/
ian@0 954
ian@0 955 void ACPI_INTERNAL_VAR_XFACE
ian@0 956 acpi_ut_error(char *module_name, u32 line_number, char *format, ...)
ian@0 957 {
ian@0 958 va_list args;
ian@0 959
ian@0 960 acpi_os_printf("ACPI Error (%s-%04d): ", module_name, line_number);
ian@0 961
ian@0 962 va_start(args, format);
ian@0 963 acpi_os_vprintf(format, args);
ian@0 964 acpi_os_printf(" [%X]\n", ACPI_CA_VERSION);
ian@0 965 }
ian@0 966
ian@0 967 void ACPI_INTERNAL_VAR_XFACE
ian@0 968 acpi_ut_exception(char *module_name,
ian@0 969 u32 line_number, acpi_status status, char *format, ...)
ian@0 970 {
ian@0 971 va_list args;
ian@0 972
ian@0 973 acpi_os_printf("ACPI Exception (%s-%04d): %s, ", module_name,
ian@0 974 line_number, acpi_format_exception(status));
ian@0 975
ian@0 976 va_start(args, format);
ian@0 977 acpi_os_vprintf(format, args);
ian@0 978 acpi_os_printf(" [%X]\n", ACPI_CA_VERSION);
ian@0 979 }
ian@0 980 EXPORT_SYMBOL(acpi_ut_exception);
ian@0 981
ian@0 982 void ACPI_INTERNAL_VAR_XFACE
ian@0 983 acpi_ut_warning(char *module_name, u32 line_number, char *format, ...)
ian@0 984 {
ian@0 985 va_list args;
ian@0 986
ian@0 987 acpi_os_printf("ACPI Warning (%s-%04d): ", module_name, line_number);
ian@0 988
ian@0 989 va_start(args, format);
ian@0 990 acpi_os_vprintf(format, args);
ian@0 991 acpi_os_printf(" [%X]\n", ACPI_CA_VERSION);
ian@0 992 }
ian@0 993
ian@0 994 void ACPI_INTERNAL_VAR_XFACE
ian@0 995 acpi_ut_info(char *module_name, u32 line_number, char *format, ...)
ian@0 996 {
ian@0 997 va_list args;
ian@0 998
ian@0 999 acpi_os_printf("ACPI (%s-%04d): ", module_name, line_number);
ian@0 1000
ian@0 1001 va_start(args, format);
ian@0 1002 acpi_os_vprintf(format, args);
ian@0 1003 acpi_os_printf(" [%X]\n", ACPI_CA_VERSION);
ian@0 1004 }