| #ifndef THIRD_PARTY_MILOTIC_EXTERNAL_CC_TLBMC_HAL_FRU_SCANNER_I2C_H_ |
| #define THIRD_PARTY_MILOTIC_EXTERNAL_CC_TLBMC_HAL_FRU_SCANNER_I2C_H_ |
| |
| #include <cstddef> |
| #include <cstdint> |
| #include <memory> |
| #include <optional> |
| #include <string> |
| #include <utility> |
| #include <vector> |
| |
| #include "absl/container/flat_hash_map.h" |
| #include "absl/container/flat_hash_set.h" |
| #include "absl/status/statusor.h" |
| #include "absl/strings/string_view.h" |
| #include "absl/time/time.h" |
| #include "io/ioctl.h" |
| #include "io/smbus/kernel_dev.h" |
| #include "io/smbus/smbus.h" |
| #include "time/clock.h" |
| #include "tlbmc/hal/fru_scanner.h" |
| #include "tlbmc/utils/fru_utils.h" |
| |
| namespace milotic_tlbmc { |
| |
| constexpr int kI2cFruScanStart = 0x50; |
| constexpr int kI2cFruScanEnd = 0x57; |
| |
| // Context for the scan. |
| struct ScanContext { |
| // Map of bus to addresses that are blocked. |
| absl::flat_hash_map<size_t, std::optional<absl::flat_hash_set<size_t>>> |
| bus_block_list; |
| // Map of bus to addresses that have already been scanned. |
| absl::flat_hash_map<size_t, absl::flat_hash_set<size_t>> fru_addresses_list; |
| }; |
| |
| class FruScannerI2c : public FruScanner { |
| public: |
| struct Options { |
| std::string root_dir; |
| std::string i2c_dev_dir; |
| absl::flat_hash_map<size_t, std::optional<absl::flat_hash_set<size_t>>> |
| bus_block_list; |
| }; |
| |
| static std::unique_ptr<FruScannerI2c> Create(const Options& options); |
| |
| absl::StatusOr<std::vector<std::unique_ptr<I2cFruInfo>>> ScanAllI2cFrus() |
| override; |
| |
| absl::StatusOr<std::unique_ptr<I2cFruInfo>> GetI2cFruInfoFromBus( |
| int bus, int address, absl::Duration delay_between_reads) override; |
| |
| absl::StatusOr<std::unique_ptr<I2cFruInfo>> ScanDirectI2cFru( |
| int bus, int address, absl::Duration delay_between_reads); |
| |
| protected: |
| FruScannerI2c( |
| absl::string_view root_dir, absl::string_view i2c_dev_dir, |
| const absl::flat_hash_map< |
| size_t, std::optional<absl::flat_hash_set<size_t>>>& bus_block_list) |
| : root_dir_(root_dir), |
| scan_context_{.bus_block_list = bus_block_list, |
| .fru_addresses_list = {}}, |
| sys_ioctl_(), |
| smbus_access_(std::make_unique<ecclesia::KernelSmbusAccess>( |
| std::string(i2c_dev_dir), &sys_ioctl_)) {} |
| |
| void FindI2CDevices(const absl::flat_hash_set<int>& i2c_buses, |
| BusMap& bus_map); |
| |
| std::pair<std::vector<uint8_t>, bool> ReadFruContentsFromI2c( |
| int i2c_bus, int address, |
| absl::Duration delay_between_reads = absl::ZeroDuration()); |
| |
| // Returns the list of valid FRU addresses found on the given i2c bus. |
| // devices: Map of address to FRU data. |
| // skip_list: List of addresses to skip. |
| // root_found: List of addresses found at root bus. |
| absl::flat_hash_set<size_t> FindI2cEeproms( |
| int i2cBus, const std::shared_ptr<DeviceMap>& devices, |
| absl::string_view root_dir, |
| const absl::flat_hash_set<size_t>& root_blocked_addresses, |
| absl::flat_hash_set<size_t>& root_found_addresses); |
| |
| std::string root_dir_; |
| ScanContext scan_context_; |
| ecclesia::SysIoctl sys_ioctl_; |
| std::unique_ptr<ecclesia::SmbusAccessInterface> smbus_access_; |
| ecclesia::Clock* clock_ = ecclesia::Clock::RealClock(); |
| }; |
| |
| } // namespace milotic_tlbmc |
| |
| #endif // THIRD_PARTY_MILOTIC_EXTERNAL_CC_TLBMC_HAL_FRU_SCANNER_I2C_H_ |