Index: uspace/lib/drv/generic/driver.c
===================================================================
--- uspace/lib/drv/generic/driver.c	(revision be2a38ad69d4e9a07b4e8871b3c9fcce28423470)
+++ uspace/lib/drv/generic/driver.c	(revision 56fd7cf53b8ee7af3e78e2237e566926562e0291)
@@ -36,4 +36,6 @@
 /** @file
  */
+
+#define _DDF_DATA_IMPLANT
 
 #include <assert.h>
@@ -58,4 +60,5 @@
 #include "ddf/driver.h"
 #include "ddf/interrupt.h"
+#include "private/driver.h"
 
 /** Driver structure */
@@ -523,4 +526,6 @@
 static void delete_device(ddf_dev_t *dev)
 {
+	if (dev->parent_sess)
+		async_hangup(dev->parent_sess);
 	if (dev->driver_data != NULL)
 		free(dev->driver_data);
@@ -597,4 +602,96 @@
 }
 
+/** Implant foreign driver-specific device data.
+ *
+ * XXX This is used to transition USB to new interface. Do not use
+ * in new code. Use of this function must be removed.
+ */
+void ddf_fun_data_implant(ddf_fun_t *fun, void *data)
+{
+	assert(fun->driver_data == NULL);
+	fun->driver_data = data;
+}
+
+/** Return driver-specific device data. */
+void *ddf_dev_data_get(ddf_dev_t *dev)
+{
+	return dev->driver_data;
+}
+
+/** Get device handle. */
+devman_handle_t ddf_dev_get_handle(ddf_dev_t *dev)
+{
+	return dev->handle;
+}
+
+/** Return device name.
+ *
+ * @param dev	Device
+ * @return	Device name. Valid as long as @a dev is valid.
+ */
+const char *ddf_dev_get_name(ddf_dev_t *dev)
+{
+	return dev->name;
+}
+
+/** Create session with the parent function.
+ *
+ * The session will be automatically closed when @a dev is destroyed.
+ *
+ * @param dev	Device
+ * @param mgmt	Exchange management style
+ * @return	New session or NULL if session could not be created
+ */
+async_sess_t *ddf_dev_parent_sess_create(ddf_dev_t *dev, exch_mgmt_t mgmt)
+{
+	assert(dev->parent_sess == NULL);
+	dev->parent_sess = devman_parent_device_connect(mgmt, dev->handle,
+	    IPC_FLAG_BLOCKING);
+
+	return dev->parent_sess;
+}
+
+/** Return existing session with the parent function.
+ *
+ * @param dev	Device
+ * @return	Existing session or NULL if there is no session
+ */
+async_sess_t *ddf_dev_parent_sess_get(ddf_dev_t *dev)
+{
+	return dev->parent_sess;
+}
+
+/** Set function name (if it was not specified when node was created.)
+ *
+ * @param dev	Device whose name has not been set yet
+ * @param name	Name, will be copied
+ * @return	EOK on success, ENOMEM if out of memory
+ */
+int ddf_fun_set_name(ddf_fun_t *dev, const char *name)
+{
+	assert(dev->name == NULL);
+
+	dev->name = str_dup(name);
+	if (dev->name == NULL)
+		return ENOENT;
+
+	return EOK;
+}
+
+/** Get device to which function belongs. */
+ddf_dev_t *ddf_fun_get_dev(ddf_fun_t *fun)
+{
+	return fun->dev;
+}
+
+/** Get function handle.
+ *
+ * XXX USB uses this, but its use should be eliminated.
+ */
+devman_handle_t ddf_fun_get_handle(ddf_fun_t *fun)
+{
+	return fun->handle;
+}
+
 /** Create a DDF function node.
  *
@@ -608,5 +705,7 @@
  * 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.
+ * a (bound) function with the same name. @a name can be NULL in which
+ * case the caller will set the name later using ddf_fun_set_name().
+ * He must do this before binding the function.
  *
  * Type: A function of type fun_inner indicates that DDF should attempt
@@ -616,5 +715,5 @@
  * @param dev		Device to which we are adding function
  * @param ftype		Type of function (fun_inner or fun_exposed)
- * @param name		Name of function
+ * @param name		Name of function or NULL
  *
  * @return		New function or @c NULL if memory is not available
@@ -633,8 +732,10 @@
 	fun->ftype = ftype;
 	
-	fun->name = str_dup(name);
-	if (fun->name == NULL) {
-		delete_function(fun);
-		return NULL;
+	if (name != NULL) {
+		fun->name = str_dup(name);
+		if (fun->name == NULL) {
+			delete_function(fun);
+			return NULL;
+		}
 	}
 	
@@ -654,4 +755,20 @@
 	fun->driver_data = data;
 	return data;
+}
+
+/** Return driver-specific function data. */
+void *ddf_fun_data_get(ddf_fun_t *fun)
+{
+	return fun->driver_data;
+}
+
+/** Return function name.
+ *
+ * @param fun	Function
+ * @return	Function name. Valid as long as @a fun is valid.
+ */
+const char *ddf_fun_get_name(ddf_fun_t *fun)
+{
+	return fun->name;
 }
 
@@ -805,4 +922,21 @@
 	add_match_id(&fun->match_ids, match_id);
 	return EOK;
+}
+
+/** Set function ops. */
+void ddf_fun_set_ops(ddf_fun_t *fun, ddf_dev_ops_t *dev_ops)
+{
+	assert(fun->conn_handler == NULL);
+	fun->ops = dev_ops;
+}
+
+/** Set user-defined connection handler.
+ *
+ * This allows handling connections the non-devman way.
+ */
+void ddf_fun_set_conn_handler(ddf_fun_t *fun, async_client_conn_t conn)
+{
+	assert(fun->ops == NULL);
+	fun->conn_handler = conn;
 }
 
Index: uspace/lib/drv/generic/interrupt.c
===================================================================
--- uspace/lib/drv/generic/interrupt.c	(revision be2a38ad69d4e9a07b4e8871b3c9fcce28423470)
+++ uspace/lib/drv/generic/interrupt.c	(revision 56fd7cf53b8ee7af3e78e2237e566926562e0291)
@@ -41,4 +41,5 @@
 
 #include "ddf/interrupt.h"
+#include "private/driver.h"
 
 static void driver_irq_handler(ipc_callid_t iid, ipc_call_t *icall);
Index: uspace/lib/drv/generic/private/driver.h
===================================================================
--- uspace/lib/drv/generic/private/driver.h	(revision 56fd7cf53b8ee7af3e78e2237e566926562e0291)
+++ uspace/lib/drv/generic/private/driver.h	(revision 56fd7cf53b8ee7af3e78e2237e566926562e0291)
@@ -0,0 +1,108 @@
+/*
+ * Copyright (c) 2010 Lenka Trochtova
+ * Copyright (c) 2012 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 libdrv
+ * @{
+ */
+/** @file
+ */
+
+#ifndef DDF_PRIVATE_DRIVER_H_
+#define DDF_PRIVATE_DRIVER_H_
+
+#include <async.h>
+#include <ipc/devman.h>
+#include <ipc/dev_iface.h>
+#include "dev_iface.h"
+
+/** Device structure */
+struct ddf_dev {
+	/**
+	 * Globally unique device identifier (assigned to the device by the
+	 * device manager).
+	 */
+	devman_handle_t handle;
+	
+	/** Reference count */
+	atomic_t refcnt;
+	
+	/** Session with the parent device driver */
+	async_sess_t *parent_sess;
+	
+	/** Device name */
+	const char *name;
+	
+	/** Driver-specific data associated with this device */
+	void *driver_data;
+	
+	/** Link in the list of devices handled by the driver */
+	link_t link;
+};
+
+/** Function structure */
+struct ddf_fun {
+	/** True if bound to the device manager */
+	bool bound;
+	
+	/** Function indentifier (asigned by device manager) */
+	devman_handle_t handle;
+	
+	/** Reference count */
+	atomic_t refcnt;
+	
+	/** Device which this function belogs to */
+	struct ddf_dev *dev;
+	
+	/** Function type */
+	fun_type_t ftype;
+	
+	/** Function name */
+	const char *name;
+	
+	/** List of device ids for driver matching */
+	match_id_list_t match_ids;
+	
+	/** Driver-specific data associated with this function */
+	void *driver_data;
+	
+	/** Implementation of operations provided by this function */
+	ddf_dev_ops_t *ops;
+	
+	/** Connection handler or @c NULL to use the DDF default handler. */
+	async_client_conn_t conn_handler;
+	
+	/** Link in the list of functions handled by the driver */
+	link_t link;
+};
+
+#endif
+
+/**
+ * @}
+ */
Index: uspace/lib/drv/include/ddf/driver.h
===================================================================
--- uspace/lib/drv/include/ddf/driver.h	(revision be2a38ad69d4e9a07b4e8871b3c9fcce28423470)
+++ uspace/lib/drv/include/ddf/driver.h	(revision 56fd7cf53b8ee7af3e78e2237e566926562e0291)
@@ -42,10 +42,11 @@
 #include "../dev_iface.h"
 
-typedef struct ddf_dev ddf_dev_t;
-typedef struct ddf_fun ddf_fun_t;
 
 /*
  * Device
  */
+
+typedef struct ddf_dev ddf_dev_t;
+typedef struct ddf_fun ddf_fun_t;
 
 /** Devices operations */
@@ -75,65 +76,8 @@
 
 /** Device structure */
-struct ddf_dev {
-	/**
-	 * Globally unique device identifier (assigned to the device by the
-	 * device manager).
-	 */
-	devman_handle_t handle;
-	
-	/** Reference count */
-	atomic_t refcnt;
-	
-	/**
-	 * Session to the parent device driver (if it is different from this
-	 * driver)
-	 */
-	async_sess_t *parent_sess;
-	
-	/** Device name */
-	const char *name;
-	
-	/** Driver-specific data associated with this device */
-	void *driver_data;
-	
-	/** Link in the list of devices handled by the driver */
-	link_t link;
-};
+struct ddf_dev;
 
 /** Function structure */
-struct ddf_fun {
-	/** True if bound to the device manager */
-	bool bound;
-	
-	/** Function indentifier (asigned by device manager) */
-	devman_handle_t handle;
-	
-	/** Reference count */
-	atomic_t refcnt;
-	
-	/** Device which this function belogs to */
-	ddf_dev_t *dev;
-	
-	/** Function type */
-	fun_type_t ftype;
-	
-	/** Function name */
-	const char *name;
-	
-	/** List of device ids for driver matching */
-	match_id_list_t match_ids;
-	
-	/** Driver-specific data associated with this function */
-	void *driver_data;
-	
-	/** Implementation of operations provided by this function */
-	ddf_dev_ops_t *ops;
-	
-	/** Connection handler or @c NULL to use the DDF default handler. */
-	async_client_conn_t conn_handler;
-	
-	/** Link in the list of functions handled by the driver */
-	link_t link;
-};
+struct ddf_fun;
 
 /*
@@ -167,10 +111,25 @@
 } driver_t;
 
+/** XXX Only to transition USB */
+#ifdef _DDF_DATA_IMPLANT
+extern void ddf_fun_data_implant(ddf_fun_t *, void *);
+#endif
+
 extern int ddf_driver_main(driver_t *);
 
 extern void *ddf_dev_data_alloc(ddf_dev_t *, size_t);
+extern void *ddf_dev_data_get(ddf_dev_t *);
+extern devman_handle_t ddf_dev_get_handle(ddf_dev_t *);
+extern const char *ddf_dev_get_name(ddf_dev_t *);
+extern async_sess_t *ddf_dev_parent_sess_create(ddf_dev_t *, exch_mgmt_t);
+extern async_sess_t *ddf_dev_parent_sess_get(ddf_dev_t *);
 extern ddf_fun_t *ddf_fun_create(ddf_dev_t *, fun_type_t, const char *);
+extern devman_handle_t ddf_fun_get_handle(ddf_fun_t *);
 extern void ddf_fun_destroy(ddf_fun_t *);
 extern void *ddf_fun_data_alloc(ddf_fun_t *, size_t);
+extern void *ddf_fun_data_get(ddf_fun_t *);
+extern const char *ddf_fun_get_name(ddf_fun_t *);
+extern int ddf_fun_set_name(ddf_fun_t *, const char *);
+extern ddf_dev_t *ddf_fun_get_dev(ddf_fun_t *);
 extern int ddf_fun_bind(ddf_fun_t *);
 extern int ddf_fun_unbind(ddf_fun_t *);
@@ -178,5 +137,6 @@
 extern int ddf_fun_offline(ddf_fun_t *);
 extern int ddf_fun_add_match_id(ddf_fun_t *, const char *, int);
-
+extern void ddf_fun_set_ops(ddf_fun_t *, ddf_dev_ops_t *);
+extern void ddf_fun_set_conn_handler(ddf_fun_t *, async_client_conn_t);
 extern int ddf_fun_add_to_category(ddf_fun_t *, const char *);
 
Index: uspace/lib/nic/src/nic_driver.c
===================================================================
--- uspace/lib/nic/src/nic_driver.c	(revision be2a38ad69d4e9a07b4e8871b3c9fcce28423470)
+++ uspace/lib/nic/src/nic_driver.c	(revision 56fd7cf53b8ee7af3e78e2237e566926562e0291)
@@ -47,5 +47,4 @@
 #include <sysinfo.h>
 #include <as.h>
-#include <devman.h>
 #include <ddf/interrupt.h>
 #include <ops/nic.h>
@@ -250,12 +249,12 @@
 {
 	ddf_dev_t *dev = nic_data->dev;
+	async_sess_t *parent_sess;
 	
 	/* Connect to the parent's driver. */
-	dev->parent_sess = devman_parent_device_connect(EXCHANGE_SERIALIZE,
-		dev->handle, IPC_FLAG_BLOCKING);
-	if (dev->parent_sess == NULL)
+	parent_sess = ddf_dev_parent_sess_create(dev, EXCHANGE_SERIALIZE);
+	if (parent_sess == NULL)
 		return EPARTY;
 	
-	return hw_res_get_list_parsed(nic_data->dev->parent_sess, resources, 0);
+	return hw_res_get_list_parsed(parent_sess, resources, 0);
 }
 
@@ -650,19 +649,16 @@
  *
  */
-static nic_t *nic_create(void)
-{
-	nic_t *nic_data = malloc(sizeof(nic_t));
+static nic_t *nic_create(ddf_dev_t *dev)
+{
+	nic_t *nic_data = ddf_dev_data_alloc(dev, sizeof(nic_t));
 	if (nic_data == NULL)
 		return NULL;
 	
 	/* Force zero to all uninitialized fields (e.g. added in future) */
-	bzero(nic_data, sizeof(nic_t));
 	if (nic_rxc_init(&nic_data->rx_control) != EOK) {
-		free(nic_data);
 		return NULL;
 	}
 	
 	if (nic_wol_virtues_init(&nic_data->wol_virtues) != EOK) {
-		free(nic_data);
 		return NULL;
 	}
@@ -705,13 +701,9 @@
 nic_t *nic_create_and_bind(ddf_dev_t *device)
 {
-	assert(device);
-	assert(!device->driver_data);
-	
-	nic_t *nic_data = nic_create();
+	nic_t *nic_data = nic_create(device);
 	if (!nic_data)
 		return NULL;
 	
 	nic_data->dev = device;
-	device->driver_data = nic_data;
 	
 	return nic_data;
@@ -724,11 +716,7 @@
  * @param data
  */
-static void nic_destroy(nic_t *nic_data) {
-	if (nic_data->client_session != NULL) {
-		async_hangup(nic_data->client_session);
-	}
-
+static void nic_destroy(nic_t *nic_data)
+{
 	free(nic_data->specific);
-	free(nic_data);
 }
 
@@ -740,12 +728,7 @@
  * @param device The NIC device structure
  */
-void nic_unbind_and_destroy(ddf_dev_t *device){
-	if (!device)
-		return;
-	if (!device->driver_data)
-		return;
-
-	nic_destroy((nic_t *) device->driver_data);
-	device->driver_data = NULL;
+void nic_unbind_and_destroy(ddf_dev_t *device)
+{
+	nic_destroy(nic_get_from_ddf_dev(device));
 	return;
 }
@@ -983,6 +966,6 @@
 nic_t *nic_get_from_ddf_dev(ddf_dev_t *dev)
 {
-	return (nic_t *) dev->driver_data;
-};
+	return (nic_t *) ddf_dev_data_get(dev);
+}
 
 /** 
@@ -992,6 +975,6 @@
 nic_t *nic_get_from_ddf_fun(ddf_fun_t *fun)
 {
-	return (nic_t *) fun->driver_data;
-};
+	return (nic_t *) ddf_fun_data_get(fun);
+}
 
 /**
Index: uspace/lib/nic/src/nic_impl.c
===================================================================
--- uspace/lib/nic/src/nic_impl.c	(revision be2a38ad69d4e9a07b4e8871b3c9fcce28423470)
+++ uspace/lib/nic/src/nic_impl.c	(revision 56fd7cf53b8ee7af3e78e2237e566926562e0291)
@@ -54,5 +54,5 @@
 int nic_get_state_impl(ddf_fun_t *fun, nic_device_state_t *state)
 {
-	nic_t *nic_data = (nic_t *) fun->driver_data;
+	nic_t *nic_data = nic_get_from_ddf_fun(fun);
 	fibril_rwlock_read_lock(&nic_data->main_lock);
 	*state = nic_data->state;
@@ -78,5 +78,5 @@
 	}
 
-	nic_t *nic_data = (nic_t *) fun->driver_data;
+	nic_t *nic_data = nic_get_from_ddf_fun(fun);
 
 	fibril_rwlock_write_lock(&nic_data->main_lock);
@@ -170,5 +170,5 @@
 int nic_send_frame_impl(ddf_fun_t *fun, void *data, size_t size)
 {
-	nic_t *nic_data = (nic_t *) fun->driver_data;
+	nic_t *nic_data = nic_get_from_ddf_fun(fun);
 
 	fibril_rwlock_read_lock(&nic_data->main_lock);
@@ -192,5 +192,5 @@
 int nic_callback_create_impl(ddf_fun_t *fun)
 {
-	nic_t *nic = (nic_t *) fun->driver_data;
+	nic_t *nic = nic_get_from_ddf_fun(fun);
 	fibril_rwlock_write_lock(&nic->main_lock);
 	
@@ -218,5 +218,5 @@
 {
 	assert(address);
-	nic_t *nic_data = (nic_t *) fun->driver_data;
+	nic_t *nic_data = nic_get_from_ddf_fun(fun);
 	fibril_rwlock_read_lock(&nic_data->main_lock);
 	memcpy(address, &nic_data->mac, sizeof (nic_address_t));
@@ -236,5 +236,5 @@
 int nic_get_stats_impl(ddf_fun_t *fun, nic_device_stats_t *stats)
 {
-	nic_t *nic_data = (nic_t *) fun->driver_data;
+	nic_t *nic_data = nic_get_from_ddf_fun(fun);
 	assert (stats != NULL);
 	fibril_rwlock_read_lock(&nic_data->stats_lock);
@@ -259,5 +259,5 @@
 	size_t max_count, nic_address_t *addr_list, size_t *addr_count)
 {
-	nic_t *nic_data = (nic_t *) fun->driver_data;
+	nic_t *nic_data = nic_get_from_ddf_fun(fun);
 	fibril_rwlock_read_lock(&nic_data->rxc_lock);
 	nic_rxc_unicast_get_mode(&nic_data->rx_control, mode, max_count,
@@ -291,5 +291,5 @@
 	}
 
-	nic_t *nic_data = (nic_t *) fun->driver_data;
+	nic_t *nic_data = nic_get_from_ddf_fun(fun);
 	fibril_rwlock_write_lock(&nic_data->rxc_lock);
 	int rc = ENOTSUP;
@@ -326,5 +326,5 @@
 	size_t max_count, nic_address_t *addr_list, size_t *addr_count)
 {
-	nic_t *nic_data = (nic_t *) fun->driver_data;
+	nic_t *nic_data = nic_get_from_ddf_fun(fun);
 	fibril_rwlock_read_lock(&nic_data->rxc_lock);
 	nic_rxc_multicast_get_mode(&nic_data->rx_control, mode, max_count,
@@ -358,5 +358,5 @@
 	}
 
-	nic_t *nic_data = (nic_t *) fun->dev->driver_data;
+	nic_t *nic_data = nic_get_from_ddf_fun(fun);
 	fibril_rwlock_write_lock(&nic_data->rxc_lock);
 	int rc = ENOTSUP;
@@ -382,5 +382,5 @@
 int nic_broadcast_get_mode_impl(ddf_fun_t *fun, nic_broadcast_mode_t *mode)
 {
-	nic_t *nic_data = (nic_t *) fun->driver_data;
+	nic_t *nic_data = nic_get_from_ddf_fun(fun);
 	fibril_rwlock_read_lock(&nic_data->rxc_lock);
 	nic_rxc_broadcast_get_mode(&nic_data->rx_control, mode);
@@ -402,5 +402,5 @@
 int nic_broadcast_set_mode_impl(ddf_fun_t *fun, nic_broadcast_mode_t mode)
 {
-	nic_t *nic_data = (nic_t *) fun->driver_data;
+	nic_t *nic_data = nic_get_from_ddf_fun(fun);
 	fibril_rwlock_write_lock(&nic_data->rxc_lock);
 	int rc = ENOTSUP;
@@ -429,5 +429,5 @@
 	size_t max_count, nic_address_t *addr_list, size_t *addr_count)
 {
-	nic_t *nic_data = (nic_t *) fun->driver_data;
+	nic_t *nic_data = nic_get_from_ddf_fun(fun);
 	fibril_rwlock_read_lock(&nic_data->rxc_lock);
 	nic_rxc_blocked_sources_get(&nic_data->rx_control,
@@ -452,5 +452,5 @@
 	const nic_address_t *addr_list, size_t addr_count)
 {
-	nic_t *nic_data = (nic_t *) fun->driver_data;
+	nic_t *nic_data = nic_get_from_ddf_fun(fun);
 	fibril_rwlock_write_lock(&nic_data->rxc_lock);
 	if (nic_data->on_blocked_sources_change) {
@@ -474,5 +474,5 @@
 int nic_vlan_get_mask_impl(ddf_fun_t *fun, nic_vlan_mask_t *mask)
 {
-	nic_t *nic_data = (nic_t *) fun->driver_data;
+	nic_t *nic_data = nic_get_from_ddf_fun(fun);
 	fibril_rwlock_read_lock(&nic_data->rxc_lock);
 	int rc = nic_rxc_vlan_get_mask(&nic_data->rx_control, mask);
@@ -492,5 +492,5 @@
 int nic_vlan_set_mask_impl(ddf_fun_t *fun, const nic_vlan_mask_t *mask)
 {
-	nic_t *nic_data = (nic_t *) fun->driver_data;
+	nic_t *nic_data = nic_get_from_ddf_fun(fun);
 	fibril_rwlock_write_lock(&nic_data->rxc_lock);
 	int rc = nic_rxc_vlan_set_mask(&nic_data->rx_control, mask);
@@ -520,5 +520,5 @@
 	const void *data, size_t length, nic_wv_id_t *new_id)
 {
-	nic_t *nic_data = (nic_t *) fun->driver_data;
+	nic_t *nic_data = nic_get_from_ddf_fun(fun);
 	if (nic_data->on_wol_virtue_add == NULL
 		|| nic_data->on_wol_virtue_remove == NULL) {
@@ -594,5 +594,5 @@
 int nic_wol_virtue_remove_impl(ddf_fun_t *fun, nic_wv_id_t id)
 {
-	nic_t *nic_data = (nic_t *) fun->driver_data;
+	nic_t *nic_data = nic_get_from_ddf_fun(fun);
 	if (nic_data->on_wol_virtue_add == NULL
 		|| nic_data->on_wol_virtue_remove == NULL) {
@@ -631,5 +631,5 @@
 	nic_wv_type_t *type, size_t max_length, void *data, size_t *length)
 {
-	nic_t *nic_data = (nic_t *) fun->driver_data;
+	nic_t *nic_data = nic_get_from_ddf_fun(fun);
 	fibril_rwlock_read_lock(&nic_data->wv_lock);
 	const nic_wol_virtue_t *virtue =
@@ -669,5 +669,5 @@
 	size_t max_count, nic_wv_id_t *id_list, size_t *id_count)
 {
-	nic_t *nic_data = (nic_t *) fun->driver_data;
+	nic_t *nic_data = nic_get_from_ddf_fun(fun);
 	fibril_rwlock_read_lock(&nic_data->wv_lock);
 	int rc = nic_wol_virtues_list(&nic_data->wol_virtues, type,
@@ -689,5 +689,5 @@
 int nic_wol_virtue_get_caps_impl(ddf_fun_t *fun, nic_wv_type_t type, int *count)
 {
-	nic_t *nic_data = (nic_t *) fun->driver_data;
+	nic_t *nic_data = nic_get_from_ddf_fun(fun);
 	fibril_rwlock_read_lock(&nic_data->wv_lock);
 	*count = nic_data->wol_virtues.caps_max[type]
@@ -712,5 +712,5 @@
 	nic_poll_mode_t *mode, struct timeval *period)
 {
-	nic_t *nic_data = (nic_t *) fun->driver_data;
+	nic_t *nic_data = nic_get_from_ddf_fun(fun);
 	fibril_rwlock_read_lock(&nic_data->main_lock);
 	*mode = nic_data->poll_mode;
@@ -735,5 +735,5 @@
 	nic_poll_mode_t mode, const struct timeval *period)
 {
-	nic_t *nic_data = (nic_t *) fun->driver_data;
+	nic_t *nic_data = nic_get_from_ddf_fun(fun);
 	/* If the driver does not implement the poll mode change handler it cannot
 	 * switch off interrupts and this is not supported. */
@@ -783,5 +783,5 @@
  */
 int nic_poll_now_impl(ddf_fun_t *fun) {
-	nic_t *nic_data = (nic_t *) fun->driver_data;
+	nic_t *nic_data = nic_get_from_ddf_fun(fun);
 	fibril_rwlock_read_lock(&nic_data->main_lock);
 	if (nic_data->poll_mode != NIC_POLL_ON_DEMAND) {
Index: uspace/lib/usb/include/usb/hc.h
===================================================================
--- uspace/lib/usb/include/usb/hc.h	(revision be2a38ad69d4e9a07b4e8871b3c9fcce28423470)
+++ uspace/lib/usb/include/usb/hc.h	(revision 56fd7cf53b8ee7af3e78e2237e566926562e0291)
@@ -77,6 +77,5 @@
 }
 
-int usb_hc_connection_initialize_from_device(usb_hc_connection_t *,
-    const ddf_dev_t *);
+int usb_hc_connection_initialize_from_device(usb_hc_connection_t *, ddf_dev_t *);
 
 void usb_hc_connection_deinitialize(usb_hc_connection_t *);
Index: uspace/lib/usb/src/ddfiface.c
===================================================================
--- uspace/lib/usb/src/ddfiface.c	(revision be2a38ad69d4e9a07b4e8871b3c9fcce28423470)
+++ uspace/lib/usb/src/ddfiface.c	(revision 56fd7cf53b8ee7af3e78e2237e566926562e0291)
@@ -68,5 +68,5 @@
 {
 	assert(fun);
-	return usb_get_hc_by_handle(fun->handle, handle);
+	return usb_get_hc_by_handle(ddf_fun_get_handle(fun), handle);
 }
 
@@ -82,5 +82,5 @@
 
 	if (handle != NULL) {
-		*handle = fun->handle;
+		*handle = ddf_fun_get_handle(fun);
 	}
 
@@ -99,5 +99,5 @@
 {
 	assert(fun);
-	return usb_get_address_by_handle(fun->handle, address);
+	return usb_get_address_by_handle(ddf_fun_get_handle(fun), address);
 }
 
@@ -116,7 +116,5 @@
     usb_address_t *address)
 {
-	assert(fun);
-	assert(fun->driver_data);
-	const usb_hub_attached_device_t *device = fun->driver_data;
+	const usb_hub_attached_device_t *device = ddf_fun_data_get(fun);
 	assert(device->fun == fun);
 	if (address)
Index: uspace/lib/usb/src/hc.c
===================================================================
--- uspace/lib/usb/src/hc.c	(revision be2a38ad69d4e9a07b4e8871b3c9fcce28423470)
+++ uspace/lib/usb/src/hc.c	(revision 56fd7cf53b8ee7af3e78e2237e566926562e0291)
@@ -115,14 +115,11 @@
  */
 int usb_hc_connection_initialize_from_device(usb_hc_connection_t *connection,
-    const ddf_dev_t *device)
-{
-	assert(connection);
-
-	if (device == NULL) {
+    ddf_dev_t *device)
+{
+	if (device == NULL)
 		return EBADMEM;
-	}
 
 	devman_handle_t hc_handle;
-	const int rc = usb_get_hc_by_handle(device->handle, &hc_handle);
+	const int rc = usb_get_hc_by_handle(ddf_dev_get_handle(device), &hc_handle);
 	if (rc == EOK) {
 		usb_hc_connection_initialize(connection, hc_handle);
Index: uspace/lib/usbdev/src/devdrv.c
===================================================================
--- uspace/lib/usbdev/src/devdrv.c	(revision be2a38ad69d4e9a07b4e8871b3c9fcce28423470)
+++ uspace/lib/usbdev/src/devdrv.c	(revision 56fd7cf53b8ee7af3e78e2237e566926562e0291)
@@ -105,5 +105,5 @@
 	if (dev == NULL) {
 		usb_log_error("USB device `%s' structure allocation failed.\n",
-		    gen_dev->name);
+		    ddf_dev_get_name(gen_dev));
 		return ENOMEM;
 	}
@@ -114,5 +114,5 @@
 	if (rc != EOK) {
 		usb_log_error("USB device `%s' init failed (%s): %s.\n",
-		    gen_dev->name, err_msg, str_error(rc));
+		    ddf_dev_get_name(gen_dev), err_msg, str_error(rc));
 		return rc;
 	}
@@ -139,5 +139,5 @@
 		return ENOTSUP;
 	/* Just tell the driver to stop whatever it is doing */
-	usb_device_t *usb_dev = gen_dev->driver_data;
+	usb_device_t *usb_dev = ddf_dev_data_get(gen_dev);
 	const int ret = driver->ops->device_rem(usb_dev);
 	if (ret != EOK)
@@ -160,5 +160,5 @@
 	if (driver->ops->device_gone == NULL)
 		return ENOTSUP;
-	usb_device_t *usb_dev = gen_dev->driver_data;
+	usb_device_t *usb_dev = ddf_dev_data_get(gen_dev);
 	const int ret = driver->ops->device_gone(usb_dev);
 	if (ret == EOK)
@@ -415,5 +415,5 @@
 	usb_address_t address;
 
-	int rc = usb_get_info_by_handle(ddf_dev->handle,
+	int rc = usb_get_info_by_handle(ddf_dev_get_handle(ddf_dev),
 	    &hc_handle, &address, &usb_dev->interface_no);
 	if (rc != EOK) {
Index: uspace/lib/usbdev/src/devpoll.c
===================================================================
--- uspace/lib/usbdev/src/devpoll.c	(revision be2a38ad69d4e9a07b4e8871b3c9fcce28423470)
+++ uspace/lib/usbdev/src/devpoll.c	(revision 56fd7cf53b8ee7af3e78e2237e566926562e0291)
@@ -80,5 +80,5 @@
 		usb_log_debug("Poll%p: started polling of `%s' - " \
 		    "interface %d (%s,%d,%d), %zuB/%zu.\n",
-		    data, data->dev->ddf_dev->name,
+		    data, ddf_dev_get_name(data->dev->ddf_dev),
 		    (int) mapping->interface->interface_number,
 		    usb_str_class(mapping->interface->interface_class),
@@ -159,8 +159,10 @@
 		if (failed) {
 			usb_log_error("Polling of device `%s' terminated: "
-			    "recurring failures.\n", data->dev->ddf_dev->name);
+			    "recurring failures.\n", ddf_dev_get_name(
+			    data->dev->ddf_dev));
 		} else {
 			usb_log_debug("Polling of device `%s' terminated: "
-			    "driver request.\n", data->dev->ddf_dev->name);
+			    "driver request.\n", ddf_dev_get_name(
+			    data->dev->ddf_dev));
 		}
 	}
Index: uspace/lib/usbdev/src/hub.c
===================================================================
--- uspace/lib/usbdev/src/hub.c	(revision be2a38ad69d4e9a07b4e8871b3c9fcce28423470)
+++ uspace/lib/usbdev/src/hub.c	(revision 56fd7cf53b8ee7af3e78e2237e566926562e0291)
@@ -63,5 +63,5 @@
 		return EBADMEM;
 	return usb_hc_bind_address(connection,
-	    attached_device->address, attached_device->fun->handle);
+	    attached_device->address, ddf_fun_get_handle(attached_device->fun));
 }
 
@@ -287,7 +287,4 @@
 	rc = usb_hub_register_device(hc_conn, &new_device);
 	if (rc != EOK) {
-		/* We know nothing about that data. */
-		if (new_dev_data)
-			child_fun->driver_data = NULL;
 		/* The child function is already created. */
 		ddf_fun_destroy(child_fun);
Index: uspace/lib/usbdev/src/recognise.c
===================================================================
--- uspace/lib/usbdev/src/recognise.c	(revision be2a38ad69d4e9a07b4e8871b3c9fcce28423470)
+++ uspace/lib/usbdev/src/recognise.c	(revision 56fd7cf53b8ee7af3e78e2237e566926562e0291)
@@ -33,4 +33,7 @@
  * Functions for recognition of attached devices.
  */
+
+/** XXX Fix this */
+#define _DDF_DATA_IMPLANT
 
 #include <sys/types.h>
@@ -352,9 +355,10 @@
 	
 	if (dev_ops != NULL)
-		child->ops = dev_ops;
+		ddf_fun_set_ops(child, dev_ops);
 	else
-		child->ops = &child_ops;
-	
-	child->driver_data = dev_data;
+		ddf_fun_set_ops(child, &child_ops);
+	
+	ddf_fun_data_implant(child, dev_data);
+	
 	/*
 	 * Store the attached device in fun
@@ -373,7 +377,20 @@
 	}
 	
-	rc = usb_device_create_match_ids(ctrl_pipe, &child->match_ids);
+	match_id_list_t match_ids;
+	init_match_ids(&match_ids);
+	rc = usb_device_create_match_ids(ctrl_pipe, &match_ids);
 	if (rc != EOK)
 		goto failure;
+	
+	list_foreach(match_ids.ids, id_link) {
+		match_id_t *match_id = list_get_instance(id_link, match_id_t, link);
+		rc = ddf_fun_add_match_id(child, match_id->id, match_id->score);
+		if (rc != EOK) {
+			clean_match_ids(&match_ids);
+			goto failure;
+		}
+	}
+	
+	clean_match_ids(&match_ids);
 	
 	rc = ddf_fun_bind(child);
@@ -386,8 +403,4 @@
 failure:
 	if (child != NULL) {
-		/* We know nothing about the data if it came from outside. */
-		if (dev_data)
-			child->driver_data = NULL;
-		
 		/* This takes care of match_id deallocation as well. */
 		ddf_fun_destroy(child);
Index: uspace/lib/usbhost/include/usb/host/hcd.h
===================================================================
--- uspace/lib/usbhost/include/usb/host/hcd.h	(revision be2a38ad69d4e9a07b4e8871b3c9fcce28423470)
+++ uspace/lib/usbhost/include/usb/host/hcd.h	(revision 56fd7cf53b8ee7af3e78e2237e566926562e0291)
@@ -98,8 +98,7 @@
  * @return pointer cast to hcd_t*.
  */
-static inline hcd_t * fun_to_hcd(const ddf_fun_t *fun)
+static inline hcd_t *fun_to_hcd(ddf_fun_t *fun)
 {
-	assert(fun);
-	return fun->driver_data;
+	return ddf_fun_data_get(fun);
 }
 
