ACPICA: AcpiGetDevices: Eliminate unnecessary _STA calls
authorLin Ming <ming.m.lin@intel.com>
Thu, 21 Jan 2010 01:15:20 +0000 (09:15 +0800)
committerLen Brown <len.brown@intel.com>
Fri, 22 Jan 2010 17:30:05 +0000 (12:30 -0500)
In the case where a specific _HID is requested, do not run _STA
until a _HID match is found. This eliminates potentially dozens
of _STA calls during a search for a particular device/HID.

Signed-off-by: Lin Ming <ming.m.lin@intel.com>
Signed-off-by: Bob Moore <robert.moore@intel.com>
Signed-off-by: Len Brown <len.brown@intel.com>
drivers/acpi/acpica/nsxfeval.c

index c5a5357..ebef8a7 100644 (file)
@@ -562,25 +562,20 @@ acpi_ns_get_device_callback(acpi_handle obj_handle,
                return (AE_BAD_PARAMETER);
        }
 
-       /* Run _STA to determine if device is present */
-
-       status = acpi_ut_execute_STA(node, &flags);
-       if (ACPI_FAILURE(status)) {
-               return (AE_CTRL_DEPTH);
-       }
-
-       if (!(flags & ACPI_STA_DEVICE_PRESENT) &&
-           !(flags & ACPI_STA_DEVICE_FUNCTIONING)) {
-               /*
-                * Don't examine the children of the device only when the
-                * device is neither present nor functional. See ACPI spec,
-                * description of _STA for more information.
-                */
-               return (AE_CTRL_DEPTH);
-       }
-
-       /* Filter based on device HID & CID */
-
+       /*
+        * First, filter based on the device HID and CID.
+        *
+        * 01/2010: For this case where a specific HID is requested, we don't
+        * want to run _STA until we have an actual HID match. Thus, we will
+        * not unnecessarily execute _STA on devices for which the caller
+        * doesn't care about. Previously, _STA was executed unconditionally
+        * on all devices found here.
+        *
+        * A side-effect of this change is that now we will continue to search
+        * for a matching HID even under device trees where the parent device
+        * would have returned a _STA that indicates it is not present or
+        * not functioning (thus aborting the search on that branch).
+        */
        if (info->hid != NULL) {
                status = acpi_ut_execute_HID(node, &hid);
                if (status == AE_NOT_FOUND) {
@@ -620,6 +615,25 @@ acpi_ns_get_device_callback(acpi_handle obj_handle,
                }
        }
 
+       /* Run _STA to determine if device is present */
+
+       status = acpi_ut_execute_STA(node, &flags);
+       if (ACPI_FAILURE(status)) {
+               return (AE_CTRL_DEPTH);
+       }
+
+       if (!(flags & ACPI_STA_DEVICE_PRESENT) &&
+           !(flags & ACPI_STA_DEVICE_FUNCTIONING)) {
+               /*
+                * Don't examine the children of the device only when the
+                * device is neither present nor functional. See ACPI spec,
+                * description of _STA for more information.
+                */
+               return (AE_CTRL_DEPTH);
+       }
+
+       /* We have a valid device, invoke the user function */
+
        status = info->user_function(obj_handle, nesting_level, info->context,
                                     return_value);
        return (status);