Subversion Repositories Kolibri OS

Rev

Rev 1627 | Rev 1867 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1.  
  2.  
  3. #include <ddk.h>
  4. #include <linux/errno.h>
  5. #include <mutex.h>
  6. #include <pci.h>
  7. #include <syscall.h>
  8.  
  9. #include "acpi.h"
  10. #include "acpi_bus.h"
  11.  
  12.  
  13. #define PREFIX "ACPI: "
  14.  
  15. #define ACPI_BUS_CLASS          "system_bus"
  16. #define ACPI_BUS_HID            "KLBSYBUS"
  17. #define ACPI_BUS_DEVICE_NAME    "System Bus"
  18.  
  19.  
  20. #define ACPI_IS_ROOT_DEVICE(device)    (!(device)->parent)
  21.  
  22. #define STRUCT_TO_INT(s)        (*((int*)&s))
  23.  
  24.  
  25. extern struct acpi_device *acpi_root;
  26.  
  27. static LIST_HEAD(acpi_device_list);
  28. static LIST_HEAD(acpi_bus_id_list);
  29. DEFINE_MUTEX(acpi_device_lock);
  30.  
  31.  
  32. struct acpi_device_bus_id{
  33.         char bus_id[15];
  34.         unsigned int instance_no;
  35.         struct list_head node;
  36. };
  37.  
  38.  
  39. struct acpi_hardware_id {
  40.     struct list_head list;
  41.     char *id;
  42. };
  43.  
  44. #define acpi_device_name(d) ((d)->pnp.device_name)
  45. #define acpi_device_class(d)    ((d)->pnp.device_class)
  46.  
  47.  
  48. static void
  49. acpi_util_eval_error(ACPI_HANDLE h, ACPI_STRING p, ACPI_STATUS s)
  50. {
  51. #ifdef ACPI_DEBUG_OUTPUT
  52.     char prefix[80] = {'\0'};
  53.     ACPI_BUFFER buffer = {sizeof(prefix), prefix};
  54.     AcpiGetName(h, ACPI_FULL_PATHNAME, &buffer);
  55.     ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Evaluate [%s.%s]: %s\n",
  56.         (char *) prefix, p, AcpiFormatException(s)));
  57. #else
  58.     return;
  59. #endif
  60. }
  61.  
  62. ACPI_STATUS
  63. acpi_evaluate_integer(ACPI_HANDLE handle, ACPI_STRING pathname,
  64.               ACPI_OBJECT_LIST *arguments, unsigned long long *data)
  65. {
  66.     ACPI_STATUS status = AE_OK;
  67.     ACPI_OBJECT element;
  68.     ACPI_BUFFER buffer = { 0, NULL };
  69.  
  70.     if (!data)
  71.         return AE_BAD_PARAMETER;
  72.  
  73.     buffer.Length = sizeof(ACPI_OBJECT);
  74.     buffer.Pointer = &element;
  75.     status = AcpiEvaluateObject(handle, pathname, arguments, &buffer);
  76.     if (ACPI_FAILURE(status)) {
  77.         acpi_util_eval_error(handle, pathname, status);
  78.         return status;
  79.     }
  80.  
  81.     if (element.Type != ACPI_TYPE_INTEGER) {
  82.         acpi_util_eval_error(handle, pathname, AE_BAD_DATA);
  83.         return AE_BAD_DATA;
  84.     }
  85.  
  86.     *data = element.Integer.Value;
  87.  
  88.     ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Return value [%llu]\n", *data));
  89.  
  90.     return AE_OK;
  91. }
  92.  
  93.  
  94. void acpi_bus_data_handler(ACPI_HANDLE handle, void *context)
  95. {
  96.  
  97.     /* TBD */
  98.  
  99.     return;
  100. }
  101.  
  102. int acpi_bus_get_device(ACPI_HANDLE handle, struct acpi_device **device)
  103. {
  104.     ACPI_STATUS status = AE_OK;
  105.  
  106.     if (!device)
  107.     {
  108.         return -EINVAL;
  109.     };
  110.  
  111.     /* TBD: Support fixed-feature devices */
  112.  
  113.     status = AcpiGetData(handle, acpi_bus_data_handler, (void **)device);
  114.     if (ACPI_FAILURE(status) || !*device) {
  115.         ACPI_DEBUG_PRINT((ACPI_DB_INFO, "No context for object [%p]\n",
  116.                   handle));
  117.         return -ENODEV;
  118.     }
  119.     return 0;
  120. }
  121.  
  122.  
  123. ACPI_STATUS acpi_bus_get_status_handle(ACPI_HANDLE handle,
  124.                        unsigned long long *sta)
  125. {
  126.     ACPI_STATUS status;
  127.  
  128.     status = acpi_evaluate_integer(handle, "_STA", NULL, sta);
  129.     if (ACPI_SUCCESS(status))
  130.     {
  131.         return AE_OK;
  132.     };
  133.  
  134.     if (status == AE_NOT_FOUND)
  135.     {
  136.         *sta = ACPI_STA_DEVICE_PRESENT | ACPI_STA_DEVICE_ENABLED |
  137.                ACPI_STA_DEVICE_UI      | ACPI_STA_DEVICE_FUNCTIONING;
  138.         return AE_OK;
  139.     }
  140.     return status;
  141. }
  142.  
  143.  
  144.  
  145. /* --------------------------------------------------------------------------
  146.                         ACPI Bus operations
  147.    -------------------------------------------------------------------------- */
  148.  
  149. int acpi_match_device_ids(struct acpi_device *device,
  150.               const struct acpi_device_ids *ids)
  151. {
  152.     const struct acpi_device_ids *id;
  153.     struct acpi_hardware_id *hwid;
  154.  
  155.     /*
  156.      * If the device is not present, it is unnecessary to load device
  157.      * driver for it.
  158.      */
  159. //    if (!device->status.present)
  160. //        return -ENODEV;
  161.  
  162.     for (id = ids; id->id[0]; id++)
  163.         list_for_each_entry(hwid, &device->pnp.ids, list)
  164.             if (!strcmp((char *) id->id, hwid->id))
  165.                 return 0;
  166.  
  167.     return -ENOENT;
  168. }
  169.  
  170.  
  171. static int acpi_device_register(struct acpi_device *device)
  172. {
  173.     int result;
  174.     struct acpi_device_bus_id *acpi_device_bus_id, *new_bus_id;
  175.     int found = 0;
  176.  
  177.     /*
  178.      * Linkage
  179.      * -------
  180.      * Link this device to its parent and siblings.
  181.      */
  182.     INIT_LIST_HEAD(&device->children);
  183.     INIT_LIST_HEAD(&device->node);
  184.  
  185.     new_bus_id = kzalloc(sizeof(struct acpi_device_bus_id), GFP_KERNEL);
  186.     if (!new_bus_id) {
  187.                 printk(KERN_ERR PREFIX "Memory allocation error\n");
  188.         return -ENOMEM;
  189.     }
  190.  
  191.     mutex_lock(&acpi_device_lock);
  192.     /*
  193.      * Find suitable bus_id and instance number in acpi_bus_id_list
  194.      * If failed, create one and link it into acpi_bus_id_list
  195.      */
  196.     list_for_each_entry(acpi_device_bus_id, &acpi_bus_id_list, node)
  197.     {
  198.                 if (!strcmp(acpi_device_bus_id->bus_id,
  199.                 acpi_device_hid(device)))
  200.         {
  201.             acpi_device_bus_id->instance_no++;
  202.             found = 1;
  203.             kfree(new_bus_id);
  204.             break;
  205.         }
  206.     };
  207.  
  208.     if (!found)
  209.     {
  210.         acpi_device_bus_id = new_bus_id;
  211.         strcpy(acpi_device_bus_id->bus_id, acpi_device_hid(device));
  212.         acpi_device_bus_id->instance_no = 0;
  213.         list_add_tail(&acpi_device_bus_id->node, &acpi_bus_id_list);
  214.     }
  215.  
  216. //    dev_set_name(&device->dev, "%s:%02x", acpi_device_bus_id->bus_id, acpi_device_bus_id->instance_no);
  217.  
  218.     if (device->parent)
  219.         list_add_tail(&device->node, &device->parent->children);
  220.  
  221.     mutex_unlock(&acpi_device_lock);
  222.  
  223. //    device->dev.bus = &acpi_bus_type;
  224. //    device->dev.release = &acpi_device_release;
  225. //    result = device_register(&device->dev);
  226. //    if (result) {
  227. //        dev_err(&device->dev, "Error registering device\n");
  228. //        goto end;
  229. //    }
  230.  
  231.  
  232. //    device->removal_type = ACPI_BUS_REMOVAL_NORMAL;
  233.     return 0;
  234. end:
  235.     mutex_lock(&acpi_device_lock);
  236.     if (device->parent)
  237.         list_del(&device->node);
  238.     mutex_unlock(&acpi_device_lock);
  239.     return result;
  240. }
  241.  
  242.  
  243. static struct acpi_device *acpi_bus_get_parent(ACPI_HANDLE handle)
  244. {
  245.     ACPI_STATUS status;
  246.     struct      acpi_device *device;
  247.     int         ret;
  248.  
  249.     /*
  250.      * Fixed hardware devices do not appear in the namespace and do not
  251.      * have handles, but we fabricate acpi_devices for them, so we have
  252.      * to deal with them specially.
  253.      */
  254.     if (handle == NULL)
  255.         return acpi_root;
  256.  
  257.         do {
  258.         status = AcpiGetParent(handle, &handle);
  259.         if (status == AE_NULL_ENTRY)
  260.             return NULL;
  261.         if (ACPI_FAILURE(status))
  262.             return acpi_root;
  263.  
  264.         ret = acpi_bus_get_device(handle, &device);
  265.         if (ret == 0)
  266.             return device;
  267.     } while (1);
  268. }
  269.  
  270.  
  271. static int acpi_bus_get_flags(struct acpi_device *device)
  272. {
  273.     ACPI_STATUS status = AE_OK;
  274.     ACPI_HANDLE temp   = NULL;
  275.  
  276.     /* Presence of _STA indicates 'dynamic_status' */
  277.     status = AcpiGetHandle(device->handle, "_STA", &temp);
  278.     if (ACPI_SUCCESS(status))
  279.         device->flags.dynamic_status = 1;
  280.  
  281.     /* Presence of _RMV indicates 'removable' */
  282.     status = AcpiGetHandle(device->handle, "_RMV", &temp);
  283.     if (ACPI_SUCCESS(status))
  284.         device->flags.removable = 1;
  285.  
  286.     /* Presence of _EJD|_EJ0 indicates 'ejectable' */
  287.     status = AcpiGetHandle(device->handle, "_EJD", &temp);
  288.     if (ACPI_SUCCESS(status))
  289.         device->flags.ejectable = 1;
  290.     else {
  291.         status = AcpiGetHandle(device->handle, "_EJ0", &temp);
  292.         if (ACPI_SUCCESS(status))
  293.             device->flags.ejectable = 1;
  294.     }
  295.  
  296.     /* Presence of _LCK indicates 'lockable' */
  297.     status = AcpiGetHandle(device->handle, "_LCK", &temp);
  298.     if (ACPI_SUCCESS(status))
  299.         device->flags.lockable = 1;
  300.  
  301.     /* Presence of _PS0|_PR0 indicates 'power manageable' */
  302.     status = AcpiGetHandle(device->handle, "_PS0", &temp);
  303.     if (ACPI_FAILURE(status))
  304.         status = AcpiGetHandle(device->handle, "_PR0", &temp);
  305.     if (ACPI_SUCCESS(status))
  306.         device->flags.power_manageable = 1;
  307.  
  308.     /* Presence of _PRW indicates wake capable */
  309.     status = AcpiGetHandle(device->handle, "_PRW", &temp);
  310.     if (ACPI_SUCCESS(status))
  311.         device->flags.wake_capable = 1;
  312.  
  313.     /* TBD: Performance management */
  314.  
  315.     return 0;
  316. }
  317.  
  318. static void acpi_device_get_busid(struct acpi_device *device)
  319. {
  320.     char bus_id[5] = { '?', 0 };
  321.     struct acpi_buffer buffer = { sizeof(bus_id), bus_id };
  322.     int i = 0;
  323.  
  324.     /*
  325.      * Bus ID
  326.      * ------
  327.      * The device's Bus ID is simply the object name.
  328.      * TBD: Shouldn't this value be unique (within the ACPI namespace)?
  329.      */
  330.     if (ACPI_IS_ROOT_DEVICE(device)) {
  331.         strcpy(device->pnp.bus_id, "ACPI");
  332.         return;
  333.     }
  334.  
  335.     switch (device->device_type)
  336.     {
  337.         case ACPI_BUS_TYPE_POWER_BUTTON:
  338.             strcpy(device->pnp.bus_id, "PWRF");
  339.             break;
  340.         case ACPI_BUS_TYPE_SLEEP_BUTTON:
  341.             strcpy(device->pnp.bus_id, "SLPF");
  342.             break;
  343.         default:
  344.             AcpiGetName(device->handle, ACPI_SINGLE_NAME, &buffer);
  345.         /* Clean up trailing underscores (if any) */
  346.                 for (i = 3; i > 1; i--) {
  347.                 if (bus_id[i] == '_')
  348.                     bus_id[i] = '\0';
  349.                 else
  350.                     break;
  351.             }
  352.             strcpy(device->pnp.bus_id, bus_id);
  353.             break;
  354.     }
  355. }
  356.  
  357.  
  358. #define ACPI_VIDEO_OUTPUT_SWITCHING         0x0001
  359. #define ACPI_VIDEO_DEVICE_POSTING           0x0002
  360. #define ACPI_VIDEO_ROM_AVAILABLE            0x0004
  361. #define ACPI_VIDEO_BACKLIGHT                0x0008
  362. #define ACPI_VIDEO_BACKLIGHT_FORCE_VENDOR       0x0010
  363. #define ACPI_VIDEO_BACKLIGHT_FORCE_VIDEO        0x0020
  364. #define ACPI_VIDEO_OUTPUT_SWITCHING_FORCE_VENDOR    0x0040
  365. #define ACPI_VIDEO_OUTPUT_SWITCHING_FORCE_VIDEO     0x0080
  366. #define ACPI_VIDEO_BACKLIGHT_DMI_VENDOR         0x0100
  367. #define ACPI_VIDEO_BACKLIGHT_DMI_VIDEO          0x0200
  368. #define ACPI_VIDEO_OUTPUT_SWITCHING_DMI_VENDOR      0x0400
  369. #define ACPI_VIDEO_OUTPUT_SWITCHING_DMI_VIDEO       0x0800
  370.  
  371.  
  372. long acpi_is_video_device(struct acpi_device *device)
  373. {
  374.     ACPI_HANDLE h_dummy;
  375.     long video_caps = 0;
  376.  
  377.     if (!device)
  378.         return 0;
  379.  
  380.     /* Is this device able to support video switching ? */
  381.     if (ACPI_SUCCESS(AcpiGetHandle(device->handle, "_DOD", &h_dummy)) ||
  382.         ACPI_SUCCESS(AcpiGetHandle(device->handle, "_DOS", &h_dummy)))
  383.         video_caps |= ACPI_VIDEO_OUTPUT_SWITCHING;
  384.  
  385.     /* Is this device able to retrieve a video ROM ? */
  386.     if (ACPI_SUCCESS(AcpiGetHandle(device->handle, "_ROM", &h_dummy)))
  387.         video_caps |= ACPI_VIDEO_ROM_AVAILABLE;
  388.  
  389.     /* Is this device able to configure which video head to be POSTed ? */
  390.     if (ACPI_SUCCESS(AcpiGetHandle(device->handle, "_VPO", &h_dummy)) &&
  391.         ACPI_SUCCESS(AcpiGetHandle(device->handle, "_GPD", &h_dummy)) &&
  392.         ACPI_SUCCESS(AcpiGetHandle(device->handle, "_SPD", &h_dummy)))
  393.         video_caps |= ACPI_VIDEO_DEVICE_POSTING;
  394.  
  395.      return video_caps;
  396. }
  397.  
  398. /*
  399.  * acpi_bay_match - see if a device is an ejectable driver bay
  400.  *
  401.  * If an acpi object is ejectable and has one of the ACPI ATA methods defined,
  402.  * then we can safely call it an ejectable drive bay
  403.  */
  404. static int acpi_bay_match(struct acpi_device *device){
  405.     ACPI_STATUS status;
  406.     ACPI_HANDLE handle;
  407.     ACPI_HANDLE tmp;
  408.     ACPI_HANDLE phandle;
  409.  
  410.     handle = device->handle;
  411.  
  412.     status = AcpiGetHandle(handle, "_EJ0", &tmp);
  413.     if (ACPI_FAILURE(status))
  414.         return -ENODEV;
  415.  
  416.     if ((ACPI_SUCCESS(AcpiGetHandle(handle, "_GTF", &tmp))) ||
  417.         (ACPI_SUCCESS(AcpiGetHandle(handle, "_GTM", &tmp))) ||
  418.         (ACPI_SUCCESS(AcpiGetHandle(handle, "_STM", &tmp))) ||
  419.         (ACPI_SUCCESS(AcpiGetHandle(handle, "_SDD", &tmp))))
  420.         return 0;
  421.  
  422.     if (AcpiGetParent(handle, &phandle))
  423.         return -ENODEV;
  424.  
  425.     if ((ACPI_SUCCESS(AcpiGetHandle(phandle, "_GTF", &tmp))) ||
  426.         (ACPI_SUCCESS(AcpiGetHandle(phandle, "_GTM", &tmp))) ||
  427.         (ACPI_SUCCESS(AcpiGetHandle(phandle, "_STM", &tmp))) ||
  428.         (ACPI_SUCCESS(AcpiGetHandle(phandle, "_SDD", &tmp))))
  429.         return 0;
  430.  
  431.     return -ENODEV;
  432. }
  433.  
  434. /*
  435.  * acpi_dock_match - see if a device has a _DCK method
  436.  */
  437. static int acpi_dock_match(struct acpi_device *device)
  438. {
  439.     ACPI_HANDLE tmp;
  440.     return AcpiGetHandle(device->handle, "_DCK", &tmp);
  441. }
  442.  
  443. char *acpi_device_hid(struct acpi_device *device)
  444. {
  445.     struct acpi_hardware_id *hid;
  446.  
  447.     hid = list_first_entry(&device->pnp.ids, struct acpi_hardware_id, list);
  448.     return hid->id;
  449. }
  450.  
  451. static void acpi_add_id(struct acpi_device *device, const char *dev_id)
  452. {
  453.     struct acpi_hardware_id *id;
  454.  
  455.     id = kmalloc(sizeof(*id), GFP_KERNEL);
  456.     if (!id)
  457.         return;
  458.  
  459.     INIT_LIST_HEAD(&id->list);
  460.  
  461.     id->id = kmalloc(strlen(dev_id) + 1, GFP_KERNEL);
  462.     if (!id->id) {
  463.         kfree(id);
  464.         return;
  465.     }
  466.  
  467.     strcpy(id->id, dev_id);
  468.     list_add_tail(&id->list, &device->pnp.ids);
  469. }
  470.  
  471.  
  472.  
  473. static void acpi_device_set_id(struct acpi_device *device)
  474. {
  475.     ACPI_STATUS status;
  476.     ACPI_DEVICE_INFO *info;
  477.     ACPI_DEVICE_ID_LIST *cid_list;
  478.     int i;
  479.  
  480.     switch (device->device_type)
  481.     {
  482.         case ACPI_BUS_TYPE_DEVICE:
  483.                 if (ACPI_IS_ROOT_DEVICE(device)) {
  484.                 acpi_add_id(device, ACPI_SYSTEM_HID);
  485.                 break;
  486.             }
  487.  
  488.             status = AcpiGetObjectInfo(device->handle, &info);
  489.             if (ACPI_FAILURE(status)) {
  490.                 printk(KERN_ERR PREFIX "%s: Error reading device info\n", __func__);
  491.                 return;
  492.             }
  493.  
  494.             if (info->Valid & ACPI_VALID_HID)
  495.                 acpi_add_id(device, info->HardwareId.String);
  496.             if (info->Valid & ACPI_VALID_CID)
  497.             {
  498.                 cid_list = &info->CompatibleIdList;
  499.                 for (i = 0; i < cid_list->Count; i++)
  500.                     acpi_add_id(device, cid_list->Ids[i].String);
  501.             }
  502.             if (info->Valid & ACPI_VALID_ADR) {
  503.                 device->pnp.bus_address = info->Address;
  504.                 device->flags.bus_address = 1;
  505.             }
  506.  
  507.             kfree(info);
  508.  
  509.         /*
  510.          * Some devices don't reliably have _HIDs & _CIDs, so add
  511.          * synthetic HIDs to make sure drivers can find them.
  512.          */
  513.         if (acpi_is_video_device(device))
  514.             acpi_add_id(device, ACPI_VIDEO_HID);
  515.         else if (ACPI_SUCCESS(acpi_bay_match(device)))
  516.             acpi_add_id(device, ACPI_BAY_HID);
  517.         else if (ACPI_SUCCESS(acpi_dock_match(device)))
  518.             acpi_add_id(device, ACPI_DOCK_HID);
  519.         else if (!acpi_device_hid(device) &&
  520.              ACPI_IS_ROOT_DEVICE(device->parent)) {
  521.             acpi_add_id(device, ACPI_BUS_HID); /* \_SB, LNXSYBUS */
  522.             strcpy(device->pnp.device_name, ACPI_BUS_DEVICE_NAME);
  523.             strcpy(device->pnp.device_class, ACPI_BUS_CLASS);
  524.         }
  525.  
  526.         break;
  527.     case ACPI_BUS_TYPE_POWER:
  528.         acpi_add_id(device, ACPI_POWER_HID);
  529.         break;
  530.     case ACPI_BUS_TYPE_PROCESSOR:
  531.         acpi_add_id(device, ACPI_PROCESSOR_OBJECT_HID);
  532.         break;
  533.     case ACPI_BUS_TYPE_THERMAL:
  534.         acpi_add_id(device, ACPI_THERMAL_HID);
  535.         break;
  536.     case ACPI_BUS_TYPE_POWER_BUTTON:
  537.         acpi_add_id(device, ACPI_BUTTON_HID_POWERF);
  538.         break;
  539.     case ACPI_BUS_TYPE_SLEEP_BUTTON:
  540.         acpi_add_id(device, ACPI_BUTTON_HID_SLEEPF);
  541.         break;
  542.     }
  543.  
  544.     /*
  545.      * We build acpi_devices for some objects that don't have _HID or _CID,
  546.      * e.g., PCI bridges and slots.  Drivers can't bind to these objects,
  547.      * but we do use them indirectly by traversing the acpi_device tree.
  548.      * This generic ID isn't useful for driver binding, but it provides
  549.      * the useful property that "every acpi_device has an ID."
  550.      */
  551.     if (list_empty(&device->pnp.ids))
  552.         acpi_add_id(device, "device");
  553. }
  554.  
  555. static int acpi_device_set_context(struct acpi_device *device)
  556. {
  557.     ACPI_STATUS status;
  558.  
  559.     /*
  560.      * Context
  561.      * -------
  562.      * Attach this 'struct acpi_device' to the ACPI object.  This makes
  563.      * resolutions from handle->device very efficient.  Fixed hardware
  564.      * devices have no handles, so we skip them.
  565.      */
  566.     if (!device->handle)
  567.         return 0;
  568.  
  569.     status = AcpiAttachData(device->handle,
  570.                   acpi_bus_data_handler, device);
  571.     if (ACPI_SUCCESS(status))
  572.         return 0;
  573.  
  574.         printk(KERN_ERR PREFIX "Error attaching device data\n");
  575.     return -ENODEV;
  576. }
  577.  
  578.  
  579. static int acpi_add_single_object(struct acpi_device **child,
  580.                   ACPI_HANDLE handle, int type,
  581.                   unsigned long long sta,
  582.                   struct acpi_bus_ops *ops)
  583. {
  584.     int result;
  585.     struct acpi_device *device;
  586.     ACPI_BUFFER buffer = { ACPI_ALLOCATE_BUFFER, NULL };
  587.  
  588.     device = kzalloc(sizeof(struct acpi_device), GFP_KERNEL);
  589.     if (!device) {
  590.                 printk(KERN_ERR PREFIX "Memory allocation error\n");
  591.         return -ENOMEM;
  592.     }
  593.  
  594.     INIT_LIST_HEAD(&device->pnp.ids);
  595.     device->device_type = type;
  596.     device->handle = handle;
  597.     device->parent = acpi_bus_get_parent(handle);
  598.     device->bus_ops = *ops; /* workround for not call .start */
  599.     STRUCT_TO_INT(device->status) = sta;
  600.  
  601.     acpi_device_get_busid(device);
  602.  
  603.     /*
  604.      * Flags
  605.      * -----
  606.      * Note that we only look for object handles -- cannot evaluate objects
  607.      * until we know the device is present and properly initialized.
  608.      */
  609.     result = acpi_bus_get_flags(device);
  610.     if (result)
  611.         goto end;
  612.  
  613.     /*
  614.      * Initialize Device
  615.      * -----------------
  616.      * TBD: Synch with Core's enumeration/initialization process.
  617.      */
  618.     acpi_device_set_id(device);
  619.  
  620.  
  621.     if ((result = acpi_device_set_context(device)))
  622.         goto end;
  623.  
  624.     result = acpi_device_register(device);
  625.  
  626.     /*
  627.      * Bind _ADR-Based Devices when hot add
  628.      */
  629.     if (device->flags.bus_address) {
  630.         if (device->parent && device->parent->ops.bind)
  631.             device->parent->ops.bind(device);
  632.     }
  633.  
  634. end:
  635.     if (!result) {
  636.         AcpiGetName(handle, ACPI_FULL_PATHNAME, &buffer);
  637.         dbgprintf(PREFIX "Adding [%s]\n", (char *)buffer.Pointer);
  638.         kfree(buffer.Pointer);
  639.         *child = device;
  640.     };
  641.     return result;
  642. }
  643.  
  644. #define ACPI_STA_DEFAULT (ACPI_STA_DEVICE_PRESENT | ACPI_STA_DEVICE_ENABLED | \
  645.                           ACPI_STA_DEVICE_UI      | ACPI_STA_DEVICE_FUNCTIONING)
  646.  
  647. static int acpi_bus_type_and_status(ACPI_HANDLE handle, int *type,
  648.                     unsigned long long *sta)
  649. {
  650.     ACPI_STATUS status;
  651.     ACPI_OBJECT_TYPE acpi_type;
  652.  
  653.     status = AcpiGetType(handle, &acpi_type);
  654.     if (ACPI_FAILURE(status))
  655.         return -ENODEV;
  656.  
  657.     switch (acpi_type)
  658.     {
  659.         case ACPI_TYPE_ANY:     /* for ACPI_ROOT_OBJECT */
  660.         case ACPI_TYPE_DEVICE:
  661.             *type = ACPI_BUS_TYPE_DEVICE;
  662.             status = acpi_bus_get_status_handle(handle, sta);
  663.             if (ACPI_FAILURE(status))
  664.                 return -ENODEV;
  665.             break;
  666.         case ACPI_TYPE_PROCESSOR:
  667.             *type = ACPI_BUS_TYPE_PROCESSOR;
  668.             status = acpi_bus_get_status_handle(handle, sta);
  669.             if (ACPI_FAILURE(status))
  670.                 return -ENODEV;
  671.             break;
  672.         case ACPI_TYPE_THERMAL:
  673.             *type = ACPI_BUS_TYPE_THERMAL;
  674.             *sta = ACPI_STA_DEFAULT;
  675.             break;
  676.         case ACPI_TYPE_POWER:
  677.             *type = ACPI_BUS_TYPE_POWER;
  678.             *sta = ACPI_STA_DEFAULT;
  679.             break;
  680.         default:
  681.             return -ENODEV;
  682.     }
  683.  
  684.     return 0;
  685. }
  686.  
  687.  
  688. static ACPI_STATUS acpi_bus_check_add(ACPI_HANDLE handle, u32 lvl,
  689.                       void *context, void **return_value)
  690. {
  691.     struct acpi_bus_ops *ops = context;
  692.     int type;
  693.     unsigned long long sta;
  694.     struct acpi_device *device;
  695.     ACPI_STATUS status;
  696.     int result;
  697.  
  698.     result = acpi_bus_type_and_status(handle, &type, &sta);
  699.     if (result)
  700.         return AE_OK;
  701.  
  702.     if (!(sta & ACPI_STA_DEVICE_PRESENT) &&
  703.         !(sta & ACPI_STA_DEVICE_FUNCTIONING))
  704.         return AE_CTRL_DEPTH;
  705.  
  706.     /*
  707.      * We may already have an acpi_device from a previous enumeration.  If
  708.      * so, we needn't add it again, but we may still have to start it.
  709.      */
  710.     device = NULL;
  711.     acpi_bus_get_device(handle, &device);
  712.     if (ops->acpi_op_add && !device)
  713.         acpi_add_single_object(&device, handle, type, sta, ops);
  714.  
  715.     if (!device)
  716.         return AE_CTRL_DEPTH;
  717.  
  718. /*
  719.     if (ops->acpi_op_start && !(ops->acpi_op_add)) {
  720.         status = acpi_start_single_object(device);
  721.         if (ACPI_FAILURE(status))
  722.             return AE_CTRL_DEPTH;
  723.     }
  724. */
  725.  
  726.     if (!*return_value)
  727.         *return_value = device;
  728.     return AE_OK;
  729. }
  730.  
  731.  
  732. static int acpi_bus_scan(ACPI_HANDLE handle, struct acpi_bus_ops *ops,
  733.              struct acpi_device **child)
  734. {
  735.     ACPI_STATUS status;
  736.     void *device = NULL;
  737.  
  738.     status = acpi_bus_check_add(handle, 0, ops, &device);
  739.     if (ACPI_SUCCESS(status))
  740.         AcpiWalkNamespace(ACPI_TYPE_ANY, handle, ACPI_UINT32_MAX,
  741.                     acpi_bus_check_add, NULL, ops, &device);
  742.  
  743.     if (child)
  744.         *child = device;
  745.  
  746.     if (device)
  747.         return 0;
  748.     else
  749.         return -ENODEV;
  750. }
  751.  
  752.  
  753. int acpi_scan()
  754. {
  755.     int err;
  756.     struct acpi_bus_ops ops;
  757.  
  758.     memset(&ops, 0, sizeof(ops));
  759.     ops.acpi_op_add = 1;
  760.     ops.acpi_op_start = 1;
  761.  
  762.     err = acpi_bus_scan(ACPI_ROOT_OBJECT, &ops, &acpi_root);
  763.  
  764.     return err;
  765. };
  766.  
  767.