Index: kernel/generic/include/cap/cap.h
===================================================================
--- kernel/generic/include/cap/cap.h	(revision 30c27e95e487a311a88c5e35518a4cd018b0ed7f)
+++ kernel/generic/include/cap/cap.h	(revision 63d8f43468baaa1f20964c35b3aea13f36dd3e2c)
@@ -38,5 +38,4 @@
 #include <typedefs.h>
 #include <ipc/ipc.h>
-#include <ddi/irq.h>
 
 #define MAX_CAPS  64
@@ -64,8 +63,5 @@
 
 	/* The underlying kernel object. */
-	union {
-		phone_t phone;
-		irq_t irq;
-	};
+	void *kobject;
 } cap_t;
 
Index: kernel/generic/src/cap/cap.c
===================================================================
--- kernel/generic/src/cap/cap.c	(revision 30c27e95e487a311a88c5e35518a4cd018b0ed7f)
+++ kernel/generic/src/cap/cap.c	(revision 63d8f43468baaa1f20964c35b3aea13f36dd3e2c)
@@ -102,5 +102,5 @@
 	assert(handle >= 0);
 	assert(handle < MAX_CAPS);
-	assert(task->caps[handle].type != CAP_TYPE_INVALID);
+	assert(task->caps[handle].type == CAP_TYPE_ALLOCATED);
 
 	irq_spinlock_lock(&task->lock, true);
Index: kernel/generic/src/ipc/ipc.c
===================================================================
--- kernel/generic/src/ipc/ipc.c	(revision 30c27e95e487a311a88c5e35518a4cd018b0ed7f)
+++ kernel/generic/src/ipc/ipc.c	(revision 63d8f43468baaa1f20964c35b3aea13f36dd3e2c)
@@ -743,5 +743,5 @@
 	all_clean = true;
 	for_each_cap_current(cap, CAP_TYPE_PHONE) {
-		phone_t *phone = &cap->phone;
+		phone_t *phone = (phone_t *) cap->kobject;
 
 		mutex_lock(&phone->lock);
@@ -820,5 +820,5 @@
 	/* Disconnect all our phones ('ipc_phone_hangup') */
 	for_each_cap_current(cap, CAP_TYPE_PHONE) {
-		phone_t *phone = &cap->phone;
+		phone_t *phone = (phone_t *) cap->kobject;
 		ipc_phone_hangup(phone);
 	}
@@ -913,5 +913,5 @@
 	
 	for_each_cap(task, cap, CAP_TYPE_PHONE) {
-		phone_t *phone = &cap->phone;
+		phone_t *phone = (phone_t *) cap->kobject;
 	
 		if (SYNCH_FAILED(mutex_trylock(&phone->lock))) {
Index: kernel/generic/src/ipc/ipcrsc.c
===================================================================
--- kernel/generic/src/ipc/ipcrsc.c	(revision 30c27e95e487a311a88c5e35518a4cd018b0ed7f)
+++ kernel/generic/src/ipc/ipcrsc.c	(revision 63d8f43468baaa1f20964c35b3aea13f36dd3e2c)
@@ -135,4 +135,5 @@
 #include <abi/errno.h>
 #include <cap/cap.h>
+#include <mm/slab.h>
 
 /** Find call_t * in call table according to callid.
@@ -178,5 +179,5 @@
 		return NULL;
 	
-	return &cap->phone;
+	return (phone_t *) cap->kobject;
 }
 
@@ -190,6 +191,8 @@
 	assert(cap->type == CAP_TYPE_PHONE);
 
-	return (cap->phone.state == IPC_PHONE_HUNGUP) &&
-	    (atomic_get(&cap->phone.active_calls) == 0);
+	phone_t *phone = (phone_t *) cap->kobject;
+
+	return (phone->state == IPC_PHONE_HUNGUP) &&
+	    (atomic_get(&phone->active_calls) == 0);
 }
 
@@ -205,10 +208,18 @@
 	int handle = cap_alloc(task);
 	if (handle >= 0) {
+		phone_t *phone = malloc(sizeof(phone_t), FRAME_ATOMIC);
+		if (!phone) {
+			cap_free(TASK, handle);
+			return ENOMEM;
+		}
+		
+		ipc_phone_init(phone, task);
+		phone->state = IPC_PHONE_CONNECTING;
+		
 		irq_spinlock_lock(&task->lock, true);
 		cap_t *cap = cap_get(task, handle, CAP_TYPE_ALLOCATED);
-		ipc_phone_init(&cap->phone, task);
 		cap->type = CAP_TYPE_PHONE;
+		cap->kobject = (void *) phone;
 		cap->can_reclaim = phone_can_reclaim;
-		cap->phone.state = IPC_PHONE_CONNECTING;
 		irq_spinlock_unlock(&task->lock, true);
 	}
@@ -226,9 +237,16 @@
 void phone_dealloc(int handle)
 {
-	phone_t *phone = phone_get_current(handle);
+	irq_spinlock_lock(&TASK->lock, true);
+	cap_t *cap = cap_get_current(handle, CAP_TYPE_PHONE);
+	assert(cap);
+	cap->type = CAP_TYPE_ALLOCATED;
+	irq_spinlock_unlock(&TASK->lock, true);
+	
+	phone_t *phone = (phone_t *) cap->kobject;
 	
 	assert(phone);
 	assert(phone->state == IPC_PHONE_CONNECTING);
-
+	
+	free(phone);
 	cap_free(TASK, handle);
 }
Index: kernel/generic/src/ipc/irq.c
===================================================================
--- kernel/generic/src/ipc/irq.c	(revision 30c27e95e487a311a88c5e35518a4cd018b0ed7f)
+++ kernel/generic/src/ipc/irq.c	(revision 63d8f43468baaa1f20964c35b3aea13f36dd3e2c)
@@ -307,8 +307,14 @@
 	if (handle < 0)
 		return handle;
+	
+	irq_t *irq = (irq_t *) malloc(sizeof(irq_t), FRAME_ATOMIC);
+	if (!irq) {
+		cap_free(TASK, handle);
+		return ENOMEM;
+	}
+	
 	cap_t *cap = cap_get_current(handle, CAP_TYPE_ALLOCATED);
 	assert(cap);
 	
-	irq_t *irq = &cap->irq;
 	irq_initialize(irq);
 	irq->inr = inr;
@@ -321,4 +327,6 @@
 	irq->notif_cfg.counter = 0;
 	
+	cap->kobject = (void *) irq;
+	
 	/*
 	 * Insert the IRQ structure into the uspace IRQ hash table and retype
@@ -359,5 +367,5 @@
 	irq_spinlock_unlock(&TASK->lock, true);
 	
-	irq_t *irq = &cap->irq;
+	irq_t *irq = (irq_t *) cap->kobject;
 	
 	irq_spinlock_lock(&irq_uspace_hash_table_lock, true);
@@ -376,4 +384,5 @@
 	
 	/* Free up the IRQ capability and the underlying kernel object. */
+	free(cap->kobject);
 	cap_free(TASK, handle);
 	
Index: kernel/generic/src/proc/task.c
===================================================================
--- kernel/generic/src/proc/task.c	(revision 30c27e95e487a311a88c5e35518a4cd018b0ed7f)
+++ kernel/generic/src/proc/task.c	(revision 63d8f43468baaa1f20964c35b3aea13f36dd3e2c)
@@ -625,5 +625,5 @@
 	if (*additional) {
 		for_each_cap(task, cap, CAP_TYPE_PHONE) {
-			phone_t *phone = &cap->phone;
+			phone_t *phone = (void *) &cap->kobject;
 			if (phone->callee)
 				printf(" %d:%p", cap->handle, phone->callee);
