linux/drivers/acpi/scan.c
<<
>>
Prefs
   1/*
   2 * scan.c - support for transforming the ACPI namespace into individual objects
   3 */
   4
   5#include <linux/module.h>
   6#include <linux/init.h>
   7#include <linux/acpi.h>
   8
   9#include <acpi/acpi_drivers.h>
  10#include <acpi/acinterp.h>      /* for acpi_ex_eisa_id_to_string() */
  11
  12
  13#define _COMPONENT              ACPI_BUS_COMPONENT
  14ACPI_MODULE_NAME                ("scan")
  15
  16#define STRUCT_TO_INT(s)        (*((int*)&s))
  17
  18extern struct acpi_device               *acpi_root;
  19
  20
  21#define ACPI_BUS_CLASS                  "system_bus"
  22#define ACPI_BUS_HID                    "ACPI_BUS"
  23#define ACPI_BUS_DRIVER_NAME            "ACPI Bus Driver"
  24#define ACPI_BUS_DEVICE_NAME            "System Bus"
  25
  26static LIST_HEAD(acpi_device_list);
  27DEFINE_SPINLOCK(acpi_device_lock);
  28LIST_HEAD(acpi_wakeup_device_list);
  29
  30static void acpi_device_release(struct kobject * kobj)
  31{
  32        struct acpi_device * dev = container_of(kobj,struct acpi_device,kobj);
  33        if (dev->pnp.cid_list)
  34                kfree(dev->pnp.cid_list);
  35        kfree(dev);
  36}
  37
  38struct acpi_device_attribute {
  39        struct attribute attr;
  40        ssize_t (*show)(struct acpi_device *, char *);
  41        ssize_t (*store)(struct acpi_device *, const char *, size_t);
  42};
  43
  44typedef void acpi_device_sysfs_files(struct kobject *,
  45                                const struct attribute *);
  46
  47static void setup_sys_fs_device_files(struct acpi_device *dev,
  48                acpi_device_sysfs_files *func);
  49
  50#define create_sysfs_device_files(dev)  \
  51        setup_sys_fs_device_files(dev, (acpi_device_sysfs_files *)&sysfs_create_file)
  52#define remove_sysfs_device_files(dev)  \
  53        setup_sys_fs_device_files(dev, (acpi_device_sysfs_files *)&sysfs_remove_file)
  54
  55
  56#define to_acpi_device(n) container_of(n, struct acpi_device, kobj)
  57#define to_handle_attr(n) container_of(n, struct acpi_device_attribute, attr);
  58
  59static ssize_t acpi_device_attr_show(struct kobject *kobj,
  60                struct attribute *attr, char *buf)
  61{
  62        struct acpi_device *device = to_acpi_device(kobj);
  63        struct acpi_device_attribute *attribute = to_handle_attr(attr);
  64        return attribute->show ? attribute->show(device, buf) : 0;
  65}
  66static ssize_t acpi_device_attr_store(struct kobject *kobj,
  67                struct attribute *attr, const char *buf, size_t len)
  68{
  69        struct acpi_device *device = to_acpi_device(kobj);
  70        struct acpi_device_attribute *attribute = to_handle_attr(attr);
  71        return attribute->store ? attribute->store(device, buf, len) : len;
  72}
  73
  74static struct sysfs_ops acpi_device_sysfs_ops = {
  75        .show   = acpi_device_attr_show,
  76        .store  = acpi_device_attr_store,
  77};
  78
  79static struct kobj_type ktype_acpi_ns = {
  80        .sysfs_ops      = &acpi_device_sysfs_ops,
  81        .release        = acpi_device_release,
  82};
  83
  84static struct kset acpi_namespace_kset = {
  85        .kobj           = { 
  86                .name = "namespace",
  87        },
  88        .subsys = &acpi_subsys,
  89        .ktype  = &ktype_acpi_ns,
  90};
  91
  92
  93static void acpi_device_register(struct acpi_device * device, struct acpi_device * parent)
  94{
  95        /*
  96         * Linkage
  97         * -------
  98         * Link this device to its parent and siblings.
  99         */
 100        INIT_LIST_HEAD(&device->children);
 101        INIT_LIST_HEAD(&device->node);
 102        INIT_LIST_HEAD(&device->g_list);
 103        INIT_LIST_HEAD(&device->wakeup_list);
 104
 105        spin_lock(&acpi_device_lock);
 106        if (device->parent) {
 107                list_add_tail(&device->node, &device->parent->children);
 108                list_add_tail(&device->g_list,&device->parent->g_list);
 109        } else
 110                list_add_tail(&device->g_list,&acpi_device_list);
 111        if (device->wakeup.flags.valid)
 112                list_add_tail(&device->wakeup_list,&acpi_wakeup_device_list);
 113        spin_unlock(&acpi_device_lock);
 114
 115        strlcpy(device->kobj.name,device->pnp.bus_id,KOBJ_NAME_LEN);
 116        if (parent)
 117                device->kobj.parent = &parent->kobj;
 118        device->kobj.ktype = &ktype_acpi_ns;
 119        device->kobj.kset = &acpi_namespace_kset;
 120        kobject_register(&device->kobj);
 121        create_sysfs_device_files(device);
 122}
 123
 124static int
 125acpi_device_unregister (
 126        struct acpi_device      *device, 
 127        int                     type)
 128{
 129        spin_lock(&acpi_device_lock);
 130        if (device->parent) {
 131                list_del(&device->node);
 132                list_del(&device->g_list);
 133        } else
 134                list_del(&device->g_list);
 135
 136        list_del(&device->wakeup_list);
 137
 138        spin_unlock(&acpi_device_lock);
 139
 140        acpi_detach_data(device->handle, acpi_bus_data_handler);
 141        remove_sysfs_device_files(device);
 142        kobject_unregister(&device->kobj);
 143        return 0;
 144}
 145
 146void
 147acpi_bus_data_handler (
 148        acpi_handle             handle,
 149        u32                     function,
 150        void                    *context)
 151{
 152        ACPI_FUNCTION_TRACE("acpi_bus_data_handler");
 153
 154        /* TBD */
 155
 156        return_VOID;
 157}
 158
 159static int
 160acpi_bus_get_power_flags (
 161        struct acpi_device      *device)
 162{
 163        acpi_status             status = 0;
 164        acpi_handle             handle = NULL;
 165        u32                     i = 0;
 166
 167        ACPI_FUNCTION_TRACE("acpi_bus_get_power_flags");
 168
 169        /*
 170         * Power Management Flags
 171         */
 172        status = acpi_get_handle(device->handle, "_PSC", &handle);
 173        if (ACPI_SUCCESS(status))
 174                device->power.flags.explicit_get = 1;
 175        status = acpi_get_handle(device->handle, "_IRC", &handle);
 176        if (ACPI_SUCCESS(status))
 177                device->power.flags.inrush_current = 1;
 178
 179        /*
 180         * Enumerate supported power management states
 181         */
 182        for (i = ACPI_STATE_D0; i <= ACPI_STATE_D3; i++) {
 183                struct acpi_device_power_state *ps = &device->power.states[i];
 184                char            object_name[5] = {'_','P','R','0'+i,'\0'};
 185
 186                /* Evaluate "_PRx" to se if power resources are referenced */
 187                acpi_evaluate_reference(device->handle, object_name, NULL,
 188                        &ps->resources);
 189                if (ps->resources.count) {
 190                        device->power.flags.power_resources = 1;
 191                        ps->flags.valid = 1;
 192                }
 193
 194                /* Evaluate "_PSx" to see if we can do explicit sets */
 195                object_name[2] = 'S';
 196                status = acpi_get_handle(device->handle, object_name, &handle);
 197                if (ACPI_SUCCESS(status)) {
 198                        ps->flags.explicit_set = 1;
 199                        ps->flags.valid = 1;
 200                }
 201
 202                /* State is valid if we have some power control */
 203                if (ps->resources.count || ps->flags.explicit_set)
 204                        ps->flags.valid = 1;
 205
 206                ps->power = -1;         /* Unknown - driver assigned */
 207                ps->latency = -1;       /* Unknown - driver assigned */
 208        }
 209
 210        /* Set defaults for D0 and D3 states (always valid) */
 211        device->power.states[ACPI_STATE_D0].flags.valid = 1;
 212        device->power.states[ACPI_STATE_D0].power = 100;
 213        device->power.states[ACPI_STATE_D3].flags.valid = 1;
 214        device->power.states[ACPI_STATE_D3].power = 0;
 215
 216        /* TBD: System wake support and resource requirements. */
 217
 218        device->power.state = ACPI_STATE_UNKNOWN;
 219
 220        return_VALUE(0);
 221}
 222
 223int
 224acpi_match_ids (
 225        struct acpi_device      *device,
 226        char                    *ids)
 227{
 228        int error = 0;
 229        struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL};
 230
 231        if (device->flags.hardware_id)
 232                if (strstr(ids, device->pnp.hardware_id))
 233                        goto Done;
 234
 235        if (device->flags.compatible_ids) {
 236                struct acpi_compatible_id_list *cid_list = device->pnp.cid_list;
 237                int i;
 238
 239                /* compare multiple _CID entries against driver ids */
 240                for (i = 0; i < cid_list->count; i++)
 241                {
 242                        if (strstr(ids, cid_list->id[i].value))
 243                                goto Done;
 244                }
 245        }
 246        error = -ENOENT;
 247
 248 Done:
 249        if (buffer.pointer)
 250                acpi_os_free(buffer.pointer);
 251        return error;
 252}
 253
 254static acpi_status
 255acpi_bus_extract_wakeup_device_power_package (
 256        struct acpi_device      *device,
 257        union acpi_object       *package)
 258{
 259        int      i = 0;
 260        union acpi_object       *element = NULL;
 261
 262        if (!device || !package || (package->package.count < 2))
 263                return AE_BAD_PARAMETER;
 264
 265        element = &(package->package.elements[0]);
 266        if (!element)
 267                return AE_BAD_PARAMETER;
 268        if (element->type == ACPI_TYPE_PACKAGE) {
 269                if ((element->package.count < 2) ||
 270                        (element->package.elements[0].type != ACPI_TYPE_LOCAL_REFERENCE) ||
 271                        (element->package.elements[1].type != ACPI_TYPE_INTEGER))
 272                        return AE_BAD_DATA;
 273                device->wakeup.gpe_device = element->package.elements[0].reference.handle;
 274                device->wakeup.gpe_number = (u32)element->package.elements[1].integer.value;
 275        }else if (element->type == ACPI_TYPE_INTEGER) {
 276                device->wakeup.gpe_number = element->integer.value;
 277        }else
 278                return AE_BAD_DATA;
 279
 280        element = &(package->package.elements[1]);
 281        if (element->type != ACPI_TYPE_INTEGER) {
 282                return AE_BAD_DATA;
 283        }
 284        device->wakeup.sleep_state = element->integer.value;
 285
 286        if ((package->package.count - 2) > ACPI_MAX_HANDLES) {
 287                return AE_NO_MEMORY;
 288        }
 289        device->wakeup.resources.count = package->package.count - 2;
 290        for (i=0; i < device->wakeup.resources.count; i++) {
 291                element = &(package->package.elements[i + 2]);
 292                if (element->type != ACPI_TYPE_ANY ) {
 293                        return AE_BAD_DATA;
 294                }
 295
 296                device->wakeup.resources.handles[i] = element->reference.handle;
 297        }
 298
 299        return AE_OK;
 300}
 301
 302static int
 303acpi_bus_get_wakeup_device_flags (
 304        struct acpi_device      *device)
 305{
 306        acpi_status     status = 0;
 307        struct acpi_buffer      buffer = {ACPI_ALLOCATE_BUFFER, NULL};
 308        union acpi_object       *package = NULL;
 309
 310        ACPI_FUNCTION_TRACE("acpi_bus_get_wakeup_flags");
 311
 312        /* _PRW */
 313        status = acpi_evaluate_object(device->handle, "_PRW", NULL, &buffer);
 314        if (ACPI_FAILURE(status)) {
 315                ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Error evaluating _PRW\n"));
 316                goto end;
 317        }
 318
 319        package = (union acpi_object *) buffer.pointer;
 320        status = acpi_bus_extract_wakeup_device_power_package(device, package);
 321        if (ACPI_FAILURE(status)) {
 322                ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Error extracting _PRW package\n"));
 323                goto end;
 324        }
 325
 326        acpi_os_free(buffer.pointer);
 327
 328        device->wakeup.flags.valid = 1;
 329        /* Power button, Lid switch always enable wakeup*/
 330        if (!acpi_match_ids(device, "PNP0C0D,PNP0C0C,PNP0C0E"))
 331                device->wakeup.flags.run_wake = 1;
 332
 333end:
 334        if (ACPI_FAILURE(status))
 335                device->flags.wake_capable = 0;
 336        return_VALUE(0);
 337}
 338
 339/* --------------------------------------------------------------------------
 340                ACPI hotplug sysfs device file support
 341   -------------------------------------------------------------------------- */
 342static ssize_t acpi_eject_store(struct acpi_device *device, 
 343                const char *buf, size_t count);
 344
 345#define ACPI_DEVICE_ATTR(_name,_mode,_show,_store) \
 346static struct acpi_device_attribute acpi_device_attr_##_name = \
 347                __ATTR(_name, _mode, _show, _store)
 348
 349ACPI_DEVICE_ATTR(eject, 0200, NULL, acpi_eject_store);
 350
 351/**
 352 * setup_sys_fs_device_files - sets up the device files under device namespace
 353 * @@dev:       acpi_device object
 354 * @@func:      function pointer to create or destroy the device file
 355 */
 356static void
 357setup_sys_fs_device_files (
 358        struct acpi_device *dev,
 359        acpi_device_sysfs_files *func)
 360{
 361        if (dev->flags.ejectable == 1)
 362                (*(func))(&dev->kobj,&acpi_device_attr_eject.attr);
 363}
 364
 365static int
 366acpi_eject_operation(acpi_handle handle, int lockable)
 367{
 368        struct acpi_object_list arg_list;
 369        union acpi_object arg;
 370        acpi_status status = AE_OK;
 371
 372        /*
 373         * TBD: evaluate _PS3?
 374         */
 375
 376        if (lockable) {
 377                arg_list.count = 1;
 378                arg_list.pointer = &arg;
 379                arg.type = ACPI_TYPE_INTEGER;
 380                arg.integer.value = 0;
 381                acpi_evaluate_object(handle, "_LCK", &arg_list, NULL);
 382        }
 383
 384        arg_list.count = 1;
 385        arg_list.pointer = &arg;
 386        arg.type = ACPI_TYPE_INTEGER;
 387        arg.integer.value = 1;
 388
 389        /*
 390         * TBD: _EJD support.
 391         */
 392
 393        status = acpi_evaluate_object(handle, "_EJ0", &arg_list, NULL);
 394        if (ACPI_FAILURE(status)) {
 395                return(-ENODEV);
 396        }
 397
 398        return(0);
 399}
 400
 401
 402static ssize_t
 403acpi_eject_store(struct acpi_device *device, const char *buf, size_t count)
 404{
 405        int     result;
 406        int     ret = count;
 407        int     islockable;
 408        acpi_status     status;
 409        acpi_handle     handle;
 410        acpi_object_type        type = 0;
 411
 412        if ((!count) || (buf[0] != '1')) {
 413                return -EINVAL;
 414        }
 415
 416#ifndef FORCE_EJECT
 417        if (device->driver == NULL) {
 418                ret = -ENODEV;
 419                goto err;
 420        }
 421#endif
 422        status = acpi_get_type(device->handle, &type);
 423        if (ACPI_FAILURE(status) || (!device->flags.ejectable) ) {
 424                ret = -ENODEV;
 425                goto err;
 426        }
 427
 428        islockable = device->flags.lockable;
 429        handle = device->handle;
 430
 431        if (type == ACPI_TYPE_PROCESSOR)
 432                result = acpi_bus_trim(device, 0);
 433        else
 434                result = acpi_bus_trim(device, 1);
 435
 436        if (!result)
 437                result = acpi_eject_operation(handle, islockable);
 438
 439        if (result) {
 440                ret = -EBUSY;
 441        }
 442err:
 443        return ret;
 444}
 445
 446
 447/* --------------------------------------------------------------------------
 448                              Performance Management
 449   -------------------------------------------------------------------------- */
 450
 451static int
 452acpi_bus_get_perf_flags (
 453        struct acpi_device      *device)
 454{
 455        device->performance.state = ACPI_STATE_UNKNOWN;
 456        return 0;
 457}
 458
 459/* --------------------------------------------------------------------------
 460                                 Driver Management
 461   -------------------------------------------------------------------------- */
 462
 463static LIST_HEAD(acpi_bus_drivers);
 464static DECLARE_MUTEX(acpi_bus_drivers_lock);
 465
 466
 467/**
 468 * acpi_bus_match 
 469 * --------------
 470 * Checks the device's hardware (_HID) or compatible (_CID) ids to see if it
 471 * matches the specified driver's criteria.
 472 */
 473static int
 474acpi_bus_match (
 475        struct acpi_device      *device,
 476        struct acpi_driver      *driver)
 477{
 478        if (driver && driver->ops.match)
 479                return driver->ops.match(device, driver);
 480        return acpi_match_ids(device, driver->ids);
 481}
 482
 483
 484/**
 485 * acpi_bus_driver_init 
 486 * --------------------
 487 * Used to initialize a device via its device driver.  Called whenever a 
 488 * driver is bound to a device.  Invokes the driver's add() and start() ops.
 489 */
 490static int
 491acpi_bus_driver_init (
 492        struct acpi_device      *device, 
 493        struct acpi_driver      *driver)
 494{
 495        int                     result = 0;
 496
 497        ACPI_FUNCTION_TRACE("acpi_bus_driver_init");
 498
 499        if (!device || !driver)
 500                return_VALUE(-EINVAL);
 501
 502        if (!driver->ops.add)
 503                return_VALUE(-ENOSYS);
 504
 505        result = driver->ops.add(device);
 506        if (result) {
 507                device->driver = NULL;
 508                acpi_driver_data(device) = NULL;
 509                return_VALUE(result);
 510        }
 511
 512        device->driver = driver;
 513
 514        /*
 515         * TBD - Configuration Management: Assign resources to device based
 516         * upon possible configuration and currently allocated resources.
 517         */
 518
 519        if (driver->ops.start) {
 520                result = driver->ops.start(device);
 521                if (result && driver->ops.remove)
 522                        driver->ops.remove(device, ACPI_BUS_REMOVAL_NORMAL);
 523                return_VALUE(result);
 524        }
 525
 526        ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Driver successfully bound to device\n"));
 527
 528        if (driver->ops.scan) {
 529                driver->ops.scan(device);
 530        }
 531
 532        return_VALUE(0);
 533}
 534
 535static int acpi_driver_attach(struct acpi_driver * drv)
 536{
 537        struct list_head * node, * next;
 538        int count = 0;
 539
 540        ACPI_FUNCTION_TRACE("acpi_driver_attach");
 541
 542        spin_lock(&acpi_device_lock);
 543        list_for_each_safe(node, next, &acpi_device_list) {
 544                struct acpi_device * dev = container_of(node, struct acpi_device, g_list);
 545
 546                if (dev->driver || !dev->status.present)
 547                        continue;
 548                spin_unlock(&acpi_device_lock);
 549
 550                if (!acpi_bus_match(dev, drv)) {
 551                        if (!acpi_bus_driver_init(dev, drv)) {
 552                                atomic_inc(&drv->references);
 553                                count++;
 554                                ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found driver [%s] for device [%s]\n",
 555                                                  drv->name, dev->pnp.bus_id));
 556                        }
 557                }
 558                spin_lock(&acpi_device_lock);
 559        }
 560        spin_unlock(&acpi_device_lock);
 561        return_VALUE(count);
 562}
 563
 564static int acpi_driver_detach(struct acpi_driver * drv)
 565{
 566        struct list_head * node, * next;
 567
 568        ACPI_FUNCTION_TRACE("acpi_driver_detach");
 569
 570        spin_lock(&acpi_device_lock);
 571        list_for_each_safe(node,next,&acpi_device_list) {
 572                struct acpi_device * dev = container_of(node,struct acpi_device,g_list);
 573
 574                if (dev->driver == drv) {
 575                        spin_unlock(&acpi_device_lock);
 576                        if (drv->ops.remove)
 577                                drv->ops.remove(dev,ACPI_BUS_REMOVAL_NORMAL);
 578                        spin_lock(&acpi_device_lock);
 579                        dev->driver = NULL;
 580                        dev->driver_data = NULL;
 581                        atomic_dec(&drv->references);
 582                }
 583        }
 584        spin_unlock(&acpi_device_lock);
 585        return_VALUE(0);
 586}
 587
 588/**
 589 * acpi_bus_register_driver 
 590 * ------------------------ 
 591 * Registers a driver with the ACPI bus.  Searches the namespace for all
 592 * devices that match the driver's criteria and binds.  Returns the
 593 * number of devices that were claimed by the driver, or a negative
 594 * error status for failure.
 595 */
 596int
 597acpi_bus_register_driver (
 598        struct acpi_driver      *driver)
 599{
 600        int count;
 601
 602        ACPI_FUNCTION_TRACE("acpi_bus_register_driver");
 603
 604        if (acpi_disabled)
 605                return_VALUE(-ENODEV);
 606
 607        if (!driver)
 608                return_VALUE(-EINVAL);
 609
 610        spin_lock(&acpi_device_lock);
 611        list_add_tail(&driver->node, &acpi_bus_drivers);
 612        spin_unlock(&acpi_device_lock);
 613        count = acpi_driver_attach(driver);
 614
 615        return_VALUE(count);
 616}
 617EXPORT_SYMBOL(acpi_bus_register_driver);
 618
 619
 620/**
 621 * acpi_bus_unregister_driver 
 622 * --------------------------
 623 * Unregisters a driver with the ACPI bus.  Searches the namespace for all
 624 * devices that match the driver's criteria and unbinds.
 625 */
 626int
 627acpi_bus_unregister_driver (
 628        struct acpi_driver      *driver)
 629{
 630        int error = 0;
 631
 632        ACPI_FUNCTION_TRACE("acpi_bus_unregister_driver");
 633
 634        if (driver) {
 635                acpi_driver_detach(driver);
 636
 637                if (!atomic_read(&driver->references)) {
 638                        spin_lock(&acpi_device_lock);
 639                        list_del_init(&driver->node);
 640                        spin_unlock(&acpi_device_lock);
 641                } 
 642        } else 
 643                error = -EINVAL;
 644        return_VALUE(error);
 645}
 646EXPORT_SYMBOL(acpi_bus_unregister_driver);
 647
 648/**
 649 * acpi_bus_find_driver 
 650 * --------------------
 651 * Parses the list of registered drivers looking for a driver applicable for
 652 * the specified device.
 653 */
 654static int
 655acpi_bus_find_driver (
 656        struct acpi_device      *device)
 657{
 658        int                     result = 0;
 659        struct list_head        * node, *next;
 660
 661        ACPI_FUNCTION_TRACE("acpi_bus_find_driver");
 662
 663        spin_lock(&acpi_device_lock);
 664        list_for_each_safe(node,next,&acpi_bus_drivers) {
 665                struct acpi_driver * driver = container_of(node,struct acpi_driver,node);
 666
 667                atomic_inc(&driver->references);
 668                spin_unlock(&acpi_device_lock);
 669                if (!acpi_bus_match(device, driver)) {
 670                        result = acpi_bus_driver_init(device, driver);
 671                        if (!result)
 672                                goto Done;
 673                }
 674                atomic_dec(&driver->references);
 675                spin_lock(&acpi_device_lock);
 676        }
 677        spin_unlock(&acpi_device_lock);
 678
 679 Done:
 680        return_VALUE(result);
 681}
 682
 683
 684/* --------------------------------------------------------------------------
 685                                 Device Enumeration
 686   -------------------------------------------------------------------------- */
 687
 688static int 
 689acpi_bus_get_flags (
 690        struct acpi_device      *device)
 691{
 692        acpi_status             status = AE_OK;
 693        acpi_handle             temp = NULL;
 694
 695        ACPI_FUNCTION_TRACE("acpi_bus_get_flags");
 696
 697        /* Presence of _STA indicates 'dynamic_status' */
 698        status = acpi_get_handle(device->handle, "_STA", &temp);
 699        if (ACPI_SUCCESS(status))
 700                device->flags.dynamic_status = 1;
 701
 702        /* Presence of _CID indicates 'compatible_ids' */
 703        status = acpi_get_handle(device->handle, "_CID", &temp);
 704        if (ACPI_SUCCESS(status))
 705                device->flags.compatible_ids = 1;
 706
 707        /* Presence of _RMV indicates 'removable' */
 708        status = acpi_get_handle(device->handle, "_RMV", &temp);
 709        if (ACPI_SUCCESS(status))
 710                device->flags.removable = 1;
 711
 712        /* Presence of _EJD|_EJ0 indicates 'ejectable' */
 713        status = acpi_get_handle(device->handle, "_EJD", &temp);
 714        if (ACPI_SUCCESS(status))
 715                device->flags.ejectable = 1;
 716        else {
 717                status = acpi_get_handle(device->handle, "_EJ0", &temp);
 718                if (ACPI_SUCCESS(status))
 719                        device->flags.ejectable = 1;
 720        }
 721
 722        /* Presence of _LCK indicates 'lockable' */
 723        status = acpi_get_handle(device->handle, "_LCK", &temp);
 724        if (ACPI_SUCCESS(status))
 725                device->flags.lockable = 1;
 726
 727        /* Presence of _PS0|_PR0 indicates 'power manageable' */
 728        status = acpi_get_handle(device->handle, "_PS0", &temp);
 729        if (ACPI_FAILURE(status))
 730                status = acpi_get_handle(device->handle, "_PR0", &temp);
 731        if (ACPI_SUCCESS(status))
 732                device->flags.power_manageable = 1;
 733
 734        /* Presence of _PRW indicates wake capable */
 735        status = acpi_get_handle(device->handle, "_PRW", &temp);
 736        if (ACPI_SUCCESS(status))
 737                device->flags.wake_capable = 1;
 738
 739        /* TBD: Peformance management */
 740
 741        return_VALUE(0);
 742}
 743
 744static void acpi_device_get_busid(struct acpi_device * device, acpi_handle handle, int type)
 745{
 746        char                    bus_id[5] = {'?',0};
 747        struct acpi_buffer      buffer = {sizeof(bus_id), bus_id};
 748        int                     i = 0;
 749
 750        /*
 751         * Bus ID
 752         * ------
 753         * The device's Bus ID is simply the object name.
 754         * TBD: Shouldn't this value be unique (within the ACPI namespace)?
 755         */
 756        switch (type) {
 757        case ACPI_BUS_TYPE_SYSTEM:
 758                strcpy(device->pnp.bus_id, "ACPI");
 759                break;
 760        case ACPI_BUS_TYPE_POWER_BUTTON:
 761                strcpy(device->pnp.bus_id, "PWRF");
 762                break;
 763        case ACPI_BUS_TYPE_SLEEP_BUTTON:
 764                strcpy(device->pnp.bus_id, "SLPF");
 765                break;
 766        default:
 767                acpi_get_name(handle, ACPI_SINGLE_NAME, &buffer);
 768                /* Clean up trailing underscores (if any) */
 769                for (i = 3; i > 1; i--) {
 770                        if (bus_id[i] == '_')
 771                                bus_id[i] = '\0';
 772                        else
 773                                break;
 774                }
 775                strcpy(device->pnp.bus_id, bus_id);
 776                break;
 777        }
 778}
 779
 780static void acpi_device_set_id(struct acpi_device * device, struct acpi_device * parent,
 781                               acpi_handle handle, int type)
 782{
 783        struct acpi_device_info *info;
 784        struct acpi_buffer      buffer = {ACPI_ALLOCATE_BUFFER, NULL};
 785        char                    *hid = NULL;
 786        char                    *uid = NULL;
 787        struct acpi_compatible_id_list *cid_list = NULL;
 788        acpi_status             status;
 789
 790        switch (type) {
 791        case ACPI_BUS_TYPE_DEVICE:
 792                status = acpi_get_object_info(handle, &buffer);
 793                if (ACPI_FAILURE(status)) {
 794                        printk("%s: Error reading device info\n",__FUNCTION__);
 795                        return;
 796                }
 797
 798                info = buffer.pointer;
 799                if (info->valid & ACPI_VALID_HID)
 800                        hid = info->hardware_id.value;
 801                if (info->valid & ACPI_VALID_UID)
 802                        uid = info->unique_id.value;
 803                if (info->valid & ACPI_VALID_CID)
 804                        cid_list = &info->compatibility_id;
 805                if (info->valid & ACPI_VALID_ADR) {
 806                        device->pnp.bus_address = info->address;
 807                        device->flags.bus_address = 1;
 808                }
 809                break;
 810        case ACPI_BUS_TYPE_POWER:
 811                hid = ACPI_POWER_HID;
 812                break;
 813        case ACPI_BUS_TYPE_PROCESSOR:
 814                hid = ACPI_PROCESSOR_HID;
 815                break;
 816        case ACPI_BUS_TYPE_SYSTEM:
 817                hid = ACPI_SYSTEM_HID;
 818                break;
 819        case ACPI_BUS_TYPE_THERMAL:
 820                hid = ACPI_THERMAL_HID;
 821                break;
 822        case ACPI_BUS_TYPE_POWER_BUTTON:
 823                hid = ACPI_BUTTON_HID_POWERF;
 824                break;
 825        case ACPI_BUS_TYPE_SLEEP_BUTTON:
 826                hid = ACPI_BUTTON_HID_SLEEPF;
 827                break;
 828        }
 829
 830        /* 
 831         * \_SB
 832         * ----
 833         * Fix for the system root bus device -- the only root-level device.
 834         */
 835        if ((parent == ACPI_ROOT_OBJECT) && (type == ACPI_BUS_TYPE_DEVICE)) {
 836                hid = ACPI_BUS_HID;
 837                strcpy(device->pnp.device_name, ACPI_BUS_DEVICE_NAME);
 838                strcpy(device->pnp.device_class, ACPI_BUS_CLASS);
 839        }
 840
 841        if (hid) {
 842                strcpy(device->pnp.hardware_id, hid);
 843                device->flags.hardware_id = 1;
 844        }
 845        if (uid) {
 846                strcpy(device->pnp.unique_id, uid);
 847                device->flags.unique_id = 1;
 848        }
 849        if (cid_list) {
 850                device->pnp.cid_list = kmalloc(cid_list->size, GFP_KERNEL);
 851                if (device->pnp.cid_list)
 852                        memcpy(device->pnp.cid_list, cid_list, cid_list->size);
 853                else
 854                        printk(KERN_ERR "Memory allocation error\n");
 855        }
 856
 857        acpi_os_free(buffer.pointer);
 858}
 859
 860int acpi_device_set_context(struct acpi_device * device, int type)
 861{
 862        acpi_status status = AE_OK;
 863        int result = 0;
 864        /*
 865         * Context
 866         * -------
 867         * Attach this 'struct acpi_device' to the ACPI object.  This makes
 868         * resolutions from handle->device very efficient.  Note that we need
 869         * to be careful with fixed-feature devices as they all attach to the
 870         * root object.
 871         */
 872        if (type != ACPI_BUS_TYPE_POWER_BUTTON && 
 873            type != ACPI_BUS_TYPE_SLEEP_BUTTON) {
 874                status = acpi_attach_data(device->handle,
 875                        acpi_bus_data_handler, device);
 876
 877                if (ACPI_FAILURE(status)) {
 878                        printk("Error attaching device data\n");
 879                        result = -ENODEV;
 880                }
 881        }
 882        return result;
 883}
 884
 885void acpi_device_get_debug_info(struct acpi_device * device, acpi_handle handle, int type)
 886{
 887#ifdef CONFIG_ACPI_DEBUG_OUTPUT
 888        char            *type_string = NULL;
 889        char            name[80] = {'?','\0'};
 890        struct acpi_buffer      buffer = {sizeof(name), name};
 891
 892        switch (type) {
 893        case ACPI_BUS_TYPE_DEVICE:
 894                type_string = "Device";
 895                acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer);
 896                break;
 897        case ACPI_BUS_TYPE_POWER:
 898                type_string = "Power Resource";
 899                acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer);
 900                break;
 901        case ACPI_BUS_TYPE_PROCESSOR:
 902                type_string = "Processor";
 903                acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer);
 904                break;
 905        case ACPI_BUS_TYPE_SYSTEM:
 906                type_string = "System";
 907                acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer);
 908                break;
 909        case ACPI_BUS_TYPE_THERMAL:
 910                type_string = "Thermal Zone";
 911                acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer);
 912                break;
 913        case ACPI_BUS_TYPE_POWER_BUTTON:
 914                type_string = "Power Button";
 915                sprintf(name, "PWRB");
 916                break;
 917        case ACPI_BUS_TYPE_SLEEP_BUTTON:
 918                type_string = "Sleep Button";
 919                sprintf(name, "SLPB");
 920                break;
 921        }
 922
 923        printk(KERN_DEBUG "Found %s %s [%p]\n", type_string, name, handle);
 924#endif /*CONFIG_ACPI_DEBUG_OUTPUT*/
 925}
 926
 927
 928int
 929acpi_bus_remove (
 930        struct acpi_device *dev,
 931        int rmdevice)
 932{
 933        int                     result = 0;
 934        struct acpi_driver      *driver;
 935        
 936        ACPI_FUNCTION_TRACE("acpi_bus_remove");
 937
 938        if (!dev)
 939                return_VALUE(-EINVAL);
 940
 941        driver = dev->driver;
 942
 943        if ((driver) && (driver->ops.remove)) {
 944
 945                if (driver->ops.stop) {
 946                        result = driver->ops.stop(dev, ACPI_BUS_REMOVAL_EJECT);
 947                        if (result)
 948                                return_VALUE(result);
 949                }
 950
 951                result = dev->driver->ops.remove(dev, ACPI_BUS_REMOVAL_EJECT);
 952                if (result) {
 953                        return_VALUE(result);
 954                }
 955
 956                atomic_dec(&dev->driver->references);
 957                dev->driver = NULL;
 958                acpi_driver_data(dev) = NULL;
 959        }
 960
 961        if (!rmdevice)
 962                return_VALUE(0);
 963
 964        if (dev->flags.bus_address) {
 965                if ((dev->parent) && (dev->parent->ops.unbind))
 966                        dev->parent->ops.unbind(dev);
 967        }
 968        
 969        acpi_device_unregister(dev, ACPI_BUS_REMOVAL_EJECT);
 970
 971        return_VALUE(0);
 972}
 973
 974
 975int
 976acpi_bus_add (
 977        struct acpi_device      **child,
 978        struct acpi_device      *parent,
 979        acpi_handle             handle,
 980        int                     type)
 981{
 982        int                     result = 0;
 983        struct acpi_device      *device = NULL;
 984
 985        ACPI_FUNCTION_TRACE("acpi_bus_add");
 986
 987        if (!child)
 988                return_VALUE(-EINVAL);
 989
 990        device = kmalloc(sizeof(struct acpi_device), GFP_KERNEL);
 991        if (!device) {
 992                ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Memory allocation error\n"));
 993                return_VALUE(-ENOMEM);
 994        }
 995        memset(device, 0, sizeof(struct acpi_device));
 996
 997        device->handle = handle;
 998        device->parent = parent;
 999
1000        acpi_device_get_busid(device,handle,type);
1001
1002        /*
1003         * Flags
1004         * -----
1005         * Get prior to calling acpi_bus_get_status() so we know whether
1006         * or not _STA is present.  Note that we only look for object
1007         * handles -- cannot evaluate objects until we know the device is
1008         * present and properly initialized.
1009         */
1010        result = acpi_bus_get_flags(device);
1011        if (result)
1012                goto end;
1013
1014        /*
1015         * Status
1016         * ------
1017         * See if the device is present.  We always assume that non-Device()
1018         * objects (e.g. thermal zones, power resources, processors, etc.) are
1019         * present, functioning, etc. (at least when parent object is present).
1020         * Note that _STA has a different meaning for some objects (e.g.
1021         * power resources) so we need to be careful how we use it.
1022         */
1023        switch (type) {
1024        case ACPI_BUS_TYPE_DEVICE:
1025                result = acpi_bus_get_status(device);
1026                if (ACPI_FAILURE(result) || !device->status.present) {
1027                        result = -ENOENT;
1028                        goto end;
1029                }
1030                break;
1031        default:
1032                STRUCT_TO_INT(device->status) = 0x0F;
1033                break;
1034        }
1035
1036        /*
1037         * Initialize Device
1038         * -----------------
1039         * TBD: Synch with Core's enumeration/initialization process.
1040         */
1041
1042        /*
1043         * Hardware ID, Unique ID, & Bus Address
1044         * -------------------------------------
1045         */
1046        acpi_device_set_id(device,parent,handle,type);
1047
1048        /*
1049         * Power Management
1050         * ----------------
1051         */
1052        if (device->flags.power_manageable) {
1053                result = acpi_bus_get_power_flags(device);
1054                if (result)
1055                        goto end;
1056        }
1057
1058        /*
1059         * Wakeup device management
1060         *-----------------------
1061         */
1062        if (device->flags.wake_capable) {
1063                result = acpi_bus_get_wakeup_device_flags(device);
1064                if (result)
1065                        goto end;
1066        }
1067
1068        /*
1069         * Performance Management
1070         * ----------------------
1071         */
1072        if (device->flags.performance_manageable) {
1073                result = acpi_bus_get_perf_flags(device);
1074                if (result)
1075                        goto end;
1076        }
1077
1078        if ((result = acpi_device_set_context(device,type)))
1079                goto end;
1080
1081        acpi_device_get_debug_info(device,handle,type);
1082
1083        acpi_device_register(device,parent);
1084
1085        /*
1086         * Bind _ADR-Based Devices
1087         * -----------------------
1088         * If there's a a bus address (_ADR) then we utilize the parent's 
1089         * 'bind' function (if exists) to bind the ACPI- and natively-
1090         * enumerated device representations.
1091         */
1092        if (device->flags.bus_address) {
1093                if (device->parent && device->parent->ops.bind)
1094                        device->parent->ops.bind(device);
1095        }
1096
1097        /*
1098         * Locate & Attach Driver
1099         * ----------------------
1100         * If there's a hardware id (_HID) or compatible ids (_CID) we check
1101         * to see if there's a driver installed for this kind of device.  Note
1102         * that drivers can install before or after a device is enumerated.
1103         *
1104         * TBD: Assumes LDM provides driver hot-plug capability.
1105         */
1106        acpi_bus_find_driver(device);
1107
1108end:
1109        if (!result)
1110                *child = device;
1111        else {
1112                if (device->pnp.cid_list)
1113                        kfree(device->pnp.cid_list);
1114                kfree(device);
1115        }
1116
1117        return_VALUE(result);
1118}
1119EXPORT_SYMBOL(acpi_bus_add);
1120
1121
1122int acpi_bus_scan (struct acpi_device   *start)
1123{
1124        acpi_status             status = AE_OK;
1125        struct acpi_device      *parent = NULL;
1126        struct acpi_device      *child = NULL;
1127        acpi_handle             phandle = NULL;
1128        acpi_handle             chandle = NULL;
1129        acpi_object_type        type = 0;
1130        u32                     level = 1;
1131
1132        ACPI_FUNCTION_TRACE("acpi_bus_scan");
1133
1134        if (!start)
1135                return_VALUE(-EINVAL);
1136
1137        parent = start;
1138        phandle = start->handle;
1139        
1140        /*
1141         * Parse through the ACPI namespace, identify all 'devices', and
1142         * create a new 'struct acpi_device' for each.
1143         */
1144        while ((level > 0) && parent) {
1145
1146                status = acpi_get_next_object(ACPI_TYPE_ANY, phandle,
1147                        chandle, &chandle);
1148
1149                /*
1150                 * If this scope is exhausted then move our way back up.
1151                 */
1152                if (ACPI_FAILURE(status)) {
1153                        level--;
1154                        chandle = phandle;
1155                        acpi_get_parent(phandle, &phandle);
1156                        if (parent->parent)
1157                                parent = parent->parent;
1158                        continue;
1159                }
1160
1161                status = acpi_get_type(chandle, &type);
1162                if (ACPI_FAILURE(status))
1163                        continue;
1164
1165                /*
1166                 * If this is a scope object then parse it (depth-first).
1167                 */
1168                if (type == ACPI_TYPE_LOCAL_SCOPE) {
1169                        level++;
1170                        phandle = chandle;
1171                        chandle = NULL;
1172                        continue;
1173                }
1174
1175                /*
1176                 * We're only interested in objects that we consider 'devices'.
1177                 */
1178                switch (type) {
1179                case ACPI_TYPE_DEVICE:
1180                        type = ACPI_BUS_TYPE_DEVICE;
1181                        break;
1182                case ACPI_TYPE_PROCESSOR:
1183                        type = ACPI_BUS_TYPE_PROCESSOR;
1184                        break;
1185                case ACPI_TYPE_THERMAL:
1186                        type = ACPI_BUS_TYPE_THERMAL;
1187                        break;
1188                case ACPI_TYPE_POWER:
1189                        type = ACPI_BUS_TYPE_POWER;
1190                        break;
1191                default:
1192                        continue;
1193                }
1194
1195                status = acpi_bus_add(&child, parent, chandle, type);
1196                if (ACPI_FAILURE(status))
1197                        continue;
1198
1199                /*
1200                 * If the device is present, enabled, and functioning then
1201                 * parse its scope (depth-first).  Note that we need to
1202                 * represent absent devices to facilitate PnP notifications
1203                 * -- but only the subtree head (not all of its children,
1204                 * which will be enumerated when the parent is inserted).
1205                 *
1206                 * TBD: Need notifications and other detection mechanisms
1207                 *      in place before we can fully implement this.
1208                 */
1209                if (child->status.present) {
1210                        status = acpi_get_next_object(ACPI_TYPE_ANY, chandle,
1211                                                      NULL, NULL);
1212                        if (ACPI_SUCCESS(status)) {
1213                                level++;
1214                                phandle = chandle;
1215                                chandle = NULL;
1216                                parent = child;
1217                        }
1218                }
1219        }
1220
1221        return_VALUE(0);
1222}
1223EXPORT_SYMBOL(acpi_bus_scan);
1224
1225
1226int
1227acpi_bus_trim(struct acpi_device        *start,
1228                int rmdevice)
1229{
1230        acpi_status             status;
1231        struct acpi_device      *parent, *child;
1232        acpi_handle             phandle, chandle;
1233        acpi_object_type        type;
1234        u32                     level = 1;
1235        int                     err = 0;
1236
1237        parent  = start;
1238        phandle = start->handle;
1239        child = chandle = NULL;
1240
1241        while ((level > 0) && parent && (!err)) {
1242                status = acpi_get_next_object(ACPI_TYPE_ANY, phandle,
1243                        chandle, &chandle);
1244
1245                /*
1246                 * If this scope is exhausted then move our way back up.
1247                 */
1248                if (ACPI_FAILURE(status)) {
1249                        level--;
1250                        chandle = phandle;
1251                        acpi_get_parent(phandle, &phandle);
1252                        child = parent;
1253                        parent = parent->parent;
1254
1255                        if (level == 0)
1256                                err = acpi_bus_remove(child, rmdevice);
1257                        else
1258                                err = acpi_bus_remove(child, 1);
1259
1260                        continue;
1261                }
1262
1263                status = acpi_get_type(chandle, &type);
1264                if (ACPI_FAILURE(status)) {
1265                        continue;
1266                }
1267                /*
1268                 * If there is a device corresponding to chandle then
1269                 * parse it (depth-first).
1270                 */
1271                if (acpi_bus_get_device(chandle, &child) == 0) {
1272                        level++;
1273                        phandle = chandle;
1274                        chandle = NULL;
1275                        parent = child;
1276                }
1277                continue;
1278        }
1279        return err;
1280}
1281
1282static int
1283acpi_bus_scan_fixed (
1284        struct acpi_device      *root)
1285{
1286        int                     result = 0;
1287        struct acpi_device      *device = NULL;
1288
1289        ACPI_FUNCTION_TRACE("acpi_bus_scan_fixed");
1290
1291        if (!root)
1292                return_VALUE(-ENODEV);
1293
1294        /*
1295         * Enumerate all fixed-feature devices.
1296         */
1297        if (acpi_fadt.pwr_button == 0)
1298                result = acpi_bus_add(&device, acpi_root, 
1299                        NULL, ACPI_BUS_TYPE_POWER_BUTTON);
1300
1301        if (acpi_fadt.sleep_button == 0)
1302                result = acpi_bus_add(&device, acpi_root, 
1303                        NULL, ACPI_BUS_TYPE_SLEEP_BUTTON);
1304
1305        return_VALUE(result);
1306}
1307
1308
1309static int __init acpi_scan_init(void)
1310{
1311        int result;
1312
1313        ACPI_FUNCTION_TRACE("acpi_scan_init");
1314
1315        if (acpi_disabled)
1316                return_VALUE(0);
1317
1318        kset_register(&acpi_namespace_kset);
1319
1320        /*
1321         * Create the root device in the bus's device tree
1322         */
1323        result = acpi_bus_add(&acpi_root, NULL, ACPI_ROOT_OBJECT, 
1324                ACPI_BUS_TYPE_SYSTEM);
1325        if (result)
1326                goto Done;
1327
1328        /*
1329         * Enumerate devices in the ACPI namespace.
1330         */
1331        result = acpi_bus_scan_fixed(acpi_root);
1332        if (!result) 
1333                result = acpi_bus_scan(acpi_root);
1334
1335        if (result)
1336                acpi_device_unregister(acpi_root, ACPI_BUS_REMOVAL_NORMAL);
1337
1338 Done:
1339        return_VALUE(result);
1340}
1341
1342subsys_initcall(acpi_scan_init);
1343
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.