Index: uspace/srv/devman/Makefile
===================================================================
--- uspace/srv/devman/Makefile	(revision d1bafbfd7597f429f460d4f3da31a778e2775324)
+++ uspace/srv/devman/Makefile	(revision 38e52c92f3bfac1d2b27e99d723de774dd20d0e3)
@@ -36,4 +36,5 @@
 	devman.c \
 	driver.c \
+	fun.c \
 	main.c \
 	match.c \
Index: uspace/srv/devman/devman.c
===================================================================
--- uspace/srv/devman/devman.c	(revision d1bafbfd7597f429f460d4f3da31a778e2775324)
+++ uspace/srv/devman/devman.c	(revision 38e52c92f3bfac1d2b27e99d723de774dd20d0e3)
@@ -63,6 +63,5 @@
 #include "devman.h"
 #include "driver.h"
-
-static fun_node_t *find_node_child(dev_tree_t *, fun_node_t *, const char *);
+#include "fun.h"
 
 /* hash table operations */
@@ -455,151 +454,4 @@
 }
 
-/* Function nodes */
-
-/** Create a new function node.
- *
- * @return		A function node structure.
- */
-fun_node_t *create_fun_node(void)
-{
-	fun_node_t *fun;
-
-	fun = calloc(1, sizeof(fun_node_t));
-	if (fun == NULL)
-		return NULL;
-	
-	fun->state = FUN_INIT;
-	atomic_set(&fun->refcnt, 0);
-	fibril_mutex_initialize(&fun->busy_lock);
-	link_initialize(&fun->dev_functions);
-	list_initialize(&fun->match_ids.ids);
-	
-	return fun;
-}
-
-/** Delete a function node.
- *
- * @param fun		The device node structure.
- */
-void delete_fun_node(fun_node_t *fun)
-{
-	assert(fun->dev == NULL);
-	assert(fun->child == NULL);
-	
-	clean_match_ids(&fun->match_ids);
-	free(fun->name);
-	free(fun->pathname);
-	free(fun);
-}
-
-/** Increase function node reference count.
- *
- * @param fun	Function node
- */
-void fun_add_ref(fun_node_t *fun)
-{
-	atomic_inc(&fun->refcnt);
-}
-
-/** Decrease function node reference count.
- *
- * When the count drops to zero the function node is freed.
- *
- * @param fun	Function node
- */
-void fun_del_ref(fun_node_t *fun)
-{
-	if (atomic_predec(&fun->refcnt) == 0)
-		delete_fun_node(fun);
-}
-
-/** Make function busy for reconfiguration operations. */
-void fun_busy_lock(fun_node_t *fun)
-{
-	fibril_mutex_lock(&fun->busy_lock);
-}
-
-/** Mark end of reconfiguration operation. */
-void fun_busy_unlock(fun_node_t *fun)
-{
-	fibril_mutex_unlock(&fun->busy_lock);
-}
-
-/** Find the function node with the specified handle.
- *
- * @param tree		The device tree where we look for the device node.
- * @param handle	The handle of the function.
- * @return		The function node.
- */
-fun_node_t *find_fun_node_no_lock(dev_tree_t *tree, devman_handle_t handle)
-{
-	fun_node_t *fun;
-	
-	assert(fibril_rwlock_is_locked(&tree->rwlock));
-	
-	ht_link_t *link = hash_table_find(&tree->devman_functions, &handle);
-	if (link == NULL)
-		return NULL;
-	
-	fun = hash_table_get_inst(link, fun_node_t, devman_fun);
-	
-	return fun;
-}
-
-/** Find the function node with the specified handle.
- *
- * @param tree		The device tree where we look for the device node.
- * @param handle	The handle of the function.
- * @return		The function node.
- */
-fun_node_t *find_fun_node(dev_tree_t *tree, devman_handle_t handle)
-{
-	fun_node_t *fun = NULL;
-	
-	fibril_rwlock_read_lock(&tree->rwlock);
-	
-	fun = find_fun_node_no_lock(tree, handle);
-	if (fun != NULL)
-		fun_add_ref(fun);
-	
-	fibril_rwlock_read_unlock(&tree->rwlock);
-	
-	return fun;
-}
-
-/** Create and set device's full path in device tree.
- *
- * @param tree		Device tree
- * @param node		The device's device node.
- * @param parent	The parent device node.
- * @return		True on success, false otherwise (insufficient
- *			resources etc.).
- */
-static bool set_fun_path(dev_tree_t *tree, fun_node_t *fun, fun_node_t *parent)
-{
-	assert(fibril_rwlock_is_write_locked(&tree->rwlock));
-	assert(fun->name != NULL);
-	
-	size_t pathsize = (str_size(fun->name) + 1);
-	if (parent != NULL)
-		pathsize += str_size(parent->pathname) + 1;
-	
-	fun->pathname = (char *) malloc(pathsize);
-	if (fun->pathname == NULL) {
-		log_msg(LOG_DEFAULT, LVL_ERROR, "Failed to allocate device path.");
-		return false;
-	}
-	
-	if (parent != NULL) {
-		str_cpy(fun->pathname, pathsize, parent->pathname);
-		str_append(fun->pathname, pathsize, "/");
-		str_append(fun->pathname, pathsize, fun->name);
-	} else {
-		str_cpy(fun->pathname, pathsize, fun->name);
-	}
-	
-	return true;
-}
-
 /** Insert new device into device tree.
  *
@@ -712,102 +564,4 @@
 }
 
-/** Find function node with a specified path in the device tree.
- * 
- * @param path		The path of the function node in the device tree.
- * @param tree		The device tree.
- * @return		The function node if it is present in the tree, NULL
- *			otherwise.
- */
-fun_node_t *find_fun_node_by_path(dev_tree_t *tree, char *path)
-{
-	assert(path != NULL);
-
-	bool is_absolute = path[0] == '/';
-	if (!is_absolute) {
-		return NULL;
-	}
-
-	fibril_rwlock_read_lock(&tree->rwlock);
-	
-	fun_node_t *fun = tree->root_node;
-	fun_add_ref(fun);
-	/*
-	 * Relative path to the function from its parent (but with '/' at the
-	 * beginning)
-	 */
-	char *rel_path = path;
-	char *next_path_elem = NULL;
-	bool cont = (rel_path[1] != '\0');
-	
-	while (cont && fun != NULL) {
-		next_path_elem  = get_path_elem_end(rel_path + 1);
-		if (next_path_elem[0] == '/') {
-			cont = true;
-			next_path_elem[0] = 0;
-		} else {
-			cont = false;
-		}
-		
-		fun_node_t *cfun = find_node_child(tree, fun, rel_path + 1);
-		fun_del_ref(fun);
-		fun = cfun;
-		
-		if (cont) {
-			/* Restore the original path. */
-			next_path_elem[0] = '/';
-		}
-		rel_path = next_path_elem;
-	}
-	
-	fibril_rwlock_read_unlock(&tree->rwlock);
-	
-	return fun;
-}
-
-/** Find function with a specified name belonging to given device.
- *
- * Device tree rwlock should be held at least for reading.
- *
- * @param tree Device tree
- * @param dev Device the function belongs to.
- * @param name Function name (not path).
- * @return Function node.
- * @retval NULL No function with given name.
- */
-fun_node_t *find_fun_node_in_device(dev_tree_t *tree, dev_node_t *dev,
-    const char *name)
-{
-	assert(name != NULL);
-	assert(fibril_rwlock_is_locked(&tree->rwlock));
-
-	fun_node_t *fun;
-
-	list_foreach(dev->functions, link) {
-		fun = list_get_instance(link, fun_node_t, dev_functions);
-
-		if (str_cmp(name, fun->name) == 0) {
-			fun_add_ref(fun);
-			return fun;
-		}
-	}
-
-	return NULL;
-}
-
-/** Find child function node with a specified name.
- *
- * Device tree rwlock should be held at least for reading.
- *
- * @param tree		Device tree
- * @param parent	The parent function node.
- * @param name		The name of the child function.
- * @return		The child function node.
- */
-static fun_node_t *find_node_child(dev_tree_t *tree, fun_node_t *pfun,
-    const char *name)
-{
-	return find_fun_node_in_device(tree, pfun->child, name);
-}
-
 /* loc devices */
 
Index: uspace/srv/devman/devman.h
===================================================================
--- uspace/srv/devman/devman.h	(revision d1bafbfd7597f429f460d4f3da31a778e2775324)
+++ uspace/srv/devman/devman.h	(revision 38e52c92f3bfac1d2b27e99d723de774dd20d0e3)
@@ -244,19 +244,4 @@
 extern char *read_id(const char **);
 
-/* Function nodes */
-
-extern fun_node_t *create_fun_node(void);
-extern void delete_fun_node(fun_node_t *);
-extern void fun_add_ref(fun_node_t *);
-extern void fun_del_ref(fun_node_t *);
-extern void fun_busy_lock(fun_node_t *);
-extern void fun_busy_unlock(fun_node_t *);
-extern fun_node_t *find_fun_node_no_lock(dev_tree_t *tree,
-    devman_handle_t handle);
-extern fun_node_t *find_fun_node(dev_tree_t *tree, devman_handle_t handle);
-extern fun_node_t *find_fun_node_by_path(dev_tree_t *, char *);
-extern fun_node_t *find_fun_node_in_device(dev_tree_t *tree, dev_node_t *,
-    const char *);
-
 /* Device tree */
 
Index: uspace/srv/devman/fun.c
===================================================================
--- uspace/srv/devman/fun.c	(revision 38e52c92f3bfac1d2b27e99d723de774dd20d0e3)
+++ uspace/srv/devman/fun.c	(revision 38e52c92f3bfac1d2b27e99d723de774dd20d0e3)
@@ -0,0 +1,294 @@
+/*
+ * Copyright (c) 2010 Lenka Trochtova
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup devman
+ * @{
+ */
+
+#include <errno.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <io/log.h>
+#include <ipc/driver.h>
+#include <ipc/devman.h>
+#include <loc.h>
+#include <str_error.h>
+#include <stdio.h>
+
+#include "devman.h"
+#include "fun.h"
+
+static fun_node_t *find_node_child(dev_tree_t *, fun_node_t *, const char *);
+
+/* Function nodes */
+
+/** Create a new function node.
+ *
+ * @return		A function node structure.
+ */
+fun_node_t *create_fun_node(void)
+{
+	fun_node_t *fun;
+
+	fun = calloc(1, sizeof(fun_node_t));
+	if (fun == NULL)
+		return NULL;
+	
+	fun->state = FUN_INIT;
+	atomic_set(&fun->refcnt, 0);
+	fibril_mutex_initialize(&fun->busy_lock);
+	link_initialize(&fun->dev_functions);
+	list_initialize(&fun->match_ids.ids);
+	
+	return fun;
+}
+
+/** Delete a function node.
+ *
+ * @param fun		The device node structure.
+ */
+void delete_fun_node(fun_node_t *fun)
+{
+	assert(fun->dev == NULL);
+	assert(fun->child == NULL);
+	
+	clean_match_ids(&fun->match_ids);
+	free(fun->name);
+	free(fun->pathname);
+	free(fun);
+}
+
+/** Increase function node reference count.
+ *
+ * @param fun	Function node
+ */
+void fun_add_ref(fun_node_t *fun)
+{
+	atomic_inc(&fun->refcnt);
+}
+
+/** Decrease function node reference count.
+ *
+ * When the count drops to zero the function node is freed.
+ *
+ * @param fun	Function node
+ */
+void fun_del_ref(fun_node_t *fun)
+{
+	if (atomic_predec(&fun->refcnt) == 0)
+		delete_fun_node(fun);
+}
+
+/** Make function busy for reconfiguration operations. */
+void fun_busy_lock(fun_node_t *fun)
+{
+	fibril_mutex_lock(&fun->busy_lock);
+}
+
+/** Mark end of reconfiguration operation. */
+void fun_busy_unlock(fun_node_t *fun)
+{
+	fibril_mutex_unlock(&fun->busy_lock);
+}
+
+/** Find the function node with the specified handle.
+ *
+ * @param tree		The device tree where we look for the device node.
+ * @param handle	The handle of the function.
+ * @return		The function node.
+ */
+fun_node_t *find_fun_node_no_lock(dev_tree_t *tree, devman_handle_t handle)
+{
+	fun_node_t *fun;
+	
+	assert(fibril_rwlock_is_locked(&tree->rwlock));
+	
+	ht_link_t *link = hash_table_find(&tree->devman_functions, &handle);
+	if (link == NULL)
+		return NULL;
+	
+	fun = hash_table_get_inst(link, fun_node_t, devman_fun);
+	
+	return fun;
+}
+
+/** Find the function node with the specified handle.
+ *
+ * @param tree		The device tree where we look for the device node.
+ * @param handle	The handle of the function.
+ * @return		The function node.
+ */
+fun_node_t *find_fun_node(dev_tree_t *tree, devman_handle_t handle)
+{
+	fun_node_t *fun = NULL;
+	
+	fibril_rwlock_read_lock(&tree->rwlock);
+	
+	fun = find_fun_node_no_lock(tree, handle);
+	if (fun != NULL)
+		fun_add_ref(fun);
+	
+	fibril_rwlock_read_unlock(&tree->rwlock);
+	
+	return fun;
+}
+
+/** Create and set device's full path in device tree.
+ *
+ * @param tree		Device tree
+ * @param node		The device's device node.
+ * @param parent	The parent device node.
+ * @return		True on success, false otherwise (insufficient
+ *			resources etc.).
+ */
+bool set_fun_path(dev_tree_t *tree, fun_node_t *fun, fun_node_t *parent)
+{
+	assert(fibril_rwlock_is_write_locked(&tree->rwlock));
+	assert(fun->name != NULL);
+	
+	size_t pathsize = (str_size(fun->name) + 1);
+	if (parent != NULL)
+		pathsize += str_size(parent->pathname) + 1;
+	
+	fun->pathname = (char *) malloc(pathsize);
+	if (fun->pathname == NULL) {
+		log_msg(LOG_DEFAULT, LVL_ERROR, "Failed to allocate device path.");
+		return false;
+	}
+	
+	if (parent != NULL) {
+		str_cpy(fun->pathname, pathsize, parent->pathname);
+		str_append(fun->pathname, pathsize, "/");
+		str_append(fun->pathname, pathsize, fun->name);
+	} else {
+		str_cpy(fun->pathname, pathsize, fun->name);
+	}
+	
+	return true;
+}
+
+/** Find function node with a specified path in the device tree.
+ * 
+ * @param path		The path of the function node in the device tree.
+ * @param tree		The device tree.
+ * @return		The function node if it is present in the tree, NULL
+ *			otherwise.
+ */
+fun_node_t *find_fun_node_by_path(dev_tree_t *tree, char *path)
+{
+	assert(path != NULL);
+
+	bool is_absolute = path[0] == '/';
+	if (!is_absolute) {
+		return NULL;
+	}
+
+	fibril_rwlock_read_lock(&tree->rwlock);
+	
+	fun_node_t *fun = tree->root_node;
+	fun_add_ref(fun);
+	/*
+	 * Relative path to the function from its parent (but with '/' at the
+	 * beginning)
+	 */
+	char *rel_path = path;
+	char *next_path_elem = NULL;
+	bool cont = (rel_path[1] != '\0');
+	
+	while (cont && fun != NULL) {
+		next_path_elem  = get_path_elem_end(rel_path + 1);
+		if (next_path_elem[0] == '/') {
+			cont = true;
+			next_path_elem[0] = 0;
+		} else {
+			cont = false;
+		}
+		
+		fun_node_t *cfun = find_node_child(tree, fun, rel_path + 1);
+		fun_del_ref(fun);
+		fun = cfun;
+		
+		if (cont) {
+			/* Restore the original path. */
+			next_path_elem[0] = '/';
+		}
+		rel_path = next_path_elem;
+	}
+	
+	fibril_rwlock_read_unlock(&tree->rwlock);
+	
+	return fun;
+}
+
+/** Find function with a specified name belonging to given device.
+ *
+ * Device tree rwlock should be held at least for reading.
+ *
+ * @param tree Device tree
+ * @param dev Device the function belongs to.
+ * @param name Function name (not path).
+ * @return Function node.
+ * @retval NULL No function with given name.
+ */
+fun_node_t *find_fun_node_in_device(dev_tree_t *tree, dev_node_t *dev,
+    const char *name)
+{
+	assert(name != NULL);
+	assert(fibril_rwlock_is_locked(&tree->rwlock));
+
+	fun_node_t *fun;
+
+	list_foreach(dev->functions, link) {
+		fun = list_get_instance(link, fun_node_t, dev_functions);
+
+		if (str_cmp(name, fun->name) == 0) {
+			fun_add_ref(fun);
+			return fun;
+		}
+	}
+
+	return NULL;
+}
+
+/** Find child function node with a specified name.
+ *
+ * Device tree rwlock should be held at least for reading.
+ *
+ * @param tree		Device tree
+ * @param parent	The parent function node.
+ * @param name		The name of the child function.
+ * @return		The child function node.
+ */
+static fun_node_t *find_node_child(dev_tree_t *tree, fun_node_t *pfun,
+    const char *name)
+{
+	return find_fun_node_in_device(tree, pfun->child, name);
+}
+
+/** @}
+ */
Index: uspace/srv/devman/fun.h
===================================================================
--- uspace/srv/devman/fun.h	(revision 38e52c92f3bfac1d2b27e99d723de774dd20d0e3)
+++ uspace/srv/devman/fun.h	(revision 38e52c92f3bfac1d2b27e99d723de774dd20d0e3)
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2010 Lenka Trochtova
+ * Copyright (c) 2013 Jiri Svoboda
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup devman
+ * @{
+ */
+
+#ifndef FUN_H_
+#define FUN_H_
+
+#include "devman.h"
+
+extern fun_node_t *create_fun_node(void);
+extern void delete_fun_node(fun_node_t *);
+extern void fun_add_ref(fun_node_t *);
+extern void fun_del_ref(fun_node_t *);
+extern void fun_busy_lock(fun_node_t *);
+extern void fun_busy_unlock(fun_node_t *);
+extern fun_node_t *find_fun_node_no_lock(dev_tree_t *, devman_handle_t);
+extern fun_node_t *find_fun_node(dev_tree_t *, devman_handle_t);
+extern fun_node_t *find_fun_node_by_path(dev_tree_t *, char *);
+extern fun_node_t *find_fun_node_in_device(dev_tree_t *tree, dev_node_t *,
+    const char *);
+extern bool set_fun_path(dev_tree_t *, fun_node_t *, fun_node_t *);
+
+#endif
+
+/** @}
+ */
Index: uspace/srv/devman/main.c
===================================================================
--- uspace/srv/devman/main.c	(revision d1bafbfd7597f429f460d4f3da31a778e2775324)
+++ uspace/srv/devman/main.c	(revision 38e52c92f3bfac1d2b27e99d723de774dd20d0e3)
@@ -61,4 +61,5 @@
 #include "devman.h"
 #include "driver.h"
+#include "fun.h"
 
 #define DRIVER_DEFAULT_STORE  "/drv"
