[PATCH v3 3/4] libfdt: Add a way to determine free space

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]



The sequential-write functions currently complain if there is not enough
space in the tree for a new addition. For the Python bindings we want to
automatically expand the tree when space gets too low.

Add a function that returns the current number of free bytes.

Signed-off-by: Simon Glass <sjg@xxxxxxxxxxxx>
---

Changes in v3: None
Changes in v2: None

 libfdt/fdt_sw.c   | 13 ++++++++-----
 libfdt/libfdt.h   |  8 ++++++++
 tests/sw_states.c | 16 ++++++++++++++++
 3 files changed, 32 insertions(+), 5 deletions(-)

diff --git a/libfdt/fdt_sw.c b/libfdt/fdt_sw.c
index 178b365..2b15aa8 100644
--- a/libfdt/fdt_sw.c
+++ b/libfdt/fdt_sw.c
@@ -126,15 +126,18 @@ static int fdt_sw_probe_struct_(void *fdt)
  * Allowed functions: none
  */
 
+int fdt_free_space(void *fdt)
+{
+	return fdt_totalsize(fdt) - fdt_off_dt_struct(fdt)
+		- fdt_size_dt_strings(fdt) - fdt_size_dt_struct(fdt);
+}
+
 static void *fdt_grab_space_(void *fdt, size_t len)
 {
 	int offset = fdt_size_dt_struct(fdt);
-	int spaceleft;
-
-	spaceleft = fdt_totalsize(fdt) - fdt_off_dt_struct(fdt)
-		- fdt_size_dt_strings(fdt);
+	int spaceleft = fdt_free_space(fdt);
 
-	if ((offset + len < offset) || (offset + len > spaceleft))
+	if ((len < 0) || (len > spaceleft))
 		return NULL;
 
 	fdt_set_size_dt_struct(fdt, offset + len);
diff --git a/libfdt/libfdt.h b/libfdt/libfdt.h
index c99d28f..ca03575 100644
--- a/libfdt/libfdt.h
+++ b/libfdt/libfdt.h
@@ -1331,6 +1331,14 @@ int fdt_nop_node(void *fdt, int nodeoffset);
 
 int fdt_create(void *buf, int bufsize);
 int fdt_resize(void *fdt, void *buf, int bufsize);
+
+/**
+ * fdt_free_space - return the amount of free space in the tree
+ *
+ * This returns the number of bytes available for adding new content to a
+ * sequence-write tree. The value is >= 0.
+ */
+int fdt_free_space(void *fdt);
 int fdt_add_reservemap_entry(void *fdt, uint64_t addr, uint64_t size);
 int fdt_finish_reservemap(void *fdt);
 int fdt_begin_node(void *fdt, const char *name);
diff --git a/tests/sw_states.c b/tests/sw_states.c
index 2fd471d..0ce6f41 100644
--- a/tests/sw_states.c
+++ b/tests/sw_states.c
@@ -30,6 +30,7 @@
 #include "testdata.h"
 
 #define SPACE	65536
+#define ALIGN4(x)	ALIGN(x, 4)
 
 #define CHECK_OK(code)							\
 	do {								\
@@ -49,8 +50,17 @@
 			FAIL(#code ": %s", fdt_strerror(err));		\
 	} while (0)
 
+#define CHECK_SPACE_USED(used)						\
+	do {								\
+		expected -= used;					\
+		space = fdt_free_space(fdt);				\
+		if (space != expected)					\
+			FAIL("Space %d, expected %d", space, expected);	\
+	} while (0)
+
 int main(int argc, char *argv[])
 {
+	int space, expected;
 	void *fdt = NULL;
 	int err;
 
@@ -84,8 +94,14 @@ int main(int argc, char *argv[])
 	CHECK_BADSTATE(fdt_add_reservemap_entry(fdt, TEST_ADDR_1, TEST_SIZE_1));
 	CHECK_BADSTATE(fdt_finish_reservemap(fdt));
 
+	expected = fdt_free_space(fdt);
+
 	CHECK_OK(fdt_begin_node(fdt, ""));
+	CHECK_SPACE_USED(sizeof(struct fdt_node_header) + ALIGN4(sizeof("")));
 	CHECK_OK(fdt_property_string(fdt, "compatible", "test_tree1"));
+	CHECK_SPACE_USED(sizeof(struct fdt_property) +
+			 ALIGN4(sizeof("compatible")) +
+			 sizeof("test_tree1"));
 	CHECK_OK(fdt_property_u32(fdt, "prop-int", TEST_VALUE_1));
 	CHECK_OK(fdt_property_u64(fdt, "prop-int64", TEST_VALUE64_1));
 	CHECK_OK(fdt_property_string(fdt, "prop-str", TEST_STRING_1));
-- 
2.18.0.rc1.244.gcf134e6275-goog

--
To unsubscribe from this list: send the line "unsubscribe devicetree-compiler" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html



[Index of Archives]     [Device Tree]     [Device Tree Spec]     [Linux Driver Backports]     [Video for Linux]     [Linux USB Devel]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Yosemite Backpacking]

  Powered by Linux