summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--common/bloblist.c19
-rw-r--r--include/bloblist.h13
-rw-r--r--test/bloblist.c34
3 files changed, 65 insertions, 1 deletions
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
@@ -152,6 +152,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
*
* @addr: Address of bloblist
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;