Index: uspace/app/nic/nic.c
===================================================================
--- uspace/app/nic/nic.c	(revision 96e368a61482194923fef78ac804b0906e9668b9)
+++ uspace/app/nic/nic.c	(revision cbfece72626dbcd93661ce58b0575c5602ad9660)
@@ -60,5 +60,6 @@
 	printf("\taddr <mac_address> - set MAC address\n");
 	printf("\tspeed <10|100|1000> - set NIC speed\n");
-	printf("\tduplex <half|full> - set duplex mode\n");
+	printf("\tduplex <half|full|simplex> - set duplex mode\n");
+	printf("\tauto - enable autonegotiation\n");
 }
 
@@ -206,5 +207,5 @@
 	}
 
-	printf("[Service Name]\n");
+	printf("[Index]: [Service Name]\n");
 	for (i = 0; i < count; i++) {
 		rc = loc_service_get_name(nics[i], &svc_name);
@@ -320,4 +321,24 @@
 
 	return nic_set_operation_mode(sess, oldspeed, duplex, oldrole);
+}
+
+static int nic_set_autoneg(int i)
+{
+	async_sess_t *sess;
+	int rc;
+
+	sess = get_nic_by_index(i);
+	if (sess == NULL) {
+		printf("Specified NIC doesn't exist or cannot connect to it.\n");
+		return EINVAL;
+	}
+
+	rc = nic_autoneg_restart(sess);
+	if (rc != EOK) {
+		printf("Error restarting NIC autonegotiation.\n");
+		return EIO;
+	}
+
+	return EOK;
 }
 
@@ -376,4 +397,7 @@
 			return nic_set_duplex(index, argv[3]);
 
+		if (!str_cmp(argv[2], "auto"))
+			return nic_set_autoneg(index);
+
 	} else {
 		printf(NAME ": Invalid argument.\n");
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;
Index: uspace/lib/c/Makefile
===================================================================
--- uspace/lib/c/Makefile	(revision 96e368a61482194923fef78ac804b0906e9668b9)
+++ uspace/lib/c/Makefile	(revision cbfece72626dbcd93661ce58b0575c5602ad9660)
@@ -109,4 +109,5 @@
 	generic/iplink.c \
 	generic/iplink_srv.c \
+	generic/irc.c \
 	generic/ieee_double.c \
 	generic/power_of_ten.c \
Index: uspace/lib/c/generic/irc.c
===================================================================
--- uspace/lib/c/generic/irc.c	(revision cbfece72626dbcd93661ce58b0575c5602ad9660)
+++ uspace/lib/c/generic/irc.c	(revision cbfece72626dbcd93661ce58b0575c5602ad9660)
@@ -0,0 +1,112 @@
+/*
+ * Copyright (c) 2014 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 libc
+ * @{
+ */
+/** @file
+ */
+
+#include <assert.h>
+#include <errno.h>
+#include <ipc/irc.h>
+#include <ipc/services.h>
+#include <irc.h>
+#include <ns.h>
+#include <sysinfo.h>
+
+static async_sess_t *irc_sess;
+
+/** Connect to IRC service.
+ *
+ * @return	EOK on success, EIO on failure
+ */
+static int irc_init(void)
+{
+	sysarg_t apic;
+	sysarg_t i8259;
+
+	assert(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 == NULL)
+		return EIO;
+
+	return EOK;
+}
+
+/** Enable interrupt.
+ *
+ * @param irq	IRQ number
+ */
+int irc_enable_interrupt(int irq)
+{
+	int rc;
+
+	if (irc_sess == NULL) {
+		rc = irc_init();
+		if (rc != EOK)
+			return rc;
+	}
+
+	async_exch_t *exch = async_exchange_begin(irc_sess);
+	rc = async_req_1_0(exch, IRC_ENABLE_INTERRUPT, irq);
+	async_exchange_end(exch);
+
+	return rc;
+}
+
+
+/** Disable interrupt.
+ *
+ * @param irq	IRQ number
+ */
+int irc_disable_interrupt(int irq)
+{
+	int rc;
+
+	if (irc_sess == NULL) {
+		rc = irc_init();
+		if (rc != EOK)
+			return rc;
+	}
+
+	async_exch_t *exch = async_exchange_begin(irc_sess);
+	rc = async_req_1_0(exch, IRC_CLEAR_INTERRUPT, irq);
+	async_exchange_end(exch);
+
+	return rc;
+}
+
+/** @}
+ */
Index: uspace/lib/c/include/ipc/irc.h
===================================================================
--- uspace/lib/c/include/ipc/irc.h	(revision 96e368a61482194923fef78ac804b0906e9668b9)
+++ uspace/lib/c/include/ipc/irc.h	(revision cbfece72626dbcd93661ce58b0575c5602ad9660)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_IRC_H_
-#define LIBC_IRC_H_
+#ifndef LIBC_IPC_IRC_H_
+#define LIBC_IPC_IRC_H_
 
 #include <ipc/common.h>
Index: uspace/lib/c/include/irc.h
===================================================================
--- uspace/lib/c/include/irc.h	(revision cbfece72626dbcd93661ce58b0575c5602ad9660)
+++ uspace/lib/c/include/irc.h	(revision cbfece72626dbcd93661ce58b0575c5602ad9660)
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2014 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 libc
+ * @{
+ */
+/** @file
+ */
+
+#ifndef LIBC_IRC_H_
+#define LIBC_IRC_H_
+
+extern int irc_enable_interrupt(int);
+extern int irc_disable_interrupt(int);
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/drv/include/pci_dev_iface.h
===================================================================
--- uspace/lib/drv/include/pci_dev_iface.h	(revision 96e368a61482194923fef78ac804b0906e9668b9)
+++ uspace/lib/drv/include/pci_dev_iface.h	(revision cbfece72626dbcd93661ce58b0575c5602ad9660)
@@ -40,4 +40,5 @@
 #include "ddf/driver.h"
 
+#define PCI_VENDOR_ID  0x00
 #define PCI_DEVICE_ID  0x02
 
Index: uspace/lib/nic/include/nic.h
===================================================================
--- uspace/lib/nic/include/nic.h	(revision 96e368a61482194923fef78ac804b0906e9668b9)
+++ uspace/lib/nic/include/nic.h	(revision cbfece72626dbcd93661ce58b0575c5602ad9660)
@@ -216,5 +216,4 @@
 
 /* Functions called in add_device */
-extern int nic_connect_to_services(nic_t *);
 extern int nic_get_resources(nic_t *, hw_res_list_parsed_t *);
 extern void nic_set_specific(nic_t *, void *);
@@ -245,6 +244,4 @@
 extern void nic_received_frame(nic_t *, nic_frame_t *);
 extern void nic_received_frame_list(nic_t *, nic_frame_list_t *);
-extern void nic_disable_interrupt(nic_t *, int);
-extern void nic_enable_interrupt(nic_t *, int);
 extern nic_poll_mode_t nic_query_poll_mode(nic_t *, struct timeval *);
 
Index: uspace/lib/nic/include/nic_driver.h
===================================================================
--- uspace/lib/nic/include/nic_driver.h	(revision 96e368a61482194923fef78ac804b0906e9668b9)
+++ uspace/lib/nic/include/nic_driver.h	(revision cbfece72626dbcd93661ce58b0575c5602ad9660)
@@ -80,6 +80,4 @@
 	/** Client callback session */
 	async_sess_t *client_session;
-	/** Phone to APIC or i8259 */
-	async_sess_t *irc_session;
 	/** Current polling mode of the NIC */
 	nic_poll_mode_t poll_mode;
Index: uspace/lib/nic/src/nic_driver.c
===================================================================
--- uspace/lib/nic/src/nic_driver.c	(revision 96e368a61482194923fef78ac804b0906e9668b9)
+++ uspace/lib/nic/src/nic_driver.c	(revision cbfece72626dbcd93661ce58b0575c5602ad9660)
@@ -42,7 +42,4 @@
 #include <stdio.h>
 #include <str_error.h>
-#include <ipc/services.h>
-#include <ipc/ns.h>
-#include <ipc/irc.h>
 #include <sysinfo.h>
 #include <as.h>
@@ -378,31 +375,4 @@
 }
 
-
-/**
- * Enable interrupts for this driver.
- *
- * @param nic_data
- * @param irq			The IRQ number for this device
- */
-void nic_enable_interrupt(nic_t *nic_data, int irq)
-{
-	async_exch_t *exch = async_exchange_begin(nic_data->irc_session);
-	async_msg_1(exch, IRC_ENABLE_INTERRUPT, irq);
-	async_exchange_end(exch);
-}
-
-/**
- * Disable interrupts for this driver.
- *
- * @param nic_data
- * @param irq			The IRQ number for this device
- */
-void nic_disable_interrupt(nic_t *nic_data, int irq)
-{
-	async_exch_t *exch = async_exchange_begin(nic_data->irc_session);
-	async_msg_1(exch, IRC_CLEAR_INTERRUPT, irq);
-	async_exchange_end(exch);
-}
-
 /** Get the polling mode information from the device 
  *
@@ -420,34 +390,4 @@
 	return nic_data->poll_mode;
 };
-
-/**
- * Connect to IRC service. This function should be called only from
- * the add_device handler, thus no locking is required.
- *
- * @param nic_data
- *
- * @return EOK		If connection was successful.
- * @return EINVAL	If the IRC service cannot be determined.
- * @return EREFUSED	If IRC service cannot be connected.
- */
-int nic_connect_to_services(nic_t *nic_data)
-{
-	/* IRC service */
-	sysarg_t apic;
-	sysarg_t i8259;
-	services_t irc_service = -1;
-	if (((sysinfo_get_value("apic", &apic) == EOK) && (apic)) ||
-	    ((sysinfo_get_value("i8259", &i8259) == EOK) && (i8259)))
-		irc_service = SERVICE_IRC;
-	else
-		return EINVAL;
-	
-	nic_data->irc_session = service_connect_blocking(EXCHANGE_SERIALIZE,
-		irc_service, 0, 0);
-	if (nic_data->irc_session == NULL)
-		return errno;
-	
-	return EOK;
-}
 
 /** Inform the NICF about poll mode
@@ -668,5 +608,4 @@
 	nic_data->state = NIC_STATE_STOPPED;
 	nic_data->client_session = NULL;
-	nic_data->irc_session = NULL;
 	nic_data->poll_mode = NIC_POLL_IMMEDIATE;
 	nic_data->default_poll_mode = NIC_POLL_IMMEDIATE;
@@ -975,5 +914,5 @@
 nic_t *nic_get_from_ddf_fun(ddf_fun_t *fun)
 {
-	return (nic_t *) ddf_fun_data_get(fun);
+	return (nic_t *) ddf_dev_data_get(ddf_fun_get_dev(fun));
 }
 
Index: uspace/srv/net/ethip/arp.c
===================================================================
--- uspace/srv/net/ethip/arp.c	(revision 96e368a61482194923fef78ac804b0906e9668b9)
+++ uspace/srv/net/ethip/arp.c	(revision cbfece72626dbcd93661ce58b0575c5602ad9660)
@@ -119,7 +119,5 @@
 		return rc;
 	
-	(void) atrans_wait_timeout(ARP_REQUEST_TIMEOUT);
-	
-	return atrans_lookup(ip_addr, mac_addr);
+	return atrans_lookup_timeout(ip_addr, ARP_REQUEST_TIMEOUT, mac_addr);
 }
 
Index: uspace/srv/net/ethip/atrans.c
===================================================================
--- uspace/srv/net/ethip/atrans.c	(revision 96e368a61482194923fef78ac804b0906e9668b9)
+++ uspace/srv/net/ethip/atrans.c	(revision cbfece72626dbcd93661ce58b0575c5602ad9660)
@@ -103,25 +103,60 @@
 }
 
-int atrans_lookup(addr32_t ip_addr, addr48_t mac_addr)
+static int atrans_lookup_locked(addr32_t ip_addr, addr48_t mac_addr)
 {
-	fibril_mutex_lock(&atrans_list_lock);
 	ethip_atrans_t *atrans = atrans_find(ip_addr);
-	if (atrans == NULL) {
-		fibril_mutex_unlock(&atrans_list_lock);
+	if (atrans == NULL)
 		return ENOENT;
-	}
-	
-	fibril_mutex_unlock(&atrans_list_lock);
+
 	addr48(atrans->mac_addr, mac_addr);
 	return EOK;
 }
 
-int atrans_wait_timeout(suseconds_t timeout)
+int atrans_lookup(addr32_t ip_addr, addr48_t mac_addr)
 {
+	int rc;
+
 	fibril_mutex_lock(&atrans_list_lock);
-	int rc = fibril_condvar_wait_timeout(&atrans_cv, &atrans_list_lock,
-	    timeout);
+	rc = atrans_lookup_locked(ip_addr, mac_addr);
 	fibril_mutex_unlock(&atrans_list_lock);
-	
+
+	return rc;
+}
+
+static void atrans_lookup_timeout_handler(void *arg)
+{
+	bool *timedout = (bool *)arg;
+
+	fibril_mutex_lock(&atrans_list_lock);
+	*timedout = true;
+	fibril_mutex_unlock(&atrans_list_lock);
+	fibril_condvar_broadcast(&atrans_cv);
+}
+
+int atrans_lookup_timeout(addr32_t ip_addr, suseconds_t timeout,
+    addr48_t mac_addr)
+{
+	fibril_timer_t *t;
+	bool timedout;
+	int rc;
+
+	t = fibril_timer_create(NULL);
+	if (t == NULL)
+		return ENOMEM;
+
+	timedout = false;
+	fibril_timer_set(t, timeout, atrans_lookup_timeout_handler, &timedout);
+
+	fibril_mutex_lock(&atrans_list_lock);
+
+	while ((rc = atrans_lookup_locked(ip_addr, mac_addr)) == ENOENT &&
+	    !timedout) {
+		fibril_condvar_wait(&atrans_cv, &atrans_list_lock);
+	}
+
+	fibril_mutex_unlock(&atrans_list_lock);
+	(void) fibril_timer_clear(t);
+	fibril_timer_destroy(t);
+
 	return rc;
 }
Index: uspace/srv/net/ethip/atrans.h
===================================================================
--- uspace/srv/net/ethip/atrans.h	(revision 96e368a61482194923fef78ac804b0906e9668b9)
+++ uspace/srv/net/ethip/atrans.h	(revision cbfece72626dbcd93661ce58b0575c5602ad9660)
@@ -45,5 +45,5 @@
 extern int atrans_remove(addr32_t);
 extern int atrans_lookup(addr32_t, addr48_t);
-extern int atrans_wait_timeout(suseconds_t);
+extern int atrans_lookup_timeout(addr32_t, suseconds_t, addr48_t);
 
 #endif
Index: uspace/srv/net/inetsrv/inet_link.c
===================================================================
--- uspace/srv/net/inetsrv/inet_link.c	(revision 96e368a61482194923fef78ac804b0906e9668b9)
+++ uspace/srv/net/inetsrv/inet_link.c	(revision cbfece72626dbcd93661ce58b0575c5602ad9660)
@@ -465,10 +465,8 @@
 	list_foreach(inet_links, link_list, inet_link_t, ilink) {
 		id_list[i++] = ilink->svc_id;
-		log_msg(LOG_DEFAULT, LVL_NOTE, "add link to list");
 	}
 
 	fibril_mutex_unlock(&inet_links_lock);
 
-	log_msg(LOG_DEFAULT, LVL_NOTE, "return %zu links", count);
 	*rid_list = id_list;
 	*rcount = count;
Index: uspace/srv/net/inetsrv/pdu.c
===================================================================
--- uspace/srv/net/inetsrv/pdu.c	(revision 96e368a61482194923fef78ac804b0906e9668b9)
+++ uspace/srv/net/inetsrv/pdu.c	(revision cbfece72626dbcd93661ce58b0575c5602ad9660)
@@ -106,8 +106,8 @@
 {
 	/* Upper bound for fragment offset field */
-	size_t fragoff_limit = 1 << (FF_FRAGOFF_h - FF_FRAGOFF_l);
+	size_t fragoff_limit = 1 << (FF_FRAGOFF_h - FF_FRAGOFF_l + 1);
 	
 	/* Verify that total size of datagram is within reasonable bounds */
-	if (offs + packet->size > FRAG_OFFS_UNIT * fragoff_limit)
+	if (packet->size > FRAG_OFFS_UNIT * fragoff_limit)
 		return ELIMIT;
 	
Index: uspace/srv/net/inetsrv/reass.c
===================================================================
--- uspace/srv/net/inetsrv/reass.c	(revision 96e368a61482194923fef78ac804b0906e9668b9)
+++ uspace/srv/net/inetsrv/reass.c	(revision cbfece72626dbcd93661ce58b0575c5602ad9660)
@@ -196,4 +196,6 @@
 		return ENOMEM;
 
+	memcpy(data_copy, packet->data, packet->size);
+
 	frag->packet = *packet;
 	frag->packet.data = data_copy;
@@ -216,5 +218,5 @@
 			break;
 
-		link = link->next;
+		link = list_next(link, &rdg->frags);
 	}
 
@@ -240,15 +242,20 @@
 	assert(!list_empty(&rdg->frags));
 
+	link = list_first(&rdg->frags);
+	assert(link != NULL);
+
+	frag = list_get_instance(link, reass_frag_t,
+	    dgram_link);
+
 	/* First fragment must be at offset zero */
-	frag = list_get_instance(list_first(&rdg->frags), reass_frag_t,
-	    dgram_link);
 	if (frag->packet.offs != 0)
 		return false;
 
 	prev = frag;
+
 	while (true) {
-		link = frag->dgram_link.next;
+		link = list_next(link, &rdg->frags);
 		if (link == NULL)
-			return false;
+			break;
 
 		/* Each next fragment must follow immediately or overlap */
@@ -288,4 +295,5 @@
 	uint8_t proto;
 	reass_frag_t *frag;
+	int rc;
 
 	/*
@@ -307,5 +315,5 @@
 
 	/* Upper bound for fragment offset field */
-	fragoff_limit = 1 << (FF_FRAGOFF_h - FF_FRAGOFF_l);
+	fragoff_limit = 1 << (FF_FRAGOFF_h - FF_FRAGOFF_l + 1);
 
 	/* Verify that total size of datagram is within reasonable bounds */
@@ -343,5 +351,7 @@
 	}
 
-	return inet_recv_dgram_local(&dgram, proto);
+	rc = inet_recv_dgram_local(&dgram, proto);
+	free(dgram.data);
+	return rc;
 }
 
Index: uspace/srv/net/tcp/tqueue.c
===================================================================
--- uspace/srv/net/tcp/tqueue.c	(revision 96e368a61482194923fef78ac804b0906e9668b9)
+++ uspace/srv/net/tcp/tqueue.c	(revision cbfece72626dbcd93661ce58b0575c5602ad9660)
@@ -59,8 +59,6 @@
 static void tcp_tqueue_timer_clear(tcp_conn_t *conn);
 
-#include <stdio.h>
 int tcp_tqueue_init(tcp_tqueue_t *tqueue, tcp_conn_t *conn)
 {
-	printf("tcp_tqueue_init\n");
 	tqueue->conn = conn;
 	tqueue->timer = fibril_timer_create(&conn->lock);
@@ -80,5 +78,4 @@
 void tcp_tqueue_fini(tcp_tqueue_t *tqueue)
 {
-	printf("tcp_tqueue_fini\n");
 	if (tqueue->timer != NULL) {
 		fibril_timer_destroy(tqueue->timer);
Index: uspace/srv/net/udp/assoc.c
===================================================================
--- uspace/srv/net/udp/assoc.c	(revision 96e368a61482194923fef78ac804b0906e9668b9)
+++ uspace/srv/net/udp/assoc.c	(revision cbfece72626dbcd93661ce58b0575c5602ad9660)
@@ -275,8 +275,8 @@
 
 	rc = udp_transmit_pdu(pdu);
+	udp_pdu_delete(pdu);
+
 	if (rc != EOK)
 		return EIO;
-
-	udp_pdu_delete(pdu);
 
 	return EOK;
@@ -335,4 +335,5 @@
 		/* XXX Generate ICMP error. */
 		/* XXX Might propagate error directly by error return. */
+		udp_msg_delete(msg);
 		return;
 	}
Index: uspace/srv/net/udp/udp_type.h
===================================================================
--- uspace/srv/net/udp/udp_type.h	(revision 96e368a61482194923fef78ac804b0906e9668b9)
+++ uspace/srv/net/udp/udp_type.h	(revision cbfece72626dbcd93661ce58b0575c5602ad9660)
@@ -43,6 +43,5 @@
 #include <inet/addr.h>
 
-#define UDP_FRAGMENT_SIZE 4096
-
+#define UDP_FRAGMENT_SIZE 65535
 
 typedef enum {
