Index: kernel/generic/src/ipc/ipcrsc.c
===================================================================
--- kernel/generic/src/ipc/ipcrsc.c	(revision 9e875620ecd41735d8a5759a1e6986978cb55507)
+++ kernel/generic/src/ipc/ipcrsc.c	(revision 91b604993517a2bdc14cfe1ede6902150ab29533)
@@ -164,41 +164,28 @@
 }
 
-/** Get phone from the current task by capability handle.
- *
- * @param handle  Phone capability handle.
- * @param phone   Place to store pointer to phone.
- *
- * @return  Address of the phone kernel object.
- * @return  NULL if the capability is invalid.
- *
- */
-phone_t *phone_get(task_t *task, int handle)
-{
-	phone_t *phone;
-
-	caps_lock(task);
-	cap_t *cap = cap_get(task, handle, CAP_TYPE_PHONE);
-	phone = (phone_t *) cap->kobject;
-	caps_unlock(task);
-	if (!cap)
-		return NULL;
-	
-	return phone;
-}
-
-phone_t *phone_get_current(int handle)
-{
-	return phone_get(TASK, handle);
-}
-
-static bool phone_can_reclaim(cap_t *cap)
-{
-	assert(cap->type == CAP_TYPE_PHONE);
-
-	phone_t *phone = (phone_t *) cap->kobject;
-
-	return (phone->state == IPC_PHONE_HUNGUP) &&
-	    (atomic_get(&phone->active_calls) == 0);
-}
+static bool phone_reclaim(kobject_t *kobj)
+{
+	bool gc = false;
+
+	mutex_lock(&kobj->phone->lock);
+	if (kobj->phone->state == IPC_PHONE_HUNGUP &&
+	    atomic_get(&kobj->phone->active_calls) == 0)
+		gc = true;
+	mutex_unlock(&kobj->phone->lock);
+
+	return gc;
+}
+
+static void phone_destroy(void *arg)
+{
+	phone_t *phone = (phone_t *) arg;
+	slab_free(phone_slab, phone);
+}
+
+static kobject_ops_t phone_kobject_ops = {
+	.reclaim = phone_reclaim,
+	.destroy = phone_destroy
+};
+
 
 /** Allocate new phone in the specified task.
@@ -209,7 +196,7 @@
  * @return  Negative error code if a new capability cannot be allocated.
  */
-int phone_alloc(task_t *task)
-{
-	int handle = cap_alloc(task);
+cap_handle_t phone_alloc(task_t *task)
+{
+	cap_handle_t handle = cap_alloc(task);
 	if (handle >= 0) {
 		phone_t *phone = slab_alloc(phone_slab, FRAME_ATOMIC);
@@ -218,15 +205,19 @@
 			return ENOMEM;
 		}
-		
+		kobject_t *kobject = malloc(sizeof(kobject_t), FRAME_ATOMIC);
+		if (!kobject) {
+			cap_free(TASK, handle);
+			slab_free(phone_slab, phone);
+			return ENOMEM;
+		}
+
 		ipc_phone_init(phone, task);
 		phone->state = IPC_PHONE_CONNECTING;
+
+		kobject_initialize(kobject, KOBJECT_TYPE_PHONE, phone,
+		    &phone_kobject_ops);
+		phone->kobject = kobject;
 		
-		// FIXME: phase this out eventually
-		mutex_lock(&task->cap_info->lock);
-		cap_t *cap = cap_get(task, handle, CAP_TYPE_ALLOCATED);
-		cap->can_reclaim = phone_can_reclaim;
-		mutex_unlock(&task->cap_info->lock);
-
-		cap_publish(task, handle, CAP_TYPE_PHONE, phone);
+		cap_publish(task, handle, kobject);
 	}
 	
@@ -241,15 +232,14 @@
  *
  */
-void phone_dealloc(int handle)
-{
-	cap_t *cap = cap_unpublish(TASK, handle, CAP_TYPE_PHONE);
-	assert(cap);
-	
-	phone_t *phone = (phone_t *) cap->kobject;
-	
-	assert(phone);
-	assert(phone->state == IPC_PHONE_CONNECTING);
-	
-	slab_free(phone_slab, phone);
+void phone_dealloc(cap_handle_t handle)
+{
+	kobject_t *kobj = cap_unpublish(TASK, handle, KOBJECT_TYPE_PHONE);
+	if (!kobj)
+		return;
+	
+	assert(kobj->phone);
+	assert(kobj->phone->state == IPC_PHONE_CONNECTING);
+	
+	kobject_put(kobj);
 	cap_free(TASK, handle);
 }
@@ -260,18 +250,15 @@
  * @param box     Answerbox to which to connect the phone.
  * @return        True if the phone was connected, false otherwise.
- *
- * The procedure _enforces_ that the user first marks the phone busy (e.g. via
- * phone_alloc) and then connects the phone, otherwise race condition may
- * appear.
- *
- */
-bool phone_connect(int handle, answerbox_t *box)
-{
-	phone_t *phone = phone_get_current(handle);
-	
-	assert(phone);
-	assert(phone->state == IPC_PHONE_CONNECTING);
-	
-	return ipc_phone_connect(phone, box);
+ */
+bool phone_connect(cap_handle_t handle, answerbox_t *box)
+{
+	kobject_t *phone_obj = kobject_get(TASK, handle, KOBJECT_TYPE_PHONE);
+	if (!phone_obj)
+		return false;
+	
+	assert(phone_obj->phone->state == IPC_PHONE_CONNECTING);
+	
+	/* Hand over phone_obj reference to the answerbox */
+	return ipc_phone_connect(phone_obj->phone, box);
 }
 
