From 9625eb15017ff0cd8e616bcb2e754c7a19ea88d6 Mon Sep 17 00:00:00 2001 From: Rajas Paranjpe <52586855+ChocolateLoverRaj@users.noreply.github.com> Date: Thu, 6 Jun 2024 09:06:53 -0700 Subject: [PATCH] Use &mut File instead of raw fd for safe functions --- crosec/src/battery.rs | 33 +++---- crosec/src/commands/board_version.rs | 7 +- crosec/src/commands/charge_control.rs | 15 ++-- crosec/src/commands/fp_info.rs | 7 +- crosec/src/commands/fp_mode.rs | 12 ++- crosec/src/commands/fp_set_seed.rs | 6 +- crosec/src/commands/fp_stats.rs | 6 +- crosec/src/commands/get_chip_info.rs | 8 +- crosec/src/commands/get_cmd_versions.rs | 7 +- crosec/src/commands/get_features.rs | 7 +- crosec/src/commands/get_protocol_info.rs | 6 +- crosec/src/commands/hello.rs | 8 +- crosec/src/commands/read_mem.rs | 6 +- crosec/src/commands/set_fan_target_rpm.rs | 13 ++- crosec/src/commands/version.rs | 10 ++- crosec/src/console.rs | 9 +- crosec/src/get_number_of_fans.rs | 7 +- crosec/src/read_mem_any.rs | 5 +- crosec/src/read_mem_string.rs | 7 +- ectool/src/main.rs | 100 ++++++++++------------ 20 files changed, 146 insertions(+), 133 deletions(-) diff --git a/crosec/src/battery.rs b/crosec/src/battery.rs index f991335..c8a0d5c 100644 --- a/crosec/src/battery.rs +++ b/crosec/src/battery.rs @@ -10,7 +10,7 @@ use crate::{ EC_MEM_MAP_BATTERY_SERIAL, EC_MEM_MAP_BATTERY_TYPE, EC_MEM_MAP_BATTERY_VERSION, EC_MEM_MAP_BATTERY_VOLTAGE, }; -use std::ffi::c_int; +use std::fs::File; #[derive(Debug, Clone)] pub struct BatteryInfo { @@ -28,31 +28,32 @@ pub struct BatteryInfo { pub flags: u8, } -pub fn battery(fd: c_int) -> EcCmdResult { - if ec_cmd_get_cmd_versions(fd, CrosEcCmd::BatteryGetStatic)? & V1 != 0 { +pub fn battery(file: &mut File) -> EcCmdResult { + if ec_cmd_get_cmd_versions(file, CrosEcCmd::BatteryGetStatic)? & V1 != 0 { panic!( "Battery info needs to be gotten with the {:?} command", CrosEcCmd::BatteryGetStatic ); } else { - let battery_version = read_mem_any::(fd, EC_MEM_MAP_BATTERY_VERSION).unwrap(); + let battery_version = read_mem_any::(file, EC_MEM_MAP_BATTERY_VERSION).unwrap(); if battery_version < 1 { panic!("Battery version {battery_version} is not supported"); } - let flags = read_mem_any::(fd, EC_MEM_MAP_BATTERY_FLAGS).unwrap(); - let oem_name = read_mem_string(fd, EC_MEM_MAP_BATTERY_MANUFACTURER).unwrap(); - let model_number = read_mem_string(fd, EC_MEM_MAP_BATTERY_MODEL).unwrap(); - let chemistry = read_mem_string(fd, EC_MEM_MAP_BATTERY_TYPE).unwrap(); - let serial_number = read_mem_string(fd, EC_MEM_MAP_BATTERY_SERIAL).unwrap(); - let design_capacity = read_mem_any::(fd, EC_MEM_MAP_BATTERY_DESIGN_CAPACITY).unwrap(); + let flags = read_mem_any::(file, EC_MEM_MAP_BATTERY_FLAGS).unwrap(); + let oem_name = read_mem_string(file, EC_MEM_MAP_BATTERY_MANUFACTURER).unwrap(); + let model_number = read_mem_string(file, EC_MEM_MAP_BATTERY_MODEL).unwrap(); + let chemistry = read_mem_string(file, EC_MEM_MAP_BATTERY_TYPE).unwrap(); + let serial_number = read_mem_string(file, EC_MEM_MAP_BATTERY_SERIAL).unwrap(); + let design_capacity = + read_mem_any::(file, EC_MEM_MAP_BATTERY_DESIGN_CAPACITY).unwrap(); let last_full_charge = - read_mem_any::(fd, EC_MEM_MAP_BATTERY_LAST_FULL_CHARGE_CAPACITY).unwrap(); + read_mem_any::(file, EC_MEM_MAP_BATTERY_LAST_FULL_CHARGE_CAPACITY).unwrap(); let design_output_voltage = - read_mem_any::(fd, EC_MEM_MAP_BATTERY_DESIGN_VOLTAGE).unwrap(); - let cycle_count = read_mem_any::(fd, EC_MEM_MAP_BATTERY_CYCLE_COUNT).unwrap(); - let present_voltage = read_mem_any::(fd, EC_MEM_MAP_BATTERY_VOLTAGE).unwrap(); - let present_current = read_mem_any::(fd, EC_MEM_MAP_BATTERY_RATE).unwrap(); - let remaining_capacity = read_mem_any::(fd, EC_MEM_MAP_BATTERY_CAPACITY).unwrap(); + read_mem_any::(file, EC_MEM_MAP_BATTERY_DESIGN_VOLTAGE).unwrap(); + let cycle_count = read_mem_any::(file, EC_MEM_MAP_BATTERY_CYCLE_COUNT).unwrap(); + let present_voltage = read_mem_any::(file, EC_MEM_MAP_BATTERY_VOLTAGE).unwrap(); + let present_current = read_mem_any::(file, EC_MEM_MAP_BATTERY_RATE).unwrap(); + let remaining_capacity = read_mem_any::(file, EC_MEM_MAP_BATTERY_CAPACITY).unwrap(); Ok(BatteryInfo { flags, oem_name, diff --git a/crosec/src/commands/board_version.rs b/crosec/src/commands/board_version.rs index 3d18f7d..0b5b3de 100644 --- a/crosec/src/commands/board_version.rs +++ b/crosec/src/commands/board_version.rs @@ -1,9 +1,10 @@ -use std::ffi::c_int; +use std::fs::File; +use std::os::fd::AsRawFd; use crate::commands::CrosEcCmd; use crate::ec_command::ec_command_bytemuck; use crate::EcCmdResult; -pub fn ec_cmd_board_version(fd: c_int) -> EcCmdResult { - ec_command_bytemuck(CrosEcCmd::GetBoardVersion, 0, &(), fd) +pub fn ec_cmd_board_version(file: &mut File) -> EcCmdResult { + ec_command_bytemuck(CrosEcCmd::GetBoardVersion, 0, &(), file.as_raw_fd()) } diff --git a/crosec/src/commands/charge_control.rs b/crosec/src/commands/charge_control.rs index 2bfdb78..050dd88 100644 --- a/crosec/src/commands/charge_control.rs +++ b/crosec/src/commands/charge_control.rs @@ -3,7 +3,8 @@ use crate::commands::CrosEcCmd; use crate::ec_command::ec_command_bytemuck; use crate::EcCmdResult; use bytemuck::{Pod, Zeroable}; -use std::ffi::c_int; +use std::fs::File; +use std::os::fd::AsRawFd; #[repr(C)] #[derive(Pod, Zeroable, Copy, Clone, Default, Debug)] @@ -19,8 +20,8 @@ pub enum ChargeControl { Discharge, } -pub fn supports_get_and_sustainer(fd: c_int) -> EcCmdResult { - let versions = ec_cmd_get_cmd_versions(fd, CrosEcCmd::ChargeControl)?; +pub fn supports_get_and_sustainer(file: &mut File) -> EcCmdResult { + let versions = ec_cmd_get_cmd_versions(file, CrosEcCmd::ChargeControl)?; Ok(versions & V2 != 0) } @@ -40,15 +41,15 @@ const CHARGE_CONTROL_COMMAND_NORMAL: u32 = 0; const CHARGE_CONTROL_COMMAND_IDLE: u32 = 1; const CHARGE_CONTROL_COMMAND_DISCHARGE: u32 = 2; -pub fn get_charge_control(_fd: c_int) -> EcCmdResult { +pub fn get_charge_control(_file: &mut File) -> EcCmdResult { panic!("Not implemented yet"); } -pub fn set_charge_control(fd: c_int, charge_control: ChargeControl) -> EcCmdResult<()> { +pub fn set_charge_control(file: &mut File, charge_control: ChargeControl) -> EcCmdResult<()> { ec_command_bytemuck( CrosEcCmd::ChargeControl, { - let version = ec_cmd_get_cmd_versions(fd, CrosEcCmd::ChargeControl)?; + let version = ec_cmd_get_cmd_versions(file, CrosEcCmd::ChargeControl)?; Ok(if version & V2 != 0 { 2 } else { 1 }) }?, &EcParamsChargeControl { @@ -67,7 +68,7 @@ pub fn set_charge_control(fd: c_int, charge_control: ChargeControl) -> EcCmdResu _ => Default::default(), }, }, - fd, + file.as_raw_fd(), )?; Ok(()) } diff --git a/crosec/src/commands/fp_info.rs b/crosec/src/commands/fp_info.rs index 52a2963..b0909c2 100644 --- a/crosec/src/commands/fp_info.rs +++ b/crosec/src/commands/fp_info.rs @@ -1,4 +1,4 @@ -use std::ffi::c_int; +use std::{fs::File, os::fd::AsRawFd}; use bytemuck::{Pod, Zeroable}; @@ -29,8 +29,9 @@ pub struct EcResponseFpInfo { pub template_version: u32, } -pub fn fp_info(fd: c_int) -> EcCmdResult { - let versions = ec_cmd_get_cmd_versions(fd, CrosEcCmd::FpInfo)?; +pub fn fp_info(file: &mut File) -> EcCmdResult { + let fd = file.as_raw_fd(); + let versions = ec_cmd_get_cmd_versions(file, CrosEcCmd::FpInfo)?; if versions & V1 == 0 { panic!("fp doesn't support V1. Other versions are currently not implemented"); } diff --git a/crosec/src/commands/fp_mode.rs b/crosec/src/commands/fp_mode.rs index 4dec604..bfe2faa 100644 --- a/crosec/src/commands/fp_mode.rs +++ b/crosec/src/commands/fp_mode.rs @@ -1,5 +1,5 @@ use bytemuck::{Pod, Zeroable}; -use std::ffi::c_int; +use std::{fs::File, os::fd::AsRawFd}; use strum::IntoEnumIterator; use strum_macros::{EnumIter, EnumString, IntoStaticStr}; @@ -50,8 +50,12 @@ struct EcResponseFpMode { mode: u32, } -pub fn fp_mode(fd: c_int, mode: u32) -> EcCmdResult { - let response: EcResponseFpMode = - ec_command_bytemuck(CrosEcCmd::FpMode, 0, &EcParamsFpMode { mode }, fd)?; +pub fn fp_mode(file: &mut File, mode: u32) -> EcCmdResult { + let response: EcResponseFpMode = ec_command_bytemuck( + CrosEcCmd::FpMode, + 0, + &EcParamsFpMode { mode }, + file.as_raw_fd(), + )?; Ok(response.mode) } diff --git a/crosec/src/commands/fp_set_seed.rs b/crosec/src/commands/fp_set_seed.rs index 884e374..0bff0e2 100644 --- a/crosec/src/commands/fp_set_seed.rs +++ b/crosec/src/commands/fp_set_seed.rs @@ -1,4 +1,4 @@ -use std::ffi::c_int; +use std::{fs::File, os::fd::AsRawFd}; use bytemuck::{Pod, Zeroable}; @@ -17,7 +17,7 @@ struct EcParamsFpSeed { pub seed: [u8; FP_CONTEXT_TPM_BYTES], } -pub fn fp_set_seed(fd: c_int, seed: [u8; FP_CONTEXT_TPM_BYTES]) -> EcCmdResult<()> { +pub fn fp_set_seed(file: &mut File, seed: [u8; FP_CONTEXT_TPM_BYTES]) -> EcCmdResult<()> { ec_command_bytemuck( CrosEcCmd::FpSetSeed, 0, @@ -26,6 +26,6 @@ pub fn fp_set_seed(fd: c_int, seed: [u8; FP_CONTEXT_TPM_BYTES]) -> EcCmdResult<( reserved: Default::default(), seed, }, - fd, + file.as_raw_fd(), ) } diff --git a/crosec/src/commands/fp_stats.rs b/crosec/src/commands/fp_stats.rs index f9b7700..4d2f8f8 100644 --- a/crosec/src/commands/fp_stats.rs +++ b/crosec/src/commands/fp_stats.rs @@ -1,4 +1,4 @@ -use std::ffi::c_int; +use std::{fs::File, os::fd::AsRawFd}; use bytemuck::{Pod, Zeroable}; @@ -24,6 +24,6 @@ pub struct OverallT0 { pub hi: u32, } -pub fn fp_stats(fd: c_int) -> EcCmdResult { - ec_command_bytemuck(CrosEcCmd::FpStats, 0, &(), fd) +pub fn fp_stats(file: &mut File) -> EcCmdResult { + ec_command_bytemuck(CrosEcCmd::FpStats, 0, &(), file.as_raw_fd()) } diff --git a/crosec/src/commands/get_chip_info.rs b/crosec/src/commands/get_chip_info.rs index af755ae..744b6d5 100644 --- a/crosec/src/commands/get_chip_info.rs +++ b/crosec/src/commands/get_chip_info.rs @@ -1,5 +1,6 @@ +use std::{fs::File, os::fd::AsRawFd}; + use bytemuck::{Pod, Zeroable}; -use nix::libc::c_int; use crate::{commands::CrosEcCmd, ec_command::ec_command_bytemuck, EcCmdResult}; @@ -11,8 +12,9 @@ struct EcResponseGetChipInfo { revision: [u8; 32], } -pub fn ec_cmd_get_chip_info(fd: c_int) -> EcCmdResult<(String, String, String)> { - let response: EcResponseGetChipInfo = ec_command_bytemuck(CrosEcCmd::GetChipInfo, 0, &(), fd)?; +pub fn ec_cmd_get_chip_info(file: &mut File) -> EcCmdResult<(String, String, String)> { + let response: EcResponseGetChipInfo = + ec_command_bytemuck(CrosEcCmd::GetChipInfo, 0, &(), file.as_raw_fd())?; let vendor = String::from_utf8(response.vendor.to_vec()).unwrap_or_default(); let name = String::from_utf8(response.name.to_vec()).unwrap_or_default(); diff --git a/crosec/src/commands/get_cmd_versions.rs b/crosec/src/commands/get_cmd_versions.rs index 84e3bd3..ab0d84d 100644 --- a/crosec/src/commands/get_cmd_versions.rs +++ b/crosec/src/commands/get_cmd_versions.rs @@ -1,5 +1,7 @@ +use std::fs::File; +use std::os::fd::AsRawFd; + use bytemuck::{Pod, Zeroable}; -use nix::libc::c_int; use crate::commands::CrosEcCmd; use crate::ec_command::ec_command_bytemuck; @@ -27,7 +29,8 @@ pub const V0: u32 = 0b001; pub const V1: u32 = 0b010; pub const V2: u32 = 0b100; -pub fn ec_cmd_get_cmd_versions(fd: c_int, cmd: CrosEcCmd) -> EcCmdResult { +pub fn ec_cmd_get_cmd_versions(file: &mut File, cmd: CrosEcCmd) -> EcCmdResult { + let fd = file.as_raw_fd(); let response: EcResponseGetCmdVersion = match ec_command_bytemuck( CrosEcCmd::GetCmdVersions, 1, diff --git a/crosec/src/commands/get_features.rs b/crosec/src/commands/get_features.rs index 7a443a3..684ac4a 100644 --- a/crosec/src/commands/get_features.rs +++ b/crosec/src/commands/get_features.rs @@ -1,4 +1,5 @@ -use nix::libc::c_int; +use std::fs::File; +use std::os::fd::AsRawFd; use crate::commands::CrosEcCmd; use crate::ec_command::ec_command_bytemuck; @@ -6,6 +7,6 @@ use crate::EcCmdResult; pub const EC_FEATURE_PWM_FAN: u64 = 0b100; -pub fn ec_cmd_get_features(fd: c_int) -> EcCmdResult { - ec_command_bytemuck(CrosEcCmd::GetFeatures, 0, &(), fd) +pub fn ec_cmd_get_features(file: &mut File) -> EcCmdResult { + ec_command_bytemuck(CrosEcCmd::GetFeatures, 0, &(), file.as_raw_fd()) } diff --git a/crosec/src/commands/get_protocol_info.rs b/crosec/src/commands/get_protocol_info.rs index 3b7f64a..126840d 100644 --- a/crosec/src/commands/get_protocol_info.rs +++ b/crosec/src/commands/get_protocol_info.rs @@ -1,4 +1,4 @@ -use std::{ffi::c_int, mem::size_of}; +use std::{fs::File, mem::size_of, os::fd::AsRawFd}; use bytemuck::{Pod, Zeroable}; @@ -42,6 +42,6 @@ struct EcHostResponse { reserved: u16, } -pub fn get_protocol_info(fd: c_int) -> EcCmdResult { - ec_command_bytemuck(CrosEcCmd::GetProtocolInfo, 0, &(), fd) +pub fn get_protocol_info(file: &mut File) -> EcCmdResult { + ec_command_bytemuck(CrosEcCmd::GetProtocolInfo, 0, &(), file.as_raw_fd()) } diff --git a/crosec/src/commands/hello.rs b/crosec/src/commands/hello.rs index 7aeb109..acfa1a0 100644 --- a/crosec/src/commands/hello.rs +++ b/crosec/src/commands/hello.rs @@ -1,5 +1,7 @@ +use std::fs::File; +use std::os::fd::AsRawFd; + use bytemuck::{NoUninit, Pod, Zeroable}; -use nix::libc::c_int; use crate::ec_command::ec_command_bytemuck; use crate::{commands::CrosEcCmd, EcCmdResult}; @@ -19,14 +21,14 @@ struct EcResponseHello { out_data: u32, } -pub fn ec_cmd_hello(fd: c_int) -> EcCmdResult { +pub fn ec_cmd_hello(file: &mut File) -> EcCmdResult { let response = ec_command_bytemuck::<_, EcResponseHello>( CrosEcCmd::Hello, 0, &EcParamsHello { in_data: INPUT_DATA, }, - fd, + file.as_raw_fd(), )?; Ok(response.out_data == EXPECTED_OUTPUT) } diff --git a/crosec/src/commands/read_mem.rs b/crosec/src/commands/read_mem.rs index 2af25b8..53f2a55 100644 --- a/crosec/src/commands/read_mem.rs +++ b/crosec/src/commands/read_mem.rs @@ -1,7 +1,7 @@ use crate::CROS_EC_IOC_MAGIC; use bytemuck::{Pod, Zeroable}; use nix::ioctl_readwrite; -use std::ffi::c_int; +use std::{ffi::c_int, fs::File, os::fd::AsRawFd}; const EC_MEM_MAP_SIZE: usize = 255; @@ -21,13 +21,13 @@ struct EcResponseReadMemV2 { ioctl_readwrite!(cros_ec_read_mem, CROS_EC_IOC_MAGIC, 1, EcResponseReadMemV2); -pub fn ec_cmd_read_mem(fd: c_int, offset: u32, bytes: u32) -> Result, c_int> { +pub fn ec_cmd_read_mem(file: &mut File, offset: u32, bytes: u32) -> Result, c_int> { let mut response = EcResponseReadMemV2 { offset, bytes, buffer: [0; EC_MEM_MAP_SIZE], }; - let status = unsafe { cros_ec_read_mem(fd, &mut response) }.unwrap(); + let status = unsafe { cros_ec_read_mem(file.as_raw_fd(), &mut response) }.unwrap(); if status >= 0 { Ok(response.buffer[..bytes as usize].to_vec()) } else { diff --git a/crosec/src/commands/set_fan_target_rpm.rs b/crosec/src/commands/set_fan_target_rpm.rs index 3385b5e..2710cfe 100644 --- a/crosec/src/commands/set_fan_target_rpm.rs +++ b/crosec/src/commands/set_fan_target_rpm.rs @@ -1,5 +1,6 @@ -use std::ffi::c_int; +use std::fs::File; use std::mem::size_of; +use std::os::fd::AsRawFd; use bytemuck::{Pod, Zeroable}; @@ -30,7 +31,11 @@ impl EcParamsSetFanTargetRpmV1 { } } -pub fn ec_cmd_set_fan_target_rpm(fd: c_int, rpm: u32, fan_index: Option) -> EcCmdResult<()> { +pub fn ec_cmd_set_fan_target_rpm( + file: &mut File, + rpm: u32, + fan_index: Option, +) -> EcCmdResult<()> { // v0 can only set the RPM for all fans // v1 can set the RPM for a specific fan match fan_index { @@ -43,7 +48,7 @@ pub fn ec_cmd_set_fan_target_rpm(fd: c_int, rpm: u32, fan_index: Option) -> fan_index: index, } .to_le_bytes(), - fd, + file.as_raw_fd(), )?; } None => { @@ -51,7 +56,7 @@ pub fn ec_cmd_set_fan_target_rpm(fd: c_int, rpm: u32, fan_index: Option) -> CrosEcCmd::SetFanTargetRpm, 0, &EcParamsSetFanTargetRpmV0 { rpm }, - fd, + file.as_raw_fd(), )?; } }; diff --git a/crosec/src/commands/version.rs b/crosec/src/commands/version.rs index 0ab8fb2..033eef5 100644 --- a/crosec/src/commands/version.rs +++ b/crosec/src/commands/version.rs @@ -1,5 +1,6 @@ +use std::{fs::File, os::fd::AsRawFd}; + use bytemuck::{Pod, Zeroable}; -use nix::libc::c_int; use num_derive::FromPrimitive; use num_traits::FromPrimitive; @@ -33,7 +34,7 @@ enum EcImage { } pub fn ec_cmd_version( - fd: c_int, + file: &mut File, protocol_info: &EcResponseGetProtocolInfo, ) -> EcCmdResult<(String, String, String, String, String)> { let params = EcResponseVersionV1 { @@ -44,7 +45,8 @@ pub fn ec_cmd_version( cros_fwid_rw: [0; 32], }; - let response: EcResponseVersionV1 = ec_command_bytemuck(CrosEcCmd::Version, 0, ¶ms, fd)?; + let response: EcResponseVersionV1 = + ec_command_bytemuck(CrosEcCmd::Version, 0, ¶ms, file.as_raw_fd())?; let ro_ver = String::from_utf8(response.version_string_ro.to_vec()).unwrap_or_default(); let rw_ver = String::from_utf8(response.version_string_rw.to_vec()).unwrap_or_default(); @@ -63,7 +65,7 @@ pub fn ec_cmd_version( 0, &[0; 248], protocol_info.max_ec_output_size(), - fd, + file.as_raw_fd(), )?; let build_info = String::from_utf8(result).unwrap_or(String::from("")); diff --git a/crosec/src/console.rs b/crosec/src/console.rs index b60623b..79f371b 100644 --- a/crosec/src/console.rs +++ b/crosec/src/console.rs @@ -1,12 +1,13 @@ -use std::ffi::c_int; +use std::fs::File; +use std::os::fd::AsRawFd; use crate::commands::get_protocol_info::EcResponseGetProtocolInfo; use crate::commands::CrosEcCmd; use crate::ec_command::{ec_command_bytemuck, ec_command_with_dynamic_output_size}; use crate::EcCmdResult; -pub fn console(fd: c_int, protocol_info: &EcResponseGetProtocolInfo) -> EcCmdResult { - ec_command_bytemuck(CrosEcCmd::ConsoleSnapshot, 0, &(), fd)?; +pub fn console(file: &mut File, protocol_info: &EcResponseGetProtocolInfo) -> EcCmdResult { + ec_command_bytemuck(CrosEcCmd::ConsoleSnapshot, 0, &(), file.as_raw_fd())?; let mut console = String::default(); loop { let output = ec_command_with_dynamic_output_size( @@ -14,7 +15,7 @@ pub fn console(fd: c_int, protocol_info: &EcResponseGetProtocolInfo) -> EcCmdRes 0, Default::default(), protocol_info.max_ec_output_size(), - fd, + file.as_raw_fd(), )?; let chunk = String::from_utf8(output).unwrap(); // Get rid of trailing null characters diff --git a/crosec/src/get_number_of_fans.rs b/crosec/src/get_number_of_fans.rs index 3283cd4..949cd80 100644 --- a/crosec/src/get_number_of_fans.rs +++ b/crosec/src/get_number_of_fans.rs @@ -3,6 +3,7 @@ use crate::read_mem_any::read_mem_any; use crate::{EcError, EC_FAN_SPEED_ENTRIES, EC_FAN_SPEED_NOT_PRESENT, EC_MEM_MAP_FAN}; use std::ffi::c_int; use std::fmt::{Debug, Display, Formatter}; +use std::fs::File; #[derive(Debug)] pub enum Error { @@ -25,10 +26,10 @@ impl Display for Error { } } -pub fn get_number_of_fans(fd: c_int) -> Result { - let features = ec_cmd_get_features(fd).map_err(|e| Error::GetFeatures(e))?; +pub fn get_number_of_fans(file: &mut File) -> Result { + let features = ec_cmd_get_features(file).map_err(|e| Error::GetFeatures(e))?; let number_of_fans = if features & EC_FEATURE_PWM_FAN != 0 { - read_mem_any::<[u16; EC_FAN_SPEED_ENTRIES]>(fd, EC_MEM_MAP_FAN) + read_mem_any::<[u16; EC_FAN_SPEED_ENTRIES]>(file, EC_MEM_MAP_FAN) .map_err(|e| Error::ReadMem(e))? .into_iter() .filter(|data| *data != EC_FAN_SPEED_NOT_PRESENT) diff --git a/crosec/src/read_mem_any.rs b/crosec/src/read_mem_any.rs index 157996c..a0fb7b4 100644 --- a/crosec/src/read_mem_any.rs +++ b/crosec/src/read_mem_any.rs @@ -1,12 +1,13 @@ use std::ffi::c_int; +use std::fs::File; use std::mem::size_of; use bytemuck::AnyBitPattern; use crate::commands::read_mem::ec_cmd_read_mem; -pub fn read_mem_any(fd: c_int, offset: u8) -> Result { - let result = ec_cmd_read_mem(fd, offset as u32, size_of::() as u32)?; +pub fn read_mem_any(file: &mut File, offset: u8) -> Result { + let result = ec_cmd_read_mem(file, offset as u32, size_of::() as u32)?; let result = bytemuck::from_bytes(&result); Ok(*result) } diff --git a/crosec/src/read_mem_string.rs b/crosec/src/read_mem_string.rs index fc95453..7547b1b 100644 --- a/crosec/src/read_mem_string.rs +++ b/crosec/src/read_mem_string.rs @@ -1,8 +1,9 @@ -use std::ffi::c_int; use crate::commands::read_mem::ec_cmd_read_mem; use crate::EC_MEM_MAP_MAX_TEXT_SIZE; +use std::ffi::c_int; +use std::fs::File; -pub fn read_mem_string(fd: c_int, offset: u8) -> Result { - let string = ec_cmd_read_mem(fd, offset as u32, EC_MEM_MAP_MAX_TEXT_SIZE as u32)?; +pub fn read_mem_string(file: &mut File, offset: u8) -> Result { + let string = ec_cmd_read_mem(file, offset as u32, EC_MEM_MAP_MAX_TEXT_SIZE as u32)?; Ok(String::from_utf8(string).unwrap()) } diff --git a/ectool/src/main.rs b/ectool/src/main.rs index e45f11f..685f374 100644 --- a/ectool/src/main.rs +++ b/ectool/src/main.rs @@ -1,5 +1,4 @@ use std::fs::File; -use std::os::fd::AsRawFd; use std::str::FromStr; use clap::{Parser, Subcommand, ValueEnum}; @@ -132,9 +131,8 @@ fn main() -> Result<()> { match cli.command { Commands::Hello { device } => { - let file = File::open(device.unwrap_or_default().get_path()).unwrap(); - let fd = file.as_raw_fd(); - let status = ec_cmd_hello(fd)?; + let mut file = File::open(device.unwrap_or_default().get_path())?; + let status = ec_cmd_hello(&mut file)?; if status { println!("EC says hello!"); } else { @@ -142,11 +140,10 @@ fn main() -> Result<()> { } } Commands::Version => { - let file = File::open("/dev/cros_ec").unwrap(); - let fd = file.as_raw_fd(); - let max_sizes = get_protocol_info(fd)?; + let mut file = File::open(CROS_EC_PATH)?; + let max_sizes = get_protocol_info(&mut file)?; let (ro_ver, rw_ver, firmware_copy, build_info, tool_version) = - ec_cmd_version(fd, &max_sizes)?; + ec_cmd_version(&mut file, &max_sizes)?; println!("RO version: {ro_ver}"); println!("RW version: {rw_ver}"); println!("Firmware copy: {firmware_copy}"); @@ -154,25 +151,22 @@ fn main() -> Result<()> { println!("Tool version: {tool_version}"); } Commands::ChipInfo => { - let file = File::open("/dev/cros_ec").unwrap(); - let fd = file.as_raw_fd(); - let (vendor, name, revision) = ec_cmd_get_chip_info(fd)?; + let mut file = File::open(CROS_EC_PATH)?; + let (vendor, name, revision) = ec_cmd_get_chip_info(&mut file)?; println!("Chip info:"); println!(" vendor: {vendor}"); println!(" name: {name}"); println!(" revision: {revision}"); } Commands::BoardVersion => { - let file = File::open("/dev/cros_ec").unwrap(); - let fd = file.as_raw_fd(); - let board_version = ec_cmd_board_version(fd)?; + let mut file = File::open(CROS_EC_PATH)?; + let board_version = ec_cmd_board_version(&mut file)?; println!("Board version: {board_version}"); } Commands::CmdVersions { command } => match CrosEcCmd::from_u32(command) { Some(cmd) => { - let file = File::open("/dev/cros_ec").unwrap(); - let fd = file.as_raw_fd(); - let versions = ec_cmd_get_cmd_versions(fd, cmd)?; + let mut file = File::open(CROS_EC_PATH)?; + let versions = ec_cmd_get_cmd_versions(&mut file, cmd)?; println!("Versions: {versions:#b}"); } None => { @@ -180,9 +174,8 @@ fn main() -> Result<()> { } }, Commands::SetFanTargetRpm { rpm, index } => { - let file = File::open("/dev/cros_ec").unwrap(); - let fd = file.as_raw_fd(); - ec_cmd_set_fan_target_rpm(fd, rpm, index)?; + let mut file = File::open(CROS_EC_PATH)?; + ec_cmd_set_fan_target_rpm(&mut file, rpm, index)?; match index { Some(index) => { println!("Set RPM to {rpm} for fan {index}"); @@ -193,23 +186,20 @@ fn main() -> Result<()> { } } Commands::GetFeatures => { - let file = File::open("/dev/cros_ec").unwrap(); - let fd = file.as_raw_fd(); - let features = ec_cmd_get_features(fd)?; + let mut file = File::open(CROS_EC_PATH)?; + let features = ec_cmd_get_features(&mut file)?; println!("EC supported features: {features:#b}"); } Commands::GetNumberOfFans => { - let file = File::open("/dev/cros_ec").unwrap(); - let fd = file.as_raw_fd(); - let number_of_fans = get_number_of_fans(fd).unwrap(); + let mut file = File::open(CROS_EC_PATH)?; + let number_of_fans = get_number_of_fans(&mut file).unwrap(); println!("Number of fans: {number_of_fans}"); } Commands::GetFanRpm => { - let file = File::open("/dev/cros_ec").unwrap(); - let fd = file.as_raw_fd(); - let features = ec_cmd_get_features(fd).map_err(|e| Error::GetFeatures(e))?; + let mut file = File::open(CROS_EC_PATH)?; + let features = ec_cmd_get_features(&mut file).map_err(|e| Error::GetFeatures(e))?; if features & EC_FEATURE_PWM_FAN != 0 { - read_mem_any::<[u16; EC_FAN_SPEED_ENTRIES]>(fd, EC_MEM_MAP_FAN) + read_mem_any::<[u16; EC_FAN_SPEED_ENTRIES]>(&mut file, EC_MEM_MAP_FAN) .map_err(|e| Error::ReadMem(e))? .into_iter() .enumerate() @@ -227,26 +217,23 @@ fn main() -> Result<()> { }; } Commands::Console { device } => { - let file = File::open(device.unwrap_or_default().get_path()).unwrap(); - let fd = file.as_raw_fd(); - let max_sizes = get_protocol_info(fd)?; - let console = console(fd, &max_sizes)?; + let mut file = File::open(device.unwrap_or_default().get_path())?; + let max_sizes = get_protocol_info(&mut file)?; + let console = console(&mut file, &max_sizes)?; let console = console.trim(); println!("{console}"); } Commands::Battery => { - let file = File::open("/dev/cros_ec").unwrap(); - let fd = file.as_raw_fd(); - let battery_info = battery(fd)?; + let mut file = File::open(CROS_EC_PATH)?; + let battery_info = battery(&mut file)?; println!("{battery_info:#?}"); } Commands::ChargeControl { command } => { - let file = File::open("/dev/cros_ec").unwrap(); - let fd = file.as_raw_fd(); + let mut file = File::open(CROS_EC_PATH)?; match command { None => { - if supports_get_and_sustainer(fd)? { - let charge_control = get_charge_control(fd)?; + if supports_get_and_sustainer(&mut file)? { + let charge_control = get_charge_control(&mut file)?; println!("{charge_control:#?}"); } else { println!("This EC doesn't support getting charge control"); @@ -260,7 +247,7 @@ fn main() -> Result<()> { Some(min_percent) => { let max_percent = max_percent.unwrap_or(min_percent); set_charge_control( - fd, + &mut file, charge_control::ChargeControl::Normal(Some(Sustainer { min_percent: min_percent as i8, max_percent: max_percent as i8, @@ -269,31 +256,32 @@ fn main() -> Result<()> { println!("Set charge control to normal with sustainer from {min_percent}% to {max_percent}%"); } None => { - set_charge_control(fd, charge_control::ChargeControl::Normal(None))?; + set_charge_control( + &mut file, + charge_control::ChargeControl::Normal(None), + )?; println!("Set charge control to normal"); } }, ChargeControlSubcommands::Idle => { println!("Set charge control to idle"); - set_charge_control(fd, charge_control::ChargeControl::Idle)?; + set_charge_control(&mut file, charge_control::ChargeControl::Idle)?; } ChargeControlSubcommands::Discharge => { println!("Set charge control to discharge"); - set_charge_control(fd, charge_control::ChargeControl::Discharge)?; + set_charge_control(&mut file, charge_control::ChargeControl::Discharge)?; } }, } } Commands::FpInfo => { - let file = File::open(CROS_FP_PATH).unwrap(); - let fd = file.as_raw_fd(); - let info = fp_info(fd)?; + let mut file = File::open(CROS_FP_PATH)?; + let info = fp_info(&mut file)?; println!("{info:#?}"); } Commands::FpStats => { - let file = File::open(CROS_FP_PATH).unwrap(); - let fd = file.as_raw_fd(); - let stats = fp_stats(fd)?; + let mut file = File::open(CROS_FP_PATH)?; + let stats = fp_stats(&mut file)?; println!("{stats:#?}"); } Commands::FpSetSeed { seed } => { @@ -301,9 +289,8 @@ fn main() -> Result<()> { seed.as_bytes().to_owned(), ) { Ok(seed) => { - let file = File::open(CROS_FP_PATH).unwrap(); - let fd = file.as_raw_fd(); - fp_set_seed(fd, seed)?; + let mut file = File::open(CROS_FP_PATH)?; + fp_set_seed(&mut file, seed)?; println!("Set fp seed"); } Err(seed) => { @@ -322,9 +309,8 @@ fn main() -> Result<()> { } else { FpMode::DontChange as u32 }; - let file = File::open(CROS_FP_PATH).unwrap(); - let fd = file.as_raw_fd(); - let mode = fp_mode(fd, mode)?; + let mut file = File::open(CROS_FP_PATH)?; + let mode = fp_mode(&mut file, mode)?; let display = FpMode::display(mode); println!("FP mode: {display}"); }