Subversion Repositories HelenOS

Rev

Rev 2678 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. /*
  2.  * Copyright (c) 2006 Ondrej Palkovsky
  3.  * All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms, with or without
  6.  * modification, are permitted provided that the following conditions
  7.  * are met:
  8.  *
  9.  * - Redistributions of source code must retain the above copyright
  10.  *   notice, this list of conditions and the following disclaimer.
  11.  * - Redistributions in binary form must reproduce the above copyright
  12.  *   notice, this list of conditions and the following disclaimer in the
  13.  *   documentation and/or other materials provided with the distribution.
  14.  * - The name of the author may not be used to endorse or promote products
  15.  *   derived from this software without specific prior written permission.
  16.  *
  17.  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  18.  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  19.  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  20.  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  21.  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  22.  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  23.  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  24.  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  25.  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  26.  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  27.  */
  28.  
  29. /** @addtogroup libcipc
  30.  * @{
  31.  */
  32. /** @file
  33.  */
  34.  
  35. #ifndef LIBIPC_IPC_H_
  36. #define LIBIPC_IPC_H_
  37.  
  38. #include <kernel/ipc/ipc.h>
  39. #include <kernel/ddi/irq.h>
  40. #include <sys/types.h>
  41. #include <kernel/synch/synch.h>
  42.  
  43. typedef sysarg_t ipcarg_t;
  44. typedef struct {
  45.     ipcarg_t args[IPC_CALL_LEN];
  46.     ipcarg_t in_phone_hash;
  47. } ipc_call_t;
  48. typedef sysarg_t ipc_callid_t;
  49.  
  50. typedef void (* ipc_async_callback_t)(void *private, int retval,
  51.     ipc_call_t *data);
  52.  
  53. /*
  54.  * User-friendly wrappers for ipc_call_sync_fast() and ipc_call_sync_slow().
  55.  * They are in the form ipc_call_sync_m_n(), where m denotes the number of
  56.  * arguments of payload and n denotes number of return values. Whenever
  57.  * possible, the fast version is used.
  58.  */
  59. #define ipc_call_sync_0_0(phoneid, method) \
  60.     ipc_call_sync_fast((phoneid), (method), 0, 0, 0, 0, 0, 0, 0, 0)
  61. #define ipc_call_sync_0_1(phoneid, method, res1) \
  62.     ipc_call_sync_fast((phoneid), (method), 0, 0, 0, (res1), 0, 0, 0, 0)
  63. #define ipc_call_sync_0_2(phoneid, method, res1, res2) \
  64.     ipc_call_sync_fast((phoneid), (method), 0, 0, 0, (res1), (res2), 0, 0, 0)
  65. #define ipc_call_sync_0_3(phoneid, method, res1, res2, res3) \
  66.     ipc_call_sync_fast((phoneid), (method), 0, 0, 0, (res1), (res2), (res3), \
  67.         0, 0)
  68. #define ipc_call_sync_0_4(phoneid, method, res1, res2, res3, res4) \
  69.     ipc_call_sync_fast((phoneid), (method), 0, 0, 0, (res1), (res2), (res3), \
  70.         (res4), 0)
  71. #define ipc_call_sync_0_5(phoneid, method, res1, res2, res3, res4, res5) \
  72.     ipc_call_sync_fast((phoneid), (method), 0, 0, 0, (res1), (res2), (res3), \
  73.         (res4), (res5))
  74. #define ipc_call_sync_1_0(phoneid, method, arg1) \
  75.     ipc_call_sync_fast((phoneid), (method), (arg1), 0, 0, 0, 0, 0, 0, 0)
  76. #define ipc_call_sync_1_1(phoneid, method, arg1, res1) \
  77.     ipc_call_sync_fast((phoneid), (method), (arg1), 0, 0, (res1), 0, 0, 0, 0)
  78. #define ipc_call_sync_1_2(phoneid, method, arg1, res1, res2) \
  79.     ipc_call_sync_fast((phoneid), (method), (arg1), 0, 0, (res1), (res2), 0, \
  80.     0, 0)
  81. #define ipc_call_sync_1_3(phoneid, method, arg1, res1, res2, res3) \
  82.     ipc_call_sync_fast((phoneid), (method), (arg1), 0, 0, (res1), (res2), \
  83.     (res3), 0, 0)
  84. #define ipc_call_sync_1_4(phoneid, method, arg1, res1, res2, res3, res4) \
  85.     ipc_call_sync_fast((phoneid), (method), (arg1), 0, 0, (res1), (res2), \
  86.     (res3), (res4), 0)
  87. #define ipc_call_sync_1_5(phoneid, method, arg1, res1, res2, res3, res4, \
  88.     res5) \
  89.     ipc_call_sync_fast((phoneid), (method), (arg1), 0, 0, (res1), (res2), \
  90.         (res3), (res4), (res5))
  91. #define ipc_call_sync_2_0(phoneid, method, arg1, arg2) \
  92.     ipc_call_sync_fast((phoneid), (method), (arg1), (arg2), 0, 0, 0, 0, \
  93.     0, 0)
  94. #define ipc_call_sync_2_1(phoneid, method, arg1, arg2, res1) \
  95.     ipc_call_sync_fast((phoneid), (method), (arg1), (arg2), 0, (res1), 0, 0, \
  96.     0, 0)
  97. #define ipc_call_sync_2_2(phoneid, method, arg1, arg2, res1, res2) \
  98.     ipc_call_sync_fast((phoneid), (method), (arg1), (arg2), 0, (res1), \
  99.     (res2), 0, 0, 0)
  100. #define ipc_call_sync_2_3(phoneid, method, arg1, arg2, res1, res2, res3) \
  101.     ipc_call_sync_fast((phoneid), (method), (arg1), (arg2), 0, (res1), \
  102.     (res2), (res3), 0, 0)
  103. #define ipc_call_sync_2_4(phoneid, method, arg1, arg2, res1, res2, res3, \
  104.     res4) \
  105.     ipc_call_sync_fast((phoneid), (method), (arg1), (arg2), 0, (res1), \
  106.         (res2), (res3), (res4), 0)
  107. #define ipc_call_sync_2_5(phoneid, method, arg1, arg2, res1, res2, res3, \
  108.     res4, res5)\
  109.     ipc_call_sync_fast((phoneid), (method), (arg1), (arg2), 0, (res1), \
  110.         (res2), (res3), (res4), (res5))
  111. #define ipc_call_sync_3_0(phoneid, method, arg1, arg2, arg3) \
  112.     ipc_call_sync_fast((phoneid), (method), (arg1), (arg2), (arg3), 0, 0, 0, \
  113.     0, 0)
  114. #define ipc_call_sync_3_1(phoneid, method, arg1, arg2, arg3, res1) \
  115.     ipc_call_sync_fast((phoneid), (method), (arg1), (arg2), (arg3), (res1), \
  116.     0, 0, 0, 0)
  117. #define ipc_call_sync_3_2(phoneid, method, arg1, arg2, arg3, res1, res2) \
  118.     ipc_call_sync_fast((phoneid), (method), (arg1), (arg2), (arg3), (res1), \
  119.     (res2), 0, 0, 0)
  120. #define ipc_call_sync_3_3(phoneid, method, arg1, arg2, arg3, res1, res2, \
  121.     res3) \
  122.     ipc_call_sync_fast((phoneid), (method), (arg1), (arg2), (arg3), \
  123.         (res1), (res2), (res3), 0, 0)
  124. #define ipc_call_sync_3_4(phoneid, method, arg1, arg2, arg3, res1, res2, \
  125.     res3, res4) \
  126.     ipc_call_sync_fast((phoneid), (method), (arg1), (arg2), (arg3), \
  127.         (res1), (res2), (res3), (res4), 0)
  128. #define ipc_call_sync_3_5(phoneid, method, arg1, arg2, arg3, res1, res2, \
  129.     res3, res4, res5) \
  130.     ipc_call_sync_fast((phoneid), (method), (arg1), (arg2), (arg3), \
  131.         (res1), (res2), (res3), (res4), (res5))
  132. #define ipc_call_sync_4_0(phoneid, method, arg1, arg2, arg3, arg4) \
  133.     ipc_call_sync_slow((phoneid), (method), (arg1), (arg2), (arg3), (arg4), \
  134.     0, 0, 0, 0, 0)
  135. #define ipc_call_sync_4_1(phoneid, method, arg1, arg2, arg3, arg4, res1) \
  136.     ipc_call_sync_slow((phoneid), (method), (arg1), (arg2), (arg3), (arg4), \
  137.     (res1), 0, 0, 0, 0)
  138. #define ipc_call_sync_4_2(phoneid, method, arg1, arg2, arg3, arg4, res1, res2) \
  139.     ipc_call_sync_slow((phoneid), (method), (arg1), (arg2), (arg3), (arg4), \
  140.     (res1), (res2), 0, 0, 0)
  141. #define ipc_call_sync_4_3(phoneid, method, arg1, arg2, arg3, arg4, res1, res2, \
  142.     res3) \
  143.     ipc_call_sync_slow((phoneid), (method), (arg1), (arg2), (arg3), \
  144.         (arg4), (res1), (res2), (res3), 0, 0)
  145. #define ipc_call_sync_4_4(phoneid, method, arg1, arg2, arg3, arg4, res1, res2, \
  146.     res3, res4) \
  147.     ipc_call_sync_slow((phoneid), (method), (arg1), (arg2), (arg3), \
  148.         (arg4), (res1), (res2), (res3), (res4), 0)
  149. #define ipc_call_sync_4_5(phoneid, method, arg1, arg2, arg3, arg4, res1, res2, \
  150.     res3, res4, res5) \
  151.     ipc_call_sync_slow((phoneid), (method), (arg1), (arg2), (arg3), \
  152.         (arg4), (res1), (res2), (res3), (res4), (res5))
  153. #define ipc_call_sync_5_0(phoneid, method, arg1, arg2, arg3, arg4, arg5) \
  154.     ipc_call_sync_slow((phoneid), (method), (arg1), (arg2), (arg3), (arg4), \
  155.         (arg5), 0, 0, 0, 0, 0)
  156. #define ipc_call_sync_5_1(phoneid, method, arg1, arg2, arg3, arg4, arg5, res1) \
  157.     ipc_call_sync_slow((phoneid), (method), (arg1), (arg2), (arg3), (arg4), \
  158.         (arg5), (res1), 0, 0, 0, 0)
  159. #define ipc_call_sync_5_2(phoneid, method, arg1, arg2, arg3, arg4, arg5, res1, \
  160.     res2) \
  161.     ipc_call_sync_slow((phoneid), (method), (arg1), (arg2), (arg3), \
  162.         (arg4), (arg5), (res1), (res2), 0, 0, 0)
  163. #define ipc_call_sync_5_3(phoneid, method, arg1, arg2, arg3, arg4, arg5, res1, \
  164.     res2, res3) \
  165.     ipc_call_sync_slow((phoneid), (method), (arg1), (arg2), (arg3), \
  166.         (arg4), (arg5), (res1), (res2), (res3), 0, 0)
  167. #define ipc_call_sync_5_4(phoneid, method, arg1, arg2, arg3, arg4, arg5, res1, \
  168.     res2, res3, res4) \
  169.     ipc_call_sync_slow((phoneid), (method), (arg1), (arg2), (arg3), \
  170.         (arg4), (arg5), (res1), (res2), (res3), (res4), 0)
  171. #define ipc_call_sync_5_5(phoneid, method, arg1, arg2, arg3, arg4, arg5, res1, \
  172.     res2, res3, res4, res5) \
  173.     ipc_call_sync_slow((phoneid), (method), (arg1), (arg2), (arg3), \
  174.         (arg4), (arg5), (res1), (res2), (res3), (res4), (res5))
  175.  
  176. extern int ipc_call_sync_fast(int phoneid, ipcarg_t method, ipcarg_t arg1,
  177.     ipcarg_t arg2, ipcarg_t arg3, ipcarg_t *result1, ipcarg_t *result2,
  178.     ipcarg_t *result3, ipcarg_t *result4, ipcarg_t *result5);
  179.  
  180. extern int ipc_call_sync_slow(int phoneid, ipcarg_t method, ipcarg_t arg1,
  181.     ipcarg_t arg2, ipcarg_t arg3, ipcarg_t arg4, ipcarg_t arg5,
  182.     ipcarg_t *result1, ipcarg_t *result2, ipcarg_t *result3, ipcarg_t *result4,
  183.     ipcarg_t *result5);
  184.  
  185. extern ipc_callid_t ipc_wait_cycle(ipc_call_t *call, uint32_t usec, int flags);
  186. extern ipc_callid_t ipc_wait_for_call_timeout(ipc_call_t *data, uint32_t usec);
  187. static inline ipc_callid_t ipc_wait_for_call(ipc_call_t *data)
  188. {
  189.     return ipc_wait_for_call_timeout(data, SYNCH_NO_TIMEOUT);
  190. }
  191. extern ipc_callid_t ipc_trywait_for_call(ipc_call_t *data);
  192.  
  193. /*
  194.  * User-friendly wrappers for ipc_answer_fast() and ipc_answer_slow().
  195.  * They are in the form of ipc_answer_m(), where m is the number of return
  196.  * arguments. The macros decide between the fast and the slow version according
  197.  * to m.
  198.  */
  199. #define ipc_answer_0(callid, retval) \
  200.     ipc_answer_fast((callid), (retval), 0, 0, 0, 0)
  201. #define ipc_answer_1(callid, retval, arg1) \
  202.     ipc_answer_fast((callid), (retval), (arg1), 0, 0, 0)
  203. #define ipc_answer_2(callid, retval, arg1, arg2) \
  204.     ipc_answer_fast((callid), (retval), (arg1), (arg2), 0, 0)
  205. #define ipc_answer_3(callid, retval, arg1, arg2, arg3) \
  206.     ipc_answer_fast((callid), (retval), (arg1), (arg2), (arg3), 0)
  207. #define ipc_answer_4(callid, retval, arg1, arg2, arg3, arg4) \
  208.     ipc_answer_fast((callid), (retval), (arg1), (arg2), (arg3), (arg4))
  209. #define ipc_answer_5(callid, retval, arg1, arg2, arg3, arg4, arg5) \
  210.     ipc_answer_slow((callid), (retval), (arg1), (arg2), (arg3), (arg4), (arg5))
  211.  
  212. extern ipcarg_t ipc_answer_fast(ipc_callid_t callid, ipcarg_t retval,
  213.     ipcarg_t arg1, ipcarg_t arg2, ipcarg_t arg3, ipcarg_t arg4);
  214. extern ipcarg_t ipc_answer_slow(ipc_callid_t callid, ipcarg_t retval,
  215.     ipcarg_t arg1, ipcarg_t arg2, ipcarg_t arg3, ipcarg_t arg4, ipcarg_t arg5);
  216.  
  217. /*
  218.  * User-friendly wrappers for ipc_call_async_fast() and ipc_call_async_slow().
  219.  * They are in the form of ipc_call_async_m(), where m is the number of payload
  220.  * arguments. The macros decide between the fast and the slow version according
  221.  * to m.
  222.  */
  223. #define ipc_call_async_0(phoneid, method, private, callback, \
  224.     can_preempt) \
  225.     ipc_call_async_fast((phoneid), (method), 0, 0, 0, 0, (private), \
  226.         (callback), (can_preempt))
  227. #define ipc_call_async_1(phoneid, method, arg1, private, callback, \
  228.     can_preempt) \
  229.     ipc_call_async_fast((phoneid), (method), (arg1), 0, 0, 0, (private), \
  230.         (callback), (can_preempt))
  231. #define ipc_call_async_2(phoneid, method, arg1, arg2, private, callback, \
  232.     can_preempt) \
  233.     ipc_call_async_fast((phoneid), (method), (arg1), (arg2), 0, 0, \
  234.         (private), (callback), (can_preempt))
  235. #define ipc_call_async_3(phoneid, method, arg1, arg2, arg3, private, callback, \
  236.     can_preempt) \
  237.     ipc_call_async_fast((phoneid), (method), (arg1), (arg2), (arg3), 0, \
  238.         (private), (callback), (can_preempt))
  239. #define ipc_call_async_4(phoneid, method, arg1, arg2, arg3, arg4, private, \
  240.     callback, can_preempt) \
  241.     ipc_call_async_fast((phoneid), (method), (arg1), (arg2), (arg3), \
  242.         (arg4), (private), (callback), (can_preempt))
  243. #define ipc_call_async_5(phoneid, method, arg1, arg2, arg3, arg4, arg5, \
  244.     private, callback, can_preempt) \
  245.     ipc_call_async_slow((phoneid), (method), (arg1), (arg2), (arg3), \
  246.         (arg4), (arg5), (private), (callback), (can_preempt))
  247.  
  248. extern void ipc_call_async_fast(int phoneid, ipcarg_t method, ipcarg_t arg1,
  249.     ipcarg_t arg2, ipcarg_t arg3, ipcarg_t arg4, void *private,
  250.     ipc_async_callback_t callback, int can_preempt);
  251. extern void ipc_call_async_slow(int phoneid, ipcarg_t method, ipcarg_t arg1,
  252.     ipcarg_t arg2, ipcarg_t arg3, ipcarg_t arg4, ipcarg_t arg5, void *private,
  253.     ipc_async_callback_t callback, int can_preempt);
  254.  
  255. extern int ipc_connect_to_me(int phoneid, int arg1, int arg2, int arg3,
  256.     ipcarg_t *phone);
  257. extern int ipc_connect_me_to(int phoneid, int arg1, int arg2, int arg3);
  258. extern int ipc_hangup(int phoneid);
  259. extern int ipc_register_irq(int inr, int devno, int method, irq_code_t *code);
  260. extern int ipc_unregister_irq(int inr, int devno);
  261. extern int ipc_forward_fast(ipc_callid_t callid, int phoneid, int method,
  262.     ipcarg_t arg1, ipcarg_t arg2, int mode);
  263.  
  264.  
  265. /*
  266.  * User-friendly wrappers for ipc_share_in_start().
  267.  */
  268. #define ipc_share_in_start_0_0(phoneid, dst, size) \
  269.     ipc_share_in_start((phoneid), (dst), (size), 0, NULL)
  270. #define ipc_share_in_start_0_1(phoneid, dst, size, flags) \
  271.     ipc_share_in_start((phoneid), (dst), (size), 0, (flags))
  272. #define ipc_share_in_start_1_0(phoneid, dst, size, arg) \
  273.     ipc_share_in_start((phoneid), (dst), (size), (arg), NULL)
  274. #define ipc_share_in_start_1_1(phoneid, dst, size, arg, flags) \
  275.     ipc_share_in_start((phoneid), (dst), (size), (arg), (flags))
  276.  
  277. extern int ipc_share_in_start(int phoneid, void *dst, size_t size, ipcarg_t arg,
  278.     int *flags);
  279. extern int ipc_share_in_receive(ipc_callid_t *callid, size_t *size);
  280. extern int ipc_share_in_finalize(ipc_callid_t callid, void *src, int flags);
  281. extern int ipc_share_out_start(int phoneid, void *src, int flags);
  282. extern int ipc_share_out_receive(ipc_callid_t *callid, size_t *size, int *flags);
  283. extern int ipc_share_out_finalize(ipc_callid_t callid, void *dst);
  284. extern int ipc_data_read_start(int phoneid, void *dst, size_t size);
  285. extern int ipc_data_read_receive(ipc_callid_t *callid, size_t *size);
  286. extern int ipc_data_read_finalize(ipc_callid_t callid, void *src, size_t size);
  287. extern int ipc_data_write_start(int phoneid, void *src, size_t size);
  288. extern int ipc_data_write_receive(ipc_callid_t *callid, size_t *size);
  289. extern int ipc_data_write_finalize(ipc_callid_t callid, void *dst, size_t size);
  290.  
  291. #endif
  292.  
  293. /** @}
  294.  */
  295.