From 5b044548f5ae3e5f7cfbd4a6399f0695b4fb709b Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Mon, 27 Jan 2020 08:49:50 -0700 Subject: [PATCH] bloblist: Add a new function to add or check size A common check is to see if a blob is present, create it if not and make sure that the size is large enough. Add a function to handle this. Signed-off-by: Simon Glass --- common/bloblist.c | 19 ++++++++++++++++++- include/bloblist.h | 13 +++++++++++++ test/bloblist.c | 34 ++++++++++++++++++++++++++++++++++ 3 files changed, 65 insertions(+), 1 deletion(-) diff --git a/common/bloblist.c b/common/bloblist.c index ccf5e4b6f6..3599ffa75c 100644 --- a/common/bloblist.c +++ b/common/bloblist.c @@ -85,8 +85,10 @@ static int bloblist_ensurerec(uint tag, struct bloblist_rec **recp, int size) rec = bloblist_findrec(tag); if (rec) { - if (size && size != rec->size) + if (size && size != rec->size) { + *recp = rec; return -ESPIPE; + } } else { int ret; @@ -145,6 +147,21 @@ void *bloblist_ensure(uint tag, int size) return (void *)rec + rec->hdr_size; } +int bloblist_ensure_size_ret(uint tag, int *sizep, void **blobp) +{ + struct bloblist_rec *rec; + int ret; + + ret = bloblist_ensurerec(tag, &rec, *sizep); + if (ret == -ESPIPE) + *sizep = rec->size; + else if (ret) + return ret; + *blobp = (void *)rec + rec->hdr_size; + + return 0; +} + static u32 bloblist_calc_chksum(struct bloblist_hdr *hdr) { struct bloblist_rec *rec; diff --git a/include/bloblist.h b/include/bloblist.h index 85144010ab..8c9ce98a3b 100644 --- a/include/bloblist.h +++ b/include/bloblist.h @@ -151,6 +151,19 @@ int bloblist_ensure_size(uint tag, int size, void **blobp); */ void *bloblist_ensure(uint tag, int size); +/** + * bloblist_ensure_size_ret() - Find or add a blob + * + * Find an existing blob, or add a new one if not found + * + * @tag: Tag to add (enum bloblist_tag_t) + * @sizep: Size of the blob to create; returns size of actual blob + * @blobp: Returns a pointer to blob on success + * @return 0 if OK, -ENOSPC if it is missing and could not be added due to lack + * of space + */ +int bloblist_ensure_size_ret(uint tag, int *sizep, void **blobp); + /** * bloblist_new() - Create a new, empty bloblist of a given size * diff --git a/test/bloblist.c b/test/bloblist.c index d0f7296e0d..c78b58ea29 100644 --- a/test/bloblist.c +++ b/test/bloblist.c @@ -24,6 +24,7 @@ enum { TEST_SIZE = 10, TEST_SIZE2 = 20, + TEST_SIZE_LARGE = 0xe0, TEST_ADDR = CONFIG_BLOBLIST_ADDR, TEST_BLOBLIST_SIZE = 0x100, @@ -97,6 +98,39 @@ static int bloblist_test_blob(struct unit_test_state *uts) } BLOBLIST_TEST(bloblist_test_blob, 0); +/* Check bloblist_ensure_size_ret() */ +static int bloblist_test_blob_ensure(struct unit_test_state *uts) +{ + void *data, *data2; + int size; + + /* At the start there should be no records */ + clear_bloblist(); + ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0)); + + /* Test with an empty bloblist */ + size = TEST_SIZE; + ut_assertok(bloblist_ensure_size_ret(TEST_TAG, &size, &data)); + ut_asserteq(TEST_SIZE, size); + + /* Check that we get the same thing again */ + ut_assertok(bloblist_ensure_size_ret(TEST_TAG, &size, &data2)); + ut_asserteq(TEST_SIZE, size); + ut_asserteq_ptr(data, data2); + + /* Check that the size remains the same */ + size = TEST_SIZE2; + ut_assertok(bloblist_ensure_size_ret(TEST_TAG, &size, &data)); + ut_asserteq(TEST_SIZE, size); + + /* Check running out of space */ + size = TEST_SIZE_LARGE; + ut_asserteq(-ENOSPC, bloblist_ensure_size_ret(TEST_TAG2, &size, &data)); + + return 0; +} +BLOBLIST_TEST(bloblist_test_blob_ensure, 0); + static int bloblist_test_bad_blob(struct unit_test_state *uts) { struct bloblist_hdr *hdr;