Index: uspace/libc/generic/ipc.c
===================================================================
--- uspace/libc/generic/ipc.c	(revision 51ec40fa633067000ae92bcd7b38fde49fdfe205)
+++ uspace/libc/generic/ipc.c	(revision 84947a4204153f28ccee81dcdc393446c79f3b9d)
@@ -52,7 +52,6 @@
 #include <psthread.h>
 
-/** Structure used for keeping track of sent async msgs 
- * and queing unsent msgs
- *
+/** Structure used for keeping track of sent asynchronous calls and queing
+ * unsent calls.
  */
 typedef struct {
@@ -67,21 +66,33 @@
 			int phoneid;
 		} msg;
-	}u;
-	pstid_t ptid;   /**< Thread waiting for sending this msg */
+	} u;
+	pstid_t ptid;	/**< Pseudothread waiting for sending this call. */
 } async_call_t;
 
 LIST_INITIALIZE(dispatched_calls);
 
-/* queued_calls is protcted by async_futex, because if the
- * call cannot be sent into kernel, async framework is used
- * automatically
- */
-LIST_INITIALIZE(queued_calls); /**< List of async calls that were not accepted
-				*   by kernel */
+/** List of asynchronous calls that were not accepted by kernel.
+ *
+ * It is protected by async_futex, because if the call cannot be sent into the
+ * kernel, the async framework is used automatically.
+ */
+LIST_INITIALIZE(queued_calls);
 
 static atomic_t ipc_futex = FUTEX_INITIALIZER;
 
-int ipc_call_sync(int phoneid, ipcarg_t method, ipcarg_t arg1, 
-		  ipcarg_t *result)
+/** Make a fast synchronous call.
+ *
+ * Only one payload argument can be passed using this function. However, this
+ * function is faster than the generic ipc_call_sync_3().
+ *
+ * @param phoneid	Phone handle for the call.
+ * @param method	Requested method.
+ * @param arg1		Service-defined payload argument.
+ * @param result	If non-NULL, the return ARG1 will be stored there.
+ *
+ * @return		Negative values represent errors returned by IPC.
+ *			Otherwise the RETVAL of the answer is returned.
+ */
+int ipc_call_sync(int phoneid, ipcarg_t method, ipcarg_t arg1, ipcarg_t *result)
 {
 	ipc_call_t resdata;
@@ -89,5 +100,5 @@
 	
 	callres = __SYSCALL4(SYS_IPC_CALL_SYNC_FAST, phoneid, method, arg1,
-			     (sysarg_t)&resdata);
+	    (sysarg_t) &resdata);
 	if (callres)
 		return callres;
@@ -97,7 +108,20 @@
 }
 
-int ipc_call_sync_3(int phoneid, ipcarg_t method, ipcarg_t arg1,
-		    ipcarg_t arg2, ipcarg_t arg3,
-		    ipcarg_t *result1, ipcarg_t *result2, ipcarg_t *result3)
+/** Make a synchronous call transmitting 3 arguments of payload.
+ *
+ * @param phoneid	Phone handle for the call.
+ * @param method	Requested method.
+ * @param arg1		Service-defined payload argument.
+ * @param arg2		Service-defined payload argument.
+ * @param arg3		Service-defined payload argument.
+ * @param result1	If non-NULL, storage for the first return argument.
+ * @param result2	If non-NULL, storage for the second return argument.
+ * @param result3	If non-NULL, storage for the third return argument.
+ *
+ * @return		Negative value means IPC error.
+ *			Otherwise the RETVAL of the answer.
+ */
+int ipc_call_sync_3(int phoneid, ipcarg_t method, ipcarg_t arg1, ipcarg_t arg2,
+    ipcarg_t arg3, ipcarg_t *result1, ipcarg_t *result2, ipcarg_t *result3)
 {
 	ipc_call_t data;
@@ -109,6 +133,6 @@
 	IPC_SET_ARG3(data, arg3);
 
-	callres = __SYSCALL3(SYS_IPC_CALL_SYNC, phoneid, (sysarg_t)&data,
-			     (sysarg_t)&data);
+	callres = __SYSCALL3(SYS_IPC_CALL_SYNC, phoneid, (sysarg_t) &data,
+	    (sysarg_t) &data);
 	if (callres)
 		return callres;
@@ -123,12 +147,25 @@
 }
 
-/** Syscall to send asynchronous message */
-static	ipc_callid_t _ipc_call_async(int phoneid, ipc_call_t *data)
-{
-	return __SYSCALL2(SYS_IPC_CALL_ASYNC, phoneid, (sysarg_t)data);
-}
-
-/** Prolog to ipc_async_send functions */
-static inline async_call_t *ipc_prepare_async(void *private, ipc_async_callback_t callback)
+/** Syscall to send asynchronous message.
+ *
+ * @param phoneid	Phone handle for the call.
+ * @param data		Call data with the request.
+ *
+ * @return		Hash of the call or an error code.
+ */
+static ipc_callid_t _ipc_call_async(int phoneid, ipc_call_t *data)
+{
+	return __SYSCALL2(SYS_IPC_CALL_ASYNC, phoneid, (sysarg_t) data);
+}
+
+/** Prolog to ipc_call_async_*() functions.
+ *
+ * @param private	Argument for the answer/error callback.
+ * @param callback	Answer/error callback.
+ *
+ * @return		New, partially initialized async_call structure or NULL.
+ */
+static inline async_call_t *ipc_prepare_async(void *private,
+    ipc_async_callback_t callback)
 {
 	async_call_t *call;
@@ -146,7 +183,14 @@
 }
 
-/** Epilogue of ipc_async_send functions */
-static inline void ipc_finish_async(ipc_callid_t callid, int phoneid, 
-				    async_call_t *call, int can_preempt)
+/** Epilogue of ipc_call_async_*() functions.
+ *
+ * @param callid	Value returned by the SYS_IPC_CALL_ASYNC_* syscall.
+ * @param phoneid	Phone handle through which the call was made.
+ * @param call		async_call structure returned by ipc_prepare_async().
+ * @param can_preempt	If non-zero, the current pseudo thread can be preempted
+ *			in this call.
+ */
+static inline void ipc_finish_async(ipc_callid_t callid, int phoneid,
+    async_call_t *call, int can_preempt)
 {
 	if (!call) { /* Nothing to do regardless if failed or not */
@@ -183,5 +227,5 @@
 	}
 	call->u.callid = callid;
-	/* Add call to list of dispatched calls */
+	/* Add call to the list of dispatched calls */
 	list_append(&call->list, &dispatched_calls);
 	futex_up(&ipc_futex);
@@ -189,12 +233,27 @@
 }
 
-/** Send asynchronous message
- *
- * - if fatal error, call callback handler with proper error code
- * - if message cannot be temporarily sent, add to queue
+/** Make a fast asynchronous call.
+ *
+ * This function can only handle two arguments of payload. It is, however,
+ * faster than the more generic ipc_call_async_3().
+ *
+ * Note that this function is a void function.
+ * During normal opertation, answering this call will trigger the callback.
+ * In case of fatal error, call the callback handler with the proper error code.
+ * If the call cannot be temporarily made, queue it.
+ *
+ * @param phoneid	Phone handle for the call.
+ * @param method	Requested method.
+ * @param arg1		Service-defined payload argument.
+ * @param arg2		Service-defined payload argument.
+ * @param private	Argument to be passed to the answer/error callback.
+ * @param callback	Answer or error callback.
+ * @param can_preempt	If non-zero, the current pseudo thread will be preempted
+ *			in case the kernel temporarily refuses to accept more
+ *			asynchronous calls.
  */
 void ipc_call_async_2(int phoneid, ipcarg_t method, ipcarg_t arg1,
-		      ipcarg_t arg2, void *private,
-		      ipc_async_callback_t callback, int can_preempt)
+    ipcarg_t arg2, void *private, ipc_async_callback_t callback,
+    int can_preempt)
 {
 	async_call_t *call = NULL;
@@ -207,8 +266,11 @@
 	}
 
-	/* We need to make sure that we get callid before
-	 * another thread accesses the queue again */
+	/*
+	 * We need to make sure that we get callid before another thread
+	 * accesses the queue again.
+	 */
 	futex_down(&ipc_futex);
-	callid = __SYSCALL4(SYS_IPC_CALL_ASYNC_FAST, phoneid, method, arg1, arg2);
+	callid = __SYSCALL4(SYS_IPC_CALL_ASYNC_FAST, phoneid, method, arg1,
+	    arg2);
 
 	if (callid == IPC_CALLRET_TEMPORARY) {
@@ -225,12 +287,26 @@
 }
 
-/** Send asynchronous message
- *
- * - if fatal error, call callback handler with proper error code
- * - if message cannot be temporarily sent, add to queue
+/** Make an asynchronous call transmitting the entire payload.
+ *
+ * Note that this function is a void function.
+ * During normal opertation, answering this call will trigger the callback.
+ * In case of fatal error, call the callback handler with the proper error code.
+ * If the call cannot be temporarily made, queue it.
+ *
+ * @param phoneid	Phone handle for the call.
+ * @param method	Requested method.
+ * @param arg1		Service-defined payload argument.
+ * @param arg2		Service-defined payload argument.
+ * @param arg3		Service-defined payload argument.
+ * @param private	Argument to be passed to the answer/error callback.
+ * @param callback	Answer or error callback.
+ * @param can_preempt	If non-zero, the current pseudo thread will be preempted
+ *			in case the kernel temporarily refuses to accept more
+ *			asynchronous calls.
+ *
  */
 void ipc_call_async_3(int phoneid, ipcarg_t method, ipcarg_t arg1,
-		      ipcarg_t arg2, ipcarg_t arg3, void *private,
-		      ipc_async_callback_t callback, int can_preempt)
+    ipcarg_t arg2, ipcarg_t arg3, void *private, ipc_async_callback_t callback,
+    int can_preempt)
 {
 	async_call_t *call;
@@ -245,6 +321,8 @@
 	IPC_SET_ARG2(call->u.msg.data, arg2);
 	IPC_SET_ARG3(call->u.msg.data, arg3);
-	/* We need to make sure that we get callid before
-	 * another thread accesses the queue again */
+	/*
+	 * We need to make sure that we get callid before another thread accesses
+	 * the queue again.
+	 */
 	futex_down(&ipc_futex);
 	callid = _ipc_call_async(phoneid, &call->u.msg.data);
@@ -254,28 +332,29 @@
 
 
-/** Send a fast answer to a received call.
- *
- * The fast answer makes use of passing retval and first two arguments in registers.
- * If you need to return more, use the ipc_answer() instead.
- *
- * @param callid ID of the call being answered.
- * @param retval Return value.
- * @param arg1 First return argument.
- * @param arg2 Second return argument.
- *
- * @return Zero on success or a value from @ref errno.h on failure.
+/** Answer a received call - fast version.
+ *
+ * The fast answer makes use of passing retval and first two arguments in
+ * registers. If you need to return more, use the ipc_answer() instead.
+ *
+ * @param callid	Hash of the call being answered.
+ * @param retval	Return value.
+ * @param arg1		First return argument.
+ * @param arg2		Second return argument.
+ *
+ * @return		Zero on success or a value from @ref errno.h on failure.
  */
 ipcarg_t ipc_answer_fast(ipc_callid_t callid, ipcarg_t retval, ipcarg_t arg1,
-		ipcarg_t arg2)
+    ipcarg_t arg2)
 {
 	return __SYSCALL4(SYS_IPC_ANSWER_FAST, callid, retval, arg1, arg2);
 }
 
-/** Send a full answer to a received call.
- *
- * @param callid ID of the call being answered.
- * @param call Call data. Must be already initialized by the responder.
- *
- * @return Zero on success or a value from @ref errno.h on failure.
+/** Answer a received call - full version.
+ *
+ * @param callid	Hash of the call being answered.
+ * @param call 		Call structure with the answer.
+ *			Must be already initialized by the responder.
+ *
+ * @return		Zero on success or a value from @ref errno.h on failure.
  */
 ipcarg_t ipc_answer(ipc_callid_t callid, ipc_call_t *call)
@@ -285,5 +364,5 @@
 
 
-/** Try to dispatch queed calls from async queue */
+/** Try to dispatch queued calls from the async queue. */
 static void try_dispatch_queued_calls(void)
 {
@@ -291,15 +370,12 @@
 	ipc_callid_t callid;
 
-	/* TODO: integrate intelligently ipc_futex, so that it
-	 * is locked during ipc_call_async, until it is added
-	 * to dispatched_calls
+	/** @todo
+	 * Integrate intelligently ipc_futex, so that it is locked during
+	 * ipc_call_async_*(), until it is added to dispatched_calls.
 	 */
 	futex_down(&async_futex);
 	while (!list_empty(&queued_calls)) {
-		call = list_get_instance(queued_calls.next, async_call_t,
-					 list);
-
-		callid = _ipc_call_async(call->u.msg.phoneid,
-					 &call->u.msg.data);
+		call = list_get_instance(queued_calls.next, async_call_t, list);
+		callid = _ipc_call_async(call->u.msg.phoneid, &call->u.msg.data);
 		if (callid == IPC_CALLRET_TEMPORARY) {
 			break;
@@ -326,9 +402,14 @@
 }
 
-/** Handle received answer
- *
- * TODO: Make it use hash table
- *
- * @param callid Callid (with first bit set) of the answered call
+/** Handle a received answer.
+ *
+ * Find the hash of the answer and call the answer callback.
+ *
+ * @todo Make it use hash table.
+ *
+ * @param callid	Hash of the received answer.
+ *			The answer has the same hash as the request OR'ed with
+ *			the IPC_CALLID_ANSWERED bit.
+ * @param data		Call data of the answer.
  */
 static void handle_answer(ipc_callid_t callid, ipc_call_t *data)
@@ -341,5 +422,5 @@
 	futex_down(&ipc_futex);
 	for (item = dispatched_calls.next; item != &dispatched_calls;
-	     item = item->next) {
+	    item = item->next) {
 		call = list_get_instance(item, async_call_t, list);
 		if (call->u.callid == callid) {
@@ -348,6 +429,5 @@
 			if (call->callback)
 				call->callback(call->private, 
-					       IPC_GET_RETVAL(*data),
-					       data);
+				    IPC_GET_RETVAL(*data), data);
 			free(call);
 			return;
@@ -355,15 +435,17 @@
 	}
 	futex_up(&ipc_futex);
-	/* We may get here after async_msg, which doesn't register any callback */
-}
-
-
-/** One cycle of ipc wait for call call
- *
- * - dispatch ASYNC reoutines in the background
- * @param call Space where the message is stored
- * @param usec Timeout in microseconds
- * @param flags Flags passed to SYS_IPC_WAIT (blocking, nonblocking)
- * @return Callid of the answer.
+}
+
+
+/** Wait for a first call to come.
+ *
+ * @param call		Storage where the incoming call data will be stored.
+ * @param usec		Timeout in microseconds
+ * @param flags		Flags passed to SYS_IPC_WAIT (blocking, nonblocking).
+ *
+ * @return		Hash of the call. Note that certain bits have special
+ *			meaning. IPC_CALLID_ANSWERED will be set in an answer
+ *			and IPC_CALLID_NOTIFICATION is used for notifications.
+ *			
  */
 ipc_callid_t ipc_wait_cycle(ipc_call_t *call, uint32_t usec, int flags)
@@ -383,9 +465,10 @@
 /** Wait some time for an IPC call.
  *
- * - dispatch ASYNC reoutines in the background
- *
- * @param call Space where the message is stored
- * @param usec Timeout in microseconds.
- * @return Callid of the answer.
+ * The call will return after an answer is received.
+ *
+ * @param call		Storage where the incoming call data will be stored.
+ * @param usec		Timeout in microseconds.
+ *
+ * @return		Hash of the answer.
  */
 ipc_callid_t ipc_wait_for_call_timeout(ipc_call_t *call, uint32_t usec)
@@ -402,8 +485,6 @@
 /** Check if there is an IPC call waiting to be picked up.
  *
- * - dispatch ASYNC reoutines in the background
- *
- * @param call Space where the message is stored
- * @return Callid of the answer.
+ * @param call		Storage where the incoming call will be stored.
+ * @return		Hash of the answer.
  */
 ipc_callid_t ipc_trywait_for_call(ipc_call_t *call)
@@ -412,5 +493,6 @@
 
 	do {
-		callid = ipc_wait_cycle(call, SYNCH_NO_TIMEOUT, SYNCH_FLAGS_NON_BLOCKING);
+		callid = ipc_wait_cycle(call, SYNCH_NO_TIMEOUT,
+		    SYNCH_FLAGS_NON_BLOCKING);
 	} while (callid & IPC_CALLID_ANSWERED);
 
@@ -420,25 +502,27 @@
 /** Ask destination to do a callback connection.
  *
- * @param phoneid	Phone ID used for contacting the other side.
+ * @param phoneid	Phone handle used for contacting the other side.
+ * @param arg1		Service-defined argument.
+ * @param arg2		Service-defined argument.
+ * @param phonehash	Storage where the library will store an opaque
+ *			identifier of the phone that will be used for incoming
+ *			calls. This identifier can be used for connection
+ *			tracking.
+ *
+ * @return		Zero on success or a negative error code.
+ */
+int ipc_connect_to_me(int phoneid, int arg1, int arg2, ipcarg_t *phonehash)
+{
+	return ipc_call_sync_3(phoneid, IPC_M_CONNECT_TO_ME, arg1, arg2, 0, 0, 0,
+	    phonehash);
+}
+
+/** Ask through phone for a new connection to some service.
+ *
+ * @param phoneid	Phone handle used for contacting the other side.
  * @param arg1		User defined argument.
  * @param arg2		User defined argument.
- * @param phonehash	Pointer to a place where the library will store an opaque
- *			identifier of the phone that will be used for incoming
- *			calls.
- * @return Zero on success or a negative error code.
- */
-int ipc_connect_to_me(int phoneid, int arg1, int arg2, ipcarg_t *phonehash)
-{
-	return ipc_call_sync_3(phoneid, IPC_M_CONNECT_TO_ME, arg1, arg2, 0, 0, 0,
-	    phonehash);
-}
-
-/** Ask through phone for a new connection to some service.
- *
- * @param phoneid	Phone ID used for contacting the other side.
- * @param arg1		User defined argument.
- * @param arg2		User defined argument.
- *
- * @return New phone ID on success or a negative error code.
+ *
+ * @return		New phone handle on success or a negative error code.
  */
 int ipc_connect_me_to(int phoneid, int arg1, int arg2)
@@ -454,5 +538,10 @@
 }
 
-/* Hang up specified phone */
+/** Hang up a phone.
+ *
+ * @param phoneid	Handle of the phone to be hung up.
+ *
+ * @return		Zero on success or a negative error code.
+ */
 int ipc_hangup(int phoneid)
 {
@@ -462,22 +551,23 @@
 /** Register IRQ notification.
  *
- * @param inr IRQ number.
- * @param devno Device number of the device generating inr.
- * @param method Use this method for notifying me.
- * @param ucode Top-half pseudocode handler.
- *
- * @return Value returned by the kernel.
+ * @param inr		IRQ number.
+ * @param devno		Device number of the device generating inr.
+ * @param method	Use this method for notifying me.
+ * @param ucode		Top-half pseudocode handler.
+ *
+ * @return		Value returned by the kernel.
  */
 int ipc_register_irq(int inr, int devno, int method, irq_code_t *ucode)
 {
-	return __SYSCALL4(SYS_IPC_REGISTER_IRQ, inr, devno, method, (sysarg_t) ucode);
+	return __SYSCALL4(SYS_IPC_REGISTER_IRQ, inr, devno, method,
+	    (sysarg_t) ucode);
 }
 
 /** Unregister IRQ notification.
  *
- * @param inr IRQ number.
- * @param devno Device number of the device generating inr.
- *
- * @return Value returned by the kernel.
+ * @param inr		IRQ number.
+ * @param devno		Device number of the device generating inr.
+ *
+ * @return		Value returned by the kernel.
  */
 int ipc_unregister_irq(int inr, int devno)
@@ -486,4 +576,17 @@
 }
 
+/** Forward a received call to another destination.
+ *
+ * @param callid	Hash of the call to forward.
+ * @param phoneid	Phone handle to use for forwarding.
+ * @param method	New method for the forwarded call.
+ * @param arg1		New value of the first argument for the forwarded call.
+ *
+ * @return		Zero on success or an error code.
+ *
+ * For non-system methods, the old method and arg1 are rewritten by the new
+ * values. For system methods, the new method and arg1 are written to the old
+ * arg1 and arg2, respectivelly.
+ */
 int ipc_forward_fast(ipc_callid_t callid, int phoneid, int method, ipcarg_t arg1)
 {
