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