()
| 698 | |
| 699 | #[cfg(target_os = "linux")] |
| 700 | pub fn csme_from_sysfs() -> io::Result<CsmeInfo> { |
| 701 | let dir = Path::new("/sys/class/mei"); |
| 702 | let mut csme_info: Option<CsmeInfo> = None; |
| 703 | if dir.is_dir() { |
| 704 | for csmeme_entry in fs::read_dir(dir)? { |
| 705 | // Can currently only handle one ME. Not sure when there would be multiple? |
| 706 | assert!(csme_info.is_none()); |
| 707 | |
| 708 | let csmeme_entry = csmeme_entry?; |
| 709 | let path = csmeme_entry.path(); |
| 710 | if path.is_dir() { |
| 711 | let dev_state = fs::read_to_string(path.join("dev_state"))?; |
| 712 | // Can be one of INITIALIZING, INIT_CLIENTS, ENABLED, RESETTING, DISABLED, |
| 713 | // POWER_DOWN, POWER_UP |
| 714 | // See linux kernel at: Documentation/ABI/testing/sysfs-class-mei |
| 715 | let enabled = matches!(dev_state.as_str(), "ENABLED"); |
| 716 | |
| 717 | // Kernel gives us multiple \n separated lines in a file |
| 718 | let fw_vers = fs::read_to_string(path.join("fw_ver"))?; |
| 719 | let fw_vers = fw_vers.lines(); |
| 720 | |
| 721 | let mut infos = fw_vers.map(CsmeVersion::from); |
| 722 | let main_ver = infos.next().unwrap(); |
| 723 | let recovery_ver = infos.next().unwrap(); |
| 724 | let fitc_ver = infos.next().unwrap(); |
| 725 | // Make sure there are three and no more |
| 726 | assert_eq!(infos.next(), None); |
| 727 | |
| 728 | csme_info = Some(CsmeInfo { |
| 729 | enabled, |
| 730 | main_ver, |
| 731 | recovery_ver, |
| 732 | fitc_ver, |
| 733 | }) |
| 734 | } |
| 735 | } |
| 736 | } |
| 737 | if let Some(csme_info) = csme_info { |
| 738 | Ok(csme_info) |
| 739 | } else { |
| 740 | Err(std::io::Error::new( |
| 741 | std::io::ErrorKind::NotFound, |
| 742 | "Failed to get CSME info from sysfs", |
| 743 | )) |
| 744 | } |
| 745 | } |
| 746 | |
| 747 | #[cfg(test)] |
| 748 | mod tests { |
no outgoing calls
no test coverage detected