Index: uspace/drv/isa/isa.c
===================================================================
--- uspace/drv/isa/isa.c	(revision bab63886b1d1a9c8c49900dc50c39ee2b0c64763)
+++ uspace/drv/isa/isa.c	(revision 97a62fec5ae8981a95bc5036a2fda4084d6bea01)
@@ -106,5 +106,5 @@
 };
 
-static isa_fun_t *isa_fun_create()
+static isa_fun_t *isa_fun_create(device_t *dev, const char *name)
 {
 	isa_fun_t *fun = calloc(1, sizeof(isa_fun_t));
@@ -112,5 +112,5 @@
 		return NULL;
 
-	function_t *fnode = create_function();
+	function_t *fnode = ddf_fun_create(dev, fun_inner, name);
 	if (fnode == NULL) {
 		free(fun);
@@ -417,13 +417,9 @@
 		return NULL;
 
-	isa_fun_t *fun = isa_fun_create();
+	isa_fun_t *fun = isa_fun_create(dev, fun_name);
 	if (fun == NULL) {
 		free(fun_name);
 		return NULL;
 	}
-
-	function_t *fnode = fun->fnode;
-	fnode->name = fun_name;
-	fnode->ftype = fun_inner;
 
 	/* Allocate buffer for the list of hardware resources of the device. */
@@ -447,9 +443,10 @@
 
 	/* Set device operations to the device. */
-	fnode->ops = &isa_fun_ops;
-
-	printf(NAME ": register_function(fun, dev); function is %s.\n",
-	    fnode->name);
-	register_function(fnode, dev);
+	fun->fnode->ops = &isa_fun_ops;
+
+	printf(NAME ": Binding function %s.\n", fun->fnode->name);
+
+	/* XXX Handle error */
+	(void) ddf_fun_bind(fun->fnode);
 
 	return fun_conf;
@@ -482,8 +479,14 @@
 	printf(NAME ": adding a 'ctl' function\n");
 
-	function_t *ctl = create_function();
-	ctl->ftype = fun_exposed;
-	ctl->name = "ctl";
-	register_function(ctl, dev);
+	function_t *ctl = ddf_fun_create(dev, fun_exposed, "ctl");
+	if (ctl == NULL) {
+		printf(NAME ": Error creating control function.\n");
+		return EXDEV;
+	}
+
+	if (ddf_fun_bind(ctl) != EOK) {
+		printf(NAME ": Error binding control function.\n");
+		return EXDEV;
+	}
 
 	/* Add functions as specified in the configuration file. */
Index: uspace/drv/ns8250/ns8250.c
===================================================================
--- uspace/drv/ns8250/ns8250.c	(revision bab63886b1d1a9c8c49900dc50c39ee2b0c64763)
+++ uspace/drv/ns8250/ns8250.c	(revision 97a62fec5ae8981a95bc5036a2fda4084d6bea01)
@@ -761,11 +761,18 @@
 	}
 	
-	fun = create_function();
-	fun->ftype = fun_exposed;
-	fun->name = "a";
+	fun = ddf_fun_create(dev, fun_exposed, "a");
+	if (fun == NULL) {
+		printf(NAME ": error creating function.\n");
+		goto fail;
+	}
 	
 	/* Set device operations. */
 	fun->ops = &ns8250_dev_ops;
-	register_function(fun, dev);
+	rc = ddf_fun_bind(fun);
+	if (rc != EOK) {
+		printf(NAME ": error binding function.\n");
+		goto fail;
+	}
+
 	ns->fun = fun;
 	
@@ -777,4 +784,6 @@
 	return EOK;
 fail:
+	if (fun != NULL)
+		ddf_fun_destroy(fun);
 	if (need_cleanup)
 		ns8250_dev_cleanup(ns);
Index: uspace/drv/pciintel/pci.c
===================================================================
--- uspace/drv/pciintel/pci.c	(revision bab63886b1d1a9c8c49900dc50c39ee2b0c64763)
+++ uspace/drv/pciintel/pci.c	(revision 97a62fec5ae8981a95bc5036a2fda4084d6bea01)
@@ -69,5 +69,5 @@
 
 /** Obtain PCI bus soft-state from function soft-state */
-#define PCI_BUS_FROM_FUN(fun) (PCI_BUS(fun->fnode->dev))
+#define PCI_BUS_FROM_FUN(fun) ((fun)->busptr)
 
 static hw_resource_list_t *pciintel_get_resources(function_t *fnode)
@@ -361,7 +361,6 @@
 void pci_bus_scan(pci_bus_t *bus, int bus_num) 
 {
-	function_t *fnode = create_function();
-	pci_fun_t *fun = pci_fun_new();
-	fnode->driver_data = fun;
+	function_t *fnode;
+	pci_fun_t *fun;
 	
 	int child_bus = 0;
@@ -370,8 +369,5 @@
 	uint8_t header_type;
 	
-	/* We need this early, before registering. */
-	fun->fnode = fnode;
-	fnode->dev = bus->dnode;
-	fnode->driver_data = fun;
+	fun = pci_fun_new(bus);
 	
 	for (dnum = 0; dnum < 32; dnum++) {
@@ -402,5 +398,18 @@
 			header_type = header_type & 0x7F;
 			
-			pci_fun_create_name(fun);
+			char *fun_name = pci_fun_create_name(fun);
+			if (fun_name == NULL) {
+				printf(NAME ": out of memory.\n");
+				return;
+			}
+			
+			fnode = ddf_fun_create(bus->dnode, fun_inner, fun_name);
+			if (fnode == NULL) {
+				printf(NAME ": error creating function.\n");
+				return;
+			}
+			
+			free(fun_name);
+			fun->fnode = fnode;
 			
 			pci_alloc_resource_list(fun);
@@ -408,6 +417,6 @@
 			pci_read_interrupt(fun);
 			
-			fnode->ftype = fun_inner;
 			fnode->ops = &pci_fun_ops;
+			fnode->driver_data = fun;
 			
 			printf(NAME ": adding new function %s.\n",
@@ -416,5 +425,5 @@
 			pci_fun_create_match_ids(fun);
 			
-			if (register_function(fnode, bus->dnode) != EOK) {
+			if (ddf_fun_bind(fnode) != EOK) {
 				pci_clean_resource_list(fun);
 				clean_match_ids(&fnode->match_ids);
@@ -434,18 +443,9 @@
 			}
 			
-			/* Alloc new aux. fun. structure. */
-			fnode = create_function();
-
-			/* We need this early, before registering. */
-		    	fnode->dev = bus->dnode;
-
-			fun = pci_fun_new();
-			fun->fnode = fnode;
-			fnode->driver_data = fun;
+			fun = pci_fun_new(bus);
 		}
 	}
 	
 	if (fun->vendor_id == 0xffff) {
-		delete_function(fnode);
 		/* Free the auxiliary function structure. */
 		pci_fun_delete(fun);
@@ -455,12 +455,17 @@
 static int pci_add_device(device_t *dnode)
 {
+	pci_bus_t *bus = NULL;
+	function_t *ctl = NULL;
+	bool got_res = false;
 	int rc;
 	
 	printf(NAME ": pci_add_device\n");
-	
-	pci_bus_t *bus = pci_bus_new();
+	dnode->parent_phone = -1;
+	
+	bus = pci_bus_new();
 	if (bus == NULL) {
 		printf(NAME ": pci_add_device allocation failed.\n");
-		return ENOMEM;
+		rc = ENOMEM;
+		goto fail;
 	}
 	bus->dnode = dnode;
@@ -472,6 +477,6 @@
 		printf(NAME ": pci_add_device failed to connect to the "
 		    "parent's driver.\n");
-		pci_bus_delete(bus);
-		return dnode->parent_phone;
+		rc = dnode->parent_phone;
+		goto fail;
 	}
 	
@@ -482,8 +487,7 @@
 		printf(NAME ": pci_add_device failed to get hw resources for "
 		    "the device.\n");
-		pci_bus_delete(bus);
-		async_hangup(dnode->parent_phone);
-		return rc;
-	}
+		goto fail;
+	}
+	got_res = true;
 	
 	printf(NAME ": conf_addr = %" PRIx64 ".\n",
@@ -500,8 +504,6 @@
 	    &bus->conf_addr_port)) {
 		printf(NAME ": failed to enable configuration ports.\n");
-		pci_bus_delete(bus);
-		async_hangup(dnode->parent_phone);
-		hw_res_clean_resource_list(&hw_resources);
-		return EADDRNOTAVAIL;
+		rc = EADDRNOTAVAIL;
+		goto fail;
 	}
 	bus->conf_data_port = (char *) bus->conf_addr_port + 4;
@@ -510,8 +512,16 @@
 	printf(NAME ": adding a 'ctl' function\n");
 	
-	function_t *ctl = create_function();
-	ctl->ftype = fun_exposed;
-	ctl->name = "ctl";
-	register_function(ctl, dnode);
+	ctl = ddf_fun_create(bus->dnode, fun_exposed, "ctl");
+	if (ctl == NULL) {
+		printf(NAME ": error creating control function.\n");
+		rc = ENOMEM;
+		goto fail;
+	}
+	
+	rc = ddf_fun_bind(ctl);
+	if (rc != EOK) {
+		printf(NAME ": error binding control function.\n");
+		goto fail;
+	}
 	
 	/* Enumerate functions. */
@@ -522,4 +532,16 @@
 	
 	return EOK;
+	
+fail:
+	if (bus != NULL)
+		pci_bus_delete(bus);
+	if (dnode->parent_phone >= 0)
+		async_hangup(dnode->parent_phone);
+	if (got_res)
+		hw_res_clean_resource_list(&hw_resources);
+	if (ctl != NULL)
+		ddf_fun_destroy(ctl);
+
+	return rc;
 }
 
@@ -529,10 +551,14 @@
 }
 
-pci_fun_t *pci_fun_new(void)
-{
-	pci_fun_t *res;
-	
-	res = (pci_fun_t *) calloc(1, sizeof(pci_fun_t));
-	return res;
+pci_fun_t *pci_fun_new(pci_bus_t *bus)
+{
+	pci_fun_t *fun;
+	
+	fun = (pci_fun_t *) calloc(1, sizeof(pci_fun_t));
+	if (fun == NULL)
+		return NULL;
+
+	fun->busptr = bus;
+	return fun;
 }
 
@@ -551,5 +577,5 @@
 }
 
-void pci_fun_create_name(pci_fun_t *fun)
+char *pci_fun_create_name(pci_fun_t *fun)
 {
 	char *name = NULL;
@@ -557,5 +583,5 @@
 	asprintf(&name, "%02x:%02x.%01x", fun->bus, fun->dev,
 	    fun->fn);
-	fun->fnode->name = name;
+	return name;
 }
 
Index: uspace/drv/pciintel/pci.h
===================================================================
--- uspace/drv/pciintel/pci.h	(revision bab63886b1d1a9c8c49900dc50c39ee2b0c64763)
+++ uspace/drv/pciintel/pci.h	(revision 97a62fec5ae8981a95bc5036a2fda4084d6bea01)
@@ -45,5 +45,15 @@
 #define PCI_MAX_HW_RES 8
 
+typedef struct pciintel_bus {
+	/** DDF device node */
+	device_t *dnode;
+	uint32_t conf_io_addr;
+	void *conf_data_port;
+	void *conf_addr_port;
+	fibril_mutex_t conf_mutex;
+} pci_bus_t;
+
 typedef struct pci_fun_data {
+	pci_bus_t *busptr;
 	function_t *fnode;
 
@@ -55,13 +65,4 @@
 	hw_resource_list_t hw_resources;
 } pci_fun_t;
-
-typedef struct pciintel_bus {
-	/** DDF device node */
-	device_t *dnode;
-	uint32_t conf_io_addr;
-	void *conf_data_port;
-	void *conf_addr_port;
-	fibril_mutex_t conf_mutex;
-} pci_bus_t;
 
 extern void pci_fun_create_match_ids(pci_fun_t *);
@@ -79,8 +80,8 @@
 extern void pci_add_interrupt(pci_fun_t *, int);
 
-extern pci_fun_t *pci_fun_new(void);
+extern pci_fun_t *pci_fun_new(pci_bus_t *);
 extern void pci_fun_init(pci_fun_t *, int, int, int);
 extern void pci_fun_delete(pci_fun_t *);
-extern void pci_fun_create_name(pci_fun_t *);
+extern char *pci_fun_create_name(pci_fun_t *);
 
 extern void pci_bus_scan(pci_bus_t *, int);
Index: uspace/drv/rootpc/rootpc.c
===================================================================
--- uspace/drv/rootpc/rootpc.c	(revision bab63886b1d1a9c8c49900dc50c39ee2b0c64763)
+++ uspace/drv/rootpc/rootpc.c	(revision 97a62fec5ae8981a95bc5036a2fda4084d6bea01)
@@ -125,11 +125,9 @@
 	
 	/* Create new device. */
-	fnode = create_function();
+	fnode = ddf_fun_create(dev, fun_inner, name);
 	if (fnode == NULL)
 		goto failure;
 	
-	fnode->name = name;
 	fnode->driver_data = fun;
-	fnode->ftype = fun_inner;
 	
 	/* Initialize match id list */
@@ -146,6 +144,8 @@
 	
 	/* Register function. */
-	if (register_function(fnode, dev) != EOK)
+	if (ddf_fun_bind(fnode) != EOK) {
+		printf(NAME ": error binding function %s.\n", name);
 		goto failure;
+	}
 	printf(NAME ": registered function handle = %u\n", fnode->handle);
 	
@@ -156,8 +156,6 @@
 		match_id->id = NULL;
 	
-	if (fnode != NULL) {
-		fnode->name = NULL;
-		delete_function(fnode);
-	}
+	if (fnode != NULL)
+		ddf_fun_destroy(fnode);
 	
 	printf(NAME ": failed to add function '%s'.\n", name);
Index: uspace/drv/test1/test1.c
===================================================================
--- uspace/drv/test1/test1.c	(revision bab63886b1d1a9c8c49900dc50c39ee2b0c64763)
+++ uspace/drv/test1/test1.c	(revision 97a62fec5ae8981a95bc5036a2fda4084d6bea01)
@@ -92,13 +92,20 @@
 {
 	function_t *fun_a;
+	int rc;
 
 	printf(NAME ": add_device(name=\"%s\", handle=%d)\n",
 	    dev->name, (int) dev->handle);
 
-	fun_a = create_function();
-	fun_a->ftype = fun_exposed;
-	fun_a->name = "a";
+	fun_a = ddf_fun_create(dev, fun_exposed, "a");
+	if (fun_a == NULL) {
+		printf(NAME ": error creating function 'a'.\n");
+		return ENOMEM;
+	}
 
-	register_function(fun_a, dev);
+	rc = ddf_fun_bind(fun_a);
+	if (rc != EOK) {
+		printf(NAME ": error binding function 'a'.\n");
+		return rc;
+	}
 
 	add_function_to_class(fun_a, "virtual");
Index: uspace/drv/test2/test2.c
===================================================================
--- uspace/drv/test2/test2.c	(revision bab63886b1d1a9c8c49900dc50c39ee2b0c64763)
+++ uspace/drv/test2/test2.c	(revision 97a62fec5ae8981a95bc5036a2fda4084d6bea01)
@@ -82,5 +82,6 @@
 {
 	device_t *dev = (device_t *) arg;
-	function_t *fun;
+	function_t *fun_a;
+	int rc;
 
 	async_usleep(1000);
@@ -91,11 +92,17 @@
 	    "test1", "virtual&test1", 10);
 
-	fun = create_function();
-	fun->ftype = fun_exposed;
-	fun->name = "a";
+	fun_a = ddf_fun_create(dev, fun_exposed, "a");
+	if (fun_a == NULL) {
+		printf(NAME ": error creating function 'a'.\n");
+		return ENOMEM;
+	}
 
-	register_function(fun, dev);
+	rc = ddf_fun_bind(fun_a);
+	if (rc != EOK) {
+		printf(NAME ": error binding function 'a'.\n");
+		return rc;
+	}
 
-	add_function_to_class(fun, "virtual");
+	add_function_to_class(fun_a, "virtual");
 
 	return EOK;
