Index: generic/src/syscall/syscall.c
===================================================================
--- generic/src/syscall/syscall.c	(revision d3e7ff48035bedaa7c22200c5da1b8629500fb65)
+++ generic/src/syscall/syscall.c	(revision 5f62ef99a9c5aa3020510303c82ab8fcbfa0b83b)
@@ -57,4 +57,17 @@
 }
 
+static phone_t * get_phone(__native phoneid)
+{
+	phone_t *phone;
+
+	if (phoneid >= IPC_MAX_PHONES)
+		return NULL;
+
+	phone = &TASK->phones[phoneid];
+	if (!phone->callee)
+		return NULL;
+	return phone;
+}
+
 /** Send a call over IPC, wait for reply, return to user
  *
@@ -62,6 +75,6 @@
            -2 on 'Too many async request, handle answers first
  */
-static __native sys_ipc_call_sync(__native phoneid, __native method, 
-				   __native arg1, __native *data)
+static __native sys_ipc_call_sync_fast(__native phoneid, __native method, 
+				       __native arg1, __native *data)
 {
 	call_t call;
@@ -69,9 +82,6 @@
 	/* Special answerbox for synchronous messages */
 
-	if (phoneid >= IPC_MAX_PHONES)
-		return IPC_CALLRET_FATAL;
-
-	phone = &TASK->phones[phoneid];
-	if (!phone->callee)
+	phone = get_phone(phoneid);
+	if (!phone)
 		return IPC_CALLRET_FATAL;
 
@@ -87,5 +97,6 @@
 }
 
-static __native sys_ipc_call_sync_medium(__native phoneid, __native *data)
+/** Synchronous IPC call allowing to send whole message */
+static __native sys_ipc_call_sync(__native phoneid, __native *data)
 {
 	call_t call;
@@ -93,9 +104,6 @@
 	/* Special answerbox for synchronous messages */
 
-	if (phoneid >= IPC_MAX_PHONES)
-		return IPC_CALLRET_FATAL;
-
-	phone = &TASK->phones[phoneid];
-	if (!phone->callee)
+	phone = get_phone(phoneid);
+	if (!phone)
 		return IPC_CALLRET_FATAL;
 
@@ -110,4 +118,16 @@
 }
 
+/** Check that the task did not exceed allowed limit
+ *
+ * @return 0 - Limit OK,   -1 - limit exceeded
+ */
+static int check_call_limit(void)
+{
+	if (atomic_inc_post(&TASK->active_calls) > IPC_MAX_ASYNC_CALLS) {
+		atomic_dec(&TASK->active_calls);
+		return -1;
+	}
+	return 0;
+}
 
 /** Send an asynchronous call over ipc
@@ -116,21 +136,17 @@
            -2 on 'Too many async request, handle answers first
  */
-static __native sys_ipc_call_async(__native phoneid, __native method, 
-				   __native arg1, __native arg2)
-{
-	call_t *call;
-	phone_t *phone;
-
-	if (phoneid >= IPC_MAX_PHONES)
-		return IPC_CALLRET_FATAL;
-
-	phone = &TASK->phones[phoneid];
-	if (!phone->callee)
-		return IPC_CALLRET_FATAL;
-
-	/* TODO: Check that we did not exceed system imposed maximum
-	 * of asynchrnously sent messages
-	 * - the userspace should be able to handle it correctly
-	 */
+static __native sys_ipc_call_async_fast(__native phoneid, __native method, 
+					__native arg1, __native arg2)
+{
+	call_t *call;
+	phone_t *phone;
+
+	phone = get_phone(phoneid);
+	if (!phone)
+		return IPC_CALLRET_FATAL;
+
+	if (check_call_limit())
+		return IPC_CALLRET_TEMPORARY;
+
 	call = ipc_call_alloc();
 	IPC_SET_METHOD(call->data, method);
@@ -143,4 +159,29 @@
 }
 
+/** Synchronous IPC call allowing to send whole message
+ *
+ * @return The same as sys_ipc_call_async
+ */
+static __native sys_ipc_call_async(__native phoneid, __native *data)
+{
+	call_t *call;
+	phone_t *phone;
+
+	phone = get_phone(phoneid);
+	if (!phone)
+		return IPC_CALLRET_FATAL;
+
+	if (check_call_limit())
+		return IPC_CALLRET_TEMPORARY;
+
+	call = ipc_call_alloc();
+	copy_from_uspace(&call->data, data, sizeof(call->data));
+	
+	ipc_call(phone, call);
+
+	return (__native) call;
+}
+
+
 /** Send IPC answer */
 static __native sys_ipc_answer(__native callid, __native retval, __native arg1,
@@ -175,7 +216,9 @@
 
 	copy_to_uspace(calldata, &call->data, sizeof(call->data));
+
 	if (call->flags & IPC_CALL_ANSWERED) {
 		ASSERT(! (call->flags & IPC_CALL_STATIC_ALLOC));
 		ipc_call_free(call);
+		atomic_dec(&TASK->active_calls);
 		return ((__native)call) | IPC_CALLID_ANSWERED;
 	}
@@ -192,6 +235,7 @@
 	sys_io,
 	sys_mremap,
+	sys_ipc_call_sync_fast,
 	sys_ipc_call_sync,
-	sys_ipc_call_sync_medium,
+	sys_ipc_call_async_fast,
 	sys_ipc_call_async,
 	sys_ipc_answer,
