summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRichard Hughes <richard@hughsie.com>2021-01-15 09:48:12 +0000
committerEdward O'Callaghan <quasisec@chromium.org>2022-05-25 08:08:13 +0000
commit40892b0c08fbc8029921e91511dd3f91fc956f90 (patch)
tree56b6fccd5c99c00649369fcf097c4555313b753c
parentb86ae179adfb4acb4190ef2abe2ee8905c44f26a (diff)
downloadflashrom-40892b0c08fbc8029921e91511dd3f91fc956f90.tar.gz
flashrom-40892b0c08fbc8029921e91511dd3f91fc956f90.tar.bz2
flashrom-40892b0c08fbc8029921e91511dd3f91fc956f90.zip
libflashrom: Return progress state to the library user
Projects using libflashrom like fwupd expect the user to wait for the operation to complete. To avoid the user thinking the process has "hung" or "got stuck" report back the progress complete of the erase, write and read operations. Add a new --progress flag to the CLI to report progress of operations. Include a test for the dummy spi25 device. TEST=./test_build.sh; ./flashrom -p lspcon_i2c_spi:bus=7 -r /dev/null --progress Change-Id: I7197572bb7f19e3bdb2bde855d70a0f50fd3854c Signed-off-by: Richard Hughes <richard@hughsie.com> Signed-off-by: Daniel Campello <campello@chromium.org> Reviewed-on: https://review.coreboot.org/c/flashrom/+/49643 Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Edward O'Callaghan <quasisec@chromium.org> Reviewed-by: Anastasia Klimchuk <aklm@chromium.org> Reviewed-by: Thomas Heijligen <src@posteo.de>
-rw-r--r--82802ab.c1
-rw-r--r--at45db.c1
-rw-r--r--cli_classic.c14
-rw-r--r--cli_output.c25
-rw-r--r--dediprog.c1
-rw-r--r--en29lv640b.c1
-rw-r--r--flashrom.8.tmpl6
-rw-r--r--include/flash.h5
-rw-r--r--include/libflashrom.h29
-rw-r--r--it87spi.c1
-rw-r--r--jedec.c5
-rw-r--r--libflashrom.c19
-rw-r--r--libflashrom.map1
-rw-r--r--linux_mtd.c3
-rw-r--r--lspcon_i2c_spi.c2
-rw-r--r--realtek_mst_i2c_spi.c1
-rw-r--r--spi.c3
-rw-r--r--spi25.c7
-rw-r--r--sst28sf040.c1
-rw-r--r--tests/spi25.c59
-rw-r--r--tests/tests.c1
-rw-r--r--tests/tests.h1
22 files changed, 184 insertions, 3 deletions
diff --git a/82802ab.c b/82802ab.c
index b485c114c..1db69e6b1 100644
--- a/82802ab.c
+++ b/82802ab.c
@@ -134,6 +134,7 @@ int write_82802ab(struct flashctx *flash, const uint8_t *src, unsigned int start
chip_writeb(flash, 0x40, dst);
chip_writeb(flash, *src++, dst++);
wait_82802ab(flash);
+ update_progress(flash, FLASHROM_PROGRESS_WRITE, i + 1, len);
}
/* FIXME: Ignore errors for now. */
diff --git a/at45db.c b/at45db.c
index 5f949bb20..3f586a21f 100644
--- a/at45db.c
+++ b/at45db.c
@@ -550,6 +550,7 @@ int spi_write_at45db(struct flashctx *flash, const uint8_t *buf, unsigned int st
msg_cerr("Writing page %u failed!\n", i);
return 1;
}
+ update_progress(flash, FLASHROM_PROGRESS_WRITE, i + page_size, len);
}
return 0;
}
diff --git a/cli_classic.c b/cli_classic.c
index 83ac5383e..212534c94 100644
--- a/cli_classic.c
+++ b/cli_classic.c
@@ -79,6 +79,7 @@ static void cli_classic_usage(const char *name)
#if CONFIG_PRINT_WIKI == 1
" -z | --list-supported-wiki print supported devices in wiki syntax\n"
#endif
+ " --progress show progress percentage on the standard output\n"
" -p | --programmer <name>[:<param>] specify the programmer device. One of\n");
list_programmers_linebreak(4, 80, 0);
printf(".\n\nYou can specify one of -h, -R, -L, "
@@ -472,6 +473,7 @@ int main(int argc, char *argv[])
uint32_t wp_start = 0, wp_len = 0;
int read_it = 0, extract_it = 0, write_it = 0, erase_it = 0, verify_it = 0;
int dont_verify_it = 0, dont_verify_all = 0, list_supported = 0, operation_specified = 0;
+ int show_progress = 0;
struct flashrom_layout *layout = NULL;
static const struct programmer_entry *prog = NULL;
enum {
@@ -487,6 +489,7 @@ int main(int argc, char *argv[])
OPTION_WP_ENABLE,
OPTION_WP_DISABLE,
OPTION_WP_LIST,
+ OPTION_PROGRESS,
};
int ret = 0;
@@ -523,6 +526,7 @@ int main(int argc, char *argv[])
{"help", 0, NULL, 'h'},
{"version", 0, NULL, 'R'},
{"output", 1, NULL, 'o'},
+ {"progress", 0, NULL, OPTION_PROGRESS},
{NULL, 0, NULL, 0},
};
@@ -763,6 +767,9 @@ int main(int argc, char *argv[])
cli_classic_abort_usage("No log filename specified.\n");
}
break;
+ case OPTION_PROGRESS:
+ show_progress = 1;
+ break;
default:
cli_classic_abort_usage(NULL);
break;
@@ -934,6 +941,13 @@ int main(int argc, char *argv[])
fill_flash = &flashes[0];
+ unsigned int progress_user_data[FLASHROM_PROGRESS_NR];
+ struct flashrom_progress progress_state = {
+ .user_data = progress_user_data
+ };
+ if (show_progress)
+ flashrom_set_progress_callback(fill_flash, &flashrom_progress_cb, &progress_state);
+
print_chip_support_status(fill_flash->chip);
unsigned int limitexceeded = count_max_decode_exceedings(fill_flash);
diff --git a/cli_output.c b/cli_output.c
index 629db676d..e5b829a7d 100644
--- a/cli_output.c
+++ b/cli_output.c
@@ -64,6 +64,31 @@ void start_logging(void)
verbose_screen = oldverbose_screen;
}
+static const char *flashrom_progress_stage_to_string(enum flashrom_progress_stage stage)
+{
+ if (stage == FLASHROM_PROGRESS_READ)
+ return "READ";
+ if (stage == FLASHROM_PROGRESS_WRITE)
+ return "WRITE";
+ if (stage == FLASHROM_PROGRESS_ERASE)
+ return "ERASE";
+ return "UNKNOWN";
+}
+
+void flashrom_progress_cb(struct flashrom_flashctx *flashctx)
+{
+ struct flashrom_progress *progress_state = flashctx->progress_state;
+ unsigned int pc = 0;
+ unsigned int *percentages = progress_state->user_data;
+ if (progress_state->current > 0 && progress_state->total > 0)
+ pc = ((unsigned long long) progress_state->current * 10000llu) /
+ ((unsigned long long) progress_state->total * 100llu);
+ if (percentages[progress_state->stage] != pc) {
+ percentages[progress_state->stage] = pc;
+ msg_ginfo("[%s] %u%% complete... ", flashrom_progress_stage_to_string(progress_state->stage), pc);
+ }
+}
+
/* Please note that level is the verbosity, not the importance of the message. */
int flashrom_print_cb(enum flashrom_log_level level, const char *fmt, va_list ap)
{
diff --git a/dediprog.c b/dediprog.c
index 8a05a7c16..3bd61a08c 100644
--- a/dediprog.c
+++ b/dediprog.c
@@ -658,6 +658,7 @@ static int dediprog_spi_bulk_write(struct flashctx *flash, const uint8_t *buf, u
msg_perr("SPI bulk write failed, expected %i, got %s!\n", 512, libusb_error_name(ret));
return 1;
}
+ update_progress(flash, FLASHROM_PROGRESS_WRITE, i + 1, count);
}
return 0;
diff --git a/en29lv640b.c b/en29lv640b.c
index 5b019047e..6c0a565a8 100644
--- a/en29lv640b.c
+++ b/en29lv640b.c
@@ -48,6 +48,7 @@ int write_en29lv640b(struct flashctx *flash, const uint8_t *src, unsigned int st
#endif
dst += 2;
src += 2;
+ update_progress(flash, FLASHROM_PROGRESS_WRITE, i + 2, len);
}
/* FIXME: Ignore errors for now. */
diff --git a/flashrom.8.tmpl b/flashrom.8.tmpl
index 58f5ec0cc..3dac4b9b7 100644
--- a/flashrom.8.tmpl
+++ b/flashrom.8.tmpl
@@ -53,7 +53,8 @@ flashrom \- detect, read, write, verify and erase flash chips
[\fB\-\-wp\-status\fR] [\fB\-\-wp\-list\fR] [\fB\-\-wp\-enable\fR|\fB\-\-wp\-disable\fR]
[\fB\-\-wp\-range\fR <start>,<length>|\fB\-\-wp\-region\fR <region>]
[\fB\-n\fR] [\fB\-N\fR] [\fB\-f\fR])]
- [\fB\-V\fR[\fBV\fR[\fBV\fR]]] [\fB-o\fR <logfile>]
+ [\fB\-V\fR[\fBV\fR[\fBV\fR]]] [\fB-o\fR <logfile>] [\fB\-\-progress\fR]
+
.SH DESCRIPTION
.B flashrom
is a utility for detecting, reading, writing, verifying and erasing flash
@@ -445,6 +446,9 @@ If the file already exists, it will be overwritten. This is the recommended
way to gather logs from flashrom because they will be verbose even if the
on-screen messages are not verbose and don't require output redirection.
.TP
+.B "\-\-progress"
+Show progress percentage of operations on the standard output.
+.TP
.B "\-R, \-\-version"
Show version information and exit.
.SH PROGRAMMER-SPECIFIC INFORMATION
diff --git a/include/flash.h b/include/flash.h
index 27ade09b6..45533ba9b 100644
--- a/include/flash.h
+++ b/include/flash.h
@@ -350,6 +350,9 @@ struct flashrom_flashctx {
chip_restore_fn_cb_t func;
uint8_t status;
} chip_restore_fn[MAX_CHIP_RESTORE_FUNCTIONS];
+ /* Progress reporting */
+ flashrom_progress_callback *progress_callback;
+ struct flashrom_progress *progress_state;
};
/* Timing used in probe routines. ZERO is -2 to differentiate between an unset
@@ -446,6 +449,7 @@ int open_logfile(const char * const filename);
int close_logfile(void);
void start_logging(void);
int flashrom_print_cb(enum flashrom_log_level level, const char *fmt, va_list ap);
+void flashrom_progress_cb(struct flashrom_flashctx *flashctx);
/* Let gcc and clang check for correct printf-style format strings. */
int print(enum flashrom_log_level level, const char *fmt, ...)
#ifdef __MINGW32__
@@ -474,6 +478,7 @@ __attribute__((format(printf, 2, 3)));
#define msg_gspew(...) print(FLASHROM_MSG_SPEW, __VA_ARGS__) /* general debug spew */
#define msg_pspew(...) print(FLASHROM_MSG_SPEW, __VA_ARGS__) /* programmer debug spew */
#define msg_cspew(...) print(FLASHROM_MSG_SPEW, __VA_ARGS__) /* chip debug spew */
+void update_progress(struct flashctx *flash, enum flashrom_progress_stage stage, size_t current, size_t total);
/* spi.c */
struct spi_command {
diff --git a/include/libflashrom.h b/include/libflashrom.h
index cf1f46234..21a5785f3 100644
--- a/include/libflashrom.h
+++ b/include/libflashrom.h
@@ -69,6 +69,34 @@ typedef int(flashrom_log_callback)(enum flashrom_log_level, const char *format,
*/
void flashrom_set_log_callback(flashrom_log_callback *log_callback);
+enum flashrom_progress_stage {
+ FLASHROM_PROGRESS_READ,
+ FLASHROM_PROGRESS_WRITE,
+ FLASHROM_PROGRESS_ERASE,
+ FLASHROM_PROGRESS_NR,
+};
+struct flashrom_progress {
+ enum flashrom_progress_stage stage;
+ size_t current;
+ size_t total;
+ void *user_data;
+};
+struct flashrom_flashctx;
+typedef void(flashrom_progress_callback)(struct flashrom_flashctx *flashctx);
+/**
+ * @brief Set the progress callback function.
+ *
+ * Set a callback function which will be invoked whenever libflashrom wants
+ * to indicate the progress has changed. This allows frontends to do whatever
+ * they see fit with such values, e.g. update a progress bar in a GUI tool.
+ *
+ * @param progress_callback Pointer to the new progress callback function.
+ * @param progress_state Pointer to progress state to include with the progress
+ * callback.
+ */
+void flashrom_set_progress_callback(struct flashrom_flashctx *const flashctx,
+ flashrom_progress_callback *progress_callback, struct flashrom_progress *progress_state);
+
/** @} */ /* end flashrom-general */
/**
@@ -174,7 +202,6 @@ int flashrom_programmer_shutdown(struct flashrom_programmer *flashprog);
* @{
*/
-struct flashrom_flashctx;
/**
* @brief Probe for a flash chip.
*
diff --git a/it87spi.c b/it87spi.c
index 204816af7..a24a172a1 100644
--- a/it87spi.c
+++ b/it87spi.c
@@ -291,6 +291,7 @@ static int it8716f_spi_chip_write_256(struct flashctx *flash, const uint8_t *buf
int ret = it8716f_spi_page_program(flash, buf, start);
if (ret)
return ret;
+ update_progress(flash, FLASHROM_PROGRESS_WRITE, chip->page_size - len, chip->page_size);
start += chip->page_size;
len -= chip->page_size;
buf += chip->page_size;
diff --git a/jedec.c b/jedec.c
index 0709efa5e..2542f3e67 100644
--- a/jedec.c
+++ b/jedec.c
@@ -421,6 +421,7 @@ int write_jedec_1(struct flashctx *flash, const uint8_t *src, unsigned int start
if (write_byte_program_jedec_common(flash, src, dst, mask))
failed = 1;
dst++, src++;
+ update_progress(flash, FLASHROM_PROGRESS_WRITE, i + 1, len);
}
if (failed)
msg_cerr(" writing sector at 0x%" PRIxPTR " failed!\n", olddst);
@@ -487,6 +488,7 @@ int write_jedec(struct flashctx *flash, const uint8_t *buf, unsigned int start,
* we're OK for now.
*/
unsigned int page_size = flash->chip->page_size;
+ unsigned int nwrites = (start + len - 1) / page_size;
/* Warning: This loop has a very unusual condition and body.
* The loop needs to go through each page with at least one affected
@@ -497,7 +499,7 @@ int write_jedec(struct flashctx *flash, const uint8_t *buf, unsigned int start,
* (start + len - 1) / page_size. Since we want to include that last
* page as well, the loop condition uses <=.
*/
- for (i = start / page_size; i <= (start + len - 1) / page_size; i++) {
+ for (i = start / page_size; i <= nwrites; i++) {
/* Byte position of the first byte in the range in this page. */
/* starthere is an offset to the base address of the chip. */
starthere = max(start, i * page_size);
@@ -506,6 +508,7 @@ int write_jedec(struct flashctx *flash, const uint8_t *buf, unsigned int start,
if (write_page_write_jedec_common(flash, buf + starthere - start, starthere, lenhere))
return 1;
+ update_progress(flash, FLASHROM_PROGRESS_WRITE, i + 1, nwrites + 1);
}
return 0;
diff --git a/libflashrom.c b/libflashrom.c
index e70c1d1af..0c6613e94 100644
--- a/libflashrom.c
+++ b/libflashrom.c
@@ -65,6 +65,25 @@ int print(const enum flashrom_log_level level, const char *const fmt, ...)
return 0;
}
+void flashrom_set_progress_callback(struct flashrom_flashctx *flashctx, flashrom_progress_callback *progress_callback, struct flashrom_progress *progress_state)
+{
+ flashctx->progress_callback = progress_callback;
+ flashctx->progress_state = progress_state;
+}
+/** @private */
+void update_progress(struct flashrom_flashctx *flashctx, enum flashrom_progress_stage stage, size_t current, size_t total)
+{
+ if (flashctx->progress_callback == NULL)
+ return;
+ if (current > total)
+ current = total;
+
+ flashctx->progress_state->stage = stage;
+ flashctx->progress_state->current = current;
+ flashctx->progress_state->total = total;
+ flashctx->progress_callback(flashctx);
+}
+
const char *flashrom_version_info(void)
{
return flashrom_version;
diff --git a/libflashrom.map b/libflashrom.map
index 2249d3549..b3af70b11 100644
--- a/libflashrom.map
+++ b/libflashrom.map
@@ -24,6 +24,7 @@ LIBFLASHROM_1.0 {
flashrom_programmer_init;
flashrom_programmer_shutdown;
flashrom_set_log_callback;
+ flashrom_set_progress_callback;
flashrom_shutdown;
flashrom_version_info;
local: *;
diff --git a/linux_mtd.c b/linux_mtd.c
index 445a90359..88488c0b2 100644
--- a/linux_mtd.c
+++ b/linux_mtd.c
@@ -214,6 +214,7 @@ static int linux_mtd_read(struct flashctx *flash, uint8_t *buf,
}
i += step;
+ update_progress(flash, FLASHROM_PROGRESS_READ, i, len);
}
return 0;
@@ -256,6 +257,7 @@ static int linux_mtd_write(struct flashctx *flash, const uint8_t *buf,
}
i += step;
+ update_progress(flash, FLASHROM_PROGRESS_WRITE, i, len);
}
return 0;
@@ -292,6 +294,7 @@ static int linux_mtd_erase(struct flashctx *flash,
__func__, ret, strerror(errno));
return 1;
}
+ update_progress(flash, FLASHROM_PROGRESS_ERASE, u + data->erasesize, len);
}
return 0;
diff --git a/lspcon_i2c_spi.c b/lspcon_i2c_spi.c
index cabe21f6c..f3c11d665 100644
--- a/lspcon_i2c_spi.c
+++ b/lspcon_i2c_spi.c
@@ -354,6 +354,7 @@ static int lspcon_i2c_spi_read(struct flashctx *flash, uint8_t *buf,
for (i = 0; i < len; i += LSPCON_PAGE_SIZE) {
ret |= lspcon_i2c_spi_map_page(fd, start + i);
ret |= lspcon_i2c_spi_read_data(fd, PAGE_ADDRESS, buf + i, min(len - i, LSPCON_PAGE_SIZE));
+ update_progress(flash, FLASHROM_PROGRESS_READ, i + LSPCON_PAGE_SIZE, len);
}
return ret;
@@ -394,6 +395,7 @@ static int lspcon_i2c_spi_write_256(struct flashctx *flash, const uint8_t *buf,
for (unsigned int i = 0; i < len; i += LSPCON_PAGE_SIZE) {
ret |= lspcon_i2c_spi_map_page(fd, start + i);
ret |= lspcon_i2c_spi_write_page(fd, buf + i, min(len - i, LSPCON_PAGE_SIZE));
+ update_progress(flash, FLASHROM_PROGRESS_WRITE, i + LSPCON_PAGE_SIZE, len);
}
ret |= lspcon_i2c_spi_enable_write_protection(fd);
diff --git a/realtek_mst_i2c_spi.c b/realtek_mst_i2c_spi.c
index 954150df5..c7de2fe7d 100644
--- a/realtek_mst_i2c_spi.c
+++ b/realtek_mst_i2c_spi.c
@@ -398,6 +398,7 @@ static int realtek_mst_i2c_spi_write_256(struct flashctx *flash, const uint8_t *
ret |= realtek_mst_i2c_execute_write(fd);
if (ret)
break;
+ update_progress(flash, FLASHROM_PROGRESS_WRITE, i + RTK_PAGE_SIZE, len);
}
return ret;
diff --git a/spi.c b/spi.c
index f2e91c4d9..9f820d705 100644
--- a/spi.c
+++ b/spi.c
@@ -101,6 +101,8 @@ int spi_chip_read(struct flashctx *flash, uint8_t *buf, unsigned int start,
{
int ret;
size_t to_read;
+ size_t start_address = start;
+ size_t end_address = len - start;
for (; len; len -= to_read, buf += to_read, start += to_read) {
/* Do not cross 16MiB boundaries in a single transfer.
This helps with
@@ -110,6 +112,7 @@ int spi_chip_read(struct flashctx *flash, uint8_t *buf, unsigned int start,
ret = flash->mst->spi.read(flash, buf, start, to_read);
if (ret)
return ret;
+ update_progress(flash, FLASHROM_PROGRESS_READ, start - start_address + to_read, end_address);
}
return 0;
}
diff --git a/spi25.c b/spi25.c
index e96a38db7..39a887609 100644
--- a/spi25.c
+++ b/spi25.c
@@ -674,11 +674,14 @@ int spi_read_chunked(struct flashctx *flash, uint8_t *buf, unsigned int start,
{
int ret;
size_t to_read;
+ size_t start_address = start;
+ size_t end_address = len - start;
for (; len; len -= to_read, buf += to_read, start += to_read) {
to_read = min(chunksize, len);
ret = spi_nbyte_read(flash, start, buf, to_read);
if (ret)
return ret;
+ update_progress(flash, FLASHROM_PROGRESS_READ, start - start_address + to_read, end_address);
}
return 0;
}
@@ -698,6 +701,8 @@ int spi_write_chunked(struct flashctx *flash, const uint8_t *buf, unsigned int s
* we're OK for now.
*/
unsigned int page_size = flash->chip->page_size;
+ size_t start_address = start;
+ size_t end_address = len - start;
/* Warning: This loop has a very unusual condition and body.
* The loop needs to go through each page with at least one affected
@@ -722,6 +727,7 @@ int spi_write_chunked(struct flashctx *flash, const uint8_t *buf, unsigned int s
if (rc)
return rc;
}
+ update_progress(flash, FLASHROM_PROGRESS_WRITE, start - start_address + lenhere, end_address);
}
return 0;
@@ -741,6 +747,7 @@ int spi_chip_write_1(struct flashctx *flash, const uint8_t *buf, unsigned int st
for (i = start; i < start + len; i++) {
if (spi_nbyte_program(flash, i, buf + i - start, 1))
return 1;
+ update_progress(flash, FLASHROM_PROGRESS_WRITE, i - start, len - start);
}
return 0;
}
diff --git a/sst28sf040.c b/sst28sf040.c
index 3da25f127..9a08d6b61 100644
--- a/sst28sf040.c
+++ b/sst28sf040.c
@@ -92,6 +92,7 @@ int write_28sf040(struct flashctx *flash, const uint8_t *src, unsigned int start
/* wait for Toggle bit ready */
toggle_ready_jedec(flash, bios);
+ update_progress(flash, FLASHROM_PROGRESS_WRITE, i + 1, len);
}
return 0;
diff --git a/tests/spi25.c b/tests/spi25.c
index f57251ea8..f10191040 100644
--- a/tests/spi25.c
+++ b/tests/spi25.c
@@ -67,6 +67,65 @@ int __wrap_spi_send_command(const struct flashctx *flash,
return 0;
}
+static void spi_read_progress_cb(struct flashrom_flashctx *flashctx)
+{
+ struct flashrom_progress *progress_state = flashctx->progress_state;
+ uint32_t *cnt = (uint32_t *) progress_state->user_data;
+ assert_int_equal(0x300, progress_state->total);
+ switch (*cnt) {
+ case 0:
+ assert_int_equal(0x100, progress_state->current);
+ break;
+ case 1:
+ assert_int_equal(0x200, progress_state->current);
+ break;
+ case 2:
+ assert_int_equal(0x300, progress_state->current);
+ break;
+ case 3:
+ assert_int_equal(0x300, progress_state->current);
+ break;
+ case 4:
+ assert_int_equal(0x300, progress_state->current);
+ break;
+ default:
+ fail();
+ }
+ (*cnt)++;
+}
+
+void spi_read_chunked_test_success(void **state)
+{
+ (void) state; /* unused */
+ uint8_t buf[0x400] = { 0x0 };
+ uint32_t cnt = 0;
+ const unsigned int max_data_read = 0x100;
+ const unsigned int offset = 0x100;
+ struct registered_master mst = {
+ .spi.read = default_spi_read,
+ .spi.max_data_read = max_data_read
+ };
+
+ /* setup initial test state */
+ struct flashctx flashctx = {
+ .chip = &mock_chip,
+ .mst = &mst
+ };
+ struct flashrom_progress progress_state = {
+ .user_data = (void *) &cnt,
+ };
+ flashrom_set_progress_callback(&flashctx, spi_read_progress_cb, &progress_state);
+ for (int i = 0; i < 4; i++) {
+ expect_memory(__wrap_spi_send_command, flash,
+ &flashctx, sizeof(flashctx));
+ will_return(__wrap_spi_send_command, JEDEC_WRDI);
+ will_return(__wrap_spi_send_command, JEDEC_READ);
+ will_return(__wrap_spi_send_command, max_data_read);
+ }
+ assert_int_equal(0, spi_chip_read(&flashctx, buf, offset, sizeof(buf)));
+ assert_int_equal(5, cnt);
+}
+
void spi_write_enable_test_success(void **state)
{
(void) state; /* unused */
diff --git a/tests/tests.c b/tests/tests.c
index 2f955ff40..a719a8fd0 100644
--- a/tests/tests.c
+++ b/tests/tests.c
@@ -391,6 +391,7 @@ int main(void)
const struct CMUnitTest spi25_tests[] = {
cmocka_unit_test(spi_write_enable_test_success),
cmocka_unit_test(spi_write_disable_test_success),
+ cmocka_unit_test(spi_read_chunked_test_success),
cmocka_unit_test(probe_spi_rdid_test_success),
cmocka_unit_test(probe_spi_rdid4_test_success),
cmocka_unit_test(probe_spi_rems_test_success),
diff --git a/tests/tests.h b/tests/tests.h
index e2b221130..5ffc14565 100644
--- a/tests/tests.h
+++ b/tests/tests.h
@@ -31,6 +31,7 @@ void flashbuses_to_text_test_success(void **state);
/* spi25.c */
void spi_write_enable_test_success(void **state);
void spi_write_disable_test_success(void **state);
+void spi_read_chunked_test_success(void **state);
void probe_spi_rdid_test_success(void **state);
void probe_spi_rdid4_test_success(void **state);
void probe_spi_rems_test_success(void **state);