Index: kernel/generic/src/sysinfo/sysinfo.c
===================================================================
--- kernel/generic/src/sysinfo/sysinfo.c	(revision a80687e5d0c412f3bad3c9783431cf59986f9006)
+++ kernel/generic/src/sysinfo/sysinfo.c	(revision d8693989d41da5cff2a9dc07daabd16136877a67)
@@ -41,13 +41,21 @@
 #include <errno.h>
 
+/** Maximal sysinfo path length */
 #define SYSINFO_MAX_PATH  2048
 
 bool fb_exported = false;
 
+/** Global sysinfo tree root item */
 static sysinfo_item_t *global_root = NULL;
+
+/** Sysinfo SLAB cache */
 static slab_cache_t *sysinfo_item_slab;
 
+/** Sysinfo spinlock */
 SPINLOCK_STATIC_INITIALIZE_NAME(sysinfo_lock, "sysinfo_lock");
 
+/** Sysinfo item constructor
+ *
+ */
 static int sysinfo_item_constructor(void *obj, int kmflag)
 {
@@ -63,4 +71,11 @@
 }
 
+/** Sysinfo item destructor
+ *
+ * Note that the return value is not perfectly correct
+ * since more space might get actually freed thanks
+ * to the disposal of item->name
+ *
+ */
 static int sysinfo_item_destructor(void *obj)
 {
@@ -73,4 +88,9 @@
 }
 
+/** Initialize sysinfo subsystem
+ *
+ * Create SLAB cache for sysinfo items.
+ *
+ */
 void sysinfo_init(void)
 {
@@ -80,9 +100,20 @@
 }
 
-/** Recursively find item in sysinfo tree
+/** Recursively find an item in sysinfo tree
  *
  * Should be called with interrupts disabled
  * and sysinfo_lock held.
  *
+ * @param name    Current sysinfo path suffix.
+ * @param subtree Current sysinfo (sub)tree root item.
+ * @param ret     If the return value is NULL, this argument
+ *                can be either also NULL (i.e. no item was
+ *                found and no data was generated) or the
+ *                original pointer is used to store the value
+ *                generated by a generated subtree function.
+ *
+ * @return Found item or NULL if no item in the fixed tree
+ *         was found (N.B. ret).
+ *
  */
 static sysinfo_item_t *sysinfo_find_item(const char *name,
@@ -94,4 +125,5 @@
 	sysinfo_item_t *cur = subtree;
 	
+	/* Walk all siblings */
 	while (cur != NULL) {
 		size_t i = 0;
@@ -118,5 +150,5 @@
 				return NULL;
 			default:
-				/* Not found */
+				/* Not found, no data generated */
 				*ret = NULL;
 				return NULL;
@@ -127,4 +159,5 @@
 	}
 	
+	/* Not found, no data generated */
 	*ret = NULL;
 	return NULL;
@@ -135,4 +168,12 @@
  * Should be called with interrupts disabled
  * and sysinfo_lock held.
+ *
+ * @param name     Current sysinfo path suffix.
+ * @param psubtree Pointer to an already existing (sub)tree root
+ *                 item or where to store a new tree root item.
+ *
+ * @return Existing or newly allocated sysinfo item or NULL
+ *         if the current tree configuration does not allow to
+ *         create a new item.
  *
  */
@@ -172,4 +213,5 @@
 	sysinfo_item_t *cur = *psubtree;
 	
+	/* Walk all siblings */
 	while (cur != NULL) {
 		size_t i = 0;
@@ -199,5 +241,5 @@
 			default:
 				/* Subtree items handled by a function, this
-				 * cannot be overriden.
+				 * cannot be overriden by a constant item.
 				 */
 				return NULL;
@@ -235,5 +277,4 @@
 		}
 		
-		/* Get next sibling */
 		cur = cur->next;
 	}
@@ -244,7 +285,16 @@
 }
 
+/** Set sysinfo item with a constant numeric value
+ *
+ * @param name Sysinfo path.
+ * @param root Pointer to the root item or where to store
+ *             a new root item (NULL for global sysinfo root).
+ * @param val  Value to store in the item.
+ *
+ */
 void sysinfo_set_item_val(const char *name, sysinfo_item_t **root,
     unative_t val)
 {
+	/* Protect sysinfo tree consistency */
 	ipl_t ipl = interrupts_disable();
 	spinlock_lock(&sysinfo_lock);
@@ -263,7 +313,21 @@
 }
 
+/** Set sysinfo item with a constant binary data
+ *
+ * Note that sysinfo only stores the pointer to the
+ * binary data and does not touch it in any way. The
+ * data should be static and immortal.
+ *
+ * @param name Sysinfo path.
+ * @param root Pointer to the root item or where to store
+ *             a new root item (NULL for global sysinfo root).
+ * @param data Binary data.
+ * @param size Size of the binary data.
+ *
+ */
 void sysinfo_set_item_data(const char *name, sysinfo_item_t **root,
     void *data, size_t size)
 {
+	/* Protect sysinfo tree consistency */
 	ipl_t ipl = interrupts_disable();
 	spinlock_lock(&sysinfo_lock);
@@ -283,7 +347,16 @@
 }
 
+/** Set sysinfo item with a generated numeric value
+ *
+ * @param name Sysinfo path.
+ * @param root Pointer to the root item or where to store
+ *             a new root item (NULL for global sysinfo root).
+ * @param fn   Numeric value generator function.
+ *
+ */
 void sysinfo_set_item_fn_val(const char *name, sysinfo_item_t **root,
     sysinfo_fn_val_t fn)
 {
+	/* Protect sysinfo tree consistency */
 	ipl_t ipl = interrupts_disable();
 	spinlock_lock(&sysinfo_lock);
@@ -302,7 +375,21 @@
 }
 
+/** Set sysinfo item with a generated binary data
+ *
+ * Note that each time the generator function is called
+ * it is supposed to return a new dynamically allocated
+ * data. This data is then freed by sysinfo in the context
+ * of the current sysinfo request.
+ *
+ * @param name Sysinfo path.
+ * @param root Pointer to the root item or where to store
+ *             a new root item (NULL for global sysinfo root).
+ * @param fn   Binary data generator function.
+ *
+ */
 void sysinfo_set_item_fn_data(const char *name, sysinfo_item_t **root,
     sysinfo_fn_data_t fn)
 {
+	/* Protect sysinfo tree consistency */
 	ipl_t ipl = interrupts_disable();
 	spinlock_lock(&sysinfo_lock);
@@ -321,6 +408,14 @@
 }
 
+/** Set sysinfo item with an undefined value
+ *
+ * @param name Sysinfo path.
+ * @param root Pointer to the root item or where to store
+ *             a new root item (NULL for global sysinfo root).
+ *
+ */
 void sysinfo_set_item_undefined(const char *name, sysinfo_item_t **root)
 {
+	/* Protect sysinfo tree consistency */
 	ipl_t ipl = interrupts_disable();
 	spinlock_lock(&sysinfo_lock);
@@ -337,7 +432,16 @@
 }
 
+/** Set sysinfo item with a generated subtree
+ *
+ * @param name Sysinfo path.
+ * @param root Pointer to the root item or where to store
+ *             a new root item (NULL for global sysinfo root).
+ * @param fn   Subtree generator function.
+ *
+ */
 void sysinfo_set_subtree_fn(const char *name, sysinfo_item_t **root,
     sysinfo_fn_subtree_t fn)
 {
+	/* Protect sysinfo tree consistency */
 	ipl_t ipl = interrupts_disable();
 	spinlock_lock(&sysinfo_lock);
@@ -347,4 +451,7 @@
 	
 	sysinfo_item_t *item = sysinfo_create_path(name, root);
+	
+	/* Change the type of the subtree only if it is not already
+	   a fixed subtree */
 	if ((item != NULL) && (item->subtree_type != SYSINFO_SUBTREE_TABLE)) {
 		item->subtree_type = SYSINFO_SUBTREE_FUNCTION;
@@ -357,4 +464,6 @@
 
 /** Sysinfo dump indentation helper routine
+ *
+ * @param depth Number of indentation characters to print.
  *
  */
@@ -374,4 +483,7 @@
  * there is no better simple solution.
  *
+ * @param root  Root item of the current (sub)tree.
+ * @param depth Current depth in the sysinfo tree.
+ *
  */
 static void sysinfo_dump_internal(sysinfo_item_t *root, unsigned int depth)
@@ -379,4 +491,5 @@
 	sysinfo_item_t *cur = root;
 	
+	/* Walk all siblings */
 	while (cur != NULL) {
 		sysinfo_indent(depth);
@@ -386,4 +499,5 @@
 		size_t size;
 		
+		/* Display node value and type */
 		switch (cur->val_type) {
 		case SYSINFO_VAL_UNDEFINED:
@@ -405,4 +519,6 @@
 		case SYSINFO_VAL_FUNCTION_DATA:
 			data = cur->val.fn_data(cur, &size);
+			
+			/* N.B.: The generated binary data should be freed */
 			if (data != NULL)
 				free(data);
@@ -415,4 +531,5 @@
 		}
 		
+		/* Recursivelly nest into the subtree */
 		switch (cur->subtree_type) {
 		case SYSINFO_SUBTREE_NONE:
@@ -434,6 +551,15 @@
 }
 
+/** Dump the structure of sysinfo tree
+ *
+ * @param root  Root item of the sysinfo (sub)tree.
+ *              If it is NULL then consider the global
+ *              sysinfo tree.
+ *
+ */
 void sysinfo_dump(sysinfo_item_t *root)
 {
+	/* Avoid other functions to mess with sysinfo
+	   while we are dumping it */
 	ipl_t ipl = interrupts_disable();
 	spinlock_lock(&sysinfo_lock);
@@ -448,9 +574,16 @@
 }
 
-/** Return sysinfo item determined by name
+/** Return sysinfo item value determined by name
  *
  * Should be called with interrupts disabled
  * and sysinfo_lock held.
  *
+ * @param name Sysinfo path.
+ * @param root Root item of the sysinfo (sub)tree.
+ *             If it is NULL then consider the global
+ *             sysinfo tree.
+ *
+ * @return Item value (constant or generated).
+ *
  */
 static sysinfo_return_t sysinfo_get_item(const char *name, sysinfo_item_t **root)
@@ -459,4 +592,5 @@
 		root = &global_root;
 	
+	/* Try to find the item or generate data */
 	sysinfo_return_t ret;
 	sysinfo_return_t *ret_ptr = &ret;
@@ -464,4 +598,6 @@
 	
 	if (item != NULL) {
+		/* Item found in the fixed sysinfo tree */
+		
 		ret.tag = item->val_type;
 		switch (item->val_type) {
@@ -482,6 +618,9 @@
 		}
 	} else {
-		if (ret_ptr == NULL)
+		/* No item in the fixed sysinfo tree */
+		if (ret_ptr == NULL) {
+			/* Even no data was generated */
 			ret.tag = SYSINFO_VAL_UNDEFINED;
+		}
 	}
 	
@@ -492,5 +631,10 @@
  *
  * Should be called with interrupts disabled
- * and sysinfo_lock held.
+ * and sysinfo_lock held. The path string passed from
+ * the user space has to be properly null-terminated
+ * (the last passed character must be null).
+ *
+ * @param ptr  Sysinfo path in the user address space.
+ * @param size Size of the path string.
  *
  */
@@ -514,14 +658,33 @@
 }
 
+/** Get the sysinfo value type (syscall)
+ *
+ * The path string passed from the user space has
+ * to be properly null-terminated (the last passed
+ * character must be null).
+ *
+ * @param path_ptr  Sysinfo path in the user address space.
+ * @param path_size Size of the path string.
+ *
+ * @return Item value type.
+ *
+ */
 unative_t sys_sysinfo_get_tag(void *path_ptr, size_t path_size)
 {
-	ipl_t ipl = interrupts_disable();
-	spinlock_lock(&sysinfo_lock);
-	
+	/* Avoid other functions to mess with sysinfo
+	   while we are reading it */
+	ipl_t ipl = interrupts_disable();
+	spinlock_lock(&sysinfo_lock);
+	
+	/* Get the item */
 	sysinfo_return_t ret = sysinfo_get_item_uspace(path_ptr, path_size);
 	
+	/* N.B.: The generated binary data should be freed */
 	if ((ret.tag == SYSINFO_VAL_FUNCTION_DATA) && (ret.data.data != NULL))
 		free(ret.data.data);
 	
+	/* Map generated value types to constant types
+	   (user space does not care whether the
+	   value is constant or generated) */
 	if (ret.tag == SYSINFO_VAL_FUNCTION_VAL)
 		ret.tag = SYSINFO_VAL_VAL;
@@ -535,13 +698,31 @@
 }
 
+/** Get the sysinfo numerical value (syscall)
+ *
+ * The path string passed from the user space has
+ * to be properly null-terminated (the last passed
+ * character must be null).
+ *
+ * @param path_ptr  Sysinfo path in the user address space.
+ * @param path_size Size of the path string.
+ * @param value_ptr User space pointer where to store the
+ *                  numberical value.
+ *
+ * @return Error code (EOK in case of no error).
+ *
+ */
 unative_t sys_sysinfo_get_value(void *path_ptr, size_t path_size,
     void *value_ptr)
 {
-	ipl_t ipl = interrupts_disable();
-	spinlock_lock(&sysinfo_lock);
-	
+	/* Avoid other functions to mess with sysinfo
+	   while we are reading it */
+	ipl_t ipl = interrupts_disable();
+	spinlock_lock(&sysinfo_lock);
+	
+	/* Get the item */
 	sysinfo_return_t ret = sysinfo_get_item_uspace(path_ptr, path_size);
 	int rc;
 	
+	/* Only constant or generated numerical value is returned */
 	if ((ret.tag == SYSINFO_VAL_VAL) || (ret.tag == SYSINFO_VAL_FUNCTION_VAL))
 		rc = copy_to_uspace(value_ptr, &ret.val, sizeof(ret.val));
@@ -549,4 +730,5 @@
 		rc = EINVAL;
 	
+	/* N.B.: The generated binary data should be freed */
 	if ((ret.tag == SYSINFO_VAL_FUNCTION_DATA) && (ret.data.data != NULL))
 		free(ret.data.data);
@@ -558,13 +740,31 @@
 }
 
+/** Get the sysinfo binary data size (syscall)
+ *
+ * The path string passed from the user space has
+ * to be properly null-terminated (the last passed
+ * character must be null).
+ *
+ * @param path_ptr  Sysinfo path in the user address space.
+ * @param path_size Size of the path string.
+ * @param size_ptr  User space pointer where to store the
+ *                  binary data size.
+ *
+ * @return Error code (EOK in case of no error).
+ *
+ */
 unative_t sys_sysinfo_get_data_size(void *path_ptr, size_t path_size,
     void *size_ptr)
 {
-	ipl_t ipl = interrupts_disable();
-	spinlock_lock(&sysinfo_lock);
-	
+	/* Avoid other functions to mess with sysinfo
+	   while we are reading it */
+	ipl_t ipl = interrupts_disable();
+	spinlock_lock(&sysinfo_lock);
+	
+	/* Get the item */
 	sysinfo_return_t ret = sysinfo_get_item_uspace(path_ptr, path_size);
 	int rc;
 	
+	/* Only the size of constant or generated binary data is considered */
 	if ((ret.tag == SYSINFO_VAL_DATA) || (ret.tag == SYSINFO_VAL_FUNCTION_DATA))
 		rc = copy_to_uspace(size_ptr, &ret.data.size,
@@ -573,4 +773,5 @@
 		rc = EINVAL;
 	
+	/* N.B.: The generated binary data should be freed */
 	if ((ret.tag == SYSINFO_VAL_FUNCTION_DATA) && (ret.data.data != NULL))
 		free(ret.data.data);
@@ -582,14 +783,38 @@
 }
 
+/** Get the sysinfo binary data (syscall)
+ *
+ * The path string passed from the user space has
+ * to be properly null-terminated (the last passed
+ * character must be null).
+ *
+ * The user space buffer must be sized exactly according
+ * to the size of the binary data, otherwise the request
+ * fails.
+ *
+ * @param path_ptr    Sysinfo path in the user address space.
+ * @param path_size   Size of the path string.
+ * @param buffer_ptr  User space pointer to the buffer where
+ *                    to store the binary data.
+ * @param buffer_size User space buffer size.
+ *
+ * @return Error code (EOK in case of no error).
+ *
+ */
 unative_t sys_sysinfo_get_data(void *path_ptr, size_t path_size,
     void *buffer_ptr, size_t buffer_size)
 {
-	ipl_t ipl = interrupts_disable();
-	spinlock_lock(&sysinfo_lock);
-	
+	/* Avoid other functions to mess with sysinfo
+	   while we are reading it */
+	ipl_t ipl = interrupts_disable();
+	spinlock_lock(&sysinfo_lock);
+	
+	/* Get the item */
 	sysinfo_return_t ret = sysinfo_get_item_uspace(path_ptr, path_size);
 	int rc;
 	
+	/* Only constant or generated binary data is considered */
 	if ((ret.tag == SYSINFO_VAL_DATA) || (ret.tag == SYSINFO_VAL_FUNCTION_DATA)) {
+		/* Check destination buffer size */
 		if (ret.data.size == buffer_size)
 			rc = copy_to_uspace(buffer_ptr, ret.data.data,
@@ -600,4 +825,5 @@
 		rc = EINVAL;
 	
+	/* N.B.: The generated binary data should be freed */
 	if ((ret.tag == SYSINFO_VAL_FUNCTION_DATA) && (ret.data.data != NULL))
 		free(ret.data.data);
