Index: HelenOS.config
===================================================================
--- HelenOS.config	(revision 107f2e0ef3e7f3b7336408a40acd526c8502baf3)
+++ HelenOS.config	(revision cf22adae6847bfd38cc71105b2e33cf57afaf326)
@@ -70,5 +70,4 @@
 @ "pentium4" Pentium 4
 @ "pentium3" Pentium 3
-@ "i486" i486
 @ "core" Core Solo/Duo
 @ "athlon_xp" Athlon XP
Index: Makefile
===================================================================
--- Makefile	(revision 107f2e0ef3e7f3b7336408a40acd526c8502baf3)
+++ Makefile	(revision cf22adae6847bfd38cc71105b2e33cf57afaf326)
@@ -54,5 +54,5 @@
 
 cscope:
-	find abi kernel boot uspace -regex '^.*\.[chsS]$$' | xargs $(CSCOPE) -b -k -u -f$(CSCOPE).out
+	find kernel boot uspace -regex '^.*\.[chsS]$$' | xargs $(CSCOPE) -b -k -u -f$(CSCOPE).out
 
 # Pre-integration build check
Index: abi/include/ipc/event.h
===================================================================
--- abi/include/ipc/event.h	(revision 107f2e0ef3e7f3b7336408a40acd526c8502baf3)
+++ abi/include/ipc/event.h	(revision cf22adae6847bfd38cc71105b2e33cf57afaf326)
@@ -36,5 +36,4 @@
 #define ABI_IPC_EVENT_H_
 
-/** Global events */
 typedef enum event_type {
 	/** New data available in kernel log */
@@ -47,10 +46,4 @@
 } event_type_t;
 
-/** Per-task events. */
-typedef enum event_task_type {
-	EVENT_TASK_STATE_CHANGE = EVENT_END,
-	EVENT_TASK_END
-} event_task_type_t;
-
 #endif
 
Index: abi/include/ipc/methods.h
===================================================================
--- abi/include/ipc/methods.h	(revision 107f2e0ef3e7f3b7336408a40acd526c8502baf3)
+++ abi/include/ipc/methods.h	(revision cf22adae6847bfd38cc71105b2e33cf57afaf326)
@@ -171,16 +171,4 @@
 #define IPC_M_DATA_READ  8
 
-/** Authorize change of recipient's state in a third party task.
- * - ARG1 - user protocol defined data
- * - ARG2 - user protocol defined data
- * - ARG3 - user protocol defined data
- * - ARG5 - sender's phone to the third party task
- *
- * on EOK answer, the recipient must set:
- *
- * - ARG1 - recipient's phone to the third party task
- */
-#define IPC_M_STATE_CHANGE_AUTHORIZE	9
-
 /** Debug the recipient.
  * - ARG1 - specifies the debug method (from udebug_method_t)
@@ -188,5 +176,5 @@
  *
  */
-#define IPC_M_DEBUG 10
+#define IPC_M_DEBUG  9
 
 /** Last system IPC method */
Index: boot/Makefile.common
===================================================================
--- boot/Makefile.common	(revision 107f2e0ef3e7f3b7336408a40acd526c8502baf3)
+++ boot/Makefile.common	(revision cf22adae6847bfd38cc71105b2e33cf57afaf326)
@@ -143,5 +143,4 @@
 	$(USPACE_PATH)/app/blkdump/blkdump \
 	$(USPACE_PATH)/app/bnchmark/bnchmark \
-	$(USPACE_PATH)/app/devctl/devctl \
 	$(USPACE_PATH)/app/dltest/dltest \
 	$(USPACE_PATH)/app/dltest2/dltest2 \
Index: kernel/arch/ia32/Makefile.inc
===================================================================
--- kernel/arch/ia32/Makefile.inc	(revision 107f2e0ef3e7f3b7336408a40acd526c8502baf3)
+++ kernel/arch/ia32/Makefile.inc	(revision cf22adae6847bfd38cc71105b2e33cf57afaf326)
@@ -64,8 +64,4 @@
 endif
 
-ifeq ($(PROCESSOR),i486)
-	CMN2 = -march=i486
-endif
-
 ifeq ($(PROCESSOR),core)
 	CMN2 = -march=prescott
Index: kernel/arch/ia32/include/asm.h
===================================================================
--- kernel/arch/ia32/include/asm.h	(revision 107f2e0ef3e7f3b7336408a40acd526c8502baf3)
+++ kernel/arch/ia32/include/asm.h	(revision cf22adae6847bfd38cc71105b2e33cf57afaf326)
@@ -311,5 +311,4 @@
 }
 
-#ifndef PROCESSOR_i486
 /** Write to MSR */
 NO_TRACE static inline void write_msr(uint32_t msr, uint64_t value)
@@ -336,5 +335,4 @@
 	return ((uint64_t) dx << 32) | ax;
 }
-#endif
 
 
Index: kernel/arch/ia32/include/atomic.h
===================================================================
--- kernel/arch/ia32/include/atomic.h	(revision 107f2e0ef3e7f3b7336408a40acd526c8502baf3)
+++ kernel/arch/ia32/include/atomic.h	(revision cf22adae6847bfd38cc71105b2e33cf57afaf326)
@@ -121,7 +121,5 @@
 	asm volatile (
 		"0:\n"
-#ifndef PROCESSOR_i486
 		"pause\n"        /* Pentium 4's HT love this instruction */
-#endif
 		"mov %[count], %[tmp]\n"
 		"testl %[tmp], %[tmp]\n"
Index: kernel/arch/ia32/include/cycle.h
===================================================================
--- kernel/arch/ia32/include/cycle.h	(revision 107f2e0ef3e7f3b7336408a40acd526c8502baf3)
+++ kernel/arch/ia32/include/cycle.h	(revision cf22adae6847bfd38cc71105b2e33cf57afaf326)
@@ -40,7 +40,4 @@
 NO_TRACE static inline uint64_t get_cycle(void)
 {
-#ifdef PROCESSOR_i486
-	return 0;
-#else
 	uint64_t v;
 	
@@ -51,5 +48,4 @@
 	
 	return v;
-#endif
 }
 
Index: kernel/arch/ia32/src/asm.S
===================================================================
--- kernel/arch/ia32/src/asm.S	(revision 107f2e0ef3e7f3b7336408a40acd526c8502baf3)
+++ kernel/arch/ia32/src/asm.S	(revision cf22adae6847bfd38cc71105b2e33cf57afaf326)
@@ -405,11 +405,5 @@
 	xorl %eax, %eax
 	cmpl $(GDT_SELECTOR(KTEXT_DES)), ISTATE_OFFSET_CS(%esp)
-#ifdef PROCESSOR_i486
-	jz 0f
-	movl %eax, %ebp
-0:
-#else
 	cmovnzl %eax, %ebp
-#endif
 
 	movl %ebp, ISTATE_OFFSET_EBP_FRAME(%esp)
Index: kernel/arch/ia32/src/boot/boot.S
===================================================================
--- kernel/arch/ia32/src/boot/boot.S	(revision 107f2e0ef3e7f3b7336408a40acd526c8502baf3)
+++ kernel/arch/ia32/src/boot/boot.S	(revision cf22adae6847bfd38cc71105b2e33cf57afaf326)
@@ -97,4 +97,20 @@
 	pm_status $status_prot
 	
+	movl $(INTEL_CPUID_LEVEL), %eax
+	cpuid
+	cmp $0x0, %eax  /* any function > 0? */
+	jbe pse_unsupported
+	
+	movl $(INTEL_CPUID_STANDARD), %eax
+	cpuid
+	bt $(INTEL_PSE), %edx
+	jc pse_supported
+	
+	pse_unsupported:
+		
+		pm_error $err_pse
+	
+	pse_supported:
+	
 #include "vesa_prot.inc"
 	
@@ -124,71 +140,4 @@
 		jmp hlt0
 
-/** Calculate unmapped address of the end of the kernel. */
-calc_end_of_kernel:
-	movl $hardcoded_load_address, %edi
-	andl $0x7fffffff, %edi
-	movl (%edi), %esi
-	andl $0x7fffffff, %esi
-	
-	movl $hardcoded_ktext_size, %edi
-	andl $0x7fffffff, %edi
-	addl (%edi), %esi
-	andl $0x7fffffff, %esi
-	
-	movl $hardcoded_kdata_size, %edi
-	andl $0x7fffffff, %edi
-	addl (%edi), %esi
-	andl $0x7fffffff, %esi
-	movl %esi, end_of_kernel
-	ret
-
-/** Find free 2M (+4k for alignment) region where to store page tables */
-find_mem_for_pt:
-	/* Check if multiboot info is present */
-	cmpl $0x2BADB002, grub_eax
-	je check_multiboot_map
-	ret
-check_multiboot_map:
-	/* Copy address of the multiboot info to ebx */
-	movl grub_ebx, %ebx
-	/* Check if memory map flag is present */
-	movl (%ebx), %edx
-	andl $(1 << 6), %edx
-	jnz use_multiboot_map
-	ret
-use_multiboot_map:
-	/* Copy address of the memory map to edx */
-	movl 48(%ebx), %edx
-	movl %edx, %ecx
-	addl 44(%ebx), %ecx
-	/* Find a free region at least 2M in size */
-	check_memmap_loop:
-		/* Is this a free region? */
-		cmp $1, 20(%edx)
-		jnz next_region
-		/* Check size */
-		cmp $0, 16(%edx)
-		jnz next_region
-		cmpl $(2 * 1024 * 1024 + 4 * 1024), 12(%edx)
-		jbe next_region
-		cmp $0, 8(%edx)
-		jz found_region
-	next_region:
-		cmp %ecx, %edx
-		jbe next_region_do
-		ret
-	next_region_do:
-		addl (%edx), %edx
-		addl $4, %edx
-		jmp check_memmap_loop
-	found_region:
-		/* Use end of the found region */
-		mov 4(%edx), %ecx
-		add 12(%edx), %ecx
-		sub $(2 * 1024 * 1024), %ecx
-		mov %ecx, free_area
-	ret
-		
-
 /** Setup mapping for the kernel.
  *
@@ -199,54 +148,16 @@
 .global map_kernel
 map_kernel:
-	/* Paging features */
 	movl %cr4, %ecx
+	orl $(1 << 4), %ecx      /* PSE on */
 	andl $(~(1 << 5)), %ecx  /* PAE off */
 	movl %ecx, %cr4
 	
-	call calc_end_of_kernel
-	call find_mem_for_pt
-	mov end_of_kernel, %esi
-	mov free_area, %ecx
-	cmpl %esi, %ecx
-	jbe use_end_of_kernel
-	mov %ecx, %esi
-	/* Align address down to 4k */
-	andl $(~4095), %esi
-use_end_of_kernel:
-	
-	/* Align address to 4k */
-	addl $4095, %esi
-	andl $(~4095), %esi
-	
-	/* Allocate space for page tables*/	
-	movl %esi, pt_loc
-	movl $ballocs, %edi
-	andl $0x7fffffff, %edi
-	movl %esi, (%edi)
-	addl $4, %edi
-	movl $(2*1024*1024), (%edi)
-	
-	/* Fill page tables */
-	xorl %ecx, %ecx
-	xorl %ebx, %ebx
-	
-	floop_pt:
-		movl $((1 << 1) | (1 << 0)), %eax
-		orl %ebx, %eax
-		movl %eax, (%esi, %ecx, 4)
-		addl $(4 * 1024), %ebx
-		
-		incl %ecx
-		cmpl $(512 * 1024), %ecx
-		jl floop_pt
-	
-	/* Fill page directory */
 	movl $(page_directory + 0), %esi
 	movl $(page_directory + 2048), %edi
 	xorl %ecx, %ecx
-	movl pt_loc, %ebx
+	xorl %ebx, %ebx
 	
 	floop:
-		movl $((1 << 1) | (1 << 0)), %eax
+		movl $((1 << 7) | (1 << 1) | (1 << 0)), %eax
 		orl %ebx, %eax
 		/* Mapping 0x00000000 + %ecx * 4M => 0x00000000 + %ecx * 4M */
@@ -254,5 +165,5 @@
 		/* Mapping 0x80000000 + %ecx * 4M => 0x00000000 + %ecx * 4M */
 		movl %eax, (%edi, %ecx, 4)
-		addl $(4 * 1024), %ebx
+		addl $(4 * 1024 * 1024), %ebx
 		
 		incl %ecx
@@ -612,11 +523,4 @@
 
 grub_ebx:
-	.long 0
-
-pt_loc:
-	.long 0
-end_of_kernel:
-	.long 0
-free_area:
 	.long 0
 
Index: kernel/arch/ia32/src/cpu/cpu.c
===================================================================
--- kernel/arch/ia32/src/cpu/cpu.c	(revision 107f2e0ef3e7f3b7336408a40acd526c8502baf3)
+++ kernel/arch/ia32/src/cpu/cpu.c	(revision cf22adae6847bfd38cc71105b2e33cf57afaf326)
@@ -118,11 +118,9 @@
 		);
 	}
-
-#ifndef PROCESSOR_i486
+	
 	if (CPU->arch.fi.bits.sep) {
 		/* Setup fast SYSENTER/SYSEXIT syscalls */
 		syscall_setup_cpu();
 	}
-#endif
 }
 
Index: kernel/arch/ia32/src/proc/scheduler.c
===================================================================
--- kernel/arch/ia32/src/proc/scheduler.c	(revision 107f2e0ef3e7f3b7336408a40acd526c8502baf3)
+++ kernel/arch/ia32/src/proc/scheduler.c	(revision cf22adae6847bfd38cc71105b2e33cf57afaf326)
@@ -60,10 +60,8 @@
 	uintptr_t kstk = (uintptr_t) &THREAD->kstack[STACK_SIZE];
 	
-#ifndef PROCESSOR_i486
 	if (CPU->arch.fi.bits.sep) {
 		/* Set kernel stack for CP3 -> CPL0 switch via SYSENTER */
 		write_msr(IA32_MSR_SYSENTER_ESP, kstk - sizeof(istate_t));
 	}
-#endif
 	
 	/* Set kernel stack for CPL3 -> CPL0 switch via interrupt */
Index: kernel/arch/ia32/src/syscall.c
===================================================================
--- kernel/arch/ia32/src/syscall.c	(revision 107f2e0ef3e7f3b7336408a40acd526c8502baf3)
+++ kernel/arch/ia32/src/syscall.c	(revision cf22adae6847bfd38cc71105b2e33cf57afaf326)
@@ -39,5 +39,4 @@
 #include <arch/pm.h>
 
-#ifndef PROCESSOR_i486
 /** Enable & setup support for SYSENTER/SYSEXIT */
 void syscall_setup_cpu(void)
@@ -50,5 +49,4 @@
 	write_msr(IA32_MSR_SYSENTER_EIP, (uint32_t) sysenter_handler);
 }
-#endif
 
 /** @}
Index: kernel/generic/include/console/console.h
===================================================================
--- kernel/generic/include/console/console.h	(revision 107f2e0ef3e7f3b7336408a40acd526c8502baf3)
+++ kernel/generic/include/console/console.h	(revision cf22adae6847bfd38cc71105b2e33cf57afaf326)
@@ -63,5 +63,5 @@
 
 extern void klog_init(void);
-extern void klog_update(void *);
+extern void klog_update(void);
 
 extern wchar_t getc(indev_t *indev);
Index: kernel/generic/include/ipc/event.h
===================================================================
--- kernel/generic/include/ipc/event.h	(revision 107f2e0ef3e7f3b7336408a40acd526c8502baf3)
+++ kernel/generic/include/ipc/event.h	(revision cf22adae6847bfd38cc71105b2e33cf57afaf326)
@@ -41,7 +41,5 @@
 #include <ipc/ipc.h>
 
-struct task;
-
-typedef void (*event_callback_t)(void *);
+typedef void (*event_callback_t)(void);
 
 /** Event notification structure. */
@@ -63,9 +61,6 @@
 
 extern void event_init(void);
-extern void event_task_init(struct task *);
 extern void event_cleanup_answerbox(answerbox_t *);
 extern void event_set_unmask_callback(event_type_t, event_callback_t);
-extern void event_task_set_unmask_callback(struct task *, event_task_type_t,
-    event_callback_t);
 
 #define event_notify_0(e, m) \
@@ -82,21 +77,6 @@
 	event_notify((e), (m), (a1), (a2), (a3), (a4), (a5))
 
-#define event_task_notify_0(t, e, m) \
-	event_task_notify((t), (e), (m), 0, 0, 0, 0, 0)
-#define event_task_notify_1(t, e, m, a1) \
-	event_task_notify((t), (e), (m), (a1), 0, 0, 0, 0)
-#define event_task_notify_2(t, e, m, a1, a2) \
-	event_task_notify((t), (e), (m), (a1), (a2), 0, 0, 0)
-#define event_task_notify_3(t, e, m, a1, a2, a3) \
-	event_task_notify((t), (e), (m), (a1), (a2), (a3), 0, 0)
-#define event_task_notify_4(t, e, m, a1, a2, a3, a4) \
-	event_task_notify((t), (e), (m), (a1), (a2), (a3), (a4), 0)
-#define event_task_notify_5(t, e, m, a1, a2, a3, a4, a5) \
-	event_task_notify((t), (e), (m), (a1), (a2), (a3), (a4), (a5))
-
 extern int event_notify(event_type_t, bool, sysarg_t, sysarg_t, sysarg_t,
     sysarg_t, sysarg_t);
-extern int event_task_notify(struct task *, event_task_type_t, bool, sysarg_t, sysarg_t,
-    sysarg_t, sysarg_t, sysarg_t);
 
 extern sysarg_t sys_event_subscribe(sysarg_t, sysarg_t);
Index: kernel/generic/include/ipc/ipc.h
===================================================================
--- kernel/generic/include/ipc/ipc.h	(revision 107f2e0ef3e7f3b7336408a40acd526c8502baf3)
+++ kernel/generic/include/ipc/ipc.h	(revision cf22adae6847bfd38cc71105b2e33cf57afaf326)
@@ -40,5 +40,4 @@
 #include <synch/mutex.h>
 #include <synch/waitq.h>
-#include <typedefs.h>
 
 #define IPC_MAX_PHONES  32
@@ -99,5 +98,5 @@
 	sysarg_t args[IPC_CALL_LEN];
 	/** Task which made or forwarded the call with IPC_FF_ROUTE_FROM_ME. */
-	task_id_t task_id;
+	struct task *task;
 	/** Phone which made or last masqueraded this call. */
 	phone_t *phone;
Index: kernel/generic/include/proc/task.h
===================================================================
--- kernel/generic/include/proc/task.h	(revision 107f2e0ef3e7f3b7336408a40acd526c8502baf3)
+++ kernel/generic/include/proc/task.h	(revision cf22adae6847bfd38cc71105b2e33cf57afaf326)
@@ -38,6 +38,4 @@
 #include <cpu.h>
 #include <ipc/ipc.h>
-#include <ipc/event.h>
-#include <ipc/kbox.h>
 #include <synch/spinlock.h>
 #include <synch/mutex.h>
@@ -55,4 +53,5 @@
 #include <proc/scheduler.h>
 #include <udebug/udebug.h>
+#include <ipc/kbox.h>
 #include <mm/as.h>
 #include <abi/sysinfo.h>
@@ -94,6 +93,6 @@
 	phone_t phones[IPC_MAX_PHONES];
 	stats_ipc_t ipc_info;   /**< IPC statistics */
-	list_t sync_boxes;      /**< List of synchronous answerboxes. */
-	event_t events[EVENT_TASK_END - EVENT_END];
+	/** List of synchronous answerboxes. */
+	list_t sync_boxes;
 	
 #ifdef CONFIG_UDEBUG
Index: kernel/generic/src/console/console.c
===================================================================
--- kernel/generic/src/console/console.c	(revision 107f2e0ef3e7f3b7336408a40acd526c8502baf3)
+++ kernel/generic/src/console/console.c	(revision cf22adae6847bfd38cc71105b2e33cf57afaf326)
@@ -248,5 +248,5 @@
 }
 
-void klog_update(void *event)
+void klog_update(void)
 {
 	if (!atomic_get(&klog_inited))
@@ -327,5 +327,5 @@
 	/* Force notification on newline */
 	if (ch == '\n')
-		klog_update(NULL);
+		klog_update();
 }
 
@@ -358,5 +358,5 @@
 		free(data);
 	} else
-		klog_update(NULL);
+		klog_update();
 	
 	return size;
Index: kernel/generic/src/ipc/event.c
===================================================================
--- kernel/generic/src/ipc/event.c	(revision 107f2e0ef3e7f3b7336408a40acd526c8502baf3)
+++ kernel/generic/src/ipc/event.c	(revision cf22adae6847bfd38cc71105b2e33cf57afaf326)
@@ -40,5 +40,4 @@
 #include <synch/spinlock.h>
 #include <console/console.h>
-#include <proc/task.h>
 #include <memstr.h>
 #include <errno.h>
@@ -48,28 +47,4 @@
 static event_t events[EVENT_END];
 
-static void event_initialize(event_t *event)
-{
-	spinlock_initialize(&event->lock, "event.lock");
-	event->answerbox = NULL;
-	event->counter = 0;
-	event->imethod = 0;
-	event->masked = false;
-	event->unmask_callback = NULL;
-}
-
-static event_t *evno2event(int evno, task_t *t)
-{
-	ASSERT(evno < EVENT_TASK_END);
-
-	event_t *event;
-
-	if (evno < EVENT_END)
-		event = &events[(event_type_t) evno];
-	else
-		event = &t->events[(event_task_type_t) evno - EVENT_END];
-
-	return event;
-}
-
 /** Initialize kernel events.
  *
@@ -77,14 +52,13 @@
 void event_init(void)
 {
-	for (unsigned int i = 0; i < EVENT_END; i++)
-		event_initialize(evno2event(i, NULL));
-}
-
-void event_task_init(task_t *task)
-{
-	for (unsigned int i = EVENT_END; i < EVENT_TASK_END; i++)
-		event_initialize(evno2event(i, task));
-}
-
+	for (unsigned int i = 0; i < EVENT_END; i++) {
+		spinlock_initialize(&events[i].lock, "event.lock");
+		events[i].answerbox = NULL;
+		events[i].counter = 0;
+		events[i].imethod = 0;
+		events[i].masked = false;
+		events[i].unmask_callback = NULL;
+	}
+}
 
 /** Unsubscribe kernel events associated with an answerbox
@@ -109,11 +83,4 @@
 }
 
-static void _event_set_unmask_callback(event_t *event, event_callback_t callback)
-{
-	spinlock_lock(&event->lock);
-	event->unmask_callback = callback;
-	spinlock_unlock(&event->lock);
-}
-
 /** Define a callback function for the event unmask event.
  *
@@ -127,59 +94,7 @@
 	ASSERT(evno < EVENT_END);
 	
-	_event_set_unmask_callback(evno2event(evno, NULL), callback);
-}
-
-void event_task_set_unmask_callback(task_t *task, event_task_type_t evno,
-    event_callback_t callback)
-{
-	ASSERT(evno >= (int) EVENT_END);
-	ASSERT(evno < EVENT_TASK_END);
-		
-	_event_set_unmask_callback(evno2event(evno, task), callback);
-}
-
-static int event_enqueue(event_t *event, bool mask, sysarg_t a1, sysarg_t a2,
-    sysarg_t a3, sysarg_t a4, sysarg_t a5)
-{
-	int res;
-
-	spinlock_lock(&event->lock);
-	
-	if (event->answerbox != NULL) {
-		if (!event->masked) {
-			call_t *call = ipc_call_alloc(FRAME_ATOMIC);
-			
-			if (call) {
-				call->flags |= IPC_CALL_NOTIF;
-				call->priv = ++event->counter;
-				
-				IPC_SET_IMETHOD(call->data, event->imethod);
-				IPC_SET_ARG1(call->data, a1);
-				IPC_SET_ARG2(call->data, a2);
-				IPC_SET_ARG3(call->data, a3);
-				IPC_SET_ARG4(call->data, a4);
-				IPC_SET_ARG5(call->data, a5);
-				
-				call->data.task_id = TASK ? TASK->taskid : 0;
-				
-				irq_spinlock_lock(&event->answerbox->irq_lock, true);
-				list_append(&call->link, &event->answerbox->irq_notifs);
-				irq_spinlock_unlock(&event->answerbox->irq_lock, true);
-				
-				waitq_wakeup(&event->answerbox->wq, WAKEUP_FIRST);
-				
-				if (mask)
-					event->masked = true;
-				
-				res = EOK;
-			} else
-				res = ENOMEM;
-		} else
-			res = EBUSY;
-	} else
-		res = ENOENT;
-	
-	spinlock_unlock(&event->lock);
-	return res;
+	spinlock_lock(&events[evno].lock);
+	events[evno].unmask_callback = callback;
+	spinlock_unlock(&events[evno].lock);
 }
 
@@ -208,34 +123,43 @@
 	ASSERT(evno < EVENT_END);
 	
-	return event_enqueue(evno2event(evno, NULL), mask, a1, a2, a3, a4, a5);
-}
-
-/** Send per-task kernel notification event
- *
- * @param task Destination task.
- * @param evno Event type.
- * @param mask Mask further notifications after a successful
- *             sending.
- * @param a1   First argument.
- * @param a2   Second argument.
- * @param a3   Third argument.
- * @param a4   Fourth argument.
- * @param a5   Fifth argument.
- *
- * @return EOK if notification was successfully sent.
- * @return ENOMEM if the notification IPC message failed to allocate.
- * @return EBUSY if the notifications of the given type are
- *         currently masked.
- * @return ENOENT if the notifications of the given type are
- *         currently not subscribed.
- *
- */
-int event_task_notify(task_t *task, event_task_type_t evno, bool mask,
-    sysarg_t a1, sysarg_t a2, sysarg_t a3, sysarg_t a4, sysarg_t a5)
-{
-	ASSERT(evno >= (int) EVENT_END);
-	ASSERT(evno < EVENT_TASK_END);
-	
-	return event_enqueue(evno2event(evno, task), mask, a1, a2, a3, a4, a5);
+	spinlock_lock(&events[evno].lock);
+	
+	int ret;
+	
+	if (events[evno].answerbox != NULL) {
+		if (!events[evno].masked) {
+			call_t *call = ipc_call_alloc(FRAME_ATOMIC);
+			
+			if (call) {
+				call->flags |= IPC_CALL_NOTIF;
+				call->priv = ++events[evno].counter;
+				
+				IPC_SET_IMETHOD(call->data, events[evno].imethod);
+				IPC_SET_ARG1(call->data, a1);
+				IPC_SET_ARG2(call->data, a2);
+				IPC_SET_ARG3(call->data, a3);
+				IPC_SET_ARG4(call->data, a4);
+				IPC_SET_ARG5(call->data, a5);
+				
+				irq_spinlock_lock(&events[evno].answerbox->irq_lock, true);
+				list_append(&call->link, &events[evno].answerbox->irq_notifs);
+				irq_spinlock_unlock(&events[evno].answerbox->irq_lock, true);
+				
+				waitq_wakeup(&events[evno].answerbox->wq, WAKEUP_FIRST);
+				
+				if (mask)
+					events[evno].masked = true;
+				
+				ret = EOK;
+			} else
+				ret = ENOMEM;
+		} else
+			ret = EBUSY;
+	} else
+		ret = ENOENT;
+	
+	spinlock_unlock(&events[evno].lock);
+	
+	return ret;
 }
 
@@ -252,21 +176,23 @@
  *
  */
-static int event_subscribe(event_t *event, sysarg_t imethod,
+static int event_subscribe(event_type_t evno, sysarg_t imethod,
     answerbox_t *answerbox)
 {
+	ASSERT(evno < EVENT_END);
+	
+	spinlock_lock(&events[evno].lock);
+	
 	int res;
-
-	spinlock_lock(&event->lock);
-	
-	if (event->answerbox == NULL) {
-		event->answerbox = answerbox;
-		event->imethod = imethod;
-		event->counter = 0;
-		event->masked = false;
+	
+	if (events[evno].answerbox == NULL) {
+		events[evno].answerbox = answerbox;
+		events[evno].imethod = imethod;
+		events[evno].counter = 0;
+		events[evno].masked = false;
 		res = EOK;
 	} else
 		res = EEXISTS;
 	
-	spinlock_unlock(&event->lock);
+	spinlock_unlock(&events[evno].lock);
 	
 	return res;
@@ -278,10 +204,12 @@
  *
  */
-static void event_unmask(event_t *event)
-{
-	spinlock_lock(&event->lock);
-	event->masked = false;
-	event_callback_t callback = event->unmask_callback;
-	spinlock_unlock(&event->lock);
+static void event_unmask(event_type_t evno)
+{
+	ASSERT(evno < EVENT_END);
+	
+	spinlock_lock(&events[evno].lock);
+	events[evno].masked = false;
+	event_callback_t callback = events[evno].unmask_callback;
+	spinlock_unlock(&events[evno].lock);
 	
 	/*
@@ -290,5 +218,5 @@
 	 */
 	if (callback != NULL)
-		callback(event);
+		callback();
 }
 
@@ -307,9 +235,9 @@
 sysarg_t sys_event_subscribe(sysarg_t evno, sysarg_t imethod)
 {
-	if (evno >= EVENT_TASK_END)
+	if (evno >= EVENT_END)
 		return ELIMIT;
 	
-	return (sysarg_t) event_subscribe(evno2event(evno, TASK),
-	    (sysarg_t) imethod, &TASK->answerbox);
+	return (sysarg_t) event_subscribe((event_type_t) evno, (sysarg_t)
+	    imethod, &TASK->answerbox);
 }
 
@@ -329,9 +257,8 @@
 sysarg_t sys_event_unmask(sysarg_t evno)
 {
-	if (evno >= EVENT_TASK_END)
+	if (evno >= EVENT_END)
 		return ELIMIT;
 	
-	event_unmask(evno2event(evno, TASK));
-
+	event_unmask((event_type_t) evno);
 	return EOK;
 }
Index: kernel/generic/src/ipc/ipc.c
===================================================================
--- kernel/generic/src/ipc/ipc.c	(revision 107f2e0ef3e7f3b7336408a40acd526c8502baf3)
+++ kernel/generic/src/ipc/ipc.c	(revision cf22adae6847bfd38cc71105b2e33cf57afaf326)
@@ -294,5 +294,5 @@
 		atomic_inc(&phone->active_calls);
 		call->data.phone = phone;
-		call->data.task_id = TASK->taskid;
+		call->data.task = TASK;
 	}
 	
@@ -406,5 +406,5 @@
 			call->caller_phone = call->data.phone;
 		call->data.phone = newphone;
-		call->data.task_id = TASK->taskid;
+		call->data.task = TASK;
 	}
 	
Index: kernel/generic/src/ipc/sysipc.c
===================================================================
--- kernel/generic/src/ipc/sysipc.c	(revision 107f2e0ef3e7f3b7336408a40acd526c8502baf3)
+++ kernel/generic/src/ipc/sysipc.c	(revision cf22adae6847bfd38cc71105b2e33cf57afaf326)
@@ -44,5 +44,4 @@
 #include <ipc/irq.h>
 #include <ipc/ipcrsc.h>
-#include <ipc/event.h>
 #include <ipc/kbox.h>
 #include <synch/waitq.h>
@@ -54,5 +53,4 @@
 #include <mm/as.h>
 #include <print.h>
-#include <macros.h>
 
 /**
@@ -136,5 +134,4 @@
 	case IPC_M_DATA_WRITE:
 	case IPC_M_DATA_READ:
-	case IPC_M_STATE_CHANGE_AUTHORIZE:
 		return true;
 	default:
@@ -167,5 +164,4 @@
 	case IPC_M_DATA_WRITE:
 	case IPC_M_DATA_READ:
-	case IPC_M_STATE_CHANGE_AUTHORIZE:
 		return true;
 	default:
@@ -253,7 +249,6 @@
 			/* The connection was accepted */
 			phone_connect(phoneid, &answer->sender->answerbox);
-			/* Set 'task ID' as arg3 and arg4 of response */
-			IPC_SET_ARG3(answer->data, LOWER32(TASK->taskid));
-			IPC_SET_ARG4(answer->data, UPPER32(TASK->taskid));
+			/* Set 'task hash' as arg4 of response */
+			IPC_SET_ARG4(answer->data, (sysarg_t) TASK);
 			/* Set 'phone hash' as arg5 of response */
 			IPC_SET_ARG5(answer->data,
@@ -339,50 +334,4 @@
 		free(answer->buffer);
 		answer->buffer = NULL;
-	} else if (IPC_GET_IMETHOD(*olddata) == IPC_M_STATE_CHANGE_AUTHORIZE) {
-		if (!IPC_GET_RETVAL(answer->data)) {
-			/* The recipient authorized the change of state. */
-			phone_t *recipient_phone;
-			task_t *other_task_s;
-			task_t *other_task_r;
-			int rc;
-
-			rc = phone_get(IPC_GET_ARG1(answer->data),
-			    &recipient_phone);
-			if (rc != EOK) {
-				IPC_SET_RETVAL(answer->data, ENOENT);
-				return ENOENT;
-			}
-
-			mutex_lock(&recipient_phone->lock);
-			if (recipient_phone->state != IPC_PHONE_CONNECTED) {
-				mutex_unlock(&recipient_phone->lock);
-				IPC_SET_RETVAL(answer->data, EINVAL);
-				return EINVAL;
-			}
-
-			other_task_r = recipient_phone->callee->task;
-			other_task_s = (task_t *) IPC_GET_ARG5(*olddata);
-
-			/*
-			 * See if both the sender and the recipient meant the
-			 * same third party task.
-			 */
-			if (other_task_r != other_task_s) {
-				IPC_SET_RETVAL(answer->data, EINVAL);
-				rc = EINVAL;
-			} else {
-				rc = event_task_notify_5(other_task_r,
-				    EVENT_TASK_STATE_CHANGE, false,
-				    IPC_GET_ARG1(*olddata),
-				    IPC_GET_ARG2(*olddata),
-				    IPC_GET_ARG3(*olddata),
-				    LOWER32(olddata->task_id),
-				    UPPER32(olddata->task_id));
-				IPC_SET_RETVAL(answer->data, rc);
-			}
-
-			mutex_unlock(&recipient_phone->lock);
-			return rc;
-		}
 	}
 	
@@ -507,25 +456,4 @@
 		}
 		
-		break;
-	}
-	case IPC_M_STATE_CHANGE_AUTHORIZE: {
-		phone_t *sender_phone;
-		task_t *other_task_s;
-
-		if (phone_get(IPC_GET_ARG5(call->data), &sender_phone) != EOK)
-			return ENOENT;
-
-		mutex_lock(&sender_phone->lock);
-		if (sender_phone->state != IPC_PHONE_CONNECTED) {
-			mutex_unlock(&sender_phone->lock);
-			return EINVAL;
-		}
-
-		other_task_s = sender_phone->callee->task;
-
-		mutex_unlock(&sender_phone->lock);
-
-		/* Remember the third party task hash. */
-		IPC_SET_ARG5(call->data, (sysarg_t) other_task_s);
 		break;
 	}
Index: kernel/generic/src/proc/task.c
===================================================================
--- kernel/generic/src/proc/task.c	(revision 107f2e0ef3e7f3b7336408a40acd526c8502baf3)
+++ kernel/generic/src/proc/task.c	(revision cf22adae6847bfd38cc71105b2e33cf57afaf326)
@@ -50,5 +50,4 @@
 #include <ipc/ipc.h>
 #include <ipc/ipcrsc.h>
-#include <ipc/event.h>
 #include <print.h>
 #include <errno.h>
@@ -58,4 +57,5 @@
 #include <syscall/copy.h>
 #include <macros.h>
+#include <ipc/event.h>
 
 /** Spinlock protecting the tasks_tree AVL tree. */
@@ -201,6 +201,4 @@
 	task->ipc_info.irq_notif_received = 0;
 	task->ipc_info.forwarded = 0;
-
-	event_task_init(task);
 	
 #ifdef CONFIG_UDEBUG
Index: uspace/Makefile
===================================================================
--- uspace/Makefile	(revision 107f2e0ef3e7f3b7336408a40acd526c8502baf3)
+++ uspace/Makefile	(revision cf22adae6847bfd38cc71105b2e33cf57afaf326)
@@ -37,5 +37,4 @@
 	app/blkdump \
 	app/bnchmark \
-	app/devctl \
 	app/edit \
 	app/ext2info \
Index: uspace/app/bdsh/exec.c
===================================================================
--- uspace/app/bdsh/exec.c	(revision 107f2e0ef3e7f3b7336408a40acd526c8502baf3)
+++ uspace/app/bdsh/exec.c	(revision cf22adae6847bfd38cc71105b2e33cf57afaf326)
@@ -40,5 +40,4 @@
 #include <str_error.h>
 #include <errno.h>
-#include <vfs/vfs.h>
 
 #include "config.h"
@@ -100,6 +99,6 @@
 	char *tmp;
 	int rc, retval, i;
-	int file_handles[3];
-	int *file_handles_p[4];
+	fdi_node_t file_nodes[3];
+	fdi_node_t *file_nodes_p[4];
 	FILE *files[3];
 
@@ -112,14 +111,14 @@
 	
 	for (i = 0; i < 3 && files[i] != NULL; i++) {
-		if (fhandle(files[i], &file_handles[i]) == EOK) {
-			file_handles_p[i] = &file_handles[i];
+		if (fnode(files[i], &file_nodes[i]) == EOK) {
+			file_nodes_p[i] = &file_nodes[i];
 		}
 		else {
-			file_handles_p[i] = NULL;
+			file_nodes_p[i] = NULL;
 		}
 	}
-	file_handles_p[i] = NULL;
+	file_nodes_p[i] = NULL;
 
-	rc = task_spawnvf(&tid, tmp, (const char **) argv, file_handles_p);
+	rc = task_spawnvf(&tid, tmp, (const char **) argv, file_nodes_p);
 	free(tmp);
 
Index: pace/app/devctl/Makefile
===================================================================
--- uspace/app/devctl/Makefile	(revision 107f2e0ef3e7f3b7336408a40acd526c8502baf3)
+++ 	(revision )
@@ -1,35 +1,0 @@
-#
-# Copyright (c) 2011 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.
-#
-
-USPACE_PREFIX = ../..
-BINARY = devctl
-
-SOURCES = \
-	devctl.c
-
-include $(USPACE_PREFIX)/Makefile.common
Index: pace/app/devctl/devctl.c
===================================================================
--- uspace/app/devctl/devctl.c	(revision 107f2e0ef3e7f3b7336408a40acd526c8502baf3)
+++ 	(revision )
@@ -1,111 +1,0 @@
-/*
- * Copyright (c) 2011 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 devctl
- * @{
- */
-/** @file Control device framework (devman server).
- */
-
-#include <devman.h>
-#include <errno.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <sys/typefmt.h>
-
-#define NAME "devctl"
-
-#define MAX_NAME_LENGTH 1024
-
-static int fun_tree_print(devman_handle_t funh, int lvl)
-{
-	char name[MAX_NAME_LENGTH];
-	devman_handle_t devh;
-	devman_handle_t *cfuns;
-	size_t count, i;
-	int rc;
-	int j;
-
-	for (j = 0; j < lvl; j++)
-		printf("    ");
-
-	rc = devman_fun_get_name(funh, name, MAX_NAME_LENGTH);
-	if (rc != EOK) {
-		str_cpy(name, MAX_NAME_LENGTH, "unknown");
-		return ENOMEM;
-	}
-
-	if (name[0] == '\0')
-		str_cpy(name, MAX_NAME_LENGTH, "/");
-
-	printf("%s (%" PRIun ")\n", name, funh);
-
-	rc = devman_fun_get_child(funh, &devh);
-	if (rc == ENOENT)
-		return EOK;
-
-	if (rc != EOK) {
-		printf(NAME ": Failed getting child device for function "
-		    "%s.\n", "xxx");
-		return rc;
-	}
-
-	rc = devman_dev_get_functions(devh, &cfuns, &count);
-	if (rc != EOK) {
-		printf(NAME ": Failed getting list of functions for "
-		    "device %s.\n", "xxx");
-		return rc;
-	}
-
-	for (i = 0; i < count; i++)
-		fun_tree_print(cfuns[i], lvl + 1);
-
-	free(cfuns);
-	return EOK;
-}
-
-int main(int argc, char *argv[])
-{
-	devman_handle_t root_fun;
-	int rc;
-
-	rc = devman_fun_get_handle("/", &root_fun, 0);
-	if (rc != EOK) {
-		printf(NAME ": Error resolving root function.\n");
-		return 1;
-	}
-
-	rc = fun_tree_print(root_fun, 0);
-	if (rc != EOK)
-		return 1;
-
-	return 0;
-}
-
-/** @}
- */
Index: uspace/app/lsusb/main.c
===================================================================
--- uspace/app/lsusb/main.c	(revision 107f2e0ef3e7f3b7336408a40acd526c8502baf3)
+++ uspace/app/lsusb/main.c	(revision cf22adae6847bfd38cc71105b2e33cf57afaf326)
@@ -81,5 +81,5 @@
 		}
 		char path[MAX_PATH_LENGTH];
-		rc = devman_fun_get_path(dev_handle, path, MAX_PATH_LENGTH);
+		rc = devman_get_device_path(dev_handle, path, MAX_PATH_LENGTH);
 		if (rc != EOK) {
 			continue;
@@ -120,5 +120,5 @@
 		}
 		char path[MAX_PATH_LENGTH];
-		rc = devman_fun_get_path(hc_handle, path, MAX_PATH_LENGTH);
+		rc = devman_get_device_path(hc_handle, path, MAX_PATH_LENGTH);
 		if (rc != EOK) {
 			printf(NAME ": Error resolving path of HC with SID %"
Index: uspace/app/mkbd/main.c
===================================================================
--- uspace/app/mkbd/main.c	(revision 107f2e0ef3e7f3b7336408a40acd526c8502baf3)
+++ uspace/app/mkbd/main.c	(revision cf22adae6847bfd38cc71105b2e33cf57afaf326)
@@ -240,5 +240,5 @@
 	
 	char path[MAX_PATH_LENGTH];
-	rc = devman_fun_get_path(dev_handle, path, MAX_PATH_LENGTH);
+	rc = devman_get_device_path(dev_handle, path, MAX_PATH_LENGTH);
 	if (rc != EOK) {
 		return ENOMEM;
Index: uspace/app/tester/hw/serial/serial1.c
===================================================================
--- uspace/app/tester/hw/serial/serial1.c	(revision 107f2e0ef3e7f3b7336408a40acd526c8502baf3)
+++ uspace/app/tester/hw/serial/serial1.c	(revision cf22adae6847bfd38cc71105b2e33cf57afaf326)
@@ -72,5 +72,5 @@
 	
 	devman_handle_t handle;
-	int res = devman_fun_get_handle("/hw/pci0/00:01.0/com1/a", &handle,
+	int res = devman_device_get_handle("/hw/pci0/00:01.0/com1/a", &handle,
 	    IPC_FLAG_BLOCKING);
 	if (res != EOK)
Index: uspace/app/trace/trace.c
===================================================================
--- uspace/app/trace/trace.c	(revision 107f2e0ef3e7f3b7336408a40acd526c8502baf3)
+++ uspace/app/trace/trace.c	(revision cf22adae6847bfd38cc71105b2e33cf57afaf326)
@@ -50,5 +50,4 @@
 #include <sys/types.h>
 #include <sys/typefmt.h>
-#include <vfs/vfs.h>
 
 #include <libc.h>
@@ -587,21 +586,21 @@
 
 	/* Send default files */
-	int *files[4];
-	int fd_stdin;
-	int fd_stdout;
-	int fd_stderr;
-	
-	if ((stdin != NULL) && (fhandle(stdin, &fd_stdin) == EOK))
-		files[0] = &fd_stdin;
+	fdi_node_t *files[4];
+	fdi_node_t stdin_node;
+	fdi_node_t stdout_node;
+	fdi_node_t stderr_node;
+	
+	if ((stdin != NULL) && (fnode(stdin, &stdin_node) == EOK))
+		files[0] = &stdin_node;
 	else
 		files[0] = NULL;
 	
-	if ((stdout != NULL) && (fhandle(stdout, &fd_stdout) == EOK))
-		files[1] = &fd_stdout;
+	if ((stdout != NULL) && (fnode(stdout, &stdout_node) == EOK))
+		files[1] = &stdout_node;
 	else
 		files[1] = NULL;
 	
-	if ((stderr != NULL) && (fhandle(stderr, &fd_stderr) == EOK))
-		files[2] = &fd_stderr;
+	if ((stderr != NULL) && (fnode(stderr, &stderr_node) == EOK))
+		files[2] = &stderr_node;
 	else
 		files[2] = NULL;
@@ -762,4 +761,6 @@
 	o = oper_new("open", 2, arg_def, V_INT_ERRNO, 0, resp_def);
 	proto_add_oper(p, VFS_IN_OPEN, o);
+	o = oper_new("open_node", 4, arg_def, V_INT_ERRNO, 0, resp_def);
+	proto_add_oper(p, VFS_IN_OPEN_NODE, o);
 	o = oper_new("read", 1, arg_def, V_ERRNO, 1, resp_def);
 	proto_add_oper(p, VFS_IN_READ, o);
Index: uspace/lib/c/arch/ia32/Makefile.common
===================================================================
--- uspace/lib/c/arch/ia32/Makefile.common	(revision 107f2e0ef3e7f3b7336408a40acd526c8502baf3)
+++ uspace/lib/c/arch/ia32/Makefile.common	(revision cf22adae6847bfd38cc71105b2e33cf57afaf326)
@@ -28,9 +28,5 @@
 
 CLANG_ARCH = i386
-ifeq ($(PROCESSOR),i486)
-GCC_CFLAGS += -march=i486 -fno-omit-frame-pointer
-else
 GCC_CFLAGS += -march=pentium -fno-omit-frame-pointer
-endif
 
 ENDIANESS = LE
Index: uspace/lib/c/arch/ia32/Makefile.inc
===================================================================
--- uspace/lib/c/arch/ia32/Makefile.inc	(revision 107f2e0ef3e7f3b7336408a40acd526c8502baf3)
+++ uspace/lib/c/arch/ia32/Makefile.inc	(revision cf22adae6847bfd38cc71105b2e33cf57afaf326)
@@ -28,5 +28,5 @@
 
 ARCH_SOURCES = \
-	arch/$(UARCH)/src/entry.S \
+	arch/$(UARCH)/src/entry.s \
 	arch/$(UARCH)/src/entryjmp.s \
 	arch/$(UARCH)/src/thread_entry.s \
Index: pace/lib/c/arch/ia32/src/entry.S
===================================================================
--- uspace/lib/c/arch/ia32/src/entry.S	(revision 107f2e0ef3e7f3b7336408a40acd526c8502baf3)
+++ 	(revision )
@@ -1,67 +1,0 @@
-#
-# Copyright (c) 2005 Martin Decky
-# 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.
-#
-
-INTEL_CPUID_STANDARD = 1
-INTEL_SEP = 11
-
-.section .init, "ax"
-
-.org 0
-
-.globl __entry
-
-## User-space task entry point
-#
-# %edi contains the PCB pointer
-#
-__entry:
-	mov %ss, %ax
-	mov %ax, %ds
-	mov %ax, %es
-	mov %ax, %fs
-	# Do not set %gs, it contains descriptor that can see TLS
-
-#ifndef PROCESSOR_i486	
-	# Detect the mechanism used for making syscalls
-	movl $(INTEL_CPUID_STANDARD), %eax
-	cpuid
-	bt $(INTEL_SEP), %edx
-	jnc 0f
-	leal __syscall_fast_func, %eax
-	movl $__syscall_fast, (%eax)
-0:
-#endif
-	#
-	# Create the first stack frame.
-	#
-	pushl $0
-	movl %esp, %ebp
-	
-	# Pass the PCB pointer to __main as the first argument
-	pushl %edi
-	call __main
Index: uspace/lib/c/arch/ia32/src/entry.s
===================================================================
--- uspace/lib/c/arch/ia32/src/entry.s	(revision cf22adae6847bfd38cc71105b2e33cf57afaf326)
+++ uspace/lib/c/arch/ia32/src/entry.s	(revision cf22adae6847bfd38cc71105b2e33cf57afaf326)
@@ -0,0 +1,65 @@
+#
+# Copyright (c) 2005 Martin Decky
+# 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.
+#
+
+INTEL_CPUID_STANDARD = 1
+INTEL_SEP = 11
+
+.section .init, "ax"
+
+.org 0
+
+.globl __entry
+
+## User-space task entry point
+#
+# %edi contains the PCB pointer
+#
+__entry:
+	mov %ss, %ax
+	mov %ax, %ds
+	mov %ax, %es
+	mov %ax, %fs
+	# Do not set %gs, it contains descriptor that can see TLS
+	
+	# Detect the mechanism used for making syscalls
+	movl $(INTEL_CPUID_STANDARD), %eax
+	cpuid
+	bt $(INTEL_SEP), %edx
+	jnc 0f
+	leal __syscall_fast_func, %eax
+	movl $__syscall_fast, (%eax)
+0:
+	#
+	# Create the first stack frame.
+	#
+	pushl $0
+	movl %esp, %ebp
+	
+	# Pass the PCB pointer to __main as the first argument
+	pushl %edi
+	call __main
Index: uspace/lib/c/generic/async.c
===================================================================
--- uspace/lib/c/generic/async.c	(revision 107f2e0ef3e7f3b7336408a40acd526c8502baf3)
+++ uspace/lib/c/generic/async.c	(revision cf22adae6847bfd38cc71105b2e33cf57afaf326)
@@ -112,5 +112,4 @@
 #include <mem.h>
 #include <stdlib.h>
-#include <macros.h>
 #include "private/async.h"
 
@@ -139,5 +138,5 @@
 	link_t link;
 	
-	task_id_t in_task_id;
+	sysarg_t in_task_hash;
 	atomic_t refcnt;
 	void *data;
@@ -151,6 +150,6 @@
 	link_t link;
 	
-	/** Incoming client task ID. */
-	task_id_t in_task_id;
+	/** Incoming client task hash. */
+	sysarg_t in_task_hash;
 	
 	/** Incoming phone hash. */
@@ -204,4 +203,10 @@
 }
 
+void *async_get_client_data(void)
+{
+	assert(fibril_connection);
+	return fibril_connection->client->data;
+}
+
 /** Default fibril function that gets called to handle new connection.
  *
@@ -284,10 +289,8 @@
 {
 	assert(key);
-	assert(keys == 2);
 	assert(item);
 	
 	client_t *client = hash_table_get_instance(item, client_t, link);
-	return (key[0] == LOWER32(client->in_task_id) &&
-	    (key[1] == UPPER32(client->in_task_id)));
+	return (key[0] == client->in_task_hash);
 }
 
@@ -577,91 +580,4 @@
 }
 
-static client_t *async_client_get(task_id_t client_id, bool create)
-{
-	unsigned long key[2] = {
-		LOWER32(client_id),
-		UPPER32(client_id),
-	};
-	client_t *client = NULL;
-
-	futex_down(&async_futex);
-	link_t *lnk = hash_table_find(&client_hash_table, key);
-	if (lnk) {
-		client = hash_table_get_instance(lnk, client_t, link);
-		atomic_inc(&client->refcnt);
-	} else if (create) {
-		client = malloc(sizeof(client_t));
-		if (client) {
-			client->in_task_id = client_id;
-			client->data = async_client_data_create();
-		
-			atomic_set(&client->refcnt, 1);
-			hash_table_insert(&client_hash_table, key, &client->link);
-		}
-	}
-
-	futex_up(&async_futex);
-	return client;
-}
-
-static void async_client_put(client_t *client)
-{
-	bool destroy;
-	unsigned long key[2] = {
-		LOWER32(client->in_task_id),
-		UPPER32(client->in_task_id)
-	};
-	
-	futex_down(&async_futex);
-	
-	if (atomic_predec(&client->refcnt) == 0) {
-		hash_table_remove(&client_hash_table, key, 2);
-		destroy = true;
-	} else
-		destroy = false;
-	
-	futex_up(&async_futex);
-	
-	if (destroy) {
-		if (client->data)
-			async_client_data_destroy(client->data);
-		
-		free(client);
-	}
-}
-
-void *async_get_client_data(void)
-{
-	assert(fibril_connection);
-	return fibril_connection->client->data;
-}
-
-void *async_get_client_data_by_id(task_id_t client_id)
-{
-	client_t *client = async_client_get(client_id, false);
-	if (!client)
-		return NULL;
-	if (!client->data) {
-		async_client_put(client);
-		return NULL;
-	}
-
-	return client->data;
-}
-
-void async_put_client_data_by_id(task_id_t client_id)
-{
-	client_t *client = async_client_get(client_id, false);
-
-	assert(client);
-	assert(client->data);
-
-	/* Drop the reference we got in async_get_client_data_by_hash(). */
-	async_client_put(client);
-
-	/* Drop our own reference we got at the beginning of this function. */
-	async_client_put(client);
-}
-
 /** Wrapper for client connection fibril.
  *
@@ -682,4 +598,6 @@
 	 */
 	fibril_connection = (connection_t *) arg;
+	
+	futex_down(&async_futex);
 	
 	/*
@@ -688,11 +606,30 @@
 	 * hash in a new tracking structure.
 	 */
-
-	client_t *client = async_client_get(fibril_connection->in_task_id, true);
-	if (!client) {
-		ipc_answer_0(fibril_connection->callid, ENOMEM);
-		return 0;
-	}
-
+	
+	unsigned long key = fibril_connection->in_task_hash;
+	link_t *lnk = hash_table_find(&client_hash_table, &key);
+	
+	client_t *client;
+	
+	if (lnk) {
+		client = hash_table_get_instance(lnk, client_t, link);
+		atomic_inc(&client->refcnt);
+	} else {
+		client = malloc(sizeof(client_t));
+		if (!client) {
+			ipc_answer_0(fibril_connection->callid, ENOMEM);
+			futex_up(&async_futex);
+			return 0;
+		}
+		
+		client->in_task_hash = fibril_connection->in_task_hash;
+		client->data = async_client_data_create();
+		
+		atomic_set(&client->refcnt, 1);
+		hash_table_insert(&client_hash_table, &key, &client->link);
+	}
+	
+	futex_up(&async_futex);
+	
 	fibril_connection->client = client;
 	
@@ -706,5 +643,22 @@
 	 * Remove the reference for this client task connection.
 	 */
-	async_client_put(client);
+	bool destroy;
+	
+	futex_down(&async_futex);
+	
+	if (atomic_predec(&client->refcnt) == 0) {
+		hash_table_remove(&client_hash_table, &key, 1);
+		destroy = true;
+	} else
+		destroy = false;
+	
+	futex_up(&async_futex);
+	
+	if (destroy) {
+		if (client->data)
+			async_client_data_destroy(client->data);
+		
+		free(client);
+	}
 	
 	/*
@@ -712,5 +666,5 @@
 	 */
 	futex_down(&async_futex);
-	unsigned long key = fibril_connection->in_phone_hash;
+	key = fibril_connection->in_phone_hash;
 	hash_table_remove(&conn_hash_table, &key, 1);
 	futex_up(&async_futex);
@@ -746,5 +700,5 @@
  * particular fibrils.
  *
- * @param in_task_id    Identification of the incoming connection.
+ * @param in_task_hash  Identification of the incoming connection.
  * @param in_phone_hash Identification of the incoming connection.
  * @param callid        Hash of the opening IPC_M_CONNECT_ME_TO call.
@@ -760,5 +714,5 @@
  *
  */
-fid_t async_new_connection(task_id_t in_task_id, sysarg_t in_phone_hash,
+fid_t async_new_connection(sysarg_t in_task_hash, sysarg_t in_phone_hash,
     ipc_callid_t callid, ipc_call_t *call,
     async_client_conn_t cfibril, void *carg)
@@ -772,5 +726,5 @@
 	}
 	
-	conn->in_task_id = in_task_id;
+	conn->in_task_hash = in_task_hash;
 	conn->in_phone_hash = in_phone_hash;
 	list_initialize(&conn->msg_queue);
@@ -831,5 +785,5 @@
 	case IPC_M_CONNECT_ME_TO:
 		/* Open new connection with fibril, etc. */
-		async_new_connection(call->in_task_id, IPC_GET_ARG5(*call),
+		async_new_connection(call->in_task_hash, IPC_GET_ARG5(*call),
 		    callid, call, client_connection, NULL);
 		return;
@@ -979,5 +933,5 @@
 {
 	if (!hash_table_create(&client_hash_table, CLIENT_HASH_TABLE_BUCKETS,
-	    2, &client_hash_table_ops))
+	    1, &client_hash_table_ops))
 		abort();
 	
@@ -1472,17 +1426,13 @@
 		return ENOENT;
 	
-	task_id_t task_id;
-	sysarg_t task_id_lo;
-	sysarg_t task_id_hi;
+	sysarg_t task_hash;
 	sysarg_t phone_hash;
 	int rc = async_req_3_5(exch, IPC_M_CONNECT_TO_ME, arg1, arg2, arg3,
-	    NULL, NULL, &task_id_lo, &task_id_hi, &phone_hash);
+	    NULL, NULL, NULL, &task_hash, &phone_hash);
 	if (rc != EOK)
 		return rc;
-
-	task_id = (task_id_t) MERGE_LOUP32(task_id_lo, task_id_hi);
 	
 	if (client_receiver != NULL)
-		async_new_connection(task_id, phone_hash, 0, NULL,
+		async_new_connection(task_hash, phone_hash, 0, NULL,
 		    client_receiver, carg);
 	
@@ -2479,37 +2429,4 @@
 }
 
-int async_state_change_start(async_exch_t *exch, sysarg_t arg1, sysarg_t arg2,
-    sysarg_t arg3, async_exch_t *other_exch)
-{
-	return async_req_5_0(exch, IPC_M_STATE_CHANGE_AUTHORIZE,
-	    arg1, arg2, arg3, 0, other_exch->phone);
-}
-
-bool async_state_change_receive(ipc_callid_t *callid, sysarg_t *arg1,
-    sysarg_t *arg2, sysarg_t *arg3)
-{
-	assert(callid);
-
-	ipc_call_t call;
-	*callid = async_get_call(&call);
-
-	if (IPC_GET_IMETHOD(call) != IPC_M_STATE_CHANGE_AUTHORIZE)
-		return false;
-	
-	if (arg1)
-		*arg1 = IPC_GET_ARG1(call);
-	if (arg2)
-		*arg2 = IPC_GET_ARG2(call);
-	if (arg3)
-		*arg3 = IPC_GET_ARG3(call);
-
-	return true;
-}
-
-int async_state_change_finalize(ipc_callid_t callid, async_exch_t *other_exch)
-{
-	return ipc_answer_1(callid, EOK, other_exch->phone);
-}
-
 /** @}
  */
Index: uspace/lib/c/generic/devman.c
===================================================================
--- uspace/lib/c/generic/devman.c	(revision 107f2e0ef3e7f3b7336408a40acd526c8502baf3)
+++ uspace/lib/c/generic/devman.c	(revision cf22adae6847bfd38cc71105b2e33cf57afaf326)
@@ -1,5 +1,5 @@
 /*
  * Copyright (c) 2007 Josef Cejka
- * Copyright (c) 2011 Jiri Svoboda
+ * Copyright (c) 2009 Jiri Svoboda
  * Copyright (c) 2010 Lenka Trochtova
  * All rights reserved.
@@ -195,5 +195,5 @@
 	
 	exch = devman_exchange_begin(DEVMAN_DRIVER);
-	async_connect_to_me(exch, 0, 0, 0, conn, NULL);
+	async_connect_to_me(exch, 0, 0, 0, NULL, NULL);
 	devman_exchange_end(exch);
 	
@@ -342,5 +342,5 @@
 }
 
-int devman_fun_get_handle(const char *pathname, devman_handle_t *handle,
+int devman_device_get_handle(const char *pathname, devman_handle_t *handle,
     unsigned int flags)
 {
@@ -383,132 +383,5 @@
 }
 
-static int devman_get_str_internal(sysarg_t method, sysarg_t arg1, char *buf,
-    size_t buf_size)
-{
-	async_exch_t *exch;
-	ipc_call_t dreply;
-	size_t act_size;
-	sysarg_t dretval;
-	
-	exch = devman_exchange_begin_blocking(LOC_PORT_CONSUMER);
-	
-	ipc_call_t answer;
-	aid_t req = async_send_1(exch, method, arg1, &answer);
-	aid_t dreq = async_data_read(exch, buf, buf_size - 1, &dreply);
-	async_wait_for(dreq, &dretval);
-	
-	devman_exchange_end(exch);
-	
-	if (dretval != EOK) {
-		async_wait_for(req, NULL);
-		return dretval;
-	}
-	
-	sysarg_t retval;
-	async_wait_for(req, &retval);
-	
-	if (retval != EOK)
-		return retval;
-	
-	act_size = IPC_GET_ARG2(dreply);
-	assert(act_size <= buf_size - 1);
-	buf[act_size] = '\0';
-	
-	return EOK;
-}
-
-int devman_fun_get_path(devman_handle_t handle, char *buf, size_t buf_size)
-{
-	return devman_get_str_internal(DEVMAN_FUN_GET_PATH, handle, buf,
-	    buf_size);
-}
-
-int devman_fun_get_name(devman_handle_t handle, char *buf, size_t buf_size)
-{
-	return devman_get_str_internal(DEVMAN_FUN_GET_NAME, handle, buf,
-	    buf_size);
-}
-
-static int devman_get_handles_once(sysarg_t method, sysarg_t arg1,
-    devman_handle_t *handle_buf, size_t buf_size, size_t *act_size)
-{
-	async_exch_t *exch = devman_exchange_begin_blocking(DEVMAN_CLIENT);
-
-	ipc_call_t answer;
-	aid_t req = async_send_1(exch, method, arg1, &answer);
-	int rc = async_data_read_start(exch, handle_buf, buf_size);
-	
-	devman_exchange_end(exch);
-	
-	if (rc != EOK) {
-		async_wait_for(req, NULL);
-		return rc;
-	}
-	
-	sysarg_t retval;
-	async_wait_for(req, &retval);
-	
-	if (retval != EOK) {
-		return retval;
-	}
-	
-	*act_size = IPC_GET_ARG1(answer);
-	return EOK;
-}
-
-/** Get list of handles.
- *
- * Returns an allocated array of handles.
- *
- * @param method	IPC method
- * @param arg1		IPC argument 1
- * @param data		Place to store pointer to array of handles
- * @param count		Place to store number of handles
- * @return 		EOK on success or negative error code
- */
-static int devman_get_handles_internal(sysarg_t method, sysarg_t arg1,
-    devman_handle_t **data, size_t *count)
-{
-	devman_handle_t *handles;
-	size_t act_size;
-	size_t alloc_size;
-	int rc;
-
-	*data = NULL;
-	act_size = 0;	/* silence warning */
-
-	rc = devman_get_handles_once(method, arg1, NULL, 0,
-	    &act_size);
-	if (rc != EOK)
-		return rc;
-
-	alloc_size = act_size;
-	handles = malloc(alloc_size);
-	if (handles == NULL)
-		return ENOMEM;
-
-	while (true) {
-		rc = devman_get_handles_once(method, arg1, handles, alloc_size,
-		    &act_size);
-		if (rc != EOK)
-			return rc;
-
-		if (act_size <= alloc_size)
-			break;
-
-		alloc_size *= 2;
-		free(handles);
-
-		handles = malloc(alloc_size);
-		if (handles == NULL)
-			return ENOMEM;
-	}
-
-	*count = act_size / sizeof(devman_handle_t);
-	*data = handles;
-	return EOK;
-}
-
-int devman_fun_get_child(devman_handle_t funh, devman_handle_t *devh)
+int devman_get_device_path(devman_handle_t handle, char *path, size_t path_size)
 {
 	async_exch_t *exch = devman_exchange_begin(DEVMAN_CLIENT);
@@ -516,16 +389,45 @@
 		return ENOMEM;
 	
-	sysarg_t retval = async_req_1_1(exch, DEVMAN_FUN_GET_CHILD,
-	    funh, devh);
-	
-	devman_exchange_end(exch);
-	return (int) retval;
-}
-
-int devman_dev_get_functions(devman_handle_t devh, devman_handle_t **funcs,
-    size_t *count)
-{
-	return devman_get_handles_internal(DEVMAN_DEV_GET_FUNCTIONS,
-	    devh, funcs, count);
+	ipc_call_t answer;
+	aid_t req = async_send_1(exch, DEVMAN_DEVICE_GET_DEVICE_PATH,
+	    handle, &answer);
+	
+	ipc_call_t data_request_call;
+	aid_t data_request = async_data_read(exch, path, path_size,
+	    &data_request_call);
+	
+	devman_exchange_end(exch);
+	
+	if (data_request == 0) {
+		async_wait_for(req, NULL);
+		return ENOMEM;
+	}
+	
+	sysarg_t data_request_rc;
+	async_wait_for(data_request, &data_request_rc);
+	
+	sysarg_t opening_request_rc;
+	async_wait_for(req, &opening_request_rc);
+	
+	if (data_request_rc != EOK) {
+		/* Prefer the return code of the opening request. */
+		if (opening_request_rc != EOK)
+			return (int) opening_request_rc;
+		else
+			return (int) data_request_rc;
+	}
+	
+	if (opening_request_rc != EOK)
+		return (int) opening_request_rc;
+	
+	/* To be on the safe-side. */
+	path[path_size - 1] = 0;
+	size_t transferred_size = IPC_GET_ARG2(data_request_call);
+	if (transferred_size >= path_size)
+		return ELIMIT;
+	
+	/* Terminate the string (trailing 0 not send over IPC). */
+	path[transferred_size] = 0;
+	return EOK;
 }
 
Index: uspace/lib/c/generic/event.c
===================================================================
--- uspace/lib/c/generic/event.c	(revision 107f2e0ef3e7f3b7336408a40acd526c8502baf3)
+++ uspace/lib/c/generic/event.c	(revision cf22adae6847bfd38cc71105b2e33cf57afaf326)
@@ -54,10 +54,4 @@
 }
 
-int event_task_subscribe(event_task_type_t evno, sysarg_t imethod)
-{
-	return __SYSCALL2(SYS_EVENT_SUBSCRIBE, (sysarg_t) evno,
-	    (sysarg_t) imethod);
-}
-
 /** Unmask event notifications.
  *
@@ -72,9 +66,4 @@
 }
 
-int event_task_unmask(event_task_type_t evno)
-{
-	return __SYSCALL1(SYS_EVENT_UNMASK, (sysarg_t) evno);
-}
-
 /** @}
  */
Index: uspace/lib/c/generic/io/io.c
===================================================================
--- uspace/lib/c/generic/io/io.c	(revision 107f2e0ef3e7f3b7336408a40acd526c8502baf3)
+++ uspace/lib/c/generic/io/io.c	(revision cf22adae6847bfd38cc71105b2e33cf57afaf326)
@@ -101,8 +101,8 @@
 static LIST_INITIALIZE(files);
 
-void __stdio_init(int filc)
+void __stdio_init(int filc, fdi_node_t *filv[])
 {
 	if (filc > 0) {
-		stdin = fdopen(0, "r");
+		stdin = fopen_node(filv[0], "r");
 	} else {
 		stdin = &stdin_null;
@@ -111,5 +111,5 @@
 	
 	if (filc > 1) {
-		stdout = fdopen(1, "w");
+		stdout = fopen_node(filv[1], "w");
 	} else {
 		stdout = &stdout_klog;
@@ -118,5 +118,5 @@
 	
 	if (filc > 2) {
-		stderr = fdopen(2, "w");
+		stderr = fopen_node(filv[2], "w");
 	} else {
 		stderr = &stderr_klog;
@@ -285,4 +285,36 @@
 }
 
+FILE *fopen_node(fdi_node_t *node, const char *mode)
+{
+	int flags;
+	if (!parse_mode(mode, &flags))
+		return NULL;
+	
+	/* Open file. */
+	FILE *stream = malloc(sizeof(FILE));
+	if (stream == NULL) {
+		errno = ENOMEM;
+		return NULL;
+	}
+	
+	stream->fd = open_node(node, flags);
+	if (stream->fd < 0) {
+		/* errno was set by open_node() */
+		free(stream);
+		return NULL;
+	}
+	
+	stream->error = false;
+	stream->eof = false;
+	stream->klog = false;
+	stream->sess = NULL;
+	stream->need_sync = false;
+	_setvbuf(stream);
+	
+	list_append(&stream->link, &files);
+	
+	return stream;
+}
+
 int fclose(FILE *stream)
 {
@@ -748,10 +780,8 @@
 }
 
-int fhandle(FILE *stream, int *handle)
-{
-	if (stream->fd >= 0) {
-		*handle = stream->fd;
-		return EOK;
-	}
+int fnode(FILE *stream, fdi_node_t *node)
+{
+	if (stream->fd >= 0)
+		return fd_node(stream->fd, node);
 	
 	return ENOENT;
Index: uspace/lib/c/generic/io/printf_core.c
===================================================================
--- uspace/lib/c/generic/io/printf_core.c	(revision 107f2e0ef3e7f3b7336408a40acd526c8502baf3)
+++ uspace/lib/c/generic/io/printf_core.c	(revision cf22adae6847bfd38cc71105b2e33cf57afaf326)
@@ -206,5 +206,5 @@
 	}
 	
-	return (int) (counter);
+	return (int) (counter + 1);
 }
 
@@ -244,5 +244,5 @@
 	}
 	
-	return (int) (counter);
+	return (int) (counter + 1);
 }
 
Index: uspace/lib/c/generic/libc.c
===================================================================
--- uspace/lib/c/generic/libc.c	(revision 107f2e0ef3e7f3b7336408a40acd526c8502baf3)
+++ uspace/lib/c/generic/libc.c	(revision cf22adae6847bfd38cc71105b2e33cf57afaf326)
@@ -91,9 +91,9 @@
 		argc = 0;
 		argv = NULL;
-		__stdio_init(0);
+		__stdio_init(0, NULL);
 	} else {
 		argc = __pcb->argc;
 		argv = __pcb->argv;
-		__stdio_init(__pcb->filc);
+		__stdio_init(__pcb->filc, __pcb->filv);
 		(void) chdir(__pcb->cwd);
 	}
Index: uspace/lib/c/generic/loader.c
===================================================================
--- uspace/lib/c/generic/loader.c	(revision 107f2e0ef3e7f3b7336408a40acd526c8502baf3)
+++ uspace/lib/c/generic/loader.c	(revision cf22adae6847bfd38cc71105b2e33cf57afaf326)
@@ -256,28 +256,38 @@
  *
  */
-int loader_set_files(loader_t *ldr, int * const files[])
-{
+int loader_set_files(loader_t *ldr, fdi_node_t *const files[])
+{
+	/*
+	 * Serialize the arguments into a single array. First
+	 * compute size of the buffer needed.
+	 */
+	fdi_node_t *const *ap = files;
+	size_t count = 0;
+	while (*ap != NULL) {
+		count++;
+		ap++;
+	}
+	
+	fdi_node_t *files_buf;
+	files_buf = (fdi_node_t *) malloc(count * sizeof(fdi_node_t));
+	if (files_buf == NULL)
+		return ENOMEM;
+	
+	/* Fill the buffer */
+	size_t i;
+	for (i = 0; i < count; i++)
+		files_buf[i] = *files[i];
+	
 	/* Send serialized files to the loader */
 	async_exch_t *exch = async_exchange_begin(ldr->sess);
-	async_exch_t *vfs_exch = vfs_exchange_begin();
-	
-	int i;
-	for (i = 0; files[i]; i++);
-
-	ipc_call_t answer;
-	aid_t req = async_send_1(exch, LOADER_SET_FILES, i, &answer);
-
-	sysarg_t rc = EOK;
-	
-	for (i = 0; files[i]; i++) {
-		rc = async_state_change_start(exch, VFS_PASS_HANDLE, *files[i],
-		    0, vfs_exch); 
-		if (rc != EOK)
-			break;
-	}
-	
-	vfs_exchange_end(vfs_exch);
-	async_exchange_end(exch);
-
+	
+	ipc_call_t answer;
+	aid_t req = async_send_0(exch, LOADER_SET_FILES, &answer);
+	sysarg_t rc = async_data_write_start(exch, (void *) files_buf,
+	    count * sizeof(fdi_node_t));
+	
+	async_exchange_end(exch);
+	free(files_buf);
+	
 	if (rc != EOK) {
 		async_wait_for(req, NULL);
Index: uspace/lib/c/generic/loc.c
===================================================================
--- uspace/lib/c/generic/loc.c	(revision 107f2e0ef3e7f3b7336408a40acd526c8502baf3)
+++ uspace/lib/c/generic/loc.c	(revision cf22adae6847bfd38cc71105b2e33cf57afaf326)
@@ -315,6 +315,6 @@
 /** Register new service.
  *
- * @param fqsn Fully qualified service name
- * @param sid  Output: ID of new service
+ * @param fqsn	Fully qualified service name
+ * @param sid	Output: ID of new service
  *
  */
Index: uspace/lib/c/generic/private/async.h
===================================================================
--- uspace/lib/c/generic/private/async.h	(revision 107f2e0ef3e7f3b7336408a40acd526c8502baf3)
+++ uspace/lib/c/generic/private/async.h	(revision cf22adae6847bfd38cc71105b2e33cf57afaf326)
@@ -36,5 +36,4 @@
 #define LIBC_PRIVATE_ASYNC_H_
 
-#include <ipc/common.h>
 #include <adt/list.h>
 #include <fibril.h>
Index: uspace/lib/c/generic/private/io.h
===================================================================
--- uspace/lib/c/generic/private/io.h	(revision 107f2e0ef3e7f3b7336408a40acd526c8502baf3)
+++ uspace/lib/c/generic/private/io.h	(revision cf22adae6847bfd38cc71105b2e33cf57afaf326)
@@ -36,5 +36,7 @@
 #define LIBC_PRIVATE_IO_H_
 
-extern void __stdio_init(int);
+#include <vfs/vfs.h>
+
+extern void __stdio_init(int filc, fdi_node_t *filv[]);
 extern void __stdio_done(void);
 
Index: uspace/lib/c/generic/task.c
===================================================================
--- uspace/lib/c/generic/task.c	(revision 107f2e0ef3e7f3b7336408a40acd526c8502baf3)
+++ uspace/lib/c/generic/task.c	(revision cf22adae6847bfd38cc71105b2e33cf57afaf326)
@@ -46,5 +46,4 @@
 #include <libc.h>
 #include "private/ns.h"
-#include <vfs/vfs.h>
 
 task_id_t task_get_id(void)
@@ -103,21 +102,21 @@
 {
 	/* Send default files */
-	int *files[4];
-	int fd_stdin;
-	int fd_stdout;
-	int fd_stderr;
-	
-	if ((stdin != NULL) && (fhandle(stdin, &fd_stdin) == EOK))
-		files[0] = &fd_stdin;
+	fdi_node_t *files[4];
+	fdi_node_t stdin_node;
+	fdi_node_t stdout_node;
+	fdi_node_t stderr_node;
+	
+	if ((stdin != NULL) && (fnode(stdin, &stdin_node) == EOK))
+		files[0] = &stdin_node;
 	else
 		files[0] = NULL;
 	
-	if ((stdout != NULL) && (fhandle(stdout, &fd_stdout) == EOK))
-		files[1] = &fd_stdout;
+	if ((stdout != NULL) && (fnode(stdout, &stdout_node) == EOK))
+		files[1] = &stdout_node;
 	else
 		files[1] = NULL;
 	
-	if ((stderr != NULL) && (fhandle(stderr, &fd_stderr) == EOK))
-		files[2] = &fd_stderr;
+	if ((stderr != NULL) && (fnode(stderr, &stderr_node) == EOK))
+		files[2] = &stderr_node;
 	else
 		files[2] = NULL;
@@ -143,5 +142,5 @@
  */
 int task_spawnvf(task_id_t *id, const char *path, const char *const args[],
-    int *const files[])
+    fdi_node_t *const files[])
 {
 	/* Connect to a program loader. */
Index: uspace/lib/c/generic/vfs/vfs.c
===================================================================
--- uspace/lib/c/generic/vfs/vfs.c	(revision 107f2e0ef3e7f3b7336408a40acd526c8502baf3)
+++ uspace/lib/c/generic/vfs/vfs.c	(revision cf22adae6847bfd38cc71105b2e33cf57afaf326)
@@ -69,5 +69,5 @@
  *
  */
-async_exch_t *vfs_exchange_begin(void)
+static async_exch_t *vfs_exchange_begin(void)
 {
 	fibril_mutex_lock(&vfs_mutex);
@@ -87,5 +87,5 @@
  *
  */
-void vfs_exchange_end(async_exch_t *exch)
+static void vfs_exchange_end(async_exch_t *exch)
 {
 	async_exchange_end(exch);
@@ -329,4 +329,23 @@
 }
 
+int open_node(fdi_node_t *node, int oflag)
+{
+	async_exch_t *exch = vfs_exchange_begin();
+	
+	ipc_call_t answer;
+	aid_t req = async_send_4(exch, VFS_IN_OPEN_NODE, node->fs_handle,
+	    node->service_id, node->index, oflag, &answer);
+	
+	vfs_exchange_end(exch);
+
+	sysarg_t rc;
+	async_wait_for(req, &rc);
+	
+	if (rc != EOK)
+		return (int) rc;
+	
+	return (int) IPC_GET_ARG1(answer);
+}
+
 int close(int fildes)
 {
@@ -800,4 +819,18 @@
 }
 
+int fd_node(int fildes, fdi_node_t *node)
+{
+	struct stat stat;
+	int rc = fstat(fildes, &stat);
+	
+	if (rc == EOK) {
+		node->fs_handle = stat.fs_handle;
+		node->service_id = stat.service_id;
+		node->index = stat.index;
+	}
+	
+	return rc;
+}
+
 int dup2(int oldfd, int newfd)
 {
@@ -815,19 +848,4 @@
 }
 
-int fd_wait(void)
-{
-	async_exch_t *exch = vfs_exchange_begin();
-	
-	sysarg_t ret;
-	sysarg_t rc = async_req_0_1(exch, VFS_IN_WAIT_HANDLE, &ret);
-	
-	vfs_exchange_end(exch);
-	
-	if (rc == EOK)
-		return (int) ret;
-	
-	return (int) rc;
-}
-
 /** @}
  */
Index: uspace/lib/c/include/async.h
===================================================================
--- uspace/lib/c/include/async.h	(revision 107f2e0ef3e7f3b7336408a40acd526c8502baf3)
+++ uspace/lib/c/include/async.h	(revision cf22adae6847bfd38cc71105b2e33cf57afaf326)
@@ -176,5 +176,5 @@
 extern int async_wait_timeout(aid_t, sysarg_t *, suseconds_t);
 
-extern fid_t async_new_connection(task_id_t, sysarg_t, ipc_callid_t,
+extern fid_t async_new_connection(sysarg_t, sysarg_t, ipc_callid_t,
     ipc_call_t *, async_client_conn_t, void *);
 
@@ -186,6 +186,4 @@
 extern void async_set_client_data_destructor(async_client_data_dtor_t);
 extern void *async_get_client_data(void);
-extern void *async_get_client_data_by_id(task_id_t);
-extern void async_put_client_data_by_id(task_id_t);
 
 extern void async_set_client_connection(async_client_conn_t);
@@ -479,10 +477,4 @@
 extern async_sess_t *async_callback_receive_start(exch_mgmt_t, ipc_call_t *);
 
-extern int async_state_change_start(async_exch_t *, sysarg_t, sysarg_t,
-    sysarg_t, async_exch_t *);
-extern bool async_state_change_receive(ipc_callid_t *, sysarg_t *, sysarg_t *,
-    sysarg_t *);
-extern int async_state_change_finalize(ipc_callid_t, async_exch_t *);
-
 #endif
 
Index: uspace/lib/c/include/devman.h
===================================================================
--- uspace/lib/c/include/devman.h	(revision 107f2e0ef3e7f3b7336408a40acd526c8502baf3)
+++ uspace/lib/c/include/devman.h	(revision cf22adae6847bfd38cc71105b2e33cf57afaf326)
@@ -56,11 +56,7 @@
     unsigned int);
 
-extern int devman_fun_get_handle(const char *, devman_handle_t *,
+extern int devman_device_get_handle(const char *, devman_handle_t *,
     unsigned int);
-extern int devman_fun_get_child(devman_handle_t, devman_handle_t *);
-extern int devman_dev_get_functions(devman_handle_t, devman_handle_t **,
-    size_t *);
-extern int devman_fun_get_name(devman_handle_t, char *, size_t);
-extern int devman_fun_get_path(devman_handle_t, char *, size_t);
+extern int devman_get_device_path(devman_handle_t, char *, size_t);
 
 extern int devman_add_device_to_category(devman_handle_t, const char *);
Index: uspace/lib/c/include/event.h
===================================================================
--- uspace/lib/c/include/event.h	(revision 107f2e0ef3e7f3b7336408a40acd526c8502baf3)
+++ uspace/lib/c/include/event.h	(revision cf22adae6847bfd38cc71105b2e33cf57afaf326)
@@ -37,10 +37,7 @@
 
 #include <abi/ipc/event.h>
-#include <libarch/types.h>
 
 extern int event_subscribe(event_type_t, sysarg_t);
-extern int event_task_subscribe(event_task_type_t, sysarg_t);
 extern int event_unmask(event_type_t);
-extern int event_task_unmask(event_task_type_t);
 
 #endif
Index: uspace/lib/c/include/ipc/common.h
===================================================================
--- uspace/lib/c/include/ipc/common.h	(revision 107f2e0ef3e7f3b7336408a40acd526c8502baf3)
+++ uspace/lib/c/include/ipc/common.h	(revision cf22adae6847bfd38cc71105b2e33cf57afaf326)
@@ -39,5 +39,4 @@
 #include <abi/ipc/ipc.h>
 #include <atomic.h>
-#include <task.h>
 
 #define IPC_FLAG_BLOCKING  0x01
@@ -45,5 +44,5 @@
 typedef struct {
 	sysarg_t args[IPC_CALL_LEN];
-	task_id_t in_task_id;
+	sysarg_t in_task_hash;
 	sysarg_t in_phone_hash;
 } ipc_call_t;
Index: uspace/lib/c/include/ipc/devman.h
===================================================================
--- uspace/lib/c/include/ipc/devman.h	(revision 107f2e0ef3e7f3b7336408a40acd526c8502baf3)
+++ uspace/lib/c/include/ipc/devman.h	(revision cf22adae6847bfd38cc71105b2e33cf57afaf326)
@@ -149,8 +149,5 @@
 typedef enum {
 	DEVMAN_DEVICE_GET_HANDLE = IPC_FIRST_USER_METHOD,
-	DEVMAN_DEV_GET_FUNCTIONS,
-	DEVMAN_FUN_GET_CHILD,
-	DEVMAN_FUN_GET_NAME,
-	DEVMAN_FUN_GET_PATH,
+	DEVMAN_DEVICE_GET_DEVICE_PATH,
 	DEVMAN_FUN_SID_TO_HANDLE
 } client_to_devman_t;
Index: uspace/lib/c/include/ipc/vfs.h
===================================================================
--- uspace/lib/c/include/ipc/vfs.h	(revision 107f2e0ef3e7f3b7336408a40acd526c8502baf3)
+++ uspace/lib/c/include/ipc/vfs.h	(revision cf22adae6847bfd38cc71105b2e33cf57afaf326)
@@ -62,4 +62,5 @@
 typedef enum {
 	VFS_IN_OPEN = IPC_FIRST_USER_METHOD,
+	VFS_IN_OPEN_NODE,
 	VFS_IN_READ,
 	VFS_IN_WRITE,
@@ -77,6 +78,5 @@
 	VFS_IN_RENAME,
 	VFS_IN_STAT,
-	VFS_IN_DUP,
-	VFS_IN_WAIT_HANDLE,
+	VFS_IN_DUP
 } vfs_in_request_t;
 
Index: uspace/lib/c/include/loader/loader.h
===================================================================
--- uspace/lib/c/include/loader/loader.h	(revision 107f2e0ef3e7f3b7336408a40acd526c8502baf3)
+++ uspace/lib/c/include/loader/loader.h	(revision cf22adae6847bfd38cc71105b2e33cf57afaf326)
@@ -38,4 +38,5 @@
 
 #include <task.h>
+#include <vfs/vfs.h>
 
 /** Forward declararion */
@@ -49,5 +50,5 @@
 extern int loader_set_pathname(loader_t *, const char *);
 extern int loader_set_args(loader_t *, const char *const[]);
-extern int loader_set_files(loader_t *, int *const[]);
+extern int loader_set_files(loader_t *, fdi_node_t *const[]);
 extern int loader_load_program(loader_t *);
 extern int loader_run(loader_t *);
Index: uspace/lib/c/include/loader/pcb.h
===================================================================
--- uspace/lib/c/include/loader/pcb.h	(revision 107f2e0ef3e7f3b7336408a40acd526c8502baf3)
+++ uspace/lib/c/include/loader/pcb.h	(revision cf22adae6847bfd38cc71105b2e33cf57afaf326)
@@ -38,4 +38,5 @@
 
 #include <sys/types.h>
+#include <vfs/vfs.h>
 
 typedef void (*entry_point_t)(void);
@@ -61,5 +62,7 @@
 	
 	/** Number of preset files. */
-	unsigned int filc;
+	int filc;
+	/** Preset files. */
+	fdi_node_t **filv;
 	
 	/*
Index: uspace/lib/c/include/task.h
===================================================================
--- uspace/lib/c/include/task.h	(revision 107f2e0ef3e7f3b7336408a40acd526c8502baf3)
+++ uspace/lib/c/include/task.h	(revision cf22adae6847bfd38cc71105b2e33cf57afaf326)
@@ -37,4 +37,5 @@
 
 #include <sys/types.h>
+#include <vfs/vfs.h>
 
 typedef uint64_t task_id_t;
@@ -52,5 +53,5 @@
 extern int task_spawnv(task_id_t *, const char *path, const char *const []);
 extern int task_spawnvf(task_id_t *, const char *path, const char *const [],
-    int *const []);
+    fdi_node_t *const []);
 extern int task_spawnl(task_id_t *, const char *path, ...);
 
Index: uspace/lib/c/include/vfs/vfs.h
===================================================================
--- uspace/lib/c/include/vfs/vfs.h	(revision 107f2e0ef3e7f3b7336408a40acd526c8502baf3)
+++ uspace/lib/c/include/vfs/vfs.h	(revision cf22adae6847bfd38cc71105b2e33cf57afaf326)
@@ -40,9 +40,16 @@
 #include <ipc/loc.h>
 #include <stdio.h>
-#include <async.h>
 
-enum vfs_change_state_type {
-	VFS_PASS_HANDLE
-};
+/** Libc version of the VFS triplet.
+ *
+ * Unique identification of a file system node
+ * within a file system instance.
+ *
+ */
+typedef struct {
+	fs_handle_t fs_handle;
+	service_id_t service_id;
+	fs_index_t index;
+} fdi_node_t;
 
 extern char *absolutize(const char *, size_t *);
@@ -52,10 +59,9 @@
 extern int unmount(const char *);
 
-extern int fhandle(FILE *, int *);
+extern int open_node(fdi_node_t *, int);
+extern int fd_node(int, fdi_node_t *);
 
-extern int fd_wait(void);
-
-extern async_exch_t *vfs_exchange_begin(void);
-extern void vfs_exchange_end(async_exch_t *);
+extern FILE *fopen_node(fdi_node_t *, const char *);
+extern int fnode(FILE *, fdi_node_t *);
 
 #endif
Index: uspace/lib/drv/generic/driver.c
===================================================================
--- uspace/lib/drv/generic/driver.c	(revision 107f2e0ef3e7f3b7336408a40acd526c8502baf3)
+++ uspace/lib/drv/generic/driver.c	(revision cf22adae6847bfd38cc71105b2e33cf57afaf326)
@@ -428,16 +428,6 @@
 static void driver_connection(ipc_callid_t iid, ipc_call_t *icall, void *arg)
 {
-	sysarg_t conn_type;
-
-	if (iid == 0) {
-		/* Callback connection from devman */
-		/* XXX Use separate handler for this type of connection */
-		conn_type = DRIVER_DEVMAN;
-	} else {
-		conn_type = IPC_GET_ARG1(*icall);
-	}
-
 	/* Select interface */
-	switch (conn_type) {
+	switch ((sysarg_t) (IPC_GET_ARG1(*icall))) {
 	case DRIVER_DEVMAN:
 		/* Handle request from device manager */
Index: uspace/lib/usb/src/resolve.c
===================================================================
--- uspace/lib/usb/src/resolve.c	(revision 107f2e0ef3e7f3b7336408a40acd526c8502baf3)
+++ uspace/lib/usb/src/resolve.c	(revision cf22adae6847bfd38cc71105b2e33cf57afaf326)
@@ -152,5 +152,5 @@
 		if (str_length(func_start) > 0) {
 			char tmp_path[MAX_DEVICE_PATH ];
-			rc = devman_fun_get_path(dev_handle,
+			rc = devman_get_device_path(dev_handle,
 			    tmp_path, MAX_DEVICE_PATH);
 			if (rc != EOK) {
@@ -173,5 +173,5 @@
 
 	/* First try to get the device handle. */
-	rc = devman_fun_get_handle(path, &dev_handle, 0);
+	rc = devman_device_get_handle(path, &dev_handle, 0);
 	if (rc != EOK) {
 		free(path);
@@ -184,5 +184,5 @@
 		/* Get device handle first. */
 		devman_handle_t tmp_handle;
-		rc = devman_fun_get_handle(path, &tmp_handle, 0);
+		rc = devman_device_get_handle(path, &tmp_handle, 0);
 		if (rc != EOK) {
 			free(path);
Index: uspace/lib/usbvirt/src/device.c
===================================================================
--- uspace/lib/usbvirt/src/device.c	(revision 107f2e0ef3e7f3b7336408a40acd526c8502baf3)
+++ uspace/lib/usbvirt/src/device.c	(revision cf22adae6847bfd38cc71105b2e33cf57afaf326)
@@ -87,5 +87,5 @@
 	
 	devman_handle_t handle;
-	int rc = devman_fun_get_handle(vhc_path, &handle, 0);
+	int rc = devman_device_get_handle(vhc_path, &handle, 0);
 	if (rc != EOK)
 		return rc;
Index: uspace/srv/devman/devman.c
===================================================================
--- uspace/srv/devman/devman.c	(revision 107f2e0ef3e7f3b7336408a40acd526c8502baf3)
+++ uspace/srv/devman/devman.c	(revision cf22adae6847bfd38cc71105b2e33cf57afaf326)
@@ -548,4 +548,14 @@
 
 	fibril_mutex_lock(&driver->driver_mutex);
+	
+	async_exch_t *exch = async_exchange_begin(driver->sess);
+	async_sess_t *sess = async_connect_me_to(EXCHANGE_SERIALIZE, exch,
+	    DRIVER_DEVMAN, 0, 0);
+	async_exchange_end(exch);
+
+	if (!sess) {
+		fibril_mutex_unlock(&driver->driver_mutex);
+		return;
+	}
 
 	/*
@@ -573,5 +583,5 @@
 		fibril_mutex_unlock(&driver->driver_mutex);
 
-		add_device(driver, dev, tree);
+		add_device(sess, driver, dev, tree);
 
 		/*
@@ -593,4 +603,6 @@
 		link = driver->devices.head.next;
 	}
+
+	async_hangup(sess);
 
 	/*
@@ -706,5 +718,6 @@
  * @param node		The device's node in the device tree.
  */
-void add_device(driver_t *drv, dev_node_t *dev, dev_tree_t *tree)
+void add_device(async_sess_t *sess, driver_t *drv, dev_node_t *dev,
+    dev_tree_t *tree)
 {
 	/*
@@ -723,5 +736,5 @@
 	}
 	
-	async_exch_t *exch = async_exchange_begin(drv->sess);
+	async_exch_t *exch = async_exchange_begin(sess);
 	
 	ipc_call_t answer;
@@ -793,7 +806,16 @@
 	fibril_mutex_unlock(&drv->driver_mutex);
 
-	/* Notify the driver about the new device. */
-	if (is_running)
-		add_device(drv, dev, tree);
+	if (is_running) {
+		/* Notify the driver about the new device. */
+		async_exch_t *exch = async_exchange_begin(drv->sess);
+		async_sess_t *sess = async_connect_me_to(EXCHANGE_SERIALIZE, exch,
+		    DRIVER_DEVMAN, 0, 0);
+		async_exchange_end(exch);
+		
+		if (sess) {
+			add_device(sess, drv, dev, tree);
+			async_hangup(sess);
+		}
+	}
 	
 	return true;
@@ -897,35 +919,4 @@
 	return dev;
 }
-
-/** Get list of device functions. */
-int dev_get_functions(dev_tree_t *tree, dev_node_t *dev,
-    devman_handle_t *hdl_buf, size_t buf_size, size_t *act_size)
-{
-	size_t act_cnt;
-	size_t buf_cnt;
-
-	assert(fibril_rwlock_is_locked(&tree->rwlock));
-
-	buf_cnt = buf_size / sizeof(devman_handle_t);
-
-	act_cnt = list_count(&dev->functions);
-	*act_size = act_cnt * sizeof(devman_handle_t);
-
-	if (buf_size % sizeof(devman_handle_t) != 0)
-		return EINVAL;
-
-	size_t pos = 0;
-	list_foreach(dev->functions, item) {
-		fun_node_t *fun =
-		    list_get_instance(item, fun_node_t, dev_functions);
-
-		if (pos < buf_cnt)
-			hdl_buf[pos] = fun->handle;
-		pos++;
-	}
-
-	return EOK;
-}
-
 
 /* Function nodes */
@@ -1154,5 +1145,5 @@
 	char *rel_path = path;
 	char *next_path_elem = NULL;
-	bool cont = (rel_path[1] != '\0');
+	bool cont = true;
 	
 	while (cont && fun != NULL) {
Index: uspace/srv/devman/devman.h
===================================================================
--- uspace/srv/devman/devman.h	(revision 107f2e0ef3e7f3b7336408a40acd526c8502baf3)
+++ uspace/srv/devman/devman.h	(revision cf22adae6847bfd38cc71105b2e33cf57afaf326)
@@ -235,5 +235,5 @@
 extern void add_driver(driver_list_t *, driver_t *);
 extern void attach_driver(dev_node_t *, driver_t *);
-extern void add_device(driver_t *, dev_node_t *, dev_tree_t *);
+extern void add_device(async_sess_t *, driver_t *, dev_node_t *, dev_tree_t *);
 extern bool start_driver(driver_t *);
 
@@ -253,6 +253,4 @@
 extern dev_node_t *find_dev_node(dev_tree_t *tree, devman_handle_t handle);
 extern dev_node_t *find_dev_function(dev_node_t *, const char *);
-extern int dev_get_functions(dev_tree_t *tree, dev_node_t *, devman_handle_t *,
-    size_t, size_t *);
 
 extern fun_node_t *create_fun_node(void);
Index: uspace/srv/devman/main.c
===================================================================
--- uspace/srv/devman/main.c	(revision 107f2e0ef3e7f3b7336408a40acd526c8502baf3)
+++ uspace/srv/devman/main.c	(revision cf22adae6847bfd38cc71105b2e33cf57afaf326)
@@ -497,6 +497,7 @@
 }
 
-/** Get device name. */
-static void devman_fun_get_name(ipc_callid_t iid, ipc_call_t *icall)
+/** Find device path by its handle. */
+static void devman_get_device_path_by_handle(ipc_callid_t iid,
+    ipc_call_t *icall)
 {
 	devman_handle_t handle = IPC_GET_ARG1(*icall);
@@ -522,41 +523,4 @@
 	}
 
-	size_t sent_length = str_size(fun->name);
-	if (sent_length > data_len) {
-		sent_length = data_len;
-	}
-
-	async_data_read_finalize(data_callid, fun->name, sent_length);
-	async_answer_0(iid, EOK);
-
-	free(buffer);
-}
-
-
-/** Get device path. */
-static void devman_fun_get_path(ipc_callid_t iid, ipc_call_t *icall)
-{
-	devman_handle_t handle = IPC_GET_ARG1(*icall);
-
-	fun_node_t *fun = find_fun_node(&device_tree, handle);
-	if (fun == NULL) {
-		async_answer_0(iid, ENOMEM);
-		return;
-	}
-
-	ipc_callid_t data_callid;
-	size_t data_len;
-	if (!async_data_read_receive(&data_callid, &data_len)) {
-		async_answer_0(iid, EINVAL);
-		return;
-	}
-
-	void *buffer = malloc(data_len);
-	if (buffer == NULL) {
-		async_answer_0(data_callid, ENOMEM);
-		async_answer_0(iid, ENOMEM);
-		return;
-	}
-
 	size_t sent_length = str_size(fun->pathname);
 	if (sent_length > data_len) {
@@ -568,78 +532,4 @@
 
 	free(buffer);
-}
-
-static void devman_dev_get_functions(ipc_callid_t iid, ipc_call_t *icall)
-{
-	ipc_callid_t callid;
-	size_t size;
-	size_t act_size;
-	int rc;
-	
-	if (!async_data_read_receive(&callid, &size)) {
-		async_answer_0(callid, EREFUSED);
-		async_answer_0(iid, EREFUSED);
-		return;
-	}
-	
-	fibril_rwlock_read_lock(&device_tree.rwlock);
-	
-	dev_node_t *dev = find_dev_node_no_lock(&device_tree,
-	    IPC_GET_ARG1(*icall));
-	if (dev == NULL) {
-		fibril_rwlock_read_unlock(&device_tree.rwlock);
-		async_answer_0(callid, ENOENT);
-		async_answer_0(iid, ENOENT);
-		return;
-	}
-	
-	devman_handle_t *hdl_buf = (devman_handle_t *) malloc(size);
-	if (hdl_buf == NULL) {
-		fibril_rwlock_read_unlock(&device_tree.rwlock);
-		async_answer_0(callid, ENOMEM);
-		async_answer_0(iid, ENOMEM);
-		return;
-	}
-	
-	rc = dev_get_functions(&device_tree, dev, hdl_buf, size, &act_size);
-	if (rc != EOK) {
-		fibril_rwlock_read_unlock(&device_tree.rwlock);
-		async_answer_0(callid, rc);
-		async_answer_0(iid, rc);
-		return;
-	}
-	
-	fibril_rwlock_read_unlock(&device_tree.rwlock);
-	
-	sysarg_t retval = async_data_read_finalize(callid, hdl_buf, size);
-	free(hdl_buf);
-	
-	async_answer_1(iid, retval, act_size);
-}
-
-
-/** Get handle for child device of a function. */
-static void devman_fun_get_child(ipc_callid_t iid, ipc_call_t *icall)
-{
-	fun_node_t *fun;
-	
-	fibril_rwlock_read_lock(&device_tree.rwlock);
-	
-	fun = find_fun_node(&device_tree, IPC_GET_ARG1(*icall));
-	if (fun == NULL) {
-		fibril_rwlock_read_unlock(&device_tree.rwlock);
-		async_answer_0(iid, ENOENT);
-		return;
-	}
-	
-	if (fun->child == NULL) {
-		fibril_rwlock_read_unlock(&device_tree.rwlock);
-		async_answer_0(iid, ENOENT);
-		return;
-	}
-	
-	async_answer_1(iid, EOK, fun->child->handle);
-	
-	fibril_rwlock_read_unlock(&device_tree.rwlock);
 }
 
@@ -676,15 +566,6 @@
 			devman_function_get_handle(callid, &call);
 			break;
-		case DEVMAN_DEV_GET_FUNCTIONS:
-			devman_dev_get_functions(callid, &call);
-			break;
-		case DEVMAN_FUN_GET_CHILD:
-			devman_fun_get_child(callid, &call);
-			break;
-		case DEVMAN_FUN_GET_NAME:
-			devman_fun_get_name(callid, &call);
-			break;
-		case DEVMAN_FUN_GET_PATH:
-			devman_fun_get_path(callid, &call);
+		case DEVMAN_DEVICE_GET_DEVICE_PATH:
+			devman_get_device_path_by_handle(callid, &call);
 			break;
 		case DEVMAN_FUN_SID_TO_HANDLE:
Index: uspace/srv/hid/input/port/adb_mouse.c
===================================================================
--- uspace/srv/hid/input/port/adb_mouse.c	(revision 107f2e0ef3e7f3b7336408a40acd526c8502baf3)
+++ uspace/srv/hid/input/port/adb_mouse.c	(revision cf22adae6847bfd38cc71105b2e33cf57afaf326)
@@ -42,5 +42,4 @@
 #include <errno.h>
 #include <loc.h>
-#include <stdio.h>
 
 static mouse_dev_t *mouse_dev;
Index: uspace/srv/hw/irc/apic/apic.c
===================================================================
--- uspace/srv/hw/irc/apic/apic.c	(revision 107f2e0ef3e7f3b7336408a40acd526c8502baf3)
+++ uspace/srv/hw/irc/apic/apic.c	(revision cf22adae6847bfd38cc71105b2e33cf57afaf326)
@@ -45,5 +45,4 @@
 #include <errno.h>
 #include <async.h>
-#include <stdio.h>
 
 #define NAME  "apic"
Index: uspace/srv/loader/main.c
===================================================================
--- uspace/srv/loader/main.c	(revision 107f2e0ef3e7f3b7336408a40acd526c8502baf3)
+++ uspace/srv/loader/main.c	(revision cf22adae6847bfd38cc71105b2e33cf57afaf326)
@@ -61,5 +61,4 @@
 #include <elf/elf.h>
 #include <elf/elf_load.h>
-#include <vfs/vfs.h>
 
 #ifdef CONFIG_RTLD
@@ -90,5 +89,9 @@
 
 /** Number of preset files */
-static unsigned int filc = 0;
+static int filc = 0;
+/** Preset files vector */
+static fdi_node_t **filv = NULL;
+/** Buffer holding all preset files */
+static fdi_node_t *fil_buf = NULL;
 
 static elf_info_t prog_info;
@@ -236,23 +239,45 @@
 static void ldr_set_files(ipc_callid_t rid, ipc_call_t *request)
 {
-	size_t count = IPC_GET_ARG1(*request);
-
-	async_exch_t *vfs_exch = vfs_exchange_begin();
-
-	for (filc = 0; filc < count; filc++) {
-		ipc_callid_t callid;
-		int fd;
-
-		if (!async_state_change_receive(&callid, NULL, NULL, NULL)) {
-			async_answer_0(callid, EINVAL);
-			break;
+	fdi_node_t *buf;
+	size_t buf_size;
+	int rc = async_data_write_accept((void **) &buf, false, 0, 0,
+	    sizeof(fdi_node_t), &buf_size);
+	
+	if (rc == EOK) {
+		int count = buf_size / sizeof(fdi_node_t);
+		
+		/*
+		 * Allocate new filv
+		 */
+		fdi_node_t **_filv = (fdi_node_t **) calloc(count + 1, sizeof(fdi_node_t *));
+		if (_filv == NULL) {
+			free(buf);
+			async_answer_0(rid, ENOMEM);
+			return;
 		}
-		async_state_change_finalize(callid, vfs_exch);
-		fd = fd_wait();
-		assert(fd == (int) filc);
-	}
-
-	vfs_exchange_end(vfs_exch);
-
+		
+		/*
+		 * Fill the new filv with argument pointers
+		 */
+		int i;
+		for (i = 0; i < count; i++)
+			_filv[i] = &buf[i];
+		
+		_filv[count] = NULL;
+		
+		/*
+		 * Copy temporary data to global variables
+		 */
+		if (fil_buf != NULL)
+			free(fil_buf);
+		
+		if (filv != NULL)
+			free(filv);
+		
+		filc = count;
+		fil_buf = buf;
+		filv = _filv;
+	}
+	
 	async_answer_0(rid, EOK);
 }
@@ -283,4 +308,5 @@
 	
 	pcb.filc = filc;
+	pcb.filv = filv;
 	
 	if (prog_info.interp == NULL) {
Index: uspace/srv/loc/loc.h
===================================================================
--- uspace/srv/loc/loc.h	(revision 107f2e0ef3e7f3b7336408a40acd526c8502baf3)
+++ uspace/srv/loc/loc.h	(revision cf22adae6847bfd38cc71105b2e33cf57afaf326)
@@ -36,5 +36,4 @@
 #define LOC_H_
 
-#include <ipc/loc.h>
 #include <async.h>
 #include <fibril_synch.h>
Index: uspace/srv/vfs/vfs.c
===================================================================
--- uspace/srv/vfs/vfs.c	(revision 107f2e0ef3e7f3b7336408a40acd526c8502baf3)
+++ uspace/srv/vfs/vfs.c	(revision cf22adae6847bfd38cc71105b2e33cf57afaf326)
@@ -36,8 +36,5 @@
  */
 
-#include <vfs/vfs.h>
 #include <ipc/services.h>
-#include <abi/ipc/event.h>
-#include <event.h>
 #include <ns.h>
 #include <async.h>
@@ -48,12 +45,7 @@
 #include <as.h>
 #include <atomic.h>
-#include <macros.h>
 #include "vfs.h"
 
 #define NAME  "vfs"
-
-enum {
-	VFS_TASK_STATE_CHANGE
-};
 
 static void vfs_connection(ipc_callid_t iid, ipc_call_t *icall, void *arg)
@@ -87,4 +79,7 @@
 		case VFS_IN_OPEN:
 			vfs_open(callid, &call);
+			break;
+		case VFS_IN_OPEN_NODE:
+			vfs_open_node(callid, &call);
 			break;
 		case VFS_IN_CLOSE:
@@ -123,8 +118,4 @@
 		case VFS_IN_DUP:
 			vfs_dup(callid, &call);
-			break;
-		case VFS_IN_WAIT_HANDLE:
-			vfs_wait_handle(callid, &call);
-			break;
 		default:
 			async_answer_0(callid, ENOTSUP);
@@ -137,19 +128,4 @@
 	 * connection fibril terminates.
 	 */
-}
-
-static void notification_received(ipc_callid_t callid, ipc_call_t *call)
-{
-	switch (IPC_GET_IMETHOD(*call)) {
-	case VFS_TASK_STATE_CHANGE:
-		if (IPC_GET_ARG1(*call) == VFS_PASS_HANDLE)
-			vfs_pass_handle(
-			    (task_id_t) MERGE_LOUP32(IPC_GET_ARG4(*call),
-			    IPC_GET_ARG5(*call)), call->in_task_id,
-			    (int) IPC_GET_ARG2(*call));
-		break;
-	default:
-		break;
-	}
 }
 
@@ -194,10 +170,4 @@
 
 	/*
-	 * Set notification handler and subscribe to notifications.
-	 */
-	async_set_interrupt_received(notification_received);
-	event_task_subscribe(EVENT_TASK_STATE_CHANGE, VFS_TASK_STATE_CHANGE);
-
-	/*
 	 * Register at the naming service.
 	 */
Index: uspace/srv/vfs/vfs.h
===================================================================
--- uspace/srv/vfs/vfs.h	(revision 107f2e0ef3e7f3b7336408a40acd526c8502baf3)
+++ uspace/srv/vfs/vfs.h	(revision cf22adae6847bfd38cc71105b2e33cf57afaf326)
@@ -41,5 +41,4 @@
 #include <bool.h>
 #include <ipc/vfs.h>
-#include <task.h>
 
 #ifndef dprintf
@@ -176,4 +175,5 @@
 extern int vfs_lookup_internal(char *, int, vfs_lookup_res_t *,
     vfs_pair_t *, ...);
+extern int vfs_open_node_internal(vfs_lookup_res_t *);
 
 extern bool vfs_nodes_init(void);
@@ -189,7 +189,4 @@
 extern void vfs_client_data_destroy(void *);
 
-extern void vfs_pass_handle(task_id_t, task_id_t, int);
-extern int vfs_wait_handle_internal(void);
-
 extern vfs_file_t *vfs_file_get(int);
 extern void vfs_file_put(vfs_file_t *);
@@ -200,5 +197,4 @@
 extern void vfs_node_addref(vfs_node_t *);
 extern void vfs_node_delref(vfs_node_t *);
-extern int vfs_open_node_remote(vfs_node_t *);
 
 extern void vfs_register(ipc_callid_t, ipc_call_t *);
@@ -206,4 +202,5 @@
 extern void vfs_unmount(ipc_callid_t, ipc_call_t *);
 extern void vfs_open(ipc_callid_t, ipc_call_t *);
+extern void vfs_open_node(ipc_callid_t, ipc_call_t *);
 extern void vfs_sync(ipc_callid_t, ipc_call_t *);
 extern void vfs_dup(ipc_callid_t, ipc_call_t *);
@@ -218,5 +215,4 @@
 extern void vfs_unlink(ipc_callid_t, ipc_call_t *);
 extern void vfs_rename(ipc_callid_t, ipc_call_t *);
-extern void vfs_wait_handle(ipc_callid_t, ipc_call_t *);
 
 #endif
Index: uspace/srv/vfs/vfs_file.c
===================================================================
--- uspace/srv/vfs/vfs_file.c	(revision 107f2e0ef3e7f3b7336408a40acd526c8502baf3)
+++ uspace/srv/vfs/vfs_file.c	(revision cf22adae6847bfd38cc71105b2e33cf57afaf326)
@@ -43,6 +43,4 @@
 #include <fibril.h>
 #include <fibril_synch.h>
-#include <adt/list.h>
-#include <task.h>
 #include "vfs.h"
 
@@ -52,57 +50,38 @@
 typedef struct {
 	fibril_mutex_t lock;
-	fibril_condvar_t cv;
-	list_t passed_handles;
 	vfs_file_t **files;
 } vfs_client_data_t;
 
-typedef struct {
-	link_t link;
-	int handle;
-} vfs_boxed_handle_t;
-
-static int _vfs_fd_free(vfs_client_data_t *, int);
-
 /** Initialize the table of open files. */
-static bool vfs_files_init(vfs_client_data_t *vfs_data)
-{
-	fibril_mutex_lock(&vfs_data->lock);
-	if (!vfs_data->files) {
-		vfs_data->files = malloc(MAX_OPEN_FILES * sizeof(vfs_file_t *));
-		if (!vfs_data->files) {
-			fibril_mutex_unlock(&vfs_data->lock);
+static bool vfs_files_init(void)
+{
+	fibril_mutex_lock(&VFS_DATA->lock);
+	if (!FILES) {
+		FILES = malloc(MAX_OPEN_FILES * sizeof(vfs_file_t *));
+		if (!FILES) {
+			fibril_mutex_unlock(&VFS_DATA->lock);
 			return false;
 		}
-		memset(vfs_data->files, 0, MAX_OPEN_FILES * sizeof(vfs_file_t *));
-	}
-	fibril_mutex_unlock(&vfs_data->lock);
+		memset(FILES, 0, MAX_OPEN_FILES * sizeof(vfs_file_t *));
+	}
+	fibril_mutex_unlock(&VFS_DATA->lock);
 	return true;
 }
 
 /** Cleanup the table of open files. */
-static void vfs_files_done(vfs_client_data_t *vfs_data)
+static void vfs_files_done(void)
 {
 	int i;
 
-	if (!vfs_data->files)
+	if (!FILES)
 		return;
 
 	for (i = 0; i < MAX_OPEN_FILES; i++) {
-		if (vfs_data->files[i])
-			(void) _vfs_fd_free(vfs_data, i);
-	}
-	
-	free(vfs_data->files);
-
-	while (!list_empty(&vfs_data->passed_handles)) {
-		link_t *lnk;
-		vfs_boxed_handle_t *bh;
-		
-		lnk = list_first(&vfs_data->passed_handles);
-		list_remove(lnk);
-
-		bh = list_get_instance(lnk, vfs_boxed_handle_t, link);
-		free(bh);
-	}
+		if (FILES[i]) {
+			(void) vfs_fd_free(i);
+		}
+	}
+	
+	free(FILES);
 }
 
@@ -114,6 +93,4 @@
 	if (vfs_data) {
 		fibril_mutex_initialize(&vfs_data->lock);
-		fibril_condvar_initialize(&vfs_data->cv);
-		list_initialize(&vfs_data->passed_handles);
 		vfs_data->files = NULL;
 	}
@@ -126,5 +103,5 @@
 	vfs_client_data_t *vfs_data = (vfs_client_data_t *) data;
 
-	vfs_files_done(vfs_data);
+	vfs_files_done();
 	free(vfs_data);
 }
@@ -154,7 +131,7 @@
  *			incremented.
  */
-static void vfs_file_addref(vfs_client_data_t *vfs_data, vfs_file_t *file)
-{
-	assert(fibril_mutex_is_locked(&vfs_data->lock));
+static void vfs_file_addref(vfs_file_t *file)
+{
+	assert(fibril_mutex_is_locked(&VFS_DATA->lock));
 
 	file->refcnt++;
@@ -166,9 +143,9 @@
  *			decremented.
  */
-static int vfs_file_delref(vfs_client_data_t *vfs_data, vfs_file_t *file)
+static int vfs_file_delref(vfs_file_t *file)
 {
 	int rc = EOK;
 
-	assert(fibril_mutex_is_locked(&vfs_data->lock));
+	assert(fibril_mutex_is_locked(&VFS_DATA->lock));
 
 	if (file->refcnt-- == 1) {
@@ -185,7 +162,16 @@
 }
 
-static int _vfs_fd_alloc(vfs_client_data_t *vfs_data, bool desc)
-{
-	if (!vfs_files_init(vfs_data))
+
+/** Allocate a file descriptor.
+ *
+ * @param desc If true, look for an available file descriptor
+ *             in a descending order.
+ *
+ * @return First available file descriptor or a negative error
+ *         code.
+ */
+int vfs_fd_alloc(bool desc)
+{
+	if (!vfs_files_init())
 		return ENOMEM;
 	
@@ -196,17 +182,17 @@
 		i = 0;
 	
-	fibril_mutex_lock(&vfs_data->lock);
+	fibril_mutex_lock(&VFS_DATA->lock);
 	while (true) {
-		if (!vfs_data->files[i]) {
-			vfs_data->files[i] = (vfs_file_t *) malloc(sizeof(vfs_file_t));
-			if (!vfs_data->files[i]) {
-				fibril_mutex_unlock(&vfs_data->lock);
+		if (!FILES[i]) {
+			FILES[i] = (vfs_file_t *) malloc(sizeof(vfs_file_t));
+			if (!FILES[i]) {
+				fibril_mutex_unlock(&VFS_DATA->lock);
 				return ENOMEM;
 			}
 			
-			memset(vfs_data->files[i], 0, sizeof(vfs_file_t));
-			fibril_mutex_initialize(&vfs_data->files[i]->lock);
-			vfs_file_addref(vfs_data, vfs_data->files[i]);
-			fibril_mutex_unlock(&vfs_data->lock);
+			memset(FILES[i], 0, sizeof(vfs_file_t));
+			fibril_mutex_initialize(&FILES[i]->lock);
+			vfs_file_addref(FILES[i]);
+			fibril_mutex_unlock(&VFS_DATA->lock);
 			return (int) i;
 		}
@@ -224,40 +210,7 @@
 		}
 	}
-	fibril_mutex_unlock(&vfs_data->lock);
+	fibril_mutex_unlock(&VFS_DATA->lock);
 	
 	return EMFILE;
-}
-
-/** Allocate a file descriptor.
- *
- * @param desc If true, look for an available file descriptor
- *             in a descending order.
- *
- * @return First available file descriptor or a negative error
- *         code.
- */
-int vfs_fd_alloc(bool desc)
-{
-	return _vfs_fd_alloc(VFS_DATA, desc);
-}
-
-static int _vfs_fd_free(vfs_client_data_t *vfs_data, int fd)
-{
-	int rc;
-
-	if (!vfs_files_init(vfs_data))
-		return ENOMEM;
-
-	fibril_mutex_lock(&vfs_data->lock);	
-	if ((fd < 0) || (fd >= MAX_OPEN_FILES) || !vfs_data->files[fd]) {
-		fibril_mutex_unlock(&vfs_data->lock);
-		return EBADF;
-	}
-	
-	rc = vfs_file_delref(vfs_data, vfs_data->files[fd]);
-	vfs_data->files[fd] = NULL;
-	fibril_mutex_unlock(&vfs_data->lock);
-	
-	return rc;
 }
 
@@ -271,5 +224,20 @@
 int vfs_fd_free(int fd)
 {
-	return _vfs_fd_free(VFS_DATA, fd);
+	int rc;
+
+	if (!vfs_files_init())
+		return ENOMEM;
+
+	fibril_mutex_lock(&VFS_DATA->lock);	
+	if ((fd < 0) || (fd >= MAX_OPEN_FILES) || (FILES[fd] == NULL)) {
+		fibril_mutex_unlock(&VFS_DATA->lock);
+		return EBADF;
+	}
+	
+	rc = vfs_file_delref(FILES[fd]);
+	FILES[fd] = NULL;
+	fibril_mutex_unlock(&VFS_DATA->lock);
+	
+	return rc;
 }
 
@@ -285,5 +253,5 @@
 int vfs_fd_assign(vfs_file_t *file, int fd)
 {
-	if (!vfs_files_init(VFS_DATA))
+	if (!vfs_files_init())
 		return ENOMEM;
 
@@ -295,5 +263,5 @@
 	
 	FILES[fd] = file;
-	vfs_file_addref(VFS_DATA, FILES[fd]);
+	vfs_file_addref(FILES[fd]);
 	fibril_mutex_unlock(&VFS_DATA->lock);
 	
@@ -301,41 +269,29 @@
 }
 
-static vfs_file_t *_vfs_file_get(vfs_client_data_t *vfs_data, int fd)
-{
-	if (!vfs_files_init(vfs_data))
+/** Find VFS file structure for a given file descriptor.
+ *
+ * @param fd		File descriptor.
+ *
+ * @return		VFS file structure corresponding to fd.
+ */
+vfs_file_t *vfs_file_get(int fd)
+{
+	if (!vfs_files_init())
 		return NULL;
 	
-	fibril_mutex_lock(&vfs_data->lock);
+	fibril_mutex_lock(&VFS_DATA->lock);
 	if ((fd >= 0) && (fd < MAX_OPEN_FILES)) {
-		vfs_file_t *file = vfs_data->files[fd];
+		vfs_file_t *file = FILES[fd];
 		if (file != NULL) {
-			vfs_file_addref(vfs_data, file);
-			fibril_mutex_unlock(&vfs_data->lock);
+			vfs_file_addref(file);
+			fibril_mutex_unlock(&VFS_DATA->lock);
 			return file;
 		}
 	}
-	fibril_mutex_unlock(&vfs_data->lock);
+	fibril_mutex_unlock(&VFS_DATA->lock);
 	
 	return NULL;
 }
 
-/** Find VFS file structure for a given file descriptor.
- *
- * @param fd		File descriptor.
- *
- * @return		VFS file structure corresponding to fd.
- */
-vfs_file_t *vfs_file_get(int fd)
-{
-	return _vfs_file_get(VFS_DATA, fd);
-}
-
-static void _vfs_file_put(vfs_client_data_t *vfs_data, vfs_file_t *file)
-{
-	fibril_mutex_lock(&vfs_data->lock);
-	vfs_file_delref(vfs_data, file);
-	fibril_mutex_unlock(&vfs_data->lock);
-}
-
 /** Stop using a file structure.
  *
@@ -344,90 +300,7 @@
 void vfs_file_put(vfs_file_t *file)
 {
-	_vfs_file_put(VFS_DATA, file);
-}
-
-void vfs_pass_handle(task_id_t donor_id, task_id_t acceptor_id, int donor_fd)
-{
-	vfs_client_data_t *donor_data = NULL;
-	vfs_client_data_t *acceptor_data = NULL;
-	vfs_file_t *donor_file = NULL;
-	vfs_file_t *acceptor_file = NULL;
-	vfs_boxed_handle_t *bh;
-	int acceptor_fd;
-
-	acceptor_data = async_get_client_data_by_id(acceptor_id);
-	if (!acceptor_data)
-		return;
-
-	bh = malloc(sizeof(vfs_boxed_handle_t));
-	assert(bh);
-
-	link_initialize(&bh->link);
-	bh->handle = -1;
-
-	donor_data = async_get_client_data_by_id(donor_id);
-	if (!donor_data)
-		goto out;
-
-	donor_file = _vfs_file_get(donor_data, donor_fd);
-	if (!donor_file)
-		goto out;
-
-	acceptor_fd = _vfs_fd_alloc(acceptor_data, false);
-	if (acceptor_fd < 0)
-		goto out;
-
-	bh->handle = acceptor_fd;
-
-	/*
-	 * Add a new reference to the underlying VFS node.
-	 */
-	vfs_node_addref(donor_file->node);
-	(void) vfs_open_node_remote(donor_file->node);
-
-	acceptor_file = _vfs_file_get(acceptor_data, acceptor_fd);
-	assert(acceptor_file);
-
-	/*
-	 * Inherit attributes from the donor.
-	 */
-	acceptor_file->node = donor_file->node;
-	acceptor_file->append = donor_file->append;
-	acceptor_file->pos = donor_file->pos;
-
-out:
-	fibril_mutex_lock(&acceptor_data->lock);
-	list_append(&bh->link, &acceptor_data->passed_handles);
-	fibril_condvar_broadcast(&acceptor_data->cv);
-	fibril_mutex_unlock(&acceptor_data->lock);
-
-	if (donor_data)
-		async_put_client_data_by_id(donor_id);
-	if (acceptor_data)
-		async_put_client_data_by_id(acceptor_id);
-	if (donor_file)
-		_vfs_file_put(donor_data, donor_file);
-	if (acceptor_file)
-		_vfs_file_put(acceptor_data, acceptor_file);
-
-}
-
-int vfs_wait_handle_internal(void)
-{
-	vfs_client_data_t *vfs_data = VFS_DATA;	
-	int fd;
-	
-	fibril_mutex_lock(&vfs_data->lock);
-	while (list_empty(&vfs_data->passed_handles))
-		fibril_condvar_wait(&vfs_data->cv, &vfs_data->lock);
-	link_t *lnk = list_first(&vfs_data->passed_handles);
-	list_remove(lnk);
-	fibril_mutex_unlock(&vfs_data->lock);
-
-	vfs_boxed_handle_t *bh = list_get_instance(lnk, vfs_boxed_handle_t, link);
-	fd = bh->handle;
-	free(bh);
-
-	return fd;
+	fibril_mutex_lock(&VFS_DATA->lock);
+	vfs_file_delref(file);
+	fibril_mutex_unlock(&VFS_DATA->lock);
 }
 
Index: uspace/srv/vfs/vfs_lookup.c
===================================================================
--- uspace/srv/vfs/vfs_lookup.c	(revision 107f2e0ef3e7f3b7336408a40acd526c8502baf3)
+++ uspace/srv/vfs/vfs_lookup.c	(revision cf22adae6847bfd38cc71105b2e33cf57afaf326)
@@ -201,4 +201,37 @@
 }
 
+/** Perform a node open operation.
+ *
+ * @return EOK on success or an error code from errno.h.
+ *
+ */
+int vfs_open_node_internal(vfs_lookup_res_t *result)
+{
+	async_exch_t *exch = vfs_exchange_grab(result->triplet.fs_handle);
+	
+	ipc_call_t answer;
+	aid_t req = async_send_2(exch, VFS_OUT_OPEN_NODE,
+	    (sysarg_t) result->triplet.service_id,
+	    (sysarg_t) result->triplet.index, &answer);
+	
+	sysarg_t rc;
+	async_wait_for(req, &rc);
+	vfs_exchange_release(exch);
+	
+	if (rc == EOK) {
+		result->size =
+		    MERGE_LOUP32(IPC_GET_ARG1(answer), IPC_GET_ARG2(answer));
+		result->lnkcnt = (unsigned int) IPC_GET_ARG3(answer);
+		if (IPC_GET_ARG4(answer) & L_FILE)
+			result->type = VFS_NODE_FILE;
+		else if (IPC_GET_ARG4(answer) & L_DIRECTORY)
+			result->type = VFS_NODE_DIRECTORY;
+		else
+			result->type = VFS_NODE_UNKNOWN;
+	}
+	
+	return rc;
+}
+
 /**
  * @}
Index: uspace/srv/vfs/vfs_node.c
===================================================================
--- uspace/srv/vfs/vfs_node.c	(revision 107f2e0ef3e7f3b7336408a40acd526c8502baf3)
+++ uspace/srv/vfs/vfs_node.c	(revision cf22adae6847bfd38cc71105b2e33cf57afaf326)
@@ -293,26 +293,4 @@
 }
 
-
-/** Perform a remote node open operation.
- *
- * @return EOK on success or an error code from errno.h.
- *
- */
-int vfs_open_node_remote(vfs_node_t *node)
-{
-	async_exch_t *exch = vfs_exchange_grab(node->fs_handle);
-	
-	ipc_call_t answer;
-	aid_t req = async_send_2(exch, VFS_OUT_OPEN_NODE,
-	    (sysarg_t) node->service_id, (sysarg_t) node->index, &answer);
-	
-	vfs_exchange_release(exch);
-
-	sysarg_t rc;
-	async_wait_for(req, &rc);
-	
-	return rc;
-}
-
 /**
  * @}
Index: uspace/srv/vfs/vfs_ops.c
===================================================================
--- uspace/srv/vfs/vfs_ops.c	(revision 107f2e0ef3e7f3b7336408a40acd526c8502baf3)
+++ uspace/srv/vfs/vfs_ops.c	(revision cf22adae6847bfd38cc71105b2e33cf57afaf326)
@@ -618,4 +618,77 @@
 }
 
+void vfs_open_node(ipc_callid_t rid, ipc_call_t *request)
+{
+	// FIXME: check for sanity of the supplied fs, dev and index
+	
+	/*
+	 * The interface is open_node(fs, dev, index, oflag).
+	 */
+	vfs_lookup_res_t lr;
+	
+	lr.triplet.fs_handle = IPC_GET_ARG1(*request);
+	lr.triplet.service_id = IPC_GET_ARG2(*request);
+	lr.triplet.index = IPC_GET_ARG3(*request);
+	int oflag = IPC_GET_ARG4(*request);
+	
+	fibril_rwlock_read_lock(&namespace_rwlock);
+	
+	int rc = vfs_open_node_internal(&lr);
+	if (rc != EOK) {
+		fibril_rwlock_read_unlock(&namespace_rwlock);
+		async_answer_0(rid, rc);
+		return;
+	}
+	
+	vfs_node_t *node = vfs_node_get(&lr);
+	fibril_rwlock_read_unlock(&namespace_rwlock);
+	
+	/* Truncate the file if requested and if necessary. */
+	if (oflag & O_TRUNC) {
+		fibril_rwlock_write_lock(&node->contents_rwlock);
+		if (node->size) {
+			rc = vfs_truncate_internal(node->fs_handle,
+			    node->service_id, node->index, 0);
+			if (rc) {
+				fibril_rwlock_write_unlock(&node->contents_rwlock);
+				vfs_node_put(node);
+				async_answer_0(rid, rc);
+				return;
+			}
+			node->size = 0;
+		}
+		fibril_rwlock_write_unlock(&node->contents_rwlock);
+	}
+	
+	/*
+	 * Get ourselves a file descriptor and the corresponding vfs_file_t
+	 * structure.
+	 */
+	int fd = vfs_fd_alloc((oflag & O_DESC) != 0);
+	if (fd < 0) {
+		vfs_node_put(node);
+		async_answer_0(rid, fd);
+		return;
+	}
+	vfs_file_t *file = vfs_file_get(fd);
+	file->node = node;
+	if (oflag & O_APPEND)
+		file->append = true;
+	
+	/*
+	 * The following increase in reference count is for the fact that the
+	 * file is being opened and that a file structure is pointing to it.
+	 * It is necessary so that the file will not disappear when
+	 * vfs_node_put() is called. The reference will be dropped by the
+	 * respective VFS_IN_CLOSE.
+	 */
+	vfs_node_addref(node);
+	vfs_node_put(node);
+	vfs_file_put(file);
+	
+	/* Success! Return the new file descriptor to the client. */
+	async_answer_1(rid, EOK, fd);
+}
+
 void vfs_sync(ipc_callid_t rid, ipc_call_t *request)
 {
@@ -1276,10 +1349,4 @@
 }
 
-void vfs_wait_handle(ipc_callid_t rid, ipc_call_t *request)
-{
-	int fd = vfs_wait_handle_internal();
-	async_answer_1(rid, EOK, fd);
-}
-
 /**
  * @}
