ia64/linux-2.6.18-xen.hg

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

balloon: try harder to balloon up under memory pressure.

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

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

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

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

Signed-off-by: Ian Campbell <ian.campbell@citrix.com>
author Keir Fraser <keir.fraser@citrix.com>
date Fri Jun 05 14:01:20 2009 +0100 (2009-06-05)
parents 831230e53067
children
line source
1 /*******************************************************************************
2 *
3 * Module Name: nsxfeval - Public interfaces to the ACPI subsystem
4 * ACPI Object evaluation interfaces
5 *
6 ******************************************************************************/
8 /*
9 * Copyright (C) 2000 - 2006, R. Byron Moore
10 * All rights reserved.
11 *
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions
14 * are met:
15 * 1. Redistributions of source code must retain the above copyright
16 * notice, this list of conditions, and the following disclaimer,
17 * without modification.
18 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
19 * substantially similar to the "NO WARRANTY" disclaimer below
20 * ("Disclaimer") and any redistribution must be conditioned upon
21 * including a substantially similar Disclaimer requirement for further
22 * binary redistribution.
23 * 3. Neither the names of the above-listed copyright holders nor the names
24 * of any contributors may be used to endorse or promote products derived
25 * from this software without specific prior written permission.
26 *
27 * Alternatively, this software may be distributed under the terms of the
28 * GNU General Public License ("GPL") version 2 as published by the Free
29 * Software Foundation.
30 *
31 * NO WARRANTY
32 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
33 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
34 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
35 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
36 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
37 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
38 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
39 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
40 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
41 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
42 * POSSIBILITY OF SUCH DAMAGES.
43 */
45 #include <acpi/acpi.h>
46 #include <acpi/acnamesp.h>
47 #include <acpi/acinterp.h>
49 #define _COMPONENT ACPI_NAMESPACE
50 ACPI_MODULE_NAME("nsxfeval")
52 #ifdef ACPI_FUTURE_USAGE
53 /*******************************************************************************
54 *
55 * FUNCTION: acpi_evaluate_object_typed
56 *
57 * PARAMETERS: Handle - Object handle (optional)
58 * Pathname - Object pathname (optional)
59 * external_params - List of parameters to pass to method,
60 * terminated by NULL. May be NULL
61 * if no parameters are being passed.
62 * return_buffer - Where to put method's return value (if
63 * any). If NULL, no value is returned.
64 * return_type - Expected type of return object
65 *
66 * RETURN: Status
67 *
68 * DESCRIPTION: Find and evaluate the given object, passing the given
69 * parameters if necessary. One of "Handle" or "Pathname" must
70 * be valid (non-null)
71 *
72 ******************************************************************************/
73 acpi_status
74 acpi_evaluate_object_typed(acpi_handle handle,
75 acpi_string pathname,
76 struct acpi_object_list * external_params,
77 struct acpi_buffer * return_buffer,
78 acpi_object_type return_type)
79 {
80 acpi_status status;
81 u8 must_free = FALSE;
83 ACPI_FUNCTION_TRACE(acpi_evaluate_object_typed);
85 /* Return buffer must be valid */
87 if (!return_buffer) {
88 return_ACPI_STATUS(AE_BAD_PARAMETER);
89 }
91 if (return_buffer->length == ACPI_ALLOCATE_BUFFER) {
92 must_free = TRUE;
93 }
95 /* Evaluate the object */
97 status =
98 acpi_evaluate_object(handle, pathname, external_params,
99 return_buffer);
100 if (ACPI_FAILURE(status)) {
101 return_ACPI_STATUS(status);
102 }
104 /* Type ANY means "don't care" */
106 if (return_type == ACPI_TYPE_ANY) {
107 return_ACPI_STATUS(AE_OK);
108 }
110 if (return_buffer->length == 0) {
112 /* Error because caller specifically asked for a return value */
114 ACPI_ERROR((AE_INFO, "No return value"));
115 return_ACPI_STATUS(AE_NULL_OBJECT);
116 }
118 /* Examine the object type returned from evaluate_object */
120 if (((union acpi_object *)return_buffer->pointer)->type == return_type) {
121 return_ACPI_STATUS(AE_OK);
122 }
124 /* Return object type does not match requested type */
126 ACPI_ERROR((AE_INFO,
127 "Incorrect return type [%s] requested [%s]",
128 acpi_ut_get_type_name(((union acpi_object *)return_buffer->
129 pointer)->type),
130 acpi_ut_get_type_name(return_type)));
132 if (must_free) {
134 /* Caller used ACPI_ALLOCATE_BUFFER, free the return buffer */
136 ACPI_FREE(return_buffer->pointer);
137 return_buffer->pointer = NULL;
138 }
140 return_buffer->length = 0;
141 return_ACPI_STATUS(AE_TYPE);
142 }
144 ACPI_EXPORT_SYMBOL(acpi_evaluate_object_typed)
145 #endif /* ACPI_FUTURE_USAGE */
147 /*******************************************************************************
148 *
149 * FUNCTION: acpi_evaluate_object
150 *
151 * PARAMETERS: Handle - Object handle (optional)
152 * Pathname - Object pathname (optional)
153 * external_params - List of parameters to pass to method,
154 * terminated by NULL. May be NULL
155 * if no parameters are being passed.
156 * return_buffer - Where to put method's return value (if
157 * any). If NULL, no value is returned.
158 *
159 * RETURN: Status
160 *
161 * DESCRIPTION: Find and evaluate the given object, passing the given
162 * parameters if necessary. One of "Handle" or "Pathname" must
163 * be valid (non-null)
164 *
165 ******************************************************************************/
166 acpi_status
167 acpi_evaluate_object(acpi_handle handle,
168 acpi_string pathname,
169 struct acpi_object_list *external_params,
170 struct acpi_buffer *return_buffer)
171 {
172 acpi_status status;
173 acpi_status status2;
174 struct acpi_evaluate_info *info;
175 acpi_size buffer_space_needed;
176 u32 i;
178 ACPI_FUNCTION_TRACE(acpi_evaluate_object);
180 /* Allocate and initialize the evaluation information block */
182 info = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_evaluate_info));
183 if (!info) {
184 return_ACPI_STATUS(AE_NO_MEMORY);
185 }
187 info->pathname = pathname;
188 info->parameter_type = ACPI_PARAM_ARGS;
190 /* Convert and validate the device handle */
192 info->prefix_node = acpi_ns_map_handle_to_node(handle);
193 if (!info->prefix_node) {
194 status = AE_BAD_PARAMETER;
195 goto cleanup;
196 }
198 /*
199 * If there are parameters to be passed to a control method, the external
200 * objects must all be converted to internal objects
201 */
202 if (external_params && external_params->count) {
203 /*
204 * Allocate a new parameter block for the internal objects
205 * Add 1 to count to allow for null terminated internal list
206 */
207 info->parameters = ACPI_ALLOCATE_ZEROED(((acpi_size)
208 external_params->
209 count +
210 1) * sizeof(void *));
211 if (!info->parameters) {
212 status = AE_NO_MEMORY;
213 goto cleanup;
214 }
216 /* Convert each external object in the list to an internal object */
218 for (i = 0; i < external_params->count; i++) {
219 status =
220 acpi_ut_copy_eobject_to_iobject(&external_params->
221 pointer[i],
222 &info->
223 parameters[i]);
224 if (ACPI_FAILURE(status)) {
225 goto cleanup;
226 }
227 }
228 info->parameters[external_params->count] = NULL;
229 }
231 /*
232 * Three major cases:
233 * 1) Fully qualified pathname
234 * 2) No handle, not fully qualified pathname (error)
235 * 3) Valid handle
236 */
237 if ((pathname) && (acpi_ns_valid_root_prefix(pathname[0]))) {
239 /* The path is fully qualified, just evaluate by name */
241 info->prefix_node = NULL;
242 status = acpi_ns_evaluate(info);
243 } else if (!handle) {
244 /*
245 * A handle is optional iff a fully qualified pathname is specified.
246 * Since we've already handled fully qualified names above, this is
247 * an error
248 */
249 if (!pathname) {
250 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
251 "Both Handle and Pathname are NULL"));
252 } else {
253 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
254 "Null Handle with relative pathname [%s]",
255 pathname));
256 }
258 status = AE_BAD_PARAMETER;
259 } else {
260 /* We have a namespace a node and a possible relative path */
262 status = acpi_ns_evaluate(info);
263 }
265 /*
266 * If we are expecting a return value, and all went well above,
267 * copy the return value to an external object.
268 */
269 if (return_buffer) {
270 if (!info->return_object) {
271 return_buffer->length = 0;
272 } else {
273 if (ACPI_GET_DESCRIPTOR_TYPE(info->return_object) ==
274 ACPI_DESC_TYPE_NAMED) {
275 /*
276 * If we received a NS Node as a return object, this means that
277 * the object we are evaluating has nothing interesting to
278 * return (such as a mutex, etc.) We return an error because
279 * these types are essentially unsupported by this interface.
280 * We don't check up front because this makes it easier to add
281 * support for various types at a later date if necessary.
282 */
283 status = AE_TYPE;
284 info->return_object = NULL; /* No need to delete a NS Node */
285 return_buffer->length = 0;
286 }
288 if (ACPI_SUCCESS(status)) {
290 /* Get the size of the returned object */
292 status =
293 acpi_ut_get_object_size(info->return_object,
294 &buffer_space_needed);
295 if (ACPI_SUCCESS(status)) {
297 /* Validate/Allocate/Clear caller buffer */
299 status =
300 acpi_ut_initialize_buffer
301 (return_buffer,
302 buffer_space_needed);
303 if (ACPI_FAILURE(status)) {
304 /*
305 * Caller's buffer is too small or a new one can't
306 * be allocated
307 */
308 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
309 "Needed buffer size %X, %s\n",
310 (u32)
311 buffer_space_needed,
312 acpi_format_exception
313 (status)));
314 } else {
315 /* We have enough space for the object, build it */
317 status =
318 acpi_ut_copy_iobject_to_eobject
319 (info->return_object,
320 return_buffer);
321 }
322 }
323 }
324 }
325 }
327 if (info->return_object) {
328 /*
329 * Delete the internal return object. NOTE: Interpreter must be
330 * locked to avoid race condition.
331 */
332 status2 = acpi_ex_enter_interpreter();
333 if (ACPI_SUCCESS(status2)) {
335 /* Remove one reference on the return object (should delete it) */
337 acpi_ut_remove_reference(info->return_object);
338 acpi_ex_exit_interpreter();
339 }
340 }
342 cleanup:
344 /* Free the input parameter list (if we created one) */
346 if (info->parameters) {
348 /* Free the allocated parameter block */
350 acpi_ut_delete_internal_object_list(info->parameters);
351 }
353 ACPI_FREE(info);
354 return_ACPI_STATUS(status);
355 }
357 ACPI_EXPORT_SYMBOL(acpi_evaluate_object)
359 /*******************************************************************************
360 *
361 * FUNCTION: acpi_walk_namespace
362 *
363 * PARAMETERS: Type - acpi_object_type to search for
364 * start_object - Handle in namespace where search begins
365 * max_depth - Depth to which search is to reach
366 * user_function - Called when an object of "Type" is found
367 * Context - Passed to user function
368 * return_value - Location where return value of
369 * user_function is put if terminated early
370 *
371 * RETURNS Return value from the user_function if terminated early.
372 * Otherwise, returns NULL.
373 *
374 * DESCRIPTION: Performs a modified depth-first walk of the namespace tree,
375 * starting (and ending) at the object specified by start_handle.
376 * The user_function is called whenever an object that matches
377 * the type parameter is found. If the user function returns
378 * a non-zero value, the search is terminated immediately and this
379 * value is returned to the caller.
380 *
381 * The point of this procedure is to provide a generic namespace
382 * walk routine that can be called from multiple places to
383 * provide multiple services; the User Function can be tailored
384 * to each task, whether it is a print function, a compare
385 * function, etc.
386 *
387 ******************************************************************************/
388 acpi_status
389 acpi_walk_namespace(acpi_object_type type,
390 acpi_handle start_object,
391 u32 max_depth,
392 acpi_walk_callback user_function,
393 void *context, void **return_value)
394 {
395 acpi_status status;
397 ACPI_FUNCTION_TRACE(acpi_walk_namespace);
399 /* Parameter validation */
401 if ((type > ACPI_TYPE_LOCAL_MAX) || (!max_depth) || (!user_function)) {
402 return_ACPI_STATUS(AE_BAD_PARAMETER);
403 }
405 /*
406 * Lock the namespace around the walk.
407 * The namespace will be unlocked/locked around each call
408 * to the user function - since this function
409 * must be allowed to make Acpi calls itself.
410 */
411 status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
412 if (ACPI_FAILURE(status)) {
413 return_ACPI_STATUS(status);
414 }
416 status = acpi_ns_walk_namespace(type, start_object, max_depth,
417 ACPI_NS_WALK_UNLOCK,
418 user_function, context, return_value);
420 (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
421 return_ACPI_STATUS(status);
422 }
424 ACPI_EXPORT_SYMBOL(acpi_walk_namespace)
426 /*******************************************************************************
427 *
428 * FUNCTION: acpi_ns_get_device_callback
429 *
430 * PARAMETERS: Callback from acpi_get_device
431 *
432 * RETURN: Status
433 *
434 * DESCRIPTION: Takes callbacks from walk_namespace and filters out all non-
435 * present devices, or if they specified a HID, it filters based
436 * on that.
437 *
438 ******************************************************************************/
439 static acpi_status
440 acpi_ns_get_device_callback(acpi_handle obj_handle,
441 u32 nesting_level,
442 void *context, void **return_value)
443 {
444 struct acpi_get_devices_info *info = context;
445 acpi_status status;
446 struct acpi_namespace_node *node;
447 u32 flags;
448 struct acpi_device_id hid;
449 struct acpi_compatible_id_list *cid;
450 acpi_native_uint i;
452 status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
453 if (ACPI_FAILURE(status)) {
454 return (status);
455 }
457 node = acpi_ns_map_handle_to_node(obj_handle);
458 status = acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
459 if (ACPI_FAILURE(status)) {
460 return (status);
461 }
463 if (!node) {
464 return (AE_BAD_PARAMETER);
465 }
467 /* Run _STA to determine if device is present */
469 status = acpi_ut_execute_STA(node, &flags);
470 if (ACPI_FAILURE(status)) {
471 return (AE_CTRL_DEPTH);
472 }
474 if (!(flags & ACPI_STA_DEVICE_PRESENT)) {
476 /* Don't examine children of the device if not present */
478 return (AE_CTRL_DEPTH);
479 }
481 /* Filter based on device HID & CID */
483 if (info->hid != NULL) {
484 status = acpi_ut_execute_HID(node, &hid);
485 if (status == AE_NOT_FOUND) {
486 return (AE_OK);
487 } else if (ACPI_FAILURE(status)) {
488 return (AE_CTRL_DEPTH);
489 }
491 if (ACPI_STRNCMP(hid.value, info->hid, sizeof(hid.value)) != 0) {
493 /* Get the list of Compatible IDs */
495 status = acpi_ut_execute_CID(node, &cid);
496 if (status == AE_NOT_FOUND) {
497 return (AE_OK);
498 } else if (ACPI_FAILURE(status)) {
499 return (AE_CTRL_DEPTH);
500 }
502 /* Walk the CID list */
504 for (i = 0; i < cid->count; i++) {
505 if (ACPI_STRNCMP(cid->id[i].value, info->hid,
506 sizeof(struct
507 acpi_compatible_id)) !=
508 0) {
509 ACPI_FREE(cid);
510 return (AE_OK);
511 }
512 }
513 ACPI_FREE(cid);
514 }
515 }
517 status = info->user_function(obj_handle, nesting_level, info->context,
518 return_value);
519 return (status);
520 }
522 /*******************************************************************************
523 *
524 * FUNCTION: acpi_get_devices
525 *
526 * PARAMETERS: HID - HID to search for. Can be NULL.
527 * user_function - Called when a matching object is found
528 * Context - Passed to user function
529 * return_value - Location where return value of
530 * user_function is put if terminated early
531 *
532 * RETURNS Return value from the user_function if terminated early.
533 * Otherwise, returns NULL.
534 *
535 * DESCRIPTION: Performs a modified depth-first walk of the namespace tree,
536 * starting (and ending) at the object specified by start_handle.
537 * The user_function is called whenever an object of type
538 * Device is found. If the user function returns
539 * a non-zero value, the search is terminated immediately and this
540 * value is returned to the caller.
541 *
542 * This is a wrapper for walk_namespace, but the callback performs
543 * additional filtering. Please see acpi_get_device_callback.
544 *
545 ******************************************************************************/
547 acpi_status
548 acpi_get_devices(char *HID,
549 acpi_walk_callback user_function,
550 void *context, void **return_value)
551 {
552 acpi_status status;
553 struct acpi_get_devices_info info;
555 ACPI_FUNCTION_TRACE(acpi_get_devices);
557 /* Parameter validation */
559 if (!user_function) {
560 return_ACPI_STATUS(AE_BAD_PARAMETER);
561 }
563 /*
564 * We're going to call their callback from OUR callback, so we need
565 * to know what it is, and their context parameter.
566 */
567 info.hid = HID;
568 info.context = context;
569 info.user_function = user_function;
571 /*
572 * Lock the namespace around the walk.
573 * The namespace will be unlocked/locked around each call
574 * to the user function - since this function
575 * must be allowed to make Acpi calls itself.
576 */
577 status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
578 if (ACPI_FAILURE(status)) {
579 return_ACPI_STATUS(status);
580 }
582 status = acpi_ns_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
583 ACPI_UINT32_MAX, ACPI_NS_WALK_UNLOCK,
584 acpi_ns_get_device_callback, &info,
585 return_value);
587 (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
588 return_ACPI_STATUS(status);
589 }
591 ACPI_EXPORT_SYMBOL(acpi_get_devices)
593 /*******************************************************************************
594 *
595 * FUNCTION: acpi_attach_data
596 *
597 * PARAMETERS: obj_handle - Namespace node
598 * Handler - Handler for this attachment
599 * Data - Pointer to data to be attached
600 *
601 * RETURN: Status
602 *
603 * DESCRIPTION: Attach arbitrary data and handler to a namespace node.
604 *
605 ******************************************************************************/
606 acpi_status
607 acpi_attach_data(acpi_handle obj_handle,
608 acpi_object_handler handler, void *data)
609 {
610 struct acpi_namespace_node *node;
611 acpi_status status;
613 /* Parameter validation */
615 if (!obj_handle || !handler || !data) {
616 return (AE_BAD_PARAMETER);
617 }
619 status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
620 if (ACPI_FAILURE(status)) {
621 return (status);
622 }
624 /* Convert and validate the handle */
626 node = acpi_ns_map_handle_to_node(obj_handle);
627 if (!node) {
628 status = AE_BAD_PARAMETER;
629 goto unlock_and_exit;
630 }
632 status = acpi_ns_attach_data(node, handler, data);
634 unlock_and_exit:
635 (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
636 return (status);
637 }
639 ACPI_EXPORT_SYMBOL(acpi_attach_data)
641 /*******************************************************************************
642 *
643 * FUNCTION: acpi_detach_data
644 *
645 * PARAMETERS: obj_handle - Namespace node handle
646 * Handler - Handler used in call to acpi_attach_data
647 *
648 * RETURN: Status
649 *
650 * DESCRIPTION: Remove data that was previously attached to a node.
651 *
652 ******************************************************************************/
653 acpi_status
654 acpi_detach_data(acpi_handle obj_handle, acpi_object_handler handler)
655 {
656 struct acpi_namespace_node *node;
657 acpi_status status;
659 /* Parameter validation */
661 if (!obj_handle || !handler) {
662 return (AE_BAD_PARAMETER);
663 }
665 status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
666 if (ACPI_FAILURE(status)) {
667 return (status);
668 }
670 /* Convert and validate the handle */
672 node = acpi_ns_map_handle_to_node(obj_handle);
673 if (!node) {
674 status = AE_BAD_PARAMETER;
675 goto unlock_and_exit;
676 }
678 status = acpi_ns_detach_data(node, handler);
680 unlock_and_exit:
681 (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
682 return (status);
683 }
685 ACPI_EXPORT_SYMBOL(acpi_detach_data)
687 /*******************************************************************************
688 *
689 * FUNCTION: acpi_get_data
690 *
691 * PARAMETERS: obj_handle - Namespace node
692 * Handler - Handler used in call to attach_data
693 * Data - Where the data is returned
694 *
695 * RETURN: Status
696 *
697 * DESCRIPTION: Retrieve data that was previously attached to a namespace node.
698 *
699 ******************************************************************************/
700 acpi_status
701 acpi_get_data(acpi_handle obj_handle, acpi_object_handler handler, void **data)
702 {
703 struct acpi_namespace_node *node;
704 acpi_status status;
706 /* Parameter validation */
708 if (!obj_handle || !handler || !data) {
709 return (AE_BAD_PARAMETER);
710 }
712 status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
713 if (ACPI_FAILURE(status)) {
714 return (status);
715 }
717 /* Convert and validate the handle */
719 node = acpi_ns_map_handle_to_node(obj_handle);
720 if (!node) {
721 status = AE_BAD_PARAMETER;
722 goto unlock_and_exit;
723 }
725 status = acpi_ns_get_attached_data(node, handler, data);
727 unlock_and_exit:
728 (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
729 return (status);
730 }
732 ACPI_EXPORT_SYMBOL(acpi_get_data)