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 * You should have received a copy of the GNU General Public License along 20 * with this program; if not, write to the Free Software Foundation, Inc., 21 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. 22 * 23 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 24 */ 25 26 #include <linux/kernel.h> 27 #include <linux/module.h> 28 #include <linux/slab.h> 29 #include <linux/init.h> 30 #include <linux/types.h> 31 #include <linux/hardirq.h> 32 #include <linux/acpi.h> 33 #include <acpi/acpi_bus.h> 34 #include <acpi/acpi_drivers.h> 35 36 #include "internal.h" 37 38 #define _COMPONENT ACPI_BUS_COMPONENT 39 ACPI_MODULE_NAME("utils"); 40 41 /* -------------------------------------------------------------------------- 42 Object Evaluation Helpers 43 -------------------------------------------------------------------------- */ 44 static void 45 acpi_util_eval_error(acpi_handle h, acpi_string p, acpi_status s) 46 { 47 #ifdef ACPI_DEBUG_OUTPUT 48 char prefix[80] = {'\0'}; 49 struct acpi_buffer buffer = {sizeof(prefix), prefix}; 50 acpi_get_name(h, ACPI_FULL_PATHNAME, &buffer); 51 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Evaluate [%s.%s]: %s\n", 52 (char *) prefix, p, acpi_format_exception(s))); 53 #else 54 return; 55 #endif 56 } 57 58 acpi_status 59 acpi_extract_package(union acpi_object *package, 60 struct acpi_buffer *format, struct acpi_buffer *buffer) 61 { 62 u32 size_required = 0; 63 u32 tail_offset = 0; 64 char *format_string = NULL; 65 u32 format_count = 0; 66 u32 i = 0; 67 u8 *head = NULL; 68 u8 *tail = NULL; 69 70 71 if (!package || (package->type != ACPI_TYPE_PACKAGE) 72 || (package->package.count < 1)) { 73 printk(KERN_WARNING PREFIX "Invalid package argument\n"); 74 return AE_BAD_PARAMETER; 75 } 76 77 if (!format || !format->pointer || (format->length < 1)) { 78 printk(KERN_WARNING PREFIX "Invalid format argument\n"); 79 return AE_BAD_PARAMETER; 80 } 81 82 if (!buffer) { 83 printk(KERN_WARNING PREFIX "Invalid buffer argument\n"); 84 return AE_BAD_PARAMETER; 85 } 86 87 format_count = (format->length / sizeof(char)) - 1; 88 if (format_count > package->package.count) { 89 printk(KERN_WARNING PREFIX "Format specifies more objects [%d]" 90 " than exist in package [%d].\n", 91 format_count, package->package.count); 92 return AE_BAD_DATA; 93 } 94 95 format_string = format->pointer; 96 97 /* 98 * Calculate size_required. 99 */ 100 for (i = 0; i < format_count; i++) { 101 102 union acpi_object *element = &(package->package.elements[i]); 103 104 if (!element) { 105 return AE_BAD_DATA; 106 } 107 108 switch (element->type) { 109 110 case ACPI_TYPE_INTEGER: 111 switch (format_string[i]) { 112 case 'N': 113 size_required += sizeof(u64); 114 tail_offset += sizeof(u64); 115 break; 116 case 'S': 117 size_required += 118 sizeof(char *) + sizeof(u64) + 119 sizeof(char); 120 tail_offset += sizeof(char *); 121 break; 122 default: 123 printk(KERN_WARNING PREFIX "Invalid package element" 124 " [%d]: got number, expecting" 125 " [%c]\n", 126 i, format_string[i]); 127 return AE_BAD_DATA; 128 break; 129 } 130 break; 131 132 case ACPI_TYPE_STRING: 133 case ACPI_TYPE_BUFFER: 134 switch (format_string[i]) { 135 case 'S': 136 size_required += 137 sizeof(char *) + 138 (element->string.length * sizeof(char)) + 139 sizeof(char); 140 tail_offset += sizeof(char *); 141 break; 142 case 'B': 143 size_required += 144 sizeof(u8 *) + 145 (element->buffer.length * sizeof(u8)); 146 tail_offset += sizeof(u8 *); 147 break; 148 default: 149 printk(KERN_WARNING PREFIX "Invalid package element" 150 " [%d] got string/buffer," 151 " expecting [%c]\n", 152 i, format_string[i]); 153 return AE_BAD_DATA; 154 break; 155 } 156 break; 157 158 case ACPI_TYPE_PACKAGE: 159 default: 160 ACPI_DEBUG_PRINT((ACPI_DB_INFO, 161 "Found unsupported element at index=%d\n", 162 i)); 163 /* TBD: handle nested packages... */ 164 return AE_SUPPORT; 165 break; 166 } 167 } 168 169 /* 170 * Validate output buffer. 171 */ 172 if (buffer->length == ACPI_ALLOCATE_BUFFER) { 173 buffer->pointer = ACPI_ALLOCATE(size_required); 174 if (!buffer->pointer) 175 return AE_NO_MEMORY; 176 buffer->length = size_required; 177 memset(buffer->pointer, 0, size_required); 178 } else { 179 if (buffer->length < size_required) { 180 buffer->length = size_required; 181 return AE_BUFFER_OVERFLOW; 182 } else if (buffer->length != size_required || 183 !buffer->pointer) { 184 return AE_BAD_PARAMETER; 185 } 186 } 187 188 head = buffer->pointer; 189 tail = buffer->pointer + tail_offset; 190 191 /* 192 * Extract package data. 193 */ 194 for (i = 0; i < format_count; i++) { 195 196 u8 **pointer = NULL; 197 union acpi_object *element = &(package->package.elements[i]); 198 199 if (!element) { 200 return AE_BAD_DATA; 201 } 202 203 switch (element->type) { 204 205 case ACPI_TYPE_INTEGER: 206 switch (format_string[i]) { 207 case 'N': 208 *((u64 *) head) = 209 element->integer.value; 210 head += sizeof(u64); 211 break; 212 case 'S': 213 pointer = (u8 **) head; 214 *pointer = tail; 215 *((u64 *) tail) = 216 element->integer.value; 217 head += sizeof(u64 *); 218 tail += sizeof(u64); 219 /* NULL terminate string */ 220 *tail = (char)0; 221 tail += sizeof(char); 222 break; 223 default: 224 /* Should never get here */ 225 break; 226 } 227 break; 228 229 case ACPI_TYPE_STRING: 230 case ACPI_TYPE_BUFFER: 231 switch (format_string[i]) { 232 case 'S': 233 pointer = (u8 **) head; 234 *pointer = tail; 235 memcpy(tail, element->string.pointer, 236 element->string.length); 237 head += sizeof(char *); 238 tail += element->string.length * sizeof(char); 239 /* NULL terminate string */ 240 *tail = (char)0; 241 tail += sizeof(char); 242 break; 243 case 'B': 244 pointer = (u8 **) head; 245 *pointer = tail; 246 memcpy(tail, element->buffer.pointer, 247 element->buffer.length); 248 head += sizeof(u8 *); 249 tail += element->buffer.length * sizeof(u8); 250 break; 251 default: 252 /* Should never get here */ 253 break; 254 } 255 break; 256 257 case ACPI_TYPE_PACKAGE: 258 /* TBD: handle nested packages... */ 259 default: 260 /* Should never get here */ 261 break; 262 } 263 } 264 265 return AE_OK; 266 } 267 268 EXPORT_SYMBOL(acpi_extract_package); 269 270 acpi_status 271 acpi_evaluate_integer(acpi_handle handle, 272 acpi_string pathname, 273 struct acpi_object_list *arguments, unsigned long long *data) 274 { 275 acpi_status status = AE_OK; 276 union acpi_object element; 277 struct acpi_buffer buffer = { 0, NULL }; 278 279 if (!data) 280 return AE_BAD_PARAMETER; 281 282 buffer.length = sizeof(union acpi_object); 283 buffer.pointer = &element; 284 status = acpi_evaluate_object(handle, pathname, arguments, &buffer); 285 if (ACPI_FAILURE(status)) { 286 acpi_util_eval_error(handle, pathname, status); 287 return status; 288 } 289 290 if (element.type != ACPI_TYPE_INTEGER) { 291 acpi_util_eval_error(handle, pathname, AE_BAD_DATA); 292 return AE_BAD_DATA; 293 } 294 295 *data = element.integer.value; 296 297 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Return value [%llu]\n", *data)); 298 299 return AE_OK; 300 } 301 302 EXPORT_SYMBOL(acpi_evaluate_integer); 303 304 acpi_status 305 acpi_evaluate_reference(acpi_handle handle, 306 acpi_string pathname, 307 struct acpi_object_list *arguments, 308 struct acpi_handle_list *list) 309 { 310 acpi_status status = AE_OK; 311 union acpi_object *package = NULL; 312 union acpi_object *element = NULL; 313 struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; 314 u32 i = 0; 315 316 317 if (!list) { 318 return AE_BAD_PARAMETER; 319 } 320 321 /* Evaluate object. */ 322 323 status = acpi_evaluate_object(handle, pathname, arguments, &buffer); 324 if (ACPI_FAILURE(status)) 325 goto end; 326 327 package = buffer.pointer; 328 329 if ((buffer.length == 0) || !package) { 330 printk(KERN_ERR PREFIX "No return object (len %X ptr %p)\n", 331 (unsigned)buffer.length, package); 332 status = AE_BAD_DATA; 333 acpi_util_eval_error(handle, pathname, status); 334 goto end; 335 } 336 if (package->type != ACPI_TYPE_PACKAGE) { 337 printk(KERN_ERR PREFIX "Expecting a [Package], found type %X\n", 338 package->type); 339 status = AE_BAD_DATA; 340 acpi_util_eval_error(handle, pathname, status); 341 goto end; 342 } 343 if (!package->package.count) { 344 printk(KERN_ERR PREFIX "[Package] has zero elements (%p)\n", 345 package); 346 status = AE_BAD_DATA; 347 acpi_util_eval_error(handle, pathname, status); 348 goto end; 349 } 350 351 if (package->package.count > ACPI_MAX_HANDLES) { 352 return AE_NO_MEMORY; 353 } 354 list->count = package->package.count; 355 356 /* Extract package data. */ 357 358 for (i = 0; i < list->count; i++) { 359 360 element = &(package->package.elements[i]); 361 362 if (element->type != ACPI_TYPE_LOCAL_REFERENCE) { 363 status = AE_BAD_DATA; 364 printk(KERN_ERR PREFIX 365 "Expecting a [Reference] package element, found type %X\n", 366 element->type); 367 acpi_util_eval_error(handle, pathname, status); 368 break; 369 } 370 371 if (!element->reference.handle) { 372 printk(KERN_WARNING PREFIX "Invalid reference in" 373 " package %s\n", pathname); 374 status = AE_NULL_ENTRY; 375 break; 376 } 377 /* Get the acpi_handle. */ 378 379 list->handles[i] = element->reference.handle; 380 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found reference [%p]\n", 381 list->handles[i])); 382 } 383 384 end: 385 if (ACPI_FAILURE(status)) { 386 list->count = 0; 387 //kfree(list->handles); 388 } 389 390 kfree(buffer.pointer); 391 392 return status; 393 } 394 395 EXPORT_SYMBOL(acpi_evaluate_reference); 396 397 acpi_status 398 acpi_get_physical_device_location(acpi_handle handle, struct acpi_pld_info **pld) 399 { 400 acpi_status status; 401 struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; 402 union acpi_object *output; 403 404 status = acpi_evaluate_object(handle, "_PLD", NULL, &buffer); 405 406 if (ACPI_FAILURE(status)) 407 return status; 408 409 output = buffer.pointer; 410 411 if (!output || output->type != ACPI_TYPE_PACKAGE 412 || !output->package.count 413 || output->package.elements[0].type != ACPI_TYPE_BUFFER 414 || output->package.elements[0].buffer.length < ACPI_PLD_REV1_BUFFER_SIZE) { 415 status = AE_TYPE; 416 goto out; 417 } 418 419 status = acpi_decode_pld_buffer( 420 output->package.elements[0].buffer.pointer, 421 output->package.elements[0].buffer.length, 422 pld); 423 424 out: 425 kfree(buffer.pointer); 426 return status; 427 } 428 EXPORT_SYMBOL(acpi_get_physical_device_location); 429 430 /** 431 * acpi_evaluate_hotplug_ost: Evaluate _OST for hotplug operations 432 * @handle: ACPI device handle 433 * @source_event: source event code 434 * @status_code: status code 435 * @status_buf: optional detailed information (NULL if none) 436 * 437 * Evaluate _OST for hotplug operations. All ACPI hotplug handlers 438 * must call this function when evaluating _OST for hotplug operations. 439 * When the platform does not support _OST, this function has no effect. 440 */ 441 acpi_status 442 acpi_evaluate_hotplug_ost(acpi_handle handle, u32 source_event, 443 u32 status_code, struct acpi_buffer *status_buf) 444 { 445 #ifdef ACPI_HOTPLUG_OST 446 union acpi_object params[3] = { 447 {.type = ACPI_TYPE_INTEGER,}, 448 {.type = ACPI_TYPE_INTEGER,}, 449 {.type = ACPI_TYPE_BUFFER,} 450 }; 451 struct acpi_object_list arg_list = {3, params}; 452 acpi_status status; 453 454 params[0].integer.value = source_event; 455 params[1].integer.value = status_code; 456 if (status_buf != NULL) { 457 params[2].buffer.pointer = status_buf->pointer; 458 params[2].buffer.length = status_buf->length; 459 } else { 460 params[2].buffer.pointer = NULL; 461 params[2].buffer.length = 0; 462 } 463 464 status = acpi_evaluate_object(handle, "_OST", &arg_list, NULL); 465 return status; 466 #else 467 return AE_OK; 468 #endif 469 } 470 EXPORT_SYMBOL(acpi_evaluate_hotplug_ost); 471 472 /** 473 * acpi_handle_printk: Print message with ACPI prefix and object path 474 * 475 * This function is called through acpi_handle_<level> macros and prints 476 * a message with ACPI prefix and object path. This function acquires 477 * the global namespace mutex to obtain an object path. In interrupt 478 * context, it shows the object path as <n/a>. 479 */ 480 void 481 acpi_handle_printk(const char *level, acpi_handle handle, const char *fmt, ...) 482 { 483 struct va_format vaf; 484 va_list args; 485 struct acpi_buffer buffer = { 486 .length = ACPI_ALLOCATE_BUFFER, 487 .pointer = NULL 488 }; 489 const char *path; 490 491 va_start(args, fmt); 492 vaf.fmt = fmt; 493 vaf.va = &args; 494 495 if (in_interrupt() || 496 acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer) != AE_OK) 497 path = "<n/a>"; 498 else 499 path = buffer.pointer; 500 501 printk("%sACPI: %s: %pV", level, path, &vaf); 502 503 va_end(args); 504 kfree(buffer.pointer); 505 } 506 EXPORT_SYMBOL(acpi_handle_printk); 507 508 /** 509 * acpi_has_method: Check whether @handle has a method named @name 510 * @handle: ACPI device handle 511 * @name: name of object or method 512 * 513 * Check whether @handle has a method named @name. 514 */ 515 bool acpi_has_method(acpi_handle handle, char *name) 516 { 517 acpi_handle tmp; 518 519 return ACPI_SUCCESS(acpi_get_handle(handle, name, &tmp)); 520 } 521 EXPORT_SYMBOL(acpi_has_method); 522 523 acpi_status acpi_execute_simple_method(acpi_handle handle, char *method, 524 u64 arg) 525 { 526 union acpi_object obj = { .type = ACPI_TYPE_INTEGER }; 527 struct acpi_object_list arg_list = { .count = 1, .pointer = &obj, }; 528 529 obj.integer.value = arg; 530 531 return acpi_evaluate_object(handle, method, &arg_list, NULL); 532 } 533 EXPORT_SYMBOL(acpi_execute_simple_method); 534 535 /** 536 * acpi_evaluate_ej0: Evaluate _EJ0 method for hotplug operations 537 * @handle: ACPI device handle 538 * 539 * Evaluate device's _EJ0 method for hotplug operations. 540 */ 541 acpi_status acpi_evaluate_ej0(acpi_handle handle) 542 { 543 acpi_status status; 544 545 status = acpi_execute_simple_method(handle, "_EJ0", 1); 546 if (status == AE_NOT_FOUND) 547 acpi_handle_warn(handle, "No _EJ0 support for device\n"); 548 else if (ACPI_FAILURE(status)) 549 acpi_handle_warn(handle, "Eject failed (0x%x)\n", status); 550 551 return status; 552 } 553 554 /** 555 * acpi_evaluate_lck: Evaluate _LCK method to lock/unlock device 556 * @handle: ACPI device handle 557 * @lock: lock device if non-zero, otherwise unlock device 558 * 559 * Evaluate device's _LCK method if present to lock/unlock device 560 */ 561 acpi_status acpi_evaluate_lck(acpi_handle handle, int lock) 562 { 563 acpi_status status; 564 565 status = acpi_execute_simple_method(handle, "_LCK", !!lock); 566 if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) { 567 if (lock) 568 acpi_handle_warn(handle, 569 "Locking device failed (0x%x)\n", status); 570 else 571 acpi_handle_warn(handle, 572 "Unlocking device failed (0x%x)\n", status); 573 } 574 575 return status; 576 } 577