blob: 86064a3630cc2ed48fe8a3f53e5180f6d142cbe0 [file] [log] [blame]
#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_