use crate::const_try;
use crate::result::{Error, Result};
pub mod acc_size;
pub mod barrier_ctrl;
pub mod barrier_support;
pub mod bkops_en;
pub mod bkops_start;
pub mod bkops_status;
pub mod bkops_support;
pub mod boot_bus_conditions;
pub mod boot_config_prot;
pub mod boot_info;
pub mod boot_size_mult;
pub mod boot_wp;
pub mod boot_wp_status;
pub mod bus_width;
pub mod cache_ctrl;
pub mod cache_flush_policy;
pub mod cache_size;
pub mod class6_ctrl;
pub mod cmd_set;
pub mod cmd_set_rev;
pub mod cmdq;
pub mod cmdq_mode_en;
pub mod command_set;
pub mod context_capabilities;
pub mod context_conf;
pub mod correctly_prg_sectors_num;
pub mod csd_structure;
pub mod data_sector_size;
pub mod data_tag_support;
pub mod device_life_time_est;
pub mod device_type;
pub mod device_version;
pub mod driver_strength;
pub mod enh_size_mult;
pub mod enh_start_addr;
pub mod erase_group_def;
pub mod erase_timeout_mult;
pub mod erased_mem_cont;
pub mod exception_events_ctrl;
pub mod exception_events_status;
pub mod ext_csd_rev;
pub mod ext_partitions_attribute;
pub mod ext_security_err;
pub mod ext_support;
pub mod ffu_arg;
pub mod ffu_features;
pub mod ffu_status;
pub mod firmware_version;
pub mod flush_cache;
pub mod fw_config;
pub mod generic_cmd6_time;
pub mod gp_size_mult;
pub mod hc_erase_grp_size;
pub mod hc_wp_grp_size;
pub mod hpi_features;
pub mod hpi_mgmt;
pub mod hs_timing;
pub mod index;
pub mod ini_timeout_ap;
pub mod ini_timeout_emu;
pub mod large_unit_size_m1;
pub mod max_enh_size_mult;
pub mod max_packed;
pub mod max_pre_loading_data_size;
pub mod min_perf;
pub mod mode_config;
pub mod mode_operation_codes;
pub mod native_sector_size;
pub mod number_of_fw_sectors_correctly_programmed;
pub mod operation_codes_timeout;
pub mod optimal_read_size;
pub mod optimal_trim_unit_size;
pub mod optimal_write_size;
pub mod out_of_interrupt_time;
pub mod packed_command_status;
pub mod packed_failure_index;
pub mod partition_config;
pub mod partition_setting_completed;
pub mod partition_switch_time;
pub mod partitioning_support;
pub mod partitions_attribute;
pub mod periodic_wakeup;
pub mod power_class;
pub mod power_class_code;
pub mod power_off_long_time;
pub mod power_off_notification;
pub mod pre_eol_info;
pub mod pre_loading_data_size;
pub mod product_state_awareness_enablement;
pub mod production_state_awareness;
pub mod production_state_awareness_timeout;
pub mod program_cid_csd_ddr_support;
pub mod pwr_cl;
pub mod rel_wr_sec_c;
pub mod rpmb_size_mult;
pub mod rst_n_function;
pub mod s_a_timeout;
pub mod s_c_vcc;
pub mod s_cmd_set;
pub mod sanitize_start;
pub mod sec_bad_blk_mgmnt;
pub mod sec_count;
pub mod sec_erase_mult;
pub mod sec_feature_support;
pub mod sec_trim_mult;
pub mod secure_removal_type;
pub mod secure_wp_info;
pub mod size_mult;
pub mod sleep_notification_time;
pub mod strobe_support;
pub mod supported_modes;
pub mod tag_size;
pub mod tcase_support;
pub mod trim_mult;
pub mod use_native_sector;
pub mod user_wp;
pub mod vendor_proprietary_health_report;
pub mod vendor_specific;
pub mod wr_rel_param;
pub mod wr_rel_set;
pub mod fields;
pub(crate) use fields::*;
#[repr(C)]
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub struct ExtCsd([u8; 512]);
impl ExtCsd {
pub const LEN: usize = 512;
#[rustfmt::skip]
pub const DEFAULT: [u8; Self::LEN] = [
0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 0u8,
0u8, 1u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 0u8, 0u8, 1u8, 1u8, 1u8, 0u8, 0u8,
0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 0u8, 0u8, 0u8, 0u8,
5u8, 0u8, 0u8, 0u8, 3u8, 5u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
];
pub const fn new() -> Self {
Self(Self::DEFAULT)
}
pub const fn into_inner(self) -> [u8; Self::LEN] {
self.0
}
pub const fn try_from_inner(val: [u8; Self::LEN]) -> Result<Self> {
let e = Self(val);
const_try!(e.acc_size());
const_try!(e.bkops_status());
const_try!(e.boot_bus_conditions());
const_try!(e.boot_wp_status());
const_try!(e.bus_width());
const_try!(e.class_6_ctrl());
const_try!(e.cmd_set());
const_try!(e.cmd_set_rev());
const_try!(e.context_capabilities());
const_try!(e.context_conf_all());
const_try!(e.csd_structure());
const_try!(e.data_sector_size());
const_try!(e.device_life_time_est_typ_a());
const_try!(e.device_life_time_est_typ_b());
const_try!(e.device_type());
const_try!(e.erased_mem_cont());
const_try!(e.exception_events_ctrl());
const_try!(e.exception_events_status());
const_try!(e.ext_csd_rev());
const_try!(e.ext_partitions_attribute());
const_try!(e.ffu_status());
const_try!(e.flush_cache());
const_try!(e.hs_timing());
const_try!(e.max_packed_reads());
const_try!(e.max_packed_writes());
const_try!(e.min_perf_ddr_r_8_52());
const_try!(e.min_perf_ddr_w_8_52());
const_try!(e.min_perf_r_8_26_4_52());
const_try!(e.min_perf_w_8_26_4_52());
const_try!(e.min_perf_r_4_26());
const_try!(e.min_perf_w_4_26());
const_try!(e.min_perf_r_8_52());
const_try!(e.min_perf_w_8_52());
const_try!(e.mode_config());
const_try!(e.mode_operation_codes());
const_try!(e.native_sector_size());
const_try!(e.operation_codes_timeout());
const_try!(e.optimal_trim_unit_size());
const_try!(e.partition_config());
const_try!(e.periodic_wakeup());
const_try!(e.power_class());
const_try!(e.power_off_notification());
const_try!(e.pre_eol_info());
const_try!(e.product_state_awareness());
const_try!(e.production_state_awareness());
const_try!(e.production_state_awareness_timeout());
const_try!(e.pwr_cl_200_130());
const_try!(e.pwr_cl_200_195());
const_try!(e.pwr_cl_26_195());
const_try!(e.pwr_cl_26_360());
const_try!(e.pwr_cl_52_195());
const_try!(e.pwr_cl_52_360());
const_try!(e.pwr_cl_ddr_200_360());
const_try!(e.pwr_cl_ddr_52_195());
const_try!(e.pwr_cl_ddr_52_360());
const_try!(e.rel_wr_sec_c());
const_try!(e.rpmb_size_mult());
const_try!(e.rst_n_function());
const_try!(e.s_a_timeout());
const_try!(e.s_c_vcc());
const_try!(e.s_c_vccq());
const_try!(e.secure_removal_type());
const_try!(e.sleep_notification_time());
const_try!(e.tag_res_size());
const_try!(e.tcase_support());
const_try!(e.use_native_sector());
Ok(e)
}
}
impl AsRef<[u8]> for ExtCsd {
fn as_ref(&self) -> &[u8] {
self.0.as_ref()
}
}
impl TryFrom<[u8; ExtCsd::LEN]> for ExtCsd {
type Error = Error;
fn try_from(val: [u8; Self::LEN]) -> Result<Self> {
Self::try_from_inner(val)
}
}
impl TryFrom<&[u8]> for ExtCsd {
type Error = Error;
fn try_from(val: &[u8]) -> Result<Self> {
match val.len() {
len if len < Self::LEN => Err(Error::invalid_length(len, Self::LEN)),
_ => <[u8; Self::LEN]>::try_from(&val[..Self::LEN])
.map_err(Error::from)
.and_then(Self::try_from),
}
}
}
impl Default for ExtCsd {
fn default() -> Self {
Self::new()
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_ext_csd() {
assert_eq!(ExtCsd::try_from_inner(ExtCsd::DEFAULT), Ok(ExtCsd::new()));
}
}