firewire_dice_protocols/tcat/
config_rom.rs1use ieee1212_config_rom::*;
10
11#[derive(Default, Debug, Clone, Copy)]
13pub struct Identifier {
14 pub vendor_id: u32,
17 pub category: u8,
19 pub product_id: u16,
21 pub serial: u32,
23}
24
25#[derive(Default, Debug, Clone, Copy)]
27pub struct RootData<'a> {
28 pub vendor_id: u32,
31 pub vendor_name: &'a str,
33 pub product_id: u32,
35 pub product_name: &'a str,
37}
38
39#[derive(Default, Debug, Clone, Copy)]
41pub struct UnitData<'a> {
42 pub model_id: u32,
44 pub model_name: &'a str,
46 pub specifier_id: u32,
48 pub version: u32,
50}
51
52const VENDOR_ID_MASK: u32 = 0xffffff00;
53const VENDOR_ID_SHIFT: usize = 8;
54const CATEGORY_MASK: u32 = 0x000000ff;
55const CATEGORY_SHIFT: usize = 0;
56const PRODUCT_ID_MASK: u32 = 0xffc00000;
57const PRODUCT_ID_SHIFT: usize = 22;
58const SERIAL_MASK: u32 = 0x003fffff;
59const SERIAL_SHIFT: usize = 0;
60
61pub trait DiceConfigRom<'a> {
63 fn get_identifier(&self) -> Option<Identifier>;
65 fn get_root_data(&'a self) -> Option<RootData<'a>>;
67 fn get_unit_data(&'a self) -> Vec<UnitData<'a>>;
69}
70
71impl<'a> DiceConfigRom<'a> for ConfigRom<'a> {
72 fn get_identifier(&self) -> Option<Identifier> {
73 if self.bus_info.len() < 12 {
74 None
75 } else {
76 let mut quadlet = [0; 4];
77
78 quadlet.copy_from_slice(&self.bus_info[8..12]);
79 let val = u32::from_be_bytes(quadlet);
80 let vendor_id = (val & VENDOR_ID_MASK) >> VENDOR_ID_SHIFT;
81 let category = ((val & CATEGORY_MASK) >> CATEGORY_SHIFT) as u8;
82
83 quadlet.copy_from_slice(&self.bus_info[12..16]);
84 let val = u32::from_be_bytes(quadlet);
85 let product_id = ((val & PRODUCT_ID_MASK) >> PRODUCT_ID_SHIFT) as u16;
86 let serial = (val & SERIAL_MASK) >> SERIAL_SHIFT;
87
88 Some(Identifier {
89 vendor_id,
90 category,
91 product_id,
92 serial,
93 })
94 }
95 }
96
97 fn get_root_data(&'a self) -> Option<RootData<'a>> {
98 let (vendor_id, vendor_name) = detect_desc_text(&self.root, KeyType::Vendor)?;
99 let (product_id, product_name) = detect_desc_text(&self.root, KeyType::Model)?;
100 let data = RootData {
101 vendor_id,
102 vendor_name,
103 product_id,
104 product_name,
105 };
106 Some(data)
107 }
108
109 fn get_unit_data(&'a self) -> Vec<UnitData<'a>> {
110 self.root
111 .iter()
112 .filter_map(|entry| {
113 let entries = EntryDataAccess::<&[Entry]>::get(entry, KeyType::Unit)?;
114 let specifier_id = entries
115 .iter()
116 .find_map(|entry| EntryDataAccess::<u32>::get(entry, KeyType::SpecifierId))?;
117 let version = entries
118 .iter()
119 .find_map(|entry| EntryDataAccess::<u32>::get(entry, KeyType::Version))?;
120 let (model_id, model_name) = detect_desc_text(entries, KeyType::Model)?;
121 let data = UnitData {
122 model_id,
123 model_name,
124 specifier_id,
125 version,
126 };
127 Some(data)
128 })
129 .collect()
130 }
131}
132
133fn detect_desc_text<'a>(entries: &'a [Entry], key_type: KeyType) -> Option<(u32, &'a str)> {
134 let mut peekable = entries.iter().peekable();
135
136 while let Some(entry) = peekable.next() {
137 let result = EntryDataAccess::<u32>::get(entry, key_type).and_then(|value| {
138 peekable.peek().and_then(|&next| {
139 EntryDataAccess::<&str>::get(next, KeyType::Descriptor).map(|name| (value, name))
140 })
141 });
142
143 if result.is_some() {
144 return result;
145 }
146 }
147
148 None
149}