Index: generic/include/ipc/ipc.h
===================================================================
--- generic/include/ipc/ipc.h	(revision ba81cab60a5926ed0eb9888e74ef22a77ec9792e)
+++ generic/include/ipc/ipc.h	(revision b4b45210fc5bef84b7f8456d96320f10dd3f5245)
@@ -38,13 +38,18 @@
 
 /* Flags for calls */
-#define IPC_CALL_ANSWERED      0x1 /**< This is answer to a call */
-#define IPC_CALL_STATIC_ALLOC  0x2 /**< This call will not be freed on error */
-#define IPC_CALL_DISPATCHED    0x4 /**< Call is in dispatch queue */
+#define IPC_CALL_ANSWERED     (1<<0) /**< This is answer to a call */
+#define IPC_CALL_STATIC_ALLOC (1<<1) /**< This call will not be freed on error */
+#define IPC_CALL_DISPATCHED   (1<<2) /**< Call is in dispatch queue */
+#define IPC_CALL_DISCARD_ANSWER (1<<3) /**< Answer will not be passed to
+					* userspace, will be discarded */
 
 /* Flags for ipc_wait_for_call */
 #define IPC_WAIT_NONBLOCKING   1
 
-/* Flags of callid */
-#define IPC_CALLID_ANSWERED  1
+/* Flags of callid (the addresses are aligned at least to 4, 
+ * that is why we can use bottom 2 bits of the call address
+ */
+#define IPC_CALLID_ANSWERED       1 /**< Type of this msg is 'answer' */
+#define IPC_CALLID_NOTIFICATION   2 /**< Type of this msg is 'notification' */
 
 /* Return values from IPC_ASYNC */
@@ -54,16 +59,16 @@
 
 /* Macros for manipulating calling data */
-#define IPC_SET_RETVAL(data, retval)   ((data)[0] = (retval))
-#define IPC_SET_METHOD(data, val)   ((data)[0] = (val))
-#define IPC_SET_ARG1(data, val)   ((data)[1] = (val))
-#define IPC_SET_ARG2(data, val)   ((data)[2] = (val))
-#define IPC_SET_ARG3(data, val)   ((data)[3] = (val))
-
-#define IPC_GET_METHOD(data)           ((data)[0])
-#define IPC_GET_RETVAL(data)           ((data)[0])
-
-#define IPC_GET_ARG1(data)              ((data)[1])
-#define IPC_GET_ARG2(data)              ((data)[2])
-#define IPC_GET_ARG3(data)              ((data)[3])
+#define IPC_SET_RETVAL(data, retval)   ((data).args[0] = (retval))
+#define IPC_SET_METHOD(data, val)   ((data).args[0] = (val))
+#define IPC_SET_ARG1(data, val)   ((data).args[1] = (val))
+#define IPC_SET_ARG2(data, val)   ((data).args[2] = (val))
+#define IPC_SET_ARG3(data, val)   ((data).args[3] = (val))
+
+#define IPC_GET_METHOD(data)           ((data).args[0])
+#define IPC_GET_RETVAL(data)           ((data).args[0])
+
+#define IPC_GET_ARG1(data)              ((data).args[1])
+#define IPC_GET_ARG2(data)              ((data).args[2])
+#define IPC_GET_ARG3(data)              ((data).args[3])
 
 /* Well known phone descriptors */
@@ -90,5 +95,5 @@
  *                     - the caller obtains taskid of the called thread
  */
-#define IPC_M_CONNECTTOME     1
+#define IPC_M_CONNECT_TO_ME     1
 /** Protocol for CONNECT - ME - TO
  *
@@ -109,8 +114,9 @@
  *
  */
-#define IPC_M_CONNECTMETO     2
-/* Control messages that the server sends to the processes 
- * about their connections.
- */
+#define IPC_M_CONNECT_ME_TO     2
+/** This message is sent to answerbox when the phone
+ * is hung up
+ */
+#define IPC_M_PHONE_HUNGUP      3
 
 
@@ -129,16 +135,12 @@
 #define IPC_MAX_PHONES  16
 
-typedef struct answerbox answerbox_t;
-typedef __native ipc_data_t[IPC_CALL_LEN];
-
+typedef struct answerbox_s answerbox_t;
+typedef struct phone_s phone_t;
 typedef struct {
-	link_t list;
-	answerbox_t *callerbox;
-	int flags;
-	task_t *sender;
-	ipc_data_t data;
-} call_t;
-
-struct answerbox {
+	__native args[IPC_CALL_LEN];
+	phone_t *phone;
+}ipc_data_t;
+
+struct answerbox_s {
 	SPINLOCK_DECLARE(lock);
 
@@ -154,10 +156,26 @@
 };
 
-typedef struct {
+struct phone_s {
 	SPINLOCK_DECLARE(lock);
 	link_t list;
 	answerbox_t *callee;
 	int busy;
-} phone_t;
+	atomic_t active_calls;
+};
+
+typedef struct {
+	link_t list;
+
+	int flags;
+
+	/* Identification of the caller */
+	task_t *sender;
+	/* The caller box is different from sender->answerbox
+	 * for synchronous calls
+	 */
+	answerbox_t *callerbox;
+
+	ipc_data_t data;
+}call_t;
 
 extern void ipc_init(void);
@@ -166,5 +184,4 @@
 extern void ipc_call(phone_t *phone, call_t *request);
 extern void ipc_call_sync(phone_t *phone, call_t *request);
-extern void ipc_phone_destroy(phone_t *phone);
 extern void ipc_phone_init(phone_t *phone);
 extern void ipc_phone_connect(phone_t *phone, answerbox_t *box);
@@ -178,4 +195,5 @@
 extern answerbox_t *ipc_phone_0;
 extern void ipc_cleanup(task_t *task);
+extern int ipc_phone_hangup(phone_t *phone);
 
 #endif
Index: generic/include/ipc/ipcrsc.h
===================================================================
--- generic/include/ipc/ipcrsc.h	(revision ba81cab60a5926ed0eb9888e74ef22a77ec9792e)
+++ generic/include/ipc/ipcrsc.h	(revision b4b45210fc5bef84b7f8456d96320f10dd3f5245)
@@ -32,7 +32,6 @@
 call_t * get_call(__native callid);
 int phone_alloc(void);
+void phone_connect(int phoneid, answerbox_t *box);
 void phone_dealloc(int phoneid);
-void phone_connect(int phoneid, answerbox_t *box);
-
 
 #endif
Index: generic/include/ipc/sysipc.h
===================================================================
--- generic/include/ipc/sysipc.h	(revision ba81cab60a5926ed0eb9888e74ef22a77ec9792e)
+++ generic/include/ipc/sysipc.h	(revision b4b45210fc5bef84b7f8456d96320f10dd3f5245)
@@ -31,13 +31,13 @@
 
 __native sys_ipc_call_sync_fast(__native phoneid, __native method, 
-				__native arg1, __native *data);
-__native sys_ipc_call_sync(__native phoneid, __native *question, 
-			   __native *reply);
+				__native arg1, ipc_data_t *data);
+__native sys_ipc_call_sync(__native phoneid, ipc_data_t *question, 
+			   ipc_data_t *reply);
 __native sys_ipc_call_async_fast(__native phoneid, __native method, 
 				 __native arg1, __native arg2);
-__native sys_ipc_call_async(__native phoneid, __native *data);
+__native sys_ipc_call_async(__native phoneid, ipc_data_t *data);
 __native sys_ipc_answer_fast(__native callid, __native retval, 
 			     __native arg1, __native arg2);
-__native sys_ipc_answer(__native callid, __native *data);
+__native sys_ipc_answer(__native callid, ipc_data_t *data);
 __native sys_ipc_connect_to_me(__native phoneid, __native arg1,
 			       __native arg2, task_id_t *taskid);
@@ -48,4 +48,5 @@
 __native sys_ipc_forward_fast(__native callid, __native phoneid,
 			      __native method, __native arg1);
+__native sys_ipc_hangup(int phoneid);
 
 
