| // Copyright 2023 The ChromiumOS Authors | |
| // Use of this source code is governed by a BSD-style license that can be | |
| // found in the LICENSE file. | |
| #include "libec/flash_read_command.h" | |
| #include <algorithm> | |
| #include <vector> | |
| namespace ec { | |
| FlashReadCommand::FlashReadCommand(uint32_t offset, | |
| uint32_t read_size, | |
| uint16_t max_packet_size) | |
| : EcCommand(EC_CMD_FLASH_READ), | |
| read_data_(read_size), | |
| offset_(offset), | |
| max_packet_size_(max_packet_size) {} | |
| std::vector<uint8_t> FlashReadCommand::GetData() const { | |
| return read_data_; | |
| } | |
| bool FlashReadCommand::Run(int fd) { | |
| uint32_t max_data_chunk = max_packet_size_; | |
| auto pos = read_data_.begin(); | |
| while (pos < read_data_.end()) { | |
| uint32_t remaining = read_data_.end() - pos; | |
| uint32_t transfer_len = std::min(max_data_chunk, remaining); | |
| Req()->offset = pos - read_data_.begin() + offset_; | |
| Req()->size = transfer_len; | |
| SetRespSize(transfer_len); | |
| if (!EcCommandRun(fd)) { | |
| return false; | |
| } | |
| if (Result() != EC_RES_SUCCESS) { | |
| LOG(ERROR) << "FLASH_READ command failed @ " << pos - read_data_.begin(); | |
| return false; | |
| } | |
| std::copy(Resp()->cbegin(), Resp()->cbegin() + transfer_len, pos); | |
| pos += transfer_len; | |
| } | |
| return true; | |
| } | |
| bool FlashReadCommand::EcCommandRun(int fd) { | |
| return EcCommand::Run(fd); | |
| } | |
| } // namespace ec |