Browse Source

Invoke _INI if needed, and correctly traverse child devices

Isaac Woods 4 years ago
parent
commit
bf6199a480
2 changed files with 19 additions and 19 deletions
  1. 12 12
      aml/src/lib.rs
  2. 7 7
      aml/src/value.rs

+ 12 - 12
aml/src/lib.rs

@@ -251,14 +251,6 @@ impl AmlContext {
         use namespace::NamespaceLevel;
         use value::StatusObject;
 
-        /*
-         * TODO:
-         *    - unconditionally execute `\_SB._INI`, if it exists
-         *    - traverse namespace, looking for devices
-         *    - if `_STA` is present, evaluate it. If not, assume device is present and functional.
-         *    - if device is present, evaluate `_INI` if it exists
-         *    - if device is present, or isn't present but is functional, traverse it's children for more devices
-         */
         /*
          * If `\_SB._INI` exists, we unconditionally execute it at the beginning of device initialization.
          */
@@ -279,17 +271,25 @@ impl AmlContext {
          */
         self.namespace.clone().traverse(|path, level: &NamespaceLevel| match level.typ {
             LevelType::Device => {
-                let sta = if level.values.contains_key(&NameSeg::from_str("_STA").unwrap()) {
+                let status = if level.values.contains_key(&NameSeg::from_str("_STA").unwrap()) {
                     self.invoke_method(&AmlName::from_str("_STA").unwrap().resolve(&path)?, Args::default())?
                         .as_status()?
                 } else {
                     StatusObject::default()
                 };
 
-                // TODO: if this object is present, evaluate _INI if it exists
+                /*
+                 * If the device is present and has an `_INI` method, invoke it.
+                 */
+                if status.present && level.values.contains_key(&NameSeg::from_str("_INI").unwrap()) {
+                    log::info!("Invoking _INI at level: {}", path);
+                    self.invoke_method(&AmlName::from_str("_INI").unwrap().resolve(&path)?, Args::default())?;
+                }
 
-                // TODO: can devices contain other devices?
-                Ok(true)
+                /*
+                 * We traverse the children of this device if it's present, or isn't present but is functional.
+                 */
+                Ok(status.present || status.functional)
             }
 
             LevelType::Scope => Ok(true),

+ 7 - 7
aml/src/value.rs

@@ -102,19 +102,19 @@ pub struct StatusObject {
     /// Whether the device is physically present. If this is `false`, `enabled` should also be `false` (i.e. a
     /// device that is not present can't be enabled). However, this is not enforced here if the firmware is doing
     /// something wrong.
-    present: bool,
+    pub present: bool,
     /// Whether the device is enabled. Both `present` and `enabled` must be `true` for the device to decode its
     /// hardware resources.
-    enabled: bool,
-    show_in_ui: bool,
-    functioning: bool,
+    pub enabled: bool,
+    pub show_in_ui: bool,
+    pub functional: bool,
     /// Only applicable for Control Method Battery Devices (`PNP0C0A`). For all other devices, ignore this value.
-    battery_present: bool,
+    pub battery_present: bool,
 }
 
 impl Default for StatusObject {
     fn default() -> Self {
-        StatusObject { present: true, enabled: true, show_in_ui: true, functioning: true, battery_present: true }
+        StatusObject { present: true, enabled: true, show_in_ui: true, functional: true, battery_present: true }
     }
 }
 
@@ -255,7 +255,7 @@ impl AmlValue {
                     present: value.get_bit(0),
                     enabled: value.get_bit(1),
                     show_in_ui: value.get_bit(2),
-                    functioning: value.get_bit(3),
+                    functional: value.get_bit(3),
                     battery_present: value.get_bit(4),
                 })
             }