ia64/linux-2.6.18-xen.hg

annotate drivers/acpi/utilities/utobject.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: utobject - ACPI object create/delete/size/cache routines
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 <acpi/acpi.h>
ian@0 45 #include <acpi/acnamesp.h>
ian@0 46 #include <acpi/amlcode.h>
ian@0 47
ian@0 48 #define _COMPONENT ACPI_UTILITIES
ian@0 49 ACPI_MODULE_NAME("utobject")
ian@0 50
ian@0 51 /* Local prototypes */
ian@0 52 static acpi_status
ian@0 53 acpi_ut_get_simple_object_size(union acpi_operand_object *obj,
ian@0 54 acpi_size * obj_length);
ian@0 55
ian@0 56 static acpi_status
ian@0 57 acpi_ut_get_package_object_size(union acpi_operand_object *obj,
ian@0 58 acpi_size * obj_length);
ian@0 59
ian@0 60 static acpi_status
ian@0 61 acpi_ut_get_element_length(u8 object_type,
ian@0 62 union acpi_operand_object *source_object,
ian@0 63 union acpi_generic_state *state, void *context);
ian@0 64
ian@0 65 /*******************************************************************************
ian@0 66 *
ian@0 67 * FUNCTION: acpi_ut_create_internal_object_dbg
ian@0 68 *
ian@0 69 * PARAMETERS: module_name - Source file name of caller
ian@0 70 * line_number - Line number of caller
ian@0 71 * component_id - Component type of caller
ian@0 72 * Type - ACPI Type of the new object
ian@0 73 *
ian@0 74 * RETURN: A new internal object, null on failure
ian@0 75 *
ian@0 76 * DESCRIPTION: Create and initialize a new internal object.
ian@0 77 *
ian@0 78 * NOTE: We always allocate the worst-case object descriptor because
ian@0 79 * these objects are cached, and we want them to be
ian@0 80 * one-size-satisifies-any-request. This in itself may not be
ian@0 81 * the most memory efficient, but the efficiency of the object
ian@0 82 * cache should more than make up for this!
ian@0 83 *
ian@0 84 ******************************************************************************/
ian@0 85
ian@0 86 union acpi_operand_object *acpi_ut_create_internal_object_dbg(char *module_name,
ian@0 87 u32 line_number,
ian@0 88 u32 component_id,
ian@0 89 acpi_object_type
ian@0 90 type)
ian@0 91 {
ian@0 92 union acpi_operand_object *object;
ian@0 93 union acpi_operand_object *second_object;
ian@0 94
ian@0 95 ACPI_FUNCTION_TRACE_STR(ut_create_internal_object_dbg,
ian@0 96 acpi_ut_get_type_name(type));
ian@0 97
ian@0 98 /* Allocate the raw object descriptor */
ian@0 99
ian@0 100 object =
ian@0 101 acpi_ut_allocate_object_desc_dbg(module_name, line_number,
ian@0 102 component_id);
ian@0 103 if (!object) {
ian@0 104 return_PTR(NULL);
ian@0 105 }
ian@0 106
ian@0 107 switch (type) {
ian@0 108 case ACPI_TYPE_REGION:
ian@0 109 case ACPI_TYPE_BUFFER_FIELD:
ian@0 110
ian@0 111 /* These types require a secondary object */
ian@0 112
ian@0 113 second_object = acpi_ut_allocate_object_desc_dbg(module_name,
ian@0 114 line_number,
ian@0 115 component_id);
ian@0 116 if (!second_object) {
ian@0 117 acpi_ut_delete_object_desc(object);
ian@0 118 return_PTR(NULL);
ian@0 119 }
ian@0 120
ian@0 121 second_object->common.type = ACPI_TYPE_LOCAL_EXTRA;
ian@0 122 second_object->common.reference_count = 1;
ian@0 123
ian@0 124 /* Link the second object to the first */
ian@0 125
ian@0 126 object->common.next_object = second_object;
ian@0 127 break;
ian@0 128
ian@0 129 default:
ian@0 130 /* All others have no secondary object */
ian@0 131 break;
ian@0 132 }
ian@0 133
ian@0 134 /* Save the object type in the object descriptor */
ian@0 135
ian@0 136 object->common.type = (u8) type;
ian@0 137
ian@0 138 /* Init the reference count */
ian@0 139
ian@0 140 object->common.reference_count = 1;
ian@0 141
ian@0 142 /* Any per-type initialization should go here */
ian@0 143
ian@0 144 return_PTR(object);
ian@0 145 }
ian@0 146
ian@0 147 /*******************************************************************************
ian@0 148 *
ian@0 149 * FUNCTION: acpi_ut_create_buffer_object
ian@0 150 *
ian@0 151 * PARAMETERS: buffer_size - Size of buffer to be created
ian@0 152 *
ian@0 153 * RETURN: Pointer to a new Buffer object, null on failure
ian@0 154 *
ian@0 155 * DESCRIPTION: Create a fully initialized buffer object
ian@0 156 *
ian@0 157 ******************************************************************************/
ian@0 158
ian@0 159 union acpi_operand_object *acpi_ut_create_buffer_object(acpi_size buffer_size)
ian@0 160 {
ian@0 161 union acpi_operand_object *buffer_desc;
ian@0 162 u8 *buffer = NULL;
ian@0 163
ian@0 164 ACPI_FUNCTION_TRACE_U32(ut_create_buffer_object, buffer_size);
ian@0 165
ian@0 166 /* Create a new Buffer object */
ian@0 167
ian@0 168 buffer_desc = acpi_ut_create_internal_object(ACPI_TYPE_BUFFER);
ian@0 169 if (!buffer_desc) {
ian@0 170 return_PTR(NULL);
ian@0 171 }
ian@0 172
ian@0 173 /* Create an actual buffer only if size > 0 */
ian@0 174
ian@0 175 if (buffer_size > 0) {
ian@0 176
ian@0 177 /* Allocate the actual buffer */
ian@0 178
ian@0 179 buffer = ACPI_ALLOCATE_ZEROED(buffer_size);
ian@0 180 if (!buffer) {
ian@0 181 ACPI_ERROR((AE_INFO, "Could not allocate size %X",
ian@0 182 (u32) buffer_size));
ian@0 183 acpi_ut_remove_reference(buffer_desc);
ian@0 184 return_PTR(NULL);
ian@0 185 }
ian@0 186 }
ian@0 187
ian@0 188 /* Complete buffer object initialization */
ian@0 189
ian@0 190 buffer_desc->buffer.flags |= AOPOBJ_DATA_VALID;
ian@0 191 buffer_desc->buffer.pointer = buffer;
ian@0 192 buffer_desc->buffer.length = (u32) buffer_size;
ian@0 193
ian@0 194 /* Return the new buffer descriptor */
ian@0 195
ian@0 196 return_PTR(buffer_desc);
ian@0 197 }
ian@0 198
ian@0 199 /*******************************************************************************
ian@0 200 *
ian@0 201 * FUNCTION: acpi_ut_create_string_object
ian@0 202 *
ian@0 203 * PARAMETERS: string_size - Size of string to be created. Does not
ian@0 204 * include NULL terminator, this is added
ian@0 205 * automatically.
ian@0 206 *
ian@0 207 * RETURN: Pointer to a new String object
ian@0 208 *
ian@0 209 * DESCRIPTION: Create a fully initialized string object
ian@0 210 *
ian@0 211 ******************************************************************************/
ian@0 212
ian@0 213 union acpi_operand_object *acpi_ut_create_string_object(acpi_size string_size)
ian@0 214 {
ian@0 215 union acpi_operand_object *string_desc;
ian@0 216 char *string;
ian@0 217
ian@0 218 ACPI_FUNCTION_TRACE_U32(ut_create_string_object, string_size);
ian@0 219
ian@0 220 /* Create a new String object */
ian@0 221
ian@0 222 string_desc = acpi_ut_create_internal_object(ACPI_TYPE_STRING);
ian@0 223 if (!string_desc) {
ian@0 224 return_PTR(NULL);
ian@0 225 }
ian@0 226
ian@0 227 /*
ian@0 228 * Allocate the actual string buffer -- (Size + 1) for NULL terminator.
ian@0 229 * NOTE: Zero-length strings are NULL terminated
ian@0 230 */
ian@0 231 string = ACPI_ALLOCATE_ZEROED(string_size + 1);
ian@0 232 if (!string) {
ian@0 233 ACPI_ERROR((AE_INFO, "Could not allocate size %X",
ian@0 234 (u32) string_size));
ian@0 235 acpi_ut_remove_reference(string_desc);
ian@0 236 return_PTR(NULL);
ian@0 237 }
ian@0 238
ian@0 239 /* Complete string object initialization */
ian@0 240
ian@0 241 string_desc->string.pointer = string;
ian@0 242 string_desc->string.length = (u32) string_size;
ian@0 243
ian@0 244 /* Return the new string descriptor */
ian@0 245
ian@0 246 return_PTR(string_desc);
ian@0 247 }
ian@0 248
ian@0 249 /*******************************************************************************
ian@0 250 *
ian@0 251 * FUNCTION: acpi_ut_valid_internal_object
ian@0 252 *
ian@0 253 * PARAMETERS: Object - Object to be validated
ian@0 254 *
ian@0 255 * RETURN: TRUE if object is valid, FALSE otherwise
ian@0 256 *
ian@0 257 * DESCRIPTION: Validate a pointer to be an union acpi_operand_object
ian@0 258 *
ian@0 259 ******************************************************************************/
ian@0 260
ian@0 261 u8 acpi_ut_valid_internal_object(void *object)
ian@0 262 {
ian@0 263
ian@0 264 ACPI_FUNCTION_NAME(ut_valid_internal_object);
ian@0 265
ian@0 266 /* Check for a null pointer */
ian@0 267
ian@0 268 if (!object) {
ian@0 269 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "**** Null Object Ptr\n"));
ian@0 270 return (FALSE);
ian@0 271 }
ian@0 272
ian@0 273 /* Check the descriptor type field */
ian@0 274
ian@0 275 switch (ACPI_GET_DESCRIPTOR_TYPE(object)) {
ian@0 276 case ACPI_DESC_TYPE_OPERAND:
ian@0 277
ian@0 278 /* The object appears to be a valid union acpi_operand_object */
ian@0 279
ian@0 280 return (TRUE);
ian@0 281
ian@0 282 default:
ian@0 283 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
ian@0 284 "%p is not not an ACPI operand obj [%s]\n",
ian@0 285 object, acpi_ut_get_descriptor_name(object)));
ian@0 286 break;
ian@0 287 }
ian@0 288
ian@0 289 return (FALSE);
ian@0 290 }
ian@0 291
ian@0 292 /*******************************************************************************
ian@0 293 *
ian@0 294 * FUNCTION: acpi_ut_allocate_object_desc_dbg
ian@0 295 *
ian@0 296 * PARAMETERS: module_name - Caller's module name (for error output)
ian@0 297 * line_number - Caller's line number (for error output)
ian@0 298 * component_id - Caller's component ID (for error output)
ian@0 299 *
ian@0 300 * RETURN: Pointer to newly allocated object descriptor. Null on error
ian@0 301 *
ian@0 302 * DESCRIPTION: Allocate a new object descriptor. Gracefully handle
ian@0 303 * error conditions.
ian@0 304 *
ian@0 305 ******************************************************************************/
ian@0 306
ian@0 307 void *acpi_ut_allocate_object_desc_dbg(char *module_name,
ian@0 308 u32 line_number, u32 component_id)
ian@0 309 {
ian@0 310 union acpi_operand_object *object;
ian@0 311
ian@0 312 ACPI_FUNCTION_TRACE(ut_allocate_object_desc_dbg);
ian@0 313
ian@0 314 object = acpi_os_acquire_object(acpi_gbl_operand_cache);
ian@0 315 if (!object) {
ian@0 316 ACPI_ERROR((module_name, line_number,
ian@0 317 "Could not allocate an object descriptor"));
ian@0 318
ian@0 319 return_PTR(NULL);
ian@0 320 }
ian@0 321
ian@0 322 /* Mark the descriptor type */
ian@0 323
ian@0 324 memset(object, 0, sizeof(union acpi_operand_object));
ian@0 325 ACPI_SET_DESCRIPTOR_TYPE(object, ACPI_DESC_TYPE_OPERAND);
ian@0 326
ian@0 327 ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS, "%p Size %X\n",
ian@0 328 object, (u32) sizeof(union acpi_operand_object)));
ian@0 329
ian@0 330 return_PTR(object);
ian@0 331 }
ian@0 332
ian@0 333 /*******************************************************************************
ian@0 334 *
ian@0 335 * FUNCTION: acpi_ut_delete_object_desc
ian@0 336 *
ian@0 337 * PARAMETERS: Object - An Acpi internal object to be deleted
ian@0 338 *
ian@0 339 * RETURN: None.
ian@0 340 *
ian@0 341 * DESCRIPTION: Free an ACPI object descriptor or add it to the object cache
ian@0 342 *
ian@0 343 ******************************************************************************/
ian@0 344
ian@0 345 void acpi_ut_delete_object_desc(union acpi_operand_object *object)
ian@0 346 {
ian@0 347 ACPI_FUNCTION_TRACE_PTR(ut_delete_object_desc, object);
ian@0 348
ian@0 349 /* Object must be an union acpi_operand_object */
ian@0 350
ian@0 351 if (ACPI_GET_DESCRIPTOR_TYPE(object) != ACPI_DESC_TYPE_OPERAND) {
ian@0 352 ACPI_ERROR((AE_INFO,
ian@0 353 "%p is not an ACPI Operand object [%s]", object,
ian@0 354 acpi_ut_get_descriptor_name(object)));
ian@0 355 return_VOID;
ian@0 356 }
ian@0 357
ian@0 358 (void)acpi_os_release_object(acpi_gbl_operand_cache, object);
ian@0 359 return_VOID;
ian@0 360 }
ian@0 361
ian@0 362 /*******************************************************************************
ian@0 363 *
ian@0 364 * FUNCTION: acpi_ut_get_simple_object_size
ian@0 365 *
ian@0 366 * PARAMETERS: internal_object - An ACPI operand object
ian@0 367 * obj_length - Where the length is returned
ian@0 368 *
ian@0 369 * RETURN: Status
ian@0 370 *
ian@0 371 * DESCRIPTION: This function is called to determine the space required to
ian@0 372 * contain a simple object for return to an external user.
ian@0 373 *
ian@0 374 * The length includes the object structure plus any additional
ian@0 375 * needed space.
ian@0 376 *
ian@0 377 ******************************************************************************/
ian@0 378
ian@0 379 static acpi_status
ian@0 380 acpi_ut_get_simple_object_size(union acpi_operand_object *internal_object,
ian@0 381 acpi_size * obj_length)
ian@0 382 {
ian@0 383 acpi_size length;
ian@0 384 acpi_status status = AE_OK;
ian@0 385
ian@0 386 ACPI_FUNCTION_TRACE_PTR(ut_get_simple_object_size, internal_object);
ian@0 387
ian@0 388 /*
ian@0 389 * Handle a null object (Could be a uninitialized package
ian@0 390 * element -- which is legal)
ian@0 391 */
ian@0 392 if (!internal_object) {
ian@0 393 *obj_length = 0;
ian@0 394 return_ACPI_STATUS(AE_OK);
ian@0 395 }
ian@0 396
ian@0 397 /* Start with the length of the Acpi object */
ian@0 398
ian@0 399 length = sizeof(union acpi_object);
ian@0 400
ian@0 401 if (ACPI_GET_DESCRIPTOR_TYPE(internal_object) == ACPI_DESC_TYPE_NAMED) {
ian@0 402
ian@0 403 /* Object is a named object (reference), just return the length */
ian@0 404
ian@0 405 *obj_length = ACPI_ROUND_UP_TO_NATIVE_WORD(length);
ian@0 406 return_ACPI_STATUS(status);
ian@0 407 }
ian@0 408
ian@0 409 /*
ian@0 410 * The final length depends on the object type
ian@0 411 * Strings and Buffers are packed right up against the parent object and
ian@0 412 * must be accessed bytewise or there may be alignment problems on
ian@0 413 * certain processors
ian@0 414 */
ian@0 415 switch (ACPI_GET_OBJECT_TYPE(internal_object)) {
ian@0 416 case ACPI_TYPE_STRING:
ian@0 417
ian@0 418 length += (acpi_size) internal_object->string.length + 1;
ian@0 419 break;
ian@0 420
ian@0 421 case ACPI_TYPE_BUFFER:
ian@0 422
ian@0 423 length += (acpi_size) internal_object->buffer.length;
ian@0 424 break;
ian@0 425
ian@0 426 case ACPI_TYPE_INTEGER:
ian@0 427 case ACPI_TYPE_PROCESSOR:
ian@0 428 case ACPI_TYPE_POWER:
ian@0 429
ian@0 430 /*
ian@0 431 * No extra data for these types
ian@0 432 */
ian@0 433 break;
ian@0 434
ian@0 435 case ACPI_TYPE_LOCAL_REFERENCE:
ian@0 436
ian@0 437 switch (internal_object->reference.opcode) {
ian@0 438 case AML_INT_NAMEPATH_OP:
ian@0 439
ian@0 440 /*
ian@0 441 * Get the actual length of the full pathname to this object.
ian@0 442 * The reference will be converted to the pathname to the object
ian@0 443 */
ian@0 444 length +=
ian@0 445 ACPI_ROUND_UP_TO_NATIVE_WORD
ian@0 446 (acpi_ns_get_pathname_length
ian@0 447 (internal_object->reference.node));
ian@0 448 break;
ian@0 449
ian@0 450 default:
ian@0 451
ian@0 452 /*
ian@0 453 * No other reference opcodes are supported.
ian@0 454 * Notably, Locals and Args are not supported, but this may be
ian@0 455 * required eventually.
ian@0 456 */
ian@0 457 ACPI_ERROR((AE_INFO,
ian@0 458 "Unsupported Reference opcode=%X in object %p",
ian@0 459 internal_object->reference.opcode,
ian@0 460 internal_object));
ian@0 461 status = AE_TYPE;
ian@0 462 break;
ian@0 463 }
ian@0 464 break;
ian@0 465
ian@0 466 default:
ian@0 467
ian@0 468 ACPI_ERROR((AE_INFO, "Unsupported type=%X in object %p",
ian@0 469 ACPI_GET_OBJECT_TYPE(internal_object),
ian@0 470 internal_object));
ian@0 471 status = AE_TYPE;
ian@0 472 break;
ian@0 473 }
ian@0 474
ian@0 475 /*
ian@0 476 * Account for the space required by the object rounded up to the next
ian@0 477 * multiple of the machine word size. This keeps each object aligned
ian@0 478 * on a machine word boundary. (preventing alignment faults on some
ian@0 479 * machines.)
ian@0 480 */
ian@0 481 *obj_length = ACPI_ROUND_UP_TO_NATIVE_WORD(length);
ian@0 482 return_ACPI_STATUS(status);
ian@0 483 }
ian@0 484
ian@0 485 /*******************************************************************************
ian@0 486 *
ian@0 487 * FUNCTION: acpi_ut_get_element_length
ian@0 488 *
ian@0 489 * PARAMETERS: acpi_pkg_callback
ian@0 490 *
ian@0 491 * RETURN: Status
ian@0 492 *
ian@0 493 * DESCRIPTION: Get the length of one package element.
ian@0 494 *
ian@0 495 ******************************************************************************/
ian@0 496
ian@0 497 static acpi_status
ian@0 498 acpi_ut_get_element_length(u8 object_type,
ian@0 499 union acpi_operand_object *source_object,
ian@0 500 union acpi_generic_state *state, void *context)
ian@0 501 {
ian@0 502 acpi_status status = AE_OK;
ian@0 503 struct acpi_pkg_info *info = (struct acpi_pkg_info *)context;
ian@0 504 acpi_size object_space;
ian@0 505
ian@0 506 switch (object_type) {
ian@0 507 case ACPI_COPY_TYPE_SIMPLE:
ian@0 508
ian@0 509 /*
ian@0 510 * Simple object - just get the size (Null object/entry is handled
ian@0 511 * here also) and sum it into the running package length
ian@0 512 */
ian@0 513 status =
ian@0 514 acpi_ut_get_simple_object_size(source_object,
ian@0 515 &object_space);
ian@0 516 if (ACPI_FAILURE(status)) {
ian@0 517 return (status);
ian@0 518 }
ian@0 519
ian@0 520 info->length += object_space;
ian@0 521 break;
ian@0 522
ian@0 523 case ACPI_COPY_TYPE_PACKAGE:
ian@0 524
ian@0 525 /* Package object - nothing much to do here, let the walk handle it */
ian@0 526
ian@0 527 info->num_packages++;
ian@0 528 state->pkg.this_target_obj = NULL;
ian@0 529 break;
ian@0 530
ian@0 531 default:
ian@0 532
ian@0 533 /* No other types allowed */
ian@0 534
ian@0 535 return (AE_BAD_PARAMETER);
ian@0 536 }
ian@0 537
ian@0 538 return (status);
ian@0 539 }
ian@0 540
ian@0 541 /*******************************************************************************
ian@0 542 *
ian@0 543 * FUNCTION: acpi_ut_get_package_object_size
ian@0 544 *
ian@0 545 * PARAMETERS: internal_object - An ACPI internal object
ian@0 546 * obj_length - Where the length is returned
ian@0 547 *
ian@0 548 * RETURN: Status
ian@0 549 *
ian@0 550 * DESCRIPTION: This function is called to determine the space required to
ian@0 551 * contain a package object for return to an external user.
ian@0 552 *
ian@0 553 * This is moderately complex since a package contains other
ian@0 554 * objects including packages.
ian@0 555 *
ian@0 556 ******************************************************************************/
ian@0 557
ian@0 558 static acpi_status
ian@0 559 acpi_ut_get_package_object_size(union acpi_operand_object *internal_object,
ian@0 560 acpi_size * obj_length)
ian@0 561 {
ian@0 562 acpi_status status;
ian@0 563 struct acpi_pkg_info info;
ian@0 564
ian@0 565 ACPI_FUNCTION_TRACE_PTR(ut_get_package_object_size, internal_object);
ian@0 566
ian@0 567 info.length = 0;
ian@0 568 info.object_space = 0;
ian@0 569 info.num_packages = 1;
ian@0 570
ian@0 571 status = acpi_ut_walk_package_tree(internal_object, NULL,
ian@0 572 acpi_ut_get_element_length, &info);
ian@0 573 if (ACPI_FAILURE(status)) {
ian@0 574 return_ACPI_STATUS(status);
ian@0 575 }
ian@0 576
ian@0 577 /*
ian@0 578 * We have handled all of the objects in all levels of the package.
ian@0 579 * just add the length of the package objects themselves.
ian@0 580 * Round up to the next machine word.
ian@0 581 */
ian@0 582 info.length += ACPI_ROUND_UP_TO_NATIVE_WORD(sizeof(union acpi_object)) *
ian@0 583 (acpi_size) info.num_packages;
ian@0 584
ian@0 585 /* Return the total package length */
ian@0 586
ian@0 587 *obj_length = info.length;
ian@0 588 return_ACPI_STATUS(status);
ian@0 589 }
ian@0 590
ian@0 591 /*******************************************************************************
ian@0 592 *
ian@0 593 * FUNCTION: acpi_ut_get_object_size
ian@0 594 *
ian@0 595 * PARAMETERS: internal_object - An ACPI internal object
ian@0 596 * obj_length - Where the length will be returned
ian@0 597 *
ian@0 598 * RETURN: Status
ian@0 599 *
ian@0 600 * DESCRIPTION: This function is called to determine the space required to
ian@0 601 * contain an object for return to an API user.
ian@0 602 *
ian@0 603 ******************************************************************************/
ian@0 604
ian@0 605 acpi_status
ian@0 606 acpi_ut_get_object_size(union acpi_operand_object *internal_object,
ian@0 607 acpi_size * obj_length)
ian@0 608 {
ian@0 609 acpi_status status;
ian@0 610
ian@0 611 ACPI_FUNCTION_ENTRY();
ian@0 612
ian@0 613 if ((ACPI_GET_DESCRIPTOR_TYPE(internal_object) ==
ian@0 614 ACPI_DESC_TYPE_OPERAND)
ian@0 615 && (ACPI_GET_OBJECT_TYPE(internal_object) == ACPI_TYPE_PACKAGE)) {
ian@0 616 status =
ian@0 617 acpi_ut_get_package_object_size(internal_object,
ian@0 618 obj_length);
ian@0 619 } else {
ian@0 620 status =
ian@0 621 acpi_ut_get_simple_object_size(internal_object, obj_length);
ian@0 622 }
ian@0 623
ian@0 624 return (status);
ian@0 625 }