Index: uspace/drv/audio/sb16/mixer_iface.c
===================================================================
--- uspace/drv/audio/sb16/mixer_iface.c	(revision 96e368a61482194923fef78ac804b0906e9668b9)
+++ uspace/drv/audio/sb16/mixer_iface.c	(revision cbfece72626dbcd93661ce58b0575c5602ad9660)
@@ -33,14 +33,21 @@
  */
 
+#include <ddf/driver.h>
 #include <errno.h>
 #include <audio_mixer_iface.h>
 
 #include "mixer.h"
+#include "sb16.h"
+
+static sb_mixer_t *fun_to_mixer(ddf_fun_t *fun)
+{
+	sb16_t *sb = (sb16_t *)ddf_dev_data_get(ddf_fun_get_dev(fun));
+	return &sb->mixer;
+}
 
 static int sb_get_info(ddf_fun_t *fun, const char** name, unsigned *items)
 {
-	assert(fun);
-	const sb_mixer_t *mixer = ddf_fun_data_get(fun);
-	assert(mixer);
+	sb_mixer_t *mixer = fun_to_mixer(fun);
+
 	if (name)
 		*name = sb_mixer_type_str(mixer->type);
@@ -54,16 +61,11 @@
     unsigned *max_level)
 {
-	assert(fun);
-	const sb_mixer_t *mixer = ddf_fun_data_get(fun);
-	assert(mixer);
-	return
-	    sb_mixer_get_control_item_info(mixer, item, name, max_level);
+	sb_mixer_t *mixer = fun_to_mixer(fun);
+	return sb_mixer_get_control_item_info(mixer, item, name, max_level);
 }
 
 static int sb_set_item_level(ddf_fun_t *fun, unsigned item, unsigned value)
 {
-	assert(fun);
-	const sb_mixer_t *mixer = ddf_fun_data_get(fun);
-	assert(mixer);
+	sb_mixer_t *mixer = fun_to_mixer(fun);
 	return sb_mixer_set_control_item_value(mixer, item, value);
 }
@@ -71,7 +73,5 @@
 static int sb_get_item_level(ddf_fun_t *fun, unsigned item, unsigned *value)
 {
-	assert(fun);
-	const sb_mixer_t *mixer = ddf_fun_data_get(fun);
-	assert(mixer);
+	sb_mixer_t *mixer = fun_to_mixer(fun);
 	return sb_mixer_get_control_item_value(mixer, item, value);
 }
Index: uspace/drv/audio/sb16/pcm_iface.c
===================================================================
--- uspace/drv/audio/sb16/pcm_iface.c	(revision 96e368a61482194923fef78ac804b0906e9668b9)
+++ uspace/drv/audio/sb16/pcm_iface.c	(revision cbfece72626dbcd93661ce58b0575c5602ad9660)
@@ -39,11 +39,10 @@
 
 #include "dsp.h"
+#include "sb16.h"
 
-static inline sb_dsp_t * fun_to_dsp(ddf_fun_t *fun)
+static inline sb_dsp_t *fun_to_dsp(ddf_fun_t *fun)
 {
-	assert(fun);
-	sb_dsp_t *dsp = ddf_fun_data_get(fun);
-	assert(dsp);
-	return dsp;
+	sb16_t *sb = (sb16_t *)ddf_dev_data_get(ddf_fun_get_dev(fun));
+	return &sb->dsp;
 }
 
Index: uspace/drv/audio/sb16/sb16.c
===================================================================
--- uspace/drv/audio/sb16/sb16.c	(revision 96e368a61482194923fef78ac804b0906e9668b9)
+++ uspace/drv/audio/sb16/sb16.c	(revision cbfece72626dbcd93661ce58b0575c5602ad9660)
@@ -27,6 +27,4 @@
  */
 
-#define _DDF_DATA_IMPLANT
-
 #include <errno.h>
 #include <str_error.h>
@@ -121,6 +119,5 @@
 		return ret;
 	}
-	//TODO remove data implant
-	ddf_fun_data_implant(dsp_fun, &sb->dsp);
+
 	ddf_fun_set_ops(dsp_fun, &sb_pcm_ops);
 	ddf_log_note("Sound blaster DSP (%x.%x) initialized.",
@@ -131,5 +128,4 @@
 		ddf_log_error(
 		    "Failed to bind PCM function: %s.", str_error(ret));
-		// TODO implanted data
 		ddf_fun_destroy(dsp_fun);
 		return ret;
@@ -141,5 +137,4 @@
 		    str_error(ret));
 		ddf_fun_unbind(dsp_fun);
-		// TODO implanted data
 		ddf_fun_destroy(dsp_fun);
 		return ret;
@@ -154,5 +149,4 @@
 		ddf_log_error("Failed to create mixer function.");
 		ddf_fun_unbind(dsp_fun);
-		// TODO implanted data
 		ddf_fun_destroy(dsp_fun);
 		return ENOMEM;
@@ -163,5 +157,4 @@
 		    str_error(ret));
 		ddf_fun_unbind(dsp_fun);
-		// TODO implanted data
 		ddf_fun_destroy(dsp_fun);
 		ddf_fun_destroy(mixer_fun);
@@ -171,5 +164,4 @@
 	ddf_log_note("Initialized mixer: %s.",
 	    sb_mixer_type_str(sb->mixer.type));
-	ddf_fun_data_implant(mixer_fun, &sb->mixer);
 	ddf_fun_set_ops(mixer_fun, &sb_mixer_ops);
 
@@ -178,9 +170,6 @@
 		ddf_log_error(
 		    "Failed to bind mixer function: %s.", str_error(ret));
-		// TODO implanted data
 		ddf_fun_destroy(mixer_fun);
-
-		ddf_fun_unbind(dsp_fun);
-		// TODO implanted data
+		ddf_fun_unbind(dsp_fun);
 		ddf_fun_destroy(dsp_fun);
 		return ret;
Index: uspace/drv/block/ahci/ahci.c
===================================================================
--- uspace/drv/block/ahci/ahci.c	(revision 96e368a61482194923fef78ac804b0906e9668b9)
+++ uspace/drv/block/ahci/ahci.c	(revision cbfece72626dbcd93661ce58b0575c5602ad9660)
@@ -38,7 +38,5 @@
 #include <device/hw_res_parsed.h>
 #include <pci_dev_iface.h>
-#include <sysinfo.h>
-#include <ipc/irc.h>
-#include <ns.h>
+#include <irc.h>
 #include <ahci_iface.h>
 #include "ahci.h"
@@ -129,5 +127,4 @@
 
 static void ahci_get_model_name(uint16_t *, char *);
-static int ahci_enable_interrupt(int);
 
 static fibril_mutex_t sata_devices_count_lock;
@@ -1195,5 +1192,5 @@
 	}
 	
-	rc = ahci_enable_interrupt(hw_res_parsed.irqs.irqs[0]);
+	rc = irc_enable_interrupt(hw_res_parsed.irqs.irqs[0]);
 	if (rc != EOK) {
 		ddf_msg(LVL_ERROR, "Failed enable interupt.");
@@ -1315,26 +1312,4 @@
 }
 
-/** Enable interrupt using SERVICE_IRC.
- *
- * @param irq Requested irq number.
- *
- * @return EOK if succeed, error code otherwise.
- *
- */
-static int ahci_enable_interrupt(int irq)
-{
-	async_sess_t *irc_sess = NULL;
-	irc_sess = service_connect_blocking(EXCHANGE_SERIALIZE, SERVICE_IRC, 0, 0);
-	if (!irc_sess)
-		return EINTR;
-	
-	async_exch_t *exch = async_exchange_begin(irc_sess);
-	const int rc = async_req_1_0(exch, IRC_ENABLE_INTERRUPT, irq);
-	async_exchange_end(exch);
-	
-	async_hangup(irc_sess);
-	return rc;
-}
-
 /*----------------------------------------------------------------------------*/
 /*-- AHCI Main routine -------------------------------------------------------*/
Index: uspace/drv/bus/isa/isa.c
===================================================================
--- uspace/drv/bus/isa/isa.c	(revision 96e368a61482194923fef78ac804b0906e9668b9)
+++ uspace/drv/bus/isa/isa.c	(revision cbfece72626dbcd93661ce58b0575c5602ad9660)
@@ -54,10 +54,6 @@
 #include <ipc/irc.h>
 #include <ipc/services.h>
-#include <sysinfo.h>
-#include <ns.h>
 #include <sys/stat.h>
-#include <ipc/irc.h>
-#include <ipc/services.h>
-#include <sysinfo.h>
+#include <irc.h>
 #include <ns.h>
 
@@ -120,37 +116,16 @@
 	assert(fun);
 
-	sysarg_t apic;
-	sysarg_t i8259;
-
-	async_sess_t *irc_sess = NULL;
-
-	if (((sysinfo_get_value("apic", &apic) == EOK) && (apic))
-	    || ((sysinfo_get_value("i8259", &i8259) == EOK) && (i8259))) {
-		irc_sess = service_connect_blocking(EXCHANGE_SERIALIZE,
-		    SERVICE_IRC, 0, 0);
-	}
-
-	if (!irc_sess)
-		return false;
-
 	const hw_resource_list_t *res = &fun->hw_resources;
 	assert(res);
 	for (size_t i = 0; i < res->count; ++i) {
 		if (res->resources[i].type == INTERRUPT) {
-			const int irq = res->resources[i].res.interrupt.irq;
-
-			async_exch_t *exch = async_exchange_begin(irc_sess);
-			const int rc =
-			    async_req_1_0(exch, IRC_ENABLE_INTERRUPT, irq);
-			async_exchange_end(exch);
-
-			if (rc != EOK) {
-				async_hangup(irc_sess);
+			int rc = irc_enable_interrupt(
+			    res->resources[i].res.interrupt.irq);
+
+			if (rc != EOK)
 				return false;
-			}
-		}
-	}
-
-	async_hangup(irc_sess);
+		}
+	}
+
 	return true;
 }
Index: uspace/drv/bus/pci/pciintel/pci.c
===================================================================
--- uspace/drv/bus/pci/pciintel/pci.c	(revision 96e368a61482194923fef78ac804b0906e9668b9)
+++ uspace/drv/bus/pci/pciintel/pci.c	(revision cbfece72626dbcd93661ce58b0575c5602ad9660)
@@ -51,8 +51,5 @@
 #include <ddf/log.h>
 #include <ipc/dev_iface.h>
-#include <ipc/irc.h>
-#include <ns.h>
-#include <ipc/services.h>
-#include <sysinfo.h>
+#include <irc.h>
 #include <ops/hw_res.h>
 #include <device/hw_res.h>
@@ -107,37 +104,16 @@
 	pci_fun_t *dev_data = pci_fun(fnode);
 	
-	sysarg_t apic;
-	sysarg_t i8259;
-	
-	async_sess_t *irc_sess = NULL;
-	
-	if (((sysinfo_get_value("apic", &apic) == EOK) && (apic))
-	    || ((sysinfo_get_value("i8259", &i8259) == EOK) && (i8259))) {
-		irc_sess = service_connect_blocking(EXCHANGE_SERIALIZE,
-		    SERVICE_IRC, 0, 0);
-	}
-	
-	if (!irc_sess)
-		return false;
-	
 	size_t i = 0;
 	hw_resource_list_t *res = &dev_data->hw_resources;
 	for (; i < res->count; i++) {
 		if (res->resources[i].type == INTERRUPT) {
-			const int irq = res->resources[i].res.interrupt.irq;
-			
-			async_exch_t *exch = async_exchange_begin(irc_sess);
-			const int rc =
-			    async_req_1_0(exch, IRC_ENABLE_INTERRUPT, irq);
-			async_exchange_end(exch);
-			
-			if (rc != EOK) {
-				async_hangup(irc_sess);
+			int rc = irc_enable_interrupt(
+			    res->resources[i].res.interrupt.irq);
+			
+			if (rc != EOK)
 				return false;
-			}
 		}
 	}
 	
-	async_hangup(irc_sess);
 	return true;
 }
Index: uspace/drv/bus/usb/usbhid/generic/hiddev.c
===================================================================
--- uspace/drv/bus/usb/usbhid/generic/hiddev.c	(revision 96e368a61482194923fef78ac804b0906e9668b9)
+++ uspace/drv/bus/usb/usbhid/generic/hiddev.c	(revision cbfece72626dbcd93661ce58b0575c5602ad9660)
@@ -35,7 +35,4 @@
  */
 
-/* XXX Fix this */
-#define _DDF_DATA_IMPLANT
-
 #include <usb/debug.h>
 #include <usb/classes/classes.h>
Index: uspace/drv/bus/usb/usbhid/kbd/kbddev.c
===================================================================
--- uspace/drv/bus/usb/usbhid/kbd/kbddev.c	(revision 96e368a61482194923fef78ac804b0906e9668b9)
+++ uspace/drv/bus/usb/usbhid/kbd/kbddev.c	(revision cbfece72626dbcd93661ce58b0575c5602ad9660)
@@ -34,7 +34,4 @@
  * USB HID keyboard device structure and API.
  */
-
-/* XXX Fix this */
-#define _DDF_DATA_IMPLANT
 
 #include <errno.h>
@@ -479,19 +476,52 @@
 }
 
-/* HID/KBD structure manipulation                                             */
-
-static int usb_kbd_create_function(usb_kbd_t *kbd_dev)
-{
-	assert(kbd_dev != NULL);
-	assert(kbd_dev->hid_dev != NULL);
-	assert(kbd_dev->hid_dev->usb_dev != NULL);
+/* API functions                                                              */
+
+/**
+ * Initialization of the USB/HID keyboard structure.
+ *
+ * This functions initializes required structures from the device's descriptors.
+ *
+ * During initialization, the keyboard is switched into boot protocol, the idle
+ * rate is set to 0 (infinity), resulting in the keyboard only reporting event
+ * when a key is pressed or released. Finally, the LED lights are turned on 
+ * according to the default setup of lock keys.
+ *
+ * @note By default, the keyboards is initialized with Num Lock turned on and 
+ *       other locks turned off.
+ *
+ * @param kbd_dev Keyboard device structure to be initialized.
+ * @param dev DDF device structure of the keyboard.
+ *
+ * @retval EOK if successful.
+ * @retval EINVAL if some parameter is not given.
+ * @return Other value inherited from function usbhid_dev_init().
+ */
+int usb_kbd_init(usb_hid_dev_t *hid_dev, void **data)
+{
+	ddf_fun_t *fun = NULL;
+	usb_kbd_t *kbd_dev = NULL;
+	usb_hid_report_path_t *path = NULL;
+	bool bound = false;
+	fid_t fid = 0;
+	int rc;
+
+	usb_log_debug("Initializing HID/KBD structure...\n");
+
+	if (hid_dev == NULL) {
+		usb_log_error(
+		    "Failed to init keyboard structure: no structure given.\n");
+		rc = EINVAL;
+		goto error;
+	}
 
 	/* Create the exposed function. */
 	usb_log_debug("Creating DDF function %s...\n", HID_KBD_FUN_NAME);
-	ddf_fun_t *fun = ddf_fun_create(kbd_dev->hid_dev->usb_dev->ddf_dev,
-	    fun_exposed, HID_KBD_FUN_NAME);
+	fun = ddf_fun_create(hid_dev->usb_dev->ddf_dev, fun_exposed,
+	    HID_KBD_FUN_NAME);
 	if (fun == NULL) {
 		usb_log_error("Could not create DDF function node.\n");
-		return ENOMEM;
+		rc = ENOMEM;
+		goto error;
 	}
 
@@ -499,13 +529,131 @@
 	 * to the DDF function. */
 	ddf_fun_set_ops(fun, &kbdops);
-	ddf_fun_data_implant(fun, kbd_dev);
-
-	int rc = ddf_fun_bind(fun);
+
+	kbd_dev = ddf_fun_data_alloc(fun, sizeof(usb_kbd_t));
+	if (kbd_dev == NULL) {
+		usb_log_error("Failed to allocate KBD device structure.\n");
+		rc = ENOMEM;
+		goto error;
+	}
+
+	kbd_dev->fun = fun;
+
+	/* Default values */
+	fibril_mutex_initialize(&kbd_dev->repeat_mtx);
+	kbd_dev->initialized = USB_KBD_STATUS_UNINITIALIZED;
+
+	/* Store link to HID device */
+	kbd_dev->hid_dev = hid_dev;
+
+	/* Modifiers and locks */
+	kbd_dev->mods = DEFAULT_ACTIVE_MODS;
+
+	/* Autorepeat */
+	kbd_dev->repeat.delay_before = DEFAULT_DELAY_BEFORE_FIRST_REPEAT;
+	kbd_dev->repeat.delay_between = DEFAULT_REPEAT_DELAY;
+
+	// TODO: make more general
+	path = usb_hid_report_path();
+	if (path == NULL) {
+		usb_log_error("Failed to create kbd report path.\n");
+		rc = ENOMEM;
+		goto error;
+	}
+
+	rc = usb_hid_report_path_append_item(path, USB_HIDUT_PAGE_KEYBOARD, 0);
+	if (rc != EOK) {
+		usb_log_error("Failed to append item to kbd report path.\n");
+		goto error;
+	}
+
+	usb_hid_report_path_set_report_id(path, 0);
+
+	kbd_dev->key_count =
+	    usb_hid_report_size(&hid_dev->report, 0, USB_HID_REPORT_TYPE_INPUT);
+
+	usb_hid_report_path_free(path);
+	path = NULL;
+
+	usb_log_debug("Size of the input report: %zu\n", kbd_dev->key_count);
+
+	kbd_dev->keys = calloc(kbd_dev->key_count, sizeof(int32_t));
+	if (kbd_dev->keys == NULL) {
+		usb_log_error("Failed to allocate key buffer.\n");
+		rc = ENOMEM;
+		goto error;
+	}
+
+	kbd_dev->keys_old = calloc(kbd_dev->key_count, sizeof(int32_t));
+	if (kbd_dev->keys_old == NULL) {
+		usb_log_error("Failed to allocate old_key buffer.\n");
+		rc = ENOMEM;
+		goto error;
+	}
+
+	/* Output report */
+	kbd_dev->output_size = 0;
+	kbd_dev->output_buffer = usb_hid_report_output(&hid_dev->report,
+	    &kbd_dev->output_size, 0);
+	if (kbd_dev->output_buffer == NULL) {
+		usb_log_error("Error creating output report buffer.\n");
+		rc = ENOMEM;
+		goto error;
+	}
+
+	usb_log_debug("Output buffer size: %zu\n", kbd_dev->output_size);
+
+	kbd_dev->led_path = usb_hid_report_path();
+	if (kbd_dev->led_path == NULL) {
+		usb_log_error("Failed to create kbd led report path.\n");
+		rc = ENOMEM;
+		goto error;
+	}
+
+	rc = usb_hid_report_path_append_item(
+	    kbd_dev->led_path, USB_HIDUT_PAGE_LED, 0);
+	if (rc != EOK) {
+		usb_log_error("Failed to append to kbd/led report path.\n");
+		goto error;
+	}
+
+	kbd_dev->led_output_size = usb_hid_report_size(
+	    &hid_dev->report, 0, USB_HID_REPORT_TYPE_OUTPUT);
+
+	usb_log_debug("Output report size (in items): %zu\n",
+	    kbd_dev->led_output_size);
+
+	kbd_dev->led_data = calloc(kbd_dev->led_output_size, sizeof(int32_t));
+	if (kbd_dev->led_data == NULL) {
+		usb_log_error("Error creating buffer for LED output report.\n");
+		rc = ENOMEM;
+		goto error;
+	}
+
+	/* Set LEDs according to initial setup.
+	 * Set Idle rate */
+	usb_kbd_set_led(hid_dev, kbd_dev);
+
+	usbhid_req_set_idle(&hid_dev->usb_dev->ctrl_pipe,
+	    hid_dev->usb_dev->interface_no, IDLE_RATE);
+
+	/* Create new fibril for auto-repeat. */
+	fid = fibril_create(usb_kbd_repeat_fibril, kbd_dev);
+	if (fid == 0) {
+		usb_log_error("Failed to start fibril for KBD auto-repeat");
+		rc = ENOMEM;
+		goto error;
+	}
+
+	kbd_dev->initialized = USB_KBD_STATUS_INITIALIZED;
+	usb_log_debug("HID/KBD device structure initialized.\n");
+
+	rc = ddf_fun_bind(fun);
 	if (rc != EOK) {
 		usb_log_error("Could not bind DDF function: %s.\n",
 		    str_error(rc));
-		ddf_fun_destroy(fun);
-		return rc;
-	}
+		goto error;
+	}
+
+	bound = true;
 
 	usb_log_debug("%s function created. Handle: %" PRIun "\n",
@@ -519,180 +667,32 @@
 		    "Could not add DDF function to category %s: %s.\n",
 		    HID_KBD_CATEGORY, str_error(rc));
-		if (ddf_fun_unbind(fun) == EOK) {
-			ddf_fun_destroy(fun);
-		} else {
-			usb_log_error(
-			    "Failed to unbind `%s', will not destroy.\n",
-			    ddf_fun_get_name(fun));
-		}
-		return rc;
-	}
-	kbd_dev->fun = fun;
-
-	return EOK;
-}
-
-/* API functions                                                              */
-
-/**
- * Initialization of the USB/HID keyboard structure.
- *
- * This functions initializes required structures from the device's descriptors.
- *
- * During initialization, the keyboard is switched into boot protocol, the idle
- * rate is set to 0 (infinity), resulting in the keyboard only reporting event
- * when a key is pressed or released. Finally, the LED lights are turned on 
- * according to the default setup of lock keys.
- *
- * @note By default, the keyboards is initialized with Num Lock turned on and 
- *       other locks turned off.
- *
- * @param kbd_dev Keyboard device structure to be initialized.
- * @param dev DDF device structure of the keyboard.
- *
- * @retval EOK if successful.
- * @retval EINVAL if some parameter is not given.
- * @return Other value inherited from function usbhid_dev_init().
- */
-int usb_kbd_init(usb_hid_dev_t *hid_dev, void **data)
-{
-	usb_log_debug("Initializing HID/KBD structure...\n");
-
-	if (hid_dev == NULL) {
-		usb_log_error(
-		    "Failed to init keyboard structure: no structure given.\n");
-		return EINVAL;
-	}
-
-	usb_kbd_t *kbd_dev = calloc(1, sizeof(usb_kbd_t));
-	if (kbd_dev == NULL) {
-		usb_log_error("Failed to allocate KBD device structure.\n");
-		return ENOMEM;
-	}
-	/* Default values */
-	fibril_mutex_initialize(&kbd_dev->repeat_mtx);
-	kbd_dev->initialized = USB_KBD_STATUS_UNINITIALIZED;
-
-	/* Store link to HID device */
-	kbd_dev->hid_dev = hid_dev;
-
-	/* Modifiers and locks */
-	kbd_dev->mods = DEFAULT_ACTIVE_MODS;
-
-	/* Autorepeat */
-	kbd_dev->repeat.delay_before = DEFAULT_DELAY_BEFORE_FIRST_REPEAT;
-	kbd_dev->repeat.delay_between = DEFAULT_REPEAT_DELAY;
-
-
-	// TODO: make more general
-	usb_hid_report_path_t *path = usb_hid_report_path();
-	if (path == NULL) {
-		usb_log_error("Failed to create kbd report path.\n");
-		usb_kbd_destroy(kbd_dev);
-		return ENOMEM;
-	}
-
-	int ret =
-	    usb_hid_report_path_append_item(path, USB_HIDUT_PAGE_KEYBOARD, 0);
-	if (ret != EOK) {
-		usb_log_error("Failed to append item to kbd report path.\n");
-		usb_hid_report_path_free(path);
-		usb_kbd_destroy(kbd_dev);
-		return ret;
-	}
-
-	usb_hid_report_path_set_report_id(path, 0);
-
-	kbd_dev->key_count =
-	    usb_hid_report_size(&hid_dev->report, 0, USB_HID_REPORT_TYPE_INPUT);
-
-	usb_hid_report_path_free(path);
-
-	usb_log_debug("Size of the input report: %zu\n", kbd_dev->key_count);
-
-	kbd_dev->keys = calloc(kbd_dev->key_count, sizeof(int32_t));
-	if (kbd_dev->keys == NULL) {
-		usb_log_error("Failed to allocate key buffer.\n");
-		usb_kbd_destroy(kbd_dev);
-		return ENOMEM;
-	}
-
-	kbd_dev->keys_old = calloc(kbd_dev->key_count, sizeof(int32_t));
-	if (kbd_dev->keys_old == NULL) {
-		usb_log_error("Failed to allocate old_key buffer.\n");
-		usb_kbd_destroy(kbd_dev);
-		return ENOMEM;
-	}
-
-	/* Output report */
-	kbd_dev->output_size = 0;
-	kbd_dev->output_buffer = usb_hid_report_output(&hid_dev->report,
-	    &kbd_dev->output_size, 0);
-	if (kbd_dev->output_buffer == NULL) {
-		usb_log_error("Error creating output report buffer.\n");
-		usb_kbd_destroy(kbd_dev);
-		return ENOMEM;
-	}
-
-	usb_log_debug("Output buffer size: %zu\n", kbd_dev->output_size);
-
-	kbd_dev->led_path = usb_hid_report_path();
-	if (kbd_dev->led_path == NULL) {
-		usb_log_error("Failed to create kbd led report path.\n");
-		usb_kbd_destroy(kbd_dev);
-		return ENOMEM;
-	}
-
-	ret = usb_hid_report_path_append_item(
-	    kbd_dev->led_path, USB_HIDUT_PAGE_LED, 0);
-	if (ret != EOK) {
-		usb_log_error("Failed to append to kbd/led report path.\n");
-		usb_kbd_destroy(kbd_dev);
-		return ret;
-	}
-
-	kbd_dev->led_output_size = usb_hid_report_size(
-	    &hid_dev->report, 0, USB_HID_REPORT_TYPE_OUTPUT);
-
-	usb_log_debug("Output report size (in items): %zu\n",
-	    kbd_dev->led_output_size);
-
-	kbd_dev->led_data = calloc(kbd_dev->led_output_size, sizeof(int32_t));
-	if (kbd_dev->led_data == NULL) {
-		usb_log_error("Error creating buffer for LED output report.\n");
-		usb_kbd_destroy(kbd_dev);
-		return ENOMEM;
-	}
-
-	/* Set LEDs according to initial setup.
-	 * Set Idle rate */
-	usb_kbd_set_led(hid_dev, kbd_dev);
-
-	usbhid_req_set_idle(&hid_dev->usb_dev->ctrl_pipe,
-	    hid_dev->usb_dev->interface_no, IDLE_RATE);
+		goto error;
+	}
+
+	fibril_add_ready(fid);
 
 	/* Save the KBD device structure into the HID device structure. */
 	*data = kbd_dev;
 
-	kbd_dev->initialized = USB_KBD_STATUS_INITIALIZED;
-	usb_log_debug("HID/KBD device structure initialized.\n");
-
-	usb_log_debug("Creating KBD function...\n");
-	ret = usb_kbd_create_function(kbd_dev);
-	if (ret != EOK) {
-		usb_kbd_destroy(kbd_dev);
-		return ret;
-	}
-
-	/* Create new fibril for auto-repeat. */
-	fid_t fid = fibril_create(usb_kbd_repeat_fibril, kbd_dev);
-	if (fid == 0) {
-		usb_log_error("Failed to start fibril for KBD auto-repeat");
-		usb_kbd_destroy(kbd_dev);
-		return ENOMEM;
-	}
-	fibril_add_ready(fid);
-
 	return EOK;
+error:
+	if (bound)
+		ddf_fun_unbind(fun);
+	if (fid != 0)
+		fibril_destroy(fid);
+	if (kbd_dev != NULL) {
+		free(kbd_dev->led_data);
+		if (kbd_dev->led_path != NULL)
+			usb_hid_report_path_free(kbd_dev->led_path);
+		if (kbd_dev->output_buffer != NULL)
+			usb_hid_report_output_free(kbd_dev->output_buffer);
+		free(kbd_dev->keys_old);
+		free(kbd_dev->keys);
+	}
+	if (path != NULL)
+		usb_hid_report_path_free(path);
+	if (fun != NULL)
+		ddf_fun_destroy(fun);
+	return rc;
 }
 
@@ -749,14 +749,6 @@
 	usb_hid_report_output_free(kbd_dev->output_buffer);
 
-	if (kbd_dev->fun) {
-		if (ddf_fun_unbind(kbd_dev->fun) != EOK) {
-			usb_log_warning("Failed to unbind %s.\n",
-			    ddf_fun_get_name(kbd_dev->fun));
-		} else {
-			usb_log_debug2("%s unbound.\n",
-			    ddf_fun_get_name(kbd_dev->fun));
-			ddf_fun_destroy(kbd_dev->fun);
-		}
-	}
+	ddf_fun_unbind(kbd_dev->fun);
+	ddf_fun_destroy(kbd_dev->fun);
 }
 
Index: uspace/drv/bus/usb/usbhid/mouse/mousedev.c
===================================================================
--- uspace/drv/bus/usb/usbhid/mouse/mousedev.c	(revision 96e368a61482194923fef78ac804b0906e9668b9)
+++ uspace/drv/bus/usb/usbhid/mouse/mousedev.c	(revision cbfece72626dbcd93661ce58b0575c5602ad9660)
@@ -34,7 +34,4 @@
  * USB Mouse driver API.
  */
-
-/* XXX Fix this */
-#define _DDF_DATA_IMPLANT
 
 #include <usb/debug.h>
@@ -249,54 +246,4 @@
 }
 
-#define FUN_UNBIND_DESTROY(fun) \
-if (fun) { \
-	if (ddf_fun_unbind((fun)) == EOK) { \
-		ddf_fun_destroy((fun)); \
-	} else { \
-		usb_log_error("Could not unbind function `%s', it " \
-		    "will not be destroyed.\n", ddf_fun_get_name(fun)); \
-	} \
-} else (void)0
-
-static int usb_mouse_create_function(usb_hid_dev_t *hid_dev, usb_mouse_t *mouse)
-{
-	assert(hid_dev != NULL);
-	assert(mouse != NULL);
-
-	/* Create the exposed function. */
-	usb_log_debug("Creating DDF function %s...\n", HID_MOUSE_FUN_NAME);
-	ddf_fun_t *fun = ddf_fun_create(hid_dev->usb_dev->ddf_dev, fun_exposed,
-	    HID_MOUSE_FUN_NAME);
-	if (fun == NULL) {
-		usb_log_error("Could not create DDF function node `%s'.\n",
-		    HID_MOUSE_FUN_NAME);
-		return ENOMEM;
-	}
-
-	ddf_fun_set_ops(fun, &ops);
-	ddf_fun_data_implant(fun, mouse);
-
-	int rc = ddf_fun_bind(fun);
-	if (rc != EOK) {
-		usb_log_error("Could not bind DDF function `%s': %s.\n",
-		    ddf_fun_get_name(fun), str_error(rc));
-		ddf_fun_destroy(fun);
-		return rc;
-	}
-
-	usb_log_debug("Adding DDF function `%s' to category %s...\n",
-	    ddf_fun_get_name(fun), HID_MOUSE_CATEGORY);
-	rc = ddf_fun_add_to_category(fun, HID_MOUSE_CATEGORY);
-	if (rc != EOK) {
-		usb_log_error(
-		    "Could not add DDF function to category %s: %s.\n",
-		    HID_MOUSE_CATEGORY, str_error(rc));
-		FUN_UNBIND_DESTROY(fun);
-		return rc;
-	}
-	mouse->mouse_fun = fun;
-	return EOK;
-}
-
 /** Get highest index of a button mentioned in given report.
  *
@@ -341,4 +288,9 @@
 int usb_mouse_init(usb_hid_dev_t *hid_dev, void **data)
 {
+	ddf_fun_t *fun = NULL;
+	usb_mouse_t *mouse_dev = NULL;
+	bool bound = false;
+	int rc;
+
 	usb_log_debug("Initializing HID/Mouse structure...\n");
 
@@ -346,12 +298,27 @@
 		usb_log_error("Failed to init mouse structure: no structure"
 		    " given.\n");
-		return EINVAL;
-	}
-
-	usb_mouse_t *mouse_dev = calloc(1, sizeof(usb_mouse_t));
+		rc = EINVAL;
+		goto error;
+	}
+
+	/* Create the exposed function. */
+	usb_log_debug("Creating DDF function %s...\n", HID_MOUSE_FUN_NAME);
+	fun = ddf_fun_create(hid_dev->usb_dev->ddf_dev, fun_exposed,
+	    HID_MOUSE_FUN_NAME);
+	if (fun == NULL) {
+		usb_log_error("Could not create DDF function node `%s'.\n",
+		    HID_MOUSE_FUN_NAME);
+		rc = ENOMEM;
+		goto error;
+	}
+
+	ddf_fun_set_ops(fun, &ops);
+
+	mouse_dev = ddf_fun_data_alloc(fun, sizeof(usb_mouse_t));
 	if (mouse_dev == NULL) {
 		usb_log_error("Error while creating USB/HID Mouse device "
 		    "structure.\n");
-		return ENOMEM;
+		rc = ENOMEM;
+		goto error;
 	}
 
@@ -368,6 +335,6 @@
 	if (mouse_dev->buttons == NULL) {
 		usb_log_error(NAME ": out of memory, giving up on device!\n");
-		free(mouse_dev);
-		return ENOMEM;
+		rc = ENOMEM;
+		goto error;
 	}
 
@@ -376,15 +343,35 @@
 	    hid_dev->usb_dev->interface_no, IDLE_RATE);
 
-	int rc = usb_mouse_create_function(hid_dev, mouse_dev);
+	rc = ddf_fun_bind(fun);
 	if (rc != EOK) {
-		free(mouse_dev->buttons);
-		free(mouse_dev);
-		return rc;
-	}
+		usb_log_error("Could not bind DDF function `%s': %s.\n",
+		    ddf_fun_get_name(fun), str_error(rc));
+		goto error;
+	}
+
+	bound = true;
+
+	usb_log_debug("Adding DDF function `%s' to category %s...\n",
+	    ddf_fun_get_name(fun), HID_MOUSE_CATEGORY);
+	rc = ddf_fun_add_to_category(fun, HID_MOUSE_CATEGORY);
+	if (rc != EOK) {
+		usb_log_error("Could not add DDF function to category %s: "
+		    "%s.\n", HID_MOUSE_CATEGORY, str_error(rc));
+		goto error;
+	}
+
+	mouse_dev->mouse_fun = fun;
 
 	/* Save the Mouse device structure into the HID device structure. */
 	*data = mouse_dev;
-
 	return EOK;
+error:
+	if (bound)
+		ddf_fun_unbind(fun);
+	if (mouse_dev != NULL)
+		free(mouse_dev->buttons);
+	if (fun != NULL)
+		ddf_fun_destroy(fun);
+	return rc;
 }
 
@@ -417,7 +404,7 @@
 	}
 
-	FUN_UNBIND_DESTROY(mouse_dev->mouse_fun);
-
+	ddf_fun_unbind(mouse_dev->mouse_fun);
 	free(mouse_dev->buttons);
+	ddf_fun_destroy(mouse_dev->mouse_fun);
 }
 
Index: uspace/drv/char/ns8250/ns8250.c
===================================================================
--- uspace/drv/char/ns8250/ns8250.c	(revision 96e368a61482194923fef78ac804b0906e9668b9)
+++ uspace/drv/char/ns8250/ns8250.c	(revision cbfece72626dbcd93661ce58b0575c5602ad9660)
@@ -57,7 +57,5 @@
 #include <ops/char_dev.h>
 
-#include <ns.h>
-#include <ipc/services.h>
-#include <ipc/irc.h>
+#include <irc.h>
 #include <device/hw_res.h>
 #include <ipc/serial_ctl.h>
@@ -488,25 +486,12 @@
 static int ns8250_interrupt_enable(ns8250_t *ns)
 {
-	/*
-	 * Enable interrupt using IRC service.
-	 * TODO: This is a temporary solution until the device framework
-	 * takes care of this itself.
-	 */
-	async_sess_t *irc_sess = service_connect_blocking(EXCHANGE_SERIALIZE,
-	    SERVICE_IRC, 0, 0);
-	if (!irc_sess) {
+	/* Enable interrupt using IRC service. */
+	int rc = irc_enable_interrupt(ns->irq);
+	if (rc != EOK)
 		return EIO;
-	}
-
-	async_exch_t *exch = async_exchange_begin(irc_sess);
-	if (!exch) {
-		return EIO;
-	}
-	async_msg_1(exch, IRC_ENABLE_INTERRUPT, ns->irq);
-	async_exchange_end(exch);
-
+	
 	/* Read LSR to clear possible previous LSR interrupt */
 	pio_read_8(&ns->regs->lsr);
-
+	
 	/* Enable interrupt on the serial port. */
 	ns8250_port_interrupts_enable(ns->regs);
Index: uspace/drv/nic/e1k/e1k.c
===================================================================
--- uspace/drv/nic/e1k/e1k.c	(revision 96e368a61482194923fef78ac804b0906e9668b9)
+++ uspace/drv/nic/e1k/e1k.c	(revision cbfece72626dbcd93661ce58b0575c5602ad9660)
@@ -33,7 +33,4 @@
  */
 
-/* XXX Fix this */
-#define _DDF_DATA_IMPLANT
-
 #include <assert.h>
 #include <stdio.h>
@@ -42,9 +39,7 @@
 #include <align.h>
 #include <byteorder.h>
-#include <sysinfo.h>
-#include <ipc/irc.h>
-#include <ipc/ns.h>
+#include <irc.h>
+#include <as.h>
 #include <ddi.h>
-#include <as.h>
 #include <ddf/log.h>
 #include <ddf/interrupt.h>
@@ -1758,5 +1753,12 @@
 	e1000_enable_interrupts(e1000);
 	
-	nic_enable_interrupt(nic, e1000->irq);
+	int rc = irc_enable_interrupt(e1000->irq);
+	if (rc != EOK) {
+		e1000_disable_interrupts(e1000);
+		fibril_mutex_unlock(&e1000->ctrl_lock);
+		fibril_mutex_unlock(&e1000->tx_lock);
+		fibril_mutex_unlock(&e1000->rx_lock);
+		return rc;
+	}
 	
 	e1000_clear_rx_ring(e1000);
@@ -1796,5 +1798,5 @@
 	e1000_disable_rx(e1000);
 	
-	nic_disable_interrupt(nic, e1000->irq);
+	irc_disable_interrupt(e1000->irq);
 	e1000_disable_interrupts(e1000);
 	
@@ -2148,13 +2150,8 @@
 	nic_set_ddf_fun(nic, fun);
 	ddf_fun_set_ops(fun, &e1000_dev_ops);
-	ddf_fun_data_implant(fun, nic);
 	
 	rc = e1000_register_int_handler(nic);
 	if (rc != EOK)
 		goto err_fun_create;
-	
-	rc = nic_connect_to_services(nic);
-	if (rc != EOK)
-		goto err_irq;
 	
 	rc = e1000_initialize_rx_structure(nic);
@@ -2379,7 +2376,8 @@
 int main(void)
 {
-	int rc = nic_driver_init(NAME);
-	if (rc != EOK)
-		return rc;
+	printf("%s: HelenOS E1000 network adapter driver\n", NAME);
+	
+	if (nic_driver_init(NAME) != EOK)
+		return 1;
 	
 	nic_driver_implement(&e1000_driver_ops, &e1000_dev_ops,
@@ -2387,5 +2385,4 @@
 	
 	ddf_log_init(NAME);
-	ddf_msg(LVL_NOTE, "HelenOS E1000 driver started");
 	return ddf_driver_main(&e1000_driver);
 }
Index: uspace/drv/nic/ne2k/ne2k.c
===================================================================
--- uspace/drv/nic/ne2k/ne2k.c	(revision 96e368a61482194923fef78ac804b0906e9668b9)
+++ uspace/drv/nic/ne2k/ne2k.c	(revision cbfece72626dbcd93661ce58b0575c5602ad9660)
@@ -38,9 +38,7 @@
  */
 
-/* XXX Fix this */
-#define _DDF_DATA_IMPLANT
-
 #include <stdio.h>
 #include <errno.h>
+#include <irc.h>
 #include <stdlib.h>
 #include <str_error.h>
@@ -256,9 +254,12 @@
 	if (!ne2k->up) {
 		int rc = ne2k_up(ne2k);
+		if (rc != EOK)
+			return rc;
+
+		rc = irc_enable_interrupt(ne2k->irq);
 		if (rc != EOK) {
+			ne2k_down(ne2k);
 			return rc;
 		}
-
-		nic_enable_interrupt(nic_data, ne2k->irq);
 	}
 	return EOK;
@@ -269,5 +270,5 @@
 	ne2k_t *ne2k = (ne2k_t *) nic_get_specific(nic_data);
 
-	nic_disable_interrupt(nic_data, ne2k->irq);
+	(void) irc_disable_interrupt(ne2k->irq);
 	ne2k->receive_configuration = RCR_AB | RCR_AM;
 	ne2k_down(ne2k);
@@ -396,10 +397,4 @@
 	}
 	
-	rc = nic_connect_to_services(nic_data);
-	if (rc != EOK) {
-		ne2k_dev_cleanup(dev);
-		return rc;
-	}
-	
 	fun = ddf_fun_create(nic_get_ddf_dev(nic_data), fun_exposed, "port0");
 	if (fun == NULL) {
@@ -407,7 +402,7 @@
 		return ENOMEM;
 	}
+	
 	nic_set_ddf_fun(nic_data, fun);
 	ddf_fun_set_ops(fun, &ne2k_dev_ops);
-	ddf_fun_data_implant(fun, nic_data);
 	
 	rc = ddf_fun_bind(fun);
@@ -443,4 +438,6 @@
 int main(int argc, char *argv[])
 {
+	printf("%s: HelenOS NE 2000 network adapter driver\n", NAME);
+	
 	nic_driver_init(NAME);
 	nic_driver_implement(&ne2k_driver_ops, &ne2k_dev_ops, &ne2k_nic_iface);
Index: uspace/drv/nic/rtl8139/driver.c
===================================================================
--- uspace/drv/nic/rtl8139/driver.c	(revision 96e368a61482194923fef78ac804b0906e9668b9)
+++ uspace/drv/nic/rtl8139/driver.c	(revision cbfece72626dbcd93661ce58b0575c5602ad9660)
@@ -27,7 +27,4 @@
  */
 
-/* XXX Fix this */
-#define _DDF_DATA_IMPLANT
-
 #include <assert.h>
 #include <errno.h>
@@ -35,5 +32,4 @@
 #include <byteorder.h>
 #include <libarch/barrier.h>
-
 #include <as.h>
 #include <ddf/log.h>
@@ -42,9 +38,6 @@
 #include <nic.h>
 #include <pci_dev_iface.h>
-
-#include <ipc/irc.h>
-#include <sysinfo.h>
-#include <ipc/ns.h>
-
+#include <irc.h>
+#include <stdio.h>
 #include <str.h>
 
@@ -960,5 +953,10 @@
 	rtl8139->int_mask = RTL_DEFAULT_INTERRUPTS;
 	rtl8139_hw_int_enable(rtl8139);
-	nic_enable_interrupt(nic_data, rtl8139->irq);
+
+	int rc = irc_enable_interrupt(rtl8139->irq);
+	if (rc != EOK) {
+		rtl8139_on_stopped(nic_data);
+		return rc;
+	}
 
 	ddf_msg(LVL_DEBUG, "Device activated, interrupt %d registered", rtl8139->irq);
@@ -1325,10 +1323,4 @@
 		goto err_pio;
 
-	rc = nic_connect_to_services(nic_data);
-	if (rc != EOK) {
-		ddf_msg(LVL_ERROR, "Failed to connect to services (%d)", rc);
-		goto err_irq;
-	}
-
 	fun = ddf_fun_create(nic_get_ddf_dev(nic_data), fun_exposed, "port0");
 	if (fun == NULL) {
@@ -1336,7 +1328,7 @@
 		goto err_srv;
 	}
+
 	nic_set_ddf_fun(nic_data, fun);
 	ddf_fun_set_ops(fun, &rtl8139_dev_ops);
-	ddf_fun_data_implant(fun, nic_data);
 
 	rc = ddf_fun_bind(fun);
@@ -1361,6 +1353,4 @@
 	ddf_fun_destroy(fun);
 err_srv:
-	/* XXX Disconnect from services */
-err_irq:
 	unregister_interrupt_handler(dev, rtl8139->irq);
 err_pio:
@@ -2180,12 +2170,14 @@
 int main(void)
 {
+	printf("%s: HelenOS RTL8139 network adapter driver\n", NAME);
+
 	int rc = nic_driver_init(NAME);
 	if (rc != EOK)
 		return rc;
-	nic_driver_implement(
-		&rtl8139_driver_ops, &rtl8139_dev_ops, &rtl8139_nic_iface);
+
+	nic_driver_implement(&rtl8139_driver_ops, &rtl8139_dev_ops,
+	    &rtl8139_nic_iface);
 
 	ddf_log_init(NAME);
-	ddf_msg(LVL_NOTE, "HelenOS RTL8139 driver started");
 	return ddf_driver_main(&rtl8139_driver);
 }
Index: uspace/drv/nic/rtl8169/defs.h
===================================================================
--- uspace/drv/nic/rtl8169/defs.h	(revision 96e368a61482194923fef78ac804b0906e9668b9)
+++ uspace/drv/nic/rtl8169/defs.h	(revision cbfece72626dbcd93661ce58b0575c5602ad9660)
@@ -39,4 +39,7 @@
 #include <sys/types.h>
 #include <ddi.h>
+
+#define	PCI_VID_REALTEK		0x10ec
+#define	PCI_VID_DLINK		0x1186
 
 /** Size of RTL8169 registers address space */
Index: uspace/drv/nic/rtl8169/driver.c
===================================================================
--- uspace/drv/nic/rtl8169/driver.c	(revision 96e368a61482194923fef78ac804b0906e9668b9)
+++ uspace/drv/nic/rtl8169/driver.c	(revision cbfece72626dbcd93661ce58b0575c5602ad9660)
@@ -33,4 +33,5 @@
 #include <align.h>
 #include <byteorder.h>
+#include <irc.h>
 #include <libarch/barrier.h>
 
@@ -388,4 +389,15 @@
 	rtl8169_t *rtl8169 = nic_get_specific(nic_data);
 
+	/* Get PCI VID & PID */
+	rc = pci_config_space_read_16(ddf_dev_parent_sess_get(dev),
+	    PCI_VENDOR_ID, &rtl8169->pci_vid);
+	if (rc != EOK)
+		return rc;
+
+	rc = pci_config_space_read_16(ddf_dev_parent_sess_get(dev),
+	    PCI_DEVICE_ID, &rtl8169->pci_pid);
+	if (rc != EOK)
+		return rc;
+
 	/* Map register space */
 	rc = pio_enable(rtl8169->regs_phys, RTL8169_IO_SIZE, &rtl8169->regs);
@@ -418,10 +430,4 @@
 	uint8_t cr_value = pio_read_8(rtl8169->regs + CR);
 	pio_write_8(rtl8169->regs + CR, cr_value | CR_TE | CR_RE);
-
-	rc = nic_connect_to_services(nic_data);
-	if (rc != EOK) {
-		ddf_msg(LVL_ERROR, "Failed to connect to services (%d)", rc);
-		goto err_irq;
-	}
 
 	fun = ddf_fun_create(nic_get_ddf_dev(nic_data), fun_exposed, "port0");
@@ -473,5 +479,6 @@
 	int rc;
 
-	rtl8169_set_hwaddr(rtl8169, addr);
+	fibril_mutex_lock(&rtl8169->rx_lock);
+	fibril_mutex_lock(&rtl8169->tx_lock);
 
 	rc = nic_report_address(nic_data, addr);
@@ -479,4 +486,9 @@
 		return rc;
 
+	rtl8169_set_hwaddr(rtl8169, addr);
+
+	fibril_mutex_unlock(&rtl8169->rx_lock);
+	fibril_mutex_unlock(&rtl8169->tx_lock);
+
 	return EOK;
 }
@@ -484,7 +496,24 @@
 static int rtl8169_get_device_info(ddf_fun_t *fun, nic_device_info_t *info)
 {
-
-	str_cpy(info->vendor_name, NIC_VENDOR_MAX_LENGTH, "Realtek");
-	str_cpy(info->model_name, NIC_MODEL_MAX_LENGTH, "RTL8169");
+	nic_t *nic_data = nic_get_from_ddf_fun(fun);
+	rtl8169_t *rtl8169 = nic_get_specific(nic_data);
+
+	str_cpy(info->vendor_name, NIC_VENDOR_MAX_LENGTH, "Unknown");
+	str_cpy(info->model_name, NIC_MODEL_MAX_LENGTH, "Unknown");
+
+	if (rtl8169->pci_vid == PCI_VID_REALTEK)
+		str_cpy(info->vendor_name, NIC_VENDOR_MAX_LENGTH, "Realtek");
+	
+	if (rtl8169->pci_vid == PCI_VID_DLINK)
+		str_cpy(info->vendor_name, NIC_VENDOR_MAX_LENGTH, "D-Link");
+	
+	if (rtl8169->pci_pid == 0x8168)
+		str_cpy(info->model_name, NIC_MODEL_MAX_LENGTH, "RTL8168");
+	
+	if (rtl8169->pci_pid == 0x8169)
+		str_cpy(info->model_name, NIC_MODEL_MAX_LENGTH, "RTL8169");
+
+	if (rtl8169->pci_pid == 0x8110)
+		str_cpy(info->model_name, NIC_MODEL_MAX_LENGTH, "RTL8110");
 
 	return EOK;
@@ -541,4 +570,7 @@
 	bmcr &= ~(BMCR_DUPLEX | BMCR_SPD_100 | BMCR_SPD_1000);
 	
+	/* Disable autonegotiation */
+	bmcr &= ~BMCR_AN_ENABLE;
+
 	if (duplex == NIC_CM_FULL_DUPLEX)
 		bmcr |= BMCR_DUPLEX;
@@ -609,4 +641,9 @@
 static int rtl8169_autoneg_restart(ddf_fun_t *fun)
 {
+	rtl8169_t *rtl8169 = nic_get_specific(nic_get_from_ddf_fun(fun));
+	uint16_t bmcr = rtl8169_mii_read(rtl8169, MII_BMCR);
+
+	bmcr |= BMCR_AN_ENABLE;
+	rtl8169_mii_write(rtl8169, MII_BMCR, bmcr);
 	return EOK;
 }
@@ -706,5 +743,5 @@
 
 	pio_write_16(rtl8169->regs + IMR, 0xffff);
-	nic_enable_interrupt(nic_data, rtl8169->irq);
+	irc_enable_interrupt(rtl8169->irq);
 
 	return EOK;
@@ -888,4 +925,10 @@
 		}
 
+		/* Receive underrun */
+		if (isr & INT_RXOVW) {
+			/* just ack.. */
+			pio_write_16(rtl8169->regs + ISR, INT_RXOVW);
+		}
+
 		if (isr & INT_SERR) {
 			ddf_msg(LVL_ERROR, "System error interrupt");
Index: uspace/drv/nic/rtl8169/driver.h
===================================================================
--- uspace/drv/nic/rtl8169/driver.h	(revision 96e368a61482194923fef78ac804b0906e9668b9)
+++ uspace/drv/nic/rtl8169/driver.h	(revision cbfece72626dbcd93661ce58b0575c5602ad9660)
@@ -55,4 +55,7 @@
 	/** The irq assigned */
 	int irq;
+	/** PCI Vendor and Product ids */
+	uint16_t pci_vid;
+	uint16_t pci_pid;
 	/** Mask of the turned interupts (IMR value) */
 	uint16_t int_mask;
