Index: kernel/generic/src/ipc/ipc.c
===================================================================
--- kernel/generic/src/ipc/ipc.c	(revision c713aa56b7ead96a13adf43127742f927e5b1d9b)
+++ kernel/generic/src/ipc/ipc.c	(revision 287e83f9b1d052d373437f8888bca9dcebd88cfc)
@@ -62,5 +62,4 @@
 
 static slab_cache_t *ipc_call_slab;
-static slab_cache_t *ipc_answerbox_slab;
 
 /** Initialize a call structure.
@@ -97,4 +96,15 @@
 }
 
+/** Initialize a statically allocated call structure.
+ *
+ * @param call		Statically allocated kernel call structure to be
+ *			initialized.
+ */
+void ipc_call_static_init(call_t *call)
+{
+	_ipc_call_init(call);
+	call->flags |= IPC_CALL_STATIC_ALLOC;
+}
+
 /** Deallocate a call structure.
  *
@@ -103,4 +113,5 @@
 void ipc_call_free(call_t *call)
 {
+	ASSERT(!(call->flags & IPC_CALL_STATIC_ALLOC));
 	/* Check to see if we have data in the IPC_M_DATA_SEND buffer. */
 	if (call->buffer)
@@ -119,5 +130,4 @@
 	spinlock_initialize(&box->irq_lock, "ipc_box_irqlock");
 	waitq_initialize(&box->wq);
-	link_initialize(&box->sync_box_link);
 	list_initialize(&box->connected_phones);
 	list_initialize(&box->calls);
@@ -169,41 +179,15 @@
 int ipc_call_sync(phone_t *phone, call_t *request)
 {
-	answerbox_t *sync_box; 
-	ipl_t ipl;
-
-	sync_box = slab_alloc(ipc_answerbox_slab, 0);
-	ipc_answerbox_init(sync_box, TASK);
-
-	/*
-	 * Put the answerbox on the TASK's list of synchronous answerboxes so
-	 * that it can be cleaned up if the call is interrupted.
-	 */
-	ipl = interrupts_disable();
-	spinlock_lock(&TASK->lock);
-	list_append(&sync_box->sync_box_link, &TASK->sync_box_head);
-	spinlock_unlock(&TASK->lock);
-	interrupts_restore(ipl);
+	answerbox_t sync_box; 
+
+	ipc_answerbox_init(&sync_box, TASK);
 
 	/* We will receive data in a special box. */
-	request->callerbox = sync_box;
+	request->callerbox = &sync_box;
 
 	ipc_call(phone, request);
-	if (!ipc_wait_for_call(sync_box, SYNCH_NO_TIMEOUT,
-	    SYNCH_FLAGS_INTERRUPTIBLE)) {
-	    	/* The answerbox and the call will be freed by ipc_cleanup(). */
+	if (!ipc_wait_for_call(&sync_box, SYNCH_NO_TIMEOUT,
+	    SYNCH_FLAGS_INTERRUPTIBLE))
 		return EINTR;
-	}
-
-	/*
-	 * The answer arrived without interruption so we can remove the
-	 * answerbox from the TASK's list of synchronous answerboxes.
-	 */
-	(void) interrupts_disable();
-	spinlock_lock(&TASK->lock);
-	list_remove(&sync_box->sync_box_link);
-	spinlock_unlock(&TASK->lock);
-	interrupts_restore(ipl);
-
-	slab_free(ipc_answerbox_slab, sync_box);
 	return EOK;
 }
@@ -212,10 +196,8 @@
  *
  * @param call		Call structure to be answered.
- * @param selflocked	If true, then TASK->answebox is locked.
- */
-static void _ipc_answer_free_call(call_t *call, bool selflocked)
+ */
+static void _ipc_answer_free_call(call_t *call)
 {
 	answerbox_t *callerbox = call->callerbox;
-	bool do_lock = ((!selflocked) || callerbox != (&TASK->answerbox));
 
 	call->flags |= IPC_CALL_ANSWERED;
@@ -228,9 +210,7 @@
 	}
 
-	if (do_lock)
-		spinlock_lock(&callerbox->lock);
+	spinlock_lock(&callerbox->lock);
 	list_append(&call->link, &callerbox->answers);
-	if (do_lock)
-		spinlock_unlock(&callerbox->lock);
+	spinlock_unlock(&callerbox->lock);
 	waitq_wakeup(&callerbox->wq, WAKEUP_FIRST);
 }
@@ -248,5 +228,5 @@
 	spinlock_unlock(&box->lock);
 	/* Send back answer */
-	_ipc_answer_free_call(call, false);
+	_ipc_answer_free_call(call);
 }
 
@@ -265,5 +245,5 @@
 	atomic_inc(&phone->active_calls);
 	IPC_SET_RETVAL(call->data, err);
-	_ipc_answer_free_call(call, false);
+	_ipc_answer_free_call(call);
 }
 
@@ -304,5 +284,5 @@
 		if (call->flags & IPC_CALL_FORWARDED) {
 			IPC_SET_RETVAL(call->data, EFORWARD);
-			_ipc_answer_free_call(call, false);
+			_ipc_answer_free_call(call);
 		} else {
 			if (phone->state == IPC_PHONE_HUNGUP)
@@ -459,5 +439,5 @@
 
 		IPC_SET_RETVAL(call->data, EHANGUP);
-		_ipc_answer_free_call(call, true);
+		_ipc_answer_free_call(call);
 	}
 }
@@ -540,5 +520,4 @@
 	int i;
 	call_t *call;
-	ipl_t ipl;
 
 	/* Disconnect all our phones ('ipc_phone_hangup') */
@@ -566,19 +545,5 @@
 	spinlock_unlock(&TASK->answerbox.lock);
 	
-	/* Wait for all answers to interrupted synchronous calls to arrive */
-	ipl = interrupts_disable();
-	while (!list_empty(&TASK->sync_box_head)) {
-		answerbox_t *box = list_get_instance(TASK->sync_box_head.next,
-		    answerbox_t, sync_box_link);
-
-		list_remove(&box->sync_box_link);
-		call = ipc_wait_for_call(box, SYNCH_NO_TIMEOUT,
-		    SYNCH_FLAGS_NONE);
-		ipc_call_free(call);
-		slab_free(ipc_answerbox_slab, box);
-	}
-	interrupts_restore(ipl);
-
-	/* Wait for all answers to asynchronous calls to arrive */
+	/* Wait for all async answers to arrive */
 	while (1) {
 		/* Go through all phones, until all are FREE... */
@@ -587,8 +552,6 @@
 		for (i = 0; i < IPC_MAX_PHONES; i++) {
 			if (TASK->phones[i].state == IPC_PHONE_HUNGUP &&
-			    atomic_get(&TASK->phones[i].active_calls) == 0) {
+			    atomic_get(&TASK->phones[i].active_calls) == 0)
 				TASK->phones[i].state = IPC_PHONE_FREE;
-				TASK->phones[i].callee = NULL;
-			}
 			
 			/* Just for sure, we might have had some 
@@ -611,4 +574,5 @@
 		ASSERT((call->flags & IPC_CALL_ANSWERED) ||
 		    (call->flags & IPC_CALL_NOTIF));
+		ASSERT(!(call->flags & IPC_CALL_STATIC_ALLOC));
 		
 		/*
@@ -629,6 +593,4 @@
 	ipc_call_slab = slab_cache_create("ipc_call", sizeof(call_t), 0, NULL,
 	    NULL, 0);
-	ipc_answerbox_slab = slab_cache_create("ipc_answerbox",
-	    sizeof(answerbox_t), 0, NULL, NULL, 0);
 }
 
