1/* 2 * acpi_utils.c - ACPI Utility Functions ($Revision: 10 $) 3 * 4 * Copyright (C) 2001, 2002 Andy Grover <andrew.grover@intel.com> 5 * Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com> 6 * 7 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 8 * 9 * This program is free software; you can redistribute it and/or modify 10 * it under the terms of the GNU General Public License as published by 11 * the Free Software Foundation; either version 2 of the License, or (at 12 * your option) any later version. 13 * 14 * This program is distributed in the hope that it will be useful, but 15 * WITHOUT ANY WARRANTY; without even the implied warranty of 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 17 * General Public License for more details. 18 * 19 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 20 */ 21 22#include <linux/kernel.h> 23#include <linux/module.h> 24#include <linux/slab.h> 25#include <linux/init.h> 26#include <linux/types.h> 27#include <linux/hardirq.h> 28#include <linux/acpi.h> 29#include <linux/dynamic_debug.h> 30 31#include "internal.h" 32 33#define _COMPONENT ACPI_BUS_COMPONENT 34ACPI_MODULE_NAME("utils"); 35 36/* -------------------------------------------------------------------------- 37 Object Evaluation Helpers 38 -------------------------------------------------------------------------- */ 39static void 40acpi_util_eval_error(acpi_handle h, acpi_string p, acpi_status s) 41{ 42#ifdef ACPI_DEBUG_OUTPUT 43 char prefix[80] = {'\0'}; 44 struct acpi_buffer buffer = {sizeof(prefix), prefix}; 45 acpi_get_name(h, ACPI_FULL_PATHNAME, &buffer); 46 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Evaluate [%s.%s]: %s\n", 47 (char *) prefix, p, acpi_format_exception(s))); 48#else 49 return; 50#endif 51} 52 53acpi_status 54acpi_extract_package(union acpi_object *package, 55 struct acpi_buffer *format, struct acpi_buffer *buffer) 56{ 57 u32 size_required = 0; 58 u32 tail_offset = 0; 59 char *format_string = NULL; 60 u32 format_count = 0; 61 u32 i = 0; 62 u8 *head = NULL; 63 u8 *tail = NULL; 64 65 66 if (!package || (package->type != ACPI_TYPE_PACKAGE) 67 || (package->package.count < 1)) { 68 printk(KERN_WARNING PREFIX "Invalid package argument\n"); 69 return AE_BAD_PARAMETER; 70 } 71 72 if (!format || !format->pointer || (format->length < 1)) { 73 printk(KERN_WARNING PREFIX "Invalid format argument\n"); 74 return AE_BAD_PARAMETER; 75 } 76 77 if (!buffer) { 78 printk(KERN_WARNING PREFIX "Invalid buffer argument\n"); 79 return AE_BAD_PARAMETER; 80 } 81 82 format_count = (format->length / sizeof(char)) - 1; 83 if (format_count > package->package.count) { 84 printk(KERN_WARNING PREFIX "Format specifies more objects [%d]" 85 " than exist in package [%d].\n", 86 format_count, package->package.count); 87 return AE_BAD_DATA; 88 } 89 90 format_string = format->pointer; 91 92 /* 93 * Calculate size_required. 94 */ 95 for (i = 0; i < format_count; i++) { 96 97 union acpi_object *element = &(package->package.elements[i]); 98 99 switch (element->type) { 100 101 case ACPI_TYPE_INTEGER: 102 switch (format_string[i]) { 103 case 'N': 104 size_required += sizeof(u64); 105 tail_offset += sizeof(u64); 106 break; 107 case 'S': 108 size_required += 109 sizeof(char *) + sizeof(u64) + 110 sizeof(char); 111 tail_offset += sizeof(char *); 112 break; 113 default: 114 printk(KERN_WARNING PREFIX "Invalid package element" 115 " [%d]: got number, expecting" 116 " [%c]\n", 117 i, format_string[i]); 118 return AE_BAD_DATA; 119 break; 120 } 121 break; 122 123 case ACPI_TYPE_STRING: 124 case ACPI_TYPE_BUFFER: 125 switch (format_string[i]) { 126 case 'S': 127 size_required += 128 sizeof(char *) + 129 (element->string.length * sizeof(char)) + 130 sizeof(char); 131 tail_offset += sizeof(char *); 132 break; 133 case 'B': 134 size_required += 135 sizeof(u8 *) + element->buffer.length; 136 tail_offset += sizeof(u8 *); 137 break; 138 default: 139 printk(KERN_WARNING PREFIX "Invalid package element" 140 " [%d] got string/buffer," 141 " expecting [%c]\n", 142 i, format_string[i]); 143 return AE_BAD_DATA; 144 break; 145 } 146 break; 147 case ACPI_TYPE_LOCAL_REFERENCE: 148 switch (format_string[i]) { 149 case 'R': 150 size_required += sizeof(void *); 151 tail_offset += sizeof(void *); 152 break; 153 default: 154 printk(KERN_WARNING PREFIX "Invalid package element" 155 " [%d] got reference," 156 " expecting [%c]\n", 157 i, format_string[i]); 158 return AE_BAD_DATA; 159 break; 160 } 161 break; 162 163 case ACPI_TYPE_PACKAGE: 164 default: 165 ACPI_DEBUG_PRINT((ACPI_DB_INFO, 166 "Found unsupported element at index=%d\n", 167 i)); 168 /* TBD: handle nested packages... */ 169 return AE_SUPPORT; 170 break; 171 } 172 } 173 174 /* 175 * Validate output buffer. 176 */ 177 if (buffer->length == ACPI_ALLOCATE_BUFFER) { 178 buffer->pointer = ACPI_ALLOCATE_ZEROED(size_required); 179 if (!buffer->pointer) 180 return AE_NO_MEMORY; 181 buffer->length = size_required; 182 } else { 183 if (buffer->length < size_required) { 184 buffer->length = size_required; 185 return AE_BUFFER_OVERFLOW; 186 } else if (buffer->length != size_required || 187 !buffer->pointer) { 188 return AE_BAD_PARAMETER; 189 } 190 } 191 192 head = buffer->pointer; 193 tail = buffer->pointer + tail_offset; 194 195 /* 196 * Extract package data. 197 */ 198 for (i = 0; i < format_count; i++) { 199 200 u8 **pointer = NULL; 201 union acpi_object *element = &(package->package.elements[i]); 202 203 if (!element) { 204 return AE_BAD_DATA; 205 } 206 207 switch (element->type) { 208 209 case ACPI_TYPE_INTEGER: 210 switch (format_string[i]) { 211 case 'N': 212 *((u64 *) head) = 213 element->integer.value; 214 head += sizeof(u64); 215 break; 216 case 'S': 217 pointer = (u8 **) head; 218 *pointer = tail; 219 *((u64 *) tail) = 220 element->integer.value; 221 head += sizeof(u64 *); 222 tail += sizeof(u64); 223 /* NULL terminate string */ 224 *tail = (char)0; 225 tail += sizeof(char); 226 break; 227 default: 228 /* Should never get here */ 229 break; 230 } 231 break; 232 233 case ACPI_TYPE_STRING: 234 case ACPI_TYPE_BUFFER: 235 switch (format_string[i]) { 236 case 'S': 237 pointer = (u8 **) head; 238 *pointer = tail; 239 memcpy(tail, element->string.pointer, 240 element->string.length); 241 head += sizeof(char *); 242 tail += element->string.length * sizeof(char); 243 /* NULL terminate string */ 244 *tail = (char)0; 245 tail += sizeof(char); 246 break; 247 case 'B': 248 pointer = (u8 **) head; 249 *pointer = tail; 250 memcpy(tail, element->buffer.pointer, 251 element->buffer.length); 252 head += sizeof(u8 *); 253 tail += element->buffer.length; 254 break; 255 default: 256 /* Should never get here */ 257 break; 258 } 259 break; 260 case ACPI_TYPE_LOCAL_REFERENCE: 261 switch (format_string[i]) { 262 case 'R': 263 *(void **)head = 264 (void *)element->reference.handle; 265 head += sizeof(void *); 266 break; 267 default: 268 /* Should never get here */ 269 break; 270 } 271 break; 272 case ACPI_TYPE_PACKAGE: 273 /* TBD: handle nested packages... */ 274 default: 275 /* Should never get here */ 276 break; 277 } 278 } 279 280 return AE_OK; 281} 282 283EXPORT_SYMBOL(acpi_extract_package); 284 285acpi_status 286acpi_evaluate_integer(acpi_handle handle, 287 acpi_string pathname, 288 struct acpi_object_list *arguments, unsigned long long *data) 289{ 290 acpi_status status = AE_OK; 291 union acpi_object element; 292 struct acpi_buffer buffer = { 0, NULL }; 293 294 if (!data) 295 return AE_BAD_PARAMETER; 296 297 buffer.length = sizeof(union acpi_object); 298 buffer.pointer = &element; 299 status = acpi_evaluate_object(handle, pathname, arguments, &buffer); 300 if (ACPI_FAILURE(status)) { 301 acpi_util_eval_error(handle, pathname, status); 302 return status; 303 } 304 305 if (element.type != ACPI_TYPE_INTEGER) { 306 acpi_util_eval_error(handle, pathname, AE_BAD_DATA); 307 return AE_BAD_DATA; 308 } 309 310 *data = element.integer.value; 311 312 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Return value [%llu]\n", *data)); 313 314 return AE_OK; 315} 316 317EXPORT_SYMBOL(acpi_evaluate_integer); 318 319acpi_status 320acpi_evaluate_reference(acpi_handle handle, 321 acpi_string pathname, 322 struct acpi_object_list *arguments, 323 struct acpi_handle_list *list) 324{ 325 acpi_status status = AE_OK; 326 union acpi_object *package = NULL; 327 union acpi_object *element = NULL; 328 struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; 329 u32 i = 0; 330 331 332 if (!list) { 333 return AE_BAD_PARAMETER; 334 } 335 336 /* Evaluate object. */ 337 338 status = acpi_evaluate_object(handle, pathname, arguments, &buffer); 339 if (ACPI_FAILURE(status)) 340 goto end; 341 342 package = buffer.pointer; 343 344 if ((buffer.length == 0) || !package) { 345 status = AE_BAD_DATA; 346 acpi_util_eval_error(handle, pathname, status); 347 goto end; 348 } 349 if (package->type != ACPI_TYPE_PACKAGE) { 350 status = AE_BAD_DATA; 351 acpi_util_eval_error(handle, pathname, status); 352 goto end; 353 } 354 if (!package->package.count) { 355 status = AE_BAD_DATA; 356 acpi_util_eval_error(handle, pathname, status); 357 goto end; 358 } 359 360 if (package->package.count > ACPI_MAX_HANDLES) { 361 return AE_NO_MEMORY; 362 } 363 list->count = package->package.count; 364 365 /* Extract package data. */ 366 367 for (i = 0; i < list->count; i++) { 368 369 element = &(package->package.elements[i]); 370 371 if (element->type != ACPI_TYPE_LOCAL_REFERENCE) { 372 status = AE_BAD_DATA; 373 acpi_util_eval_error(handle, pathname, status); 374 break; 375 } 376 377 if (!element->reference.handle) { 378 status = AE_NULL_ENTRY; 379 acpi_util_eval_error(handle, pathname, status); 380 break; 381 } 382 /* Get the acpi_handle. */ 383 384 list->handles[i] = element->reference.handle; 385 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found reference [%p]\n", 386 list->handles[i])); 387 } 388 389 end: 390 if (ACPI_FAILURE(status)) { 391 list->count = 0; 392 //kfree(list->handles); 393 } 394 395 kfree(buffer.pointer); 396 397 return status; 398} 399 400EXPORT_SYMBOL(acpi_evaluate_reference); 401 402acpi_status 403acpi_get_physical_device_location(acpi_handle handle, struct acpi_pld_info **pld) 404{ 405 acpi_status status; 406 struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; 407 union acpi_object *output; 408 409 status = acpi_evaluate_object(handle, "_PLD", NULL, &buffer); 410 411 if (ACPI_FAILURE(status)) 412 return status; 413 414 output = buffer.pointer; 415 416 if (!output || output->type != ACPI_TYPE_PACKAGE 417 || !output->package.count 418 || output->package.elements[0].type != ACPI_TYPE_BUFFER 419 || output->package.elements[0].buffer.length < ACPI_PLD_REV1_BUFFER_SIZE) { 420 status = AE_TYPE; 421 goto out; 422 } 423 424 status = acpi_decode_pld_buffer( 425 output->package.elements[0].buffer.pointer, 426 output->package.elements[0].buffer.length, 427 pld); 428 429out: 430 kfree(buffer.pointer); 431 return status; 432} 433EXPORT_SYMBOL(acpi_get_physical_device_location); 434 435/** 436 * acpi_evaluate_ost: Evaluate _OST for hotplug operations 437 * @handle: ACPI device handle 438 * @source_event: source event code 439 * @status_code: status code 440 * @status_buf: optional detailed information (NULL if none) 441 * 442 * Evaluate _OST for hotplug operations. All ACPI hotplug handlers 443 * must call this function when evaluating _OST for hotplug operations. 444 * When the platform does not support _OST, this function has no effect. 445 */ 446acpi_status 447acpi_evaluate_ost(acpi_handle handle, u32 source_event, u32 status_code, 448 struct acpi_buffer *status_buf) 449{ 450 union acpi_object params[3] = { 451 {.type = ACPI_TYPE_INTEGER,}, 452 {.type = ACPI_TYPE_INTEGER,}, 453 {.type = ACPI_TYPE_BUFFER,} 454 }; 455 struct acpi_object_list arg_list = {3, params}; 456 457 params[0].integer.value = source_event; 458 params[1].integer.value = status_code; 459 if (status_buf != NULL) { 460 params[2].buffer.pointer = status_buf->pointer; 461 params[2].buffer.length = status_buf->length; 462 } else { 463 params[2].buffer.pointer = NULL; 464 params[2].buffer.length = 0; 465 } 466 467 return acpi_evaluate_object(handle, "_OST", &arg_list, NULL); 468} 469EXPORT_SYMBOL(acpi_evaluate_ost); 470 471/** 472 * acpi_handle_path: Return the object path of handle 473 * 474 * Caller must free the returned buffer 475 */ 476static char *acpi_handle_path(acpi_handle handle) 477{ 478 struct acpi_buffer buffer = { 479 .length = ACPI_ALLOCATE_BUFFER, 480 .pointer = NULL 481 }; 482 483 if (in_interrupt() || 484 acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer) != AE_OK) 485 return NULL; 486 return buffer.pointer; 487} 488 489/** 490 * acpi_handle_printk: Print message with ACPI prefix and object path 491 * 492 * This function is called through acpi_handle_<level> macros and prints 493 * a message with ACPI prefix and object path. This function acquires 494 * the global namespace mutex to obtain an object path. In interrupt 495 * context, it shows the object path as <n/a>. 496 */ 497void 498acpi_handle_printk(const char *level, acpi_handle handle, const char *fmt, ...) 499{ 500 struct va_format vaf; 501 va_list args; 502 const char *path; 503 504 va_start(args, fmt); 505 vaf.fmt = fmt; 506 vaf.va = &args; 507 508 path = acpi_handle_path(handle); 509 printk("%sACPI: %s: %pV", level, path ? path : "<n/a>" , &vaf); 510 511 va_end(args); 512 kfree(path); 513} 514EXPORT_SYMBOL(acpi_handle_printk); 515 516#if defined(CONFIG_DYNAMIC_DEBUG) 517/** 518 * __acpi_handle_debug: pr_debug with ACPI prefix and object path 519 * 520 * This function is called through acpi_handle_debug macro and debug 521 * prints a message with ACPI prefix and object path. This function 522 * acquires the global namespace mutex to obtain an object path. In 523 * interrupt context, it shows the object path as <n/a>. 524 */ 525void 526__acpi_handle_debug(struct _ddebug *descriptor, acpi_handle handle, 527 const char *fmt, ...) 528{ 529 struct va_format vaf; 530 va_list args; 531 const char *path; 532 533 va_start(args, fmt); 534 vaf.fmt = fmt; 535 vaf.va = &args; 536 537 path = acpi_handle_path(handle); 538 __dynamic_pr_debug(descriptor, "ACPI: %s: %pV", path ? path : "<n/a>", &vaf); 539 540 va_end(args); 541 kfree(path); 542} 543EXPORT_SYMBOL(__acpi_handle_debug); 544#endif 545 546/** 547 * acpi_has_method: Check whether @handle has a method named @name 548 * @handle: ACPI device handle 549 * @name: name of object or method 550 * 551 * Check whether @handle has a method named @name. 552 */ 553bool acpi_has_method(acpi_handle handle, char *name) 554{ 555 acpi_handle tmp; 556 557 return ACPI_SUCCESS(acpi_get_handle(handle, name, &tmp)); 558} 559EXPORT_SYMBOL(acpi_has_method); 560 561acpi_status acpi_execute_simple_method(acpi_handle handle, char *method, 562 u64 arg) 563{ 564 union acpi_object obj = { .type = ACPI_TYPE_INTEGER }; 565 struct acpi_object_list arg_list = { .count = 1, .pointer = &obj, }; 566 567 obj.integer.value = arg; 568 569 return acpi_evaluate_object(handle, method, &arg_list, NULL); 570} 571EXPORT_SYMBOL(acpi_execute_simple_method); 572 573/** 574 * acpi_evaluate_ej0: Evaluate _EJ0 method for hotplug operations 575 * @handle: ACPI device handle 576 * 577 * Evaluate device's _EJ0 method for hotplug operations. 578 */ 579acpi_status acpi_evaluate_ej0(acpi_handle handle) 580{ 581 acpi_status status; 582 583 status = acpi_execute_simple_method(handle, "_EJ0", 1); 584 if (status == AE_NOT_FOUND) 585 acpi_handle_warn(handle, "No _EJ0 support for device\n"); 586 else if (ACPI_FAILURE(status)) 587 acpi_handle_warn(handle, "Eject failed (0x%x)\n", status); 588 589 return status; 590} 591 592/** 593 * acpi_evaluate_lck: Evaluate _LCK method to lock/unlock device 594 * @handle: ACPI device handle 595 * @lock: lock device if non-zero, otherwise unlock device 596 * 597 * Evaluate device's _LCK method if present to lock/unlock device 598 */ 599acpi_status acpi_evaluate_lck(acpi_handle handle, int lock) 600{ 601 acpi_status status; 602 603 status = acpi_execute_simple_method(handle, "_LCK", !!lock); 604 if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) { 605 if (lock) 606 acpi_handle_warn(handle, 607 "Locking device failed (0x%x)\n", status); 608 else 609 acpi_handle_warn(handle, 610 "Unlocking device failed (0x%x)\n", status); 611 } 612 613 return status; 614} 615 616/** 617 * acpi_evaluate_dsm - evaluate device's _DSM method 618 * @handle: ACPI device handle 619 * @uuid: UUID of requested functions, should be 16 bytes 620 * @rev: revision number of requested function 621 * @func: requested function number 622 * @argv4: the function specific parameter 623 * 624 * Evaluate device's _DSM method with specified UUID, revision id and 625 * function number. Caller needs to free the returned object. 626 * 627 * Though ACPI defines the fourth parameter for _DSM should be a package, 628 * some old BIOSes do expect a buffer or an integer etc. 629 */ 630union acpi_object * 631acpi_evaluate_dsm(acpi_handle handle, const u8 *uuid, int rev, int func, 632 union acpi_object *argv4) 633{ 634 acpi_status ret; 635 struct acpi_buffer buf = {ACPI_ALLOCATE_BUFFER, NULL}; 636 union acpi_object params[4]; 637 struct acpi_object_list input = { 638 .count = 4, 639 .pointer = params, 640 }; 641 642 params[0].type = ACPI_TYPE_BUFFER; 643 params[0].buffer.length = 16; 644 params[0].buffer.pointer = (char *)uuid; 645 params[1].type = ACPI_TYPE_INTEGER; 646 params[1].integer.value = rev; 647 params[2].type = ACPI_TYPE_INTEGER; 648 params[2].integer.value = func; 649 if (argv4) { 650 params[3] = *argv4; 651 } else { 652 params[3].type = ACPI_TYPE_PACKAGE; 653 params[3].package.count = 0; 654 params[3].package.elements = NULL; 655 } 656 657 ret = acpi_evaluate_object(handle, "_DSM", &input, &buf); 658 if (ACPI_SUCCESS(ret)) 659 return (union acpi_object *)buf.pointer; 660 661 if (ret != AE_NOT_FOUND) 662 acpi_handle_warn(handle, 663 "failed to evaluate _DSM (0x%x)\n", ret); 664 665 return NULL; 666} 667EXPORT_SYMBOL(acpi_evaluate_dsm); 668 669/** 670 * acpi_check_dsm - check if _DSM method supports requested functions. 671 * @handle: ACPI device handle 672 * @uuid: UUID of requested functions, should be 16 bytes at least 673 * @rev: revision number of requested functions 674 * @funcs: bitmap of requested functions 675 * 676 * Evaluate device's _DSM method to check whether it supports requested 677 * functions. Currently only support 64 functions at maximum, should be 678 * enough for now. 679 */ 680bool acpi_check_dsm(acpi_handle handle, const u8 *uuid, int rev, u64 funcs) 681{ 682 int i; 683 u64 mask = 0; 684 union acpi_object *obj; 685 686 if (funcs == 0) 687 return false; 688 689 obj = acpi_evaluate_dsm(handle, uuid, rev, 0, NULL); 690 if (!obj) 691 return false; 692 693 /* For compatibility, old BIOSes may return an integer */ 694 if (obj->type == ACPI_TYPE_INTEGER) 695 mask = obj->integer.value; 696 else if (obj->type == ACPI_TYPE_BUFFER) 697 for (i = 0; i < obj->buffer.length && i < 8; i++) 698 mask |= (((u8)obj->buffer.pointer[i]) << (i * 8)); 699 ACPI_FREE(obj); 700 701 /* 702 * Bit 0 indicates whether there's support for any functions other than 703 * function 0 for the specified UUID and revision. 704 */ 705 if ((mask & 0x1) && (mask & funcs) == funcs) 706 return true; 707 708 return false; 709} 710EXPORT_SYMBOL(acpi_check_dsm); 711 712/* 713 * acpi_backlight= handling, this is done here rather then in video_detect.c 714 * because __setup cannot be used in modules. 715 */ 716char acpi_video_backlight_string[16]; 717EXPORT_SYMBOL(acpi_video_backlight_string); 718 719static int __init acpi_backlight(char *str) 720{ 721 strlcpy(acpi_video_backlight_string, str, 722 sizeof(acpi_video_backlight_string)); 723 return 1; 724} 725__setup("acpi_backlight=", acpi_backlight); 726