Index: uspace/lib/drv/generic/driver.c
===================================================================
--- uspace/lib/drv/generic/driver.c	(revision 7df0477e57b823b922910c8187e059e45db8ecc2)
+++ uspace/lib/drv/generic/driver.c	(revision 97a62fec5ae8981a95bc5036a2fda4084d6bea01)
@@ -477,14 +477,12 @@
  * @return		The device structure.
  */
-function_t *create_function(void)
+static function_t *create_function(void)
 {
 	function_t *fun;
 
-	fun = malloc(sizeof(function_t));
+	fun = calloc(1, sizeof(function_t));
 	if (fun == NULL)
 		return NULL;
 
-	memset(fun, 0, sizeof(device_t));
-
 	init_match_ids(&fun->match_ids);
 	link_initialize(&fun->link);
@@ -506,5 +504,5 @@
  * @param dev		The device structure.
  */
-void delete_function(function_t *fun)
+static void delete_function(function_t *fun)
 {
 	clean_match_ids(&fun->match_ids);
@@ -514,4 +512,61 @@
 }
 
+/** Create a DDF function node.
+ *
+ * Create a DDF function (in memory). Both child devices and external clients
+ * communicate with a device via its functions.
+ *
+ * The created function node is fully formed, but only exists in the memory
+ * of the client task. In order to be visible to the system, the function
+ * must be bound using ddf_fun_bind().
+ *
+ * This function should only fail if there is not enough free memory.
+ * Specifically, this function succeeds even if @a dev already has
+ * a (bound) function with the same name.
+ *
+ * Type: A function of type fun_inner indicates that DDF should attempt
+ * to attach child devices to the function. fun_exposed means that
+ * the function should be exported to external clients (applications).
+ *
+ * @param dev		Device to which we are adding function
+ * @param ftype		Type of function (fun_inner or fun_exposed)
+ * @param name		Name of function
+ *
+ * @return		New function or @c NULL if memory is not available
+ */
+function_t *ddf_fun_create(device_t *dev, fun_type_t ftype, const char *name)
+{
+	function_t *fun;
+
+	fun = create_function();
+	if (fun == NULL)
+		return NULL;
+
+	fun->bound = false;
+	fun->dev = dev;
+	fun->ftype = ftype;
+
+	fun->name = str_dup(name);
+	if (fun->name == NULL) {
+		delete_function(fun);
+		return NULL;
+	}
+
+	return fun;
+}
+
+/** Destroy DDF function node.
+ *
+ * Destroy a function previously created with ddf_fun_create(). The function
+ * must not be bound.
+ *
+ * @param fun		Function to destroy
+ */
+void ddf_fun_destroy(function_t *fun)
+{
+	assert(fun->bound == false);
+	delete_function(fun);
+}
+
 void *function_get_ops(function_t *fun, dev_inferface_idx_t idx)
 {
@@ -522,15 +577,25 @@
 }
 
-int register_function(function_t *fun, device_t *dev)
+/** Bind a function node.
+ *
+ * Bind the specified function to the system. This effectively makes
+ * the function visible to the system (uploads it to the server).
+ *
+ * This function can fail for several reasons. Specifically,
+ * it will fail if the device already has a bound function of
+ * the same name.
+ *
+ * @param fun		Function to bind
+ * @return		EOK on success or negative error code
+ */
+int ddf_fun_bind(function_t *fun)
 {
 	assert(fun->name != NULL);
 	
 	int res;
-	
-	fun->dev = dev;
 	
 	add_to_functions_list(fun);
 	res = devman_add_function(fun->name, fun->ftype, &fun->match_ids,
-	    dev->handle, &fun->handle);
+	    fun->dev->handle, &fun->handle);
 	if (res != EOK) {
 		remove_from_functions_list(fun);
@@ -538,4 +603,5 @@
 	}
 	
+	fun->bound = true;
 	return res;
 }
@@ -556,13 +622,9 @@
 	int rc;
 	
-	fun = create_function();
+	fun = ddf_fun_create(dev, fun_inner, fun_name);
 	if (fun == NULL) {
 		rc = ENOMEM;
 		goto failure;
 	}
-	
-	fun->dev = dev;
-	fun->name = fun_name;
-	fun->ftype = fun_inner;
 	
 	m_id = create_match_id();
@@ -576,5 +638,5 @@
 	add_match_id(&fun->match_ids, m_id);
 	
-	rc = register_function(fun, dev);
+	rc = ddf_fun_bind(fun);
 	if (rc != EOK)
 		goto failure;
Index: uspace/lib/drv/include/driver.h
===================================================================
--- uspace/lib/drv/include/driver.h	(revision 7df0477e57b823b922910c8187e059e45db8ecc2)
+++ uspace/lib/drv/include/driver.h	(revision 97a62fec5ae8981a95bc5036a2fda4084d6bea01)
@@ -115,4 +115,6 @@
 /** Function structure */
 struct function {
+	/** True if bound to the device manager */
+	bool bound;
 	/** Function indentifier (asigned by device manager) */
 	devman_handle_t handle;
@@ -157,13 +159,10 @@
 int driver_main(driver_t *);
 
-/** Create new device structure.
- *
- * @return		The device structure.
- */
-extern function_t *create_function(void);
-extern void delete_function(function_t *);
+extern function_t *ddf_fun_create(device_t *, fun_type_t, const char *);
+extern void ddf_fun_destroy(function_t *);
+extern int ddf_fun_bind(function_t *);
+
 extern void *function_get_ops(function_t *, dev_inferface_idx_t);
 
-extern int register_function(function_t *, device_t *);
 extern int register_function_wrapper(device_t *, const char *, const char *,
     int);
