Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/c/generic/ipc.c

    r63f8966 r10477601  
    3838 */
    3939/** @file
    40  */ 
     40 */
    4141
    4242#include <ipc/ipc.h>
     
    4545#include <errno.h>
    4646#include <adt/list.h>
    47 #include <stdio.h>
    48 #include <unistd.h>
    4947#include <futex.h>
    50 #include <kernel/synch/synch.h>
    51 #include <async.h>
    5248#include <fibril.h>
    53 #include <assert.h>
    5449
    5550/**
    56  * Structures of this type are used for keeping track of sent asynchronous calls
    57  * and queing unsent calls.
     51 * Structures of this type are used for keeping track
     52 * of sent asynchronous calls and queing unsent calls.
    5853 */
    5954typedef struct {
    6055        link_t list;
    61 
     56       
    6257        ipc_async_callback_t callback;
    6358        void *private;
     59       
    6460        union {
    6561                ipc_callid_t callid;
     
    6965                } msg;
    7066        } u;
    71         fid_t fid;      /**< Fibril waiting for sending this call. */
     67       
     68        /** Fibril waiting for sending this call. */
     69        fid_t fid;
    7270} async_call_t;
    7371
     
    7674/** List of asynchronous calls that were not accepted by kernel.
    7775 *
    78  * It is protected by async_futex, because if the call cannot be sent into the
    79  * kernel, the async framework is used automatically.
     76 * Protected by async_futex, because if the call is not accepted
     77 * by the kernel, the async framework is used automatically.
     78 *
    8079 */
    8180LIST_INITIALIZE(queued_calls);
     
    8382static atomic_t ipc_futex = FUTEX_INITIALIZER;
    8483
    85 /** Make a fast synchronous call.
    86  *
    87  * Only three payload arguments can be passed using this function. However, this
    88  * function is faster than the generic ipc_call_sync_slow() because the payload
    89  * is passed directly in registers.
    90  *
    91  * @param phoneid       Phone handle for the call.
    92  * @param method        Requested method.
    93  * @param arg1          Service-defined payload argument.
    94  * @param arg2          Service-defined payload argument.
    95  * @param arg3          Service-defined payload argument.
    96  * @param result1       If non-NULL, the return ARG1 will be stored there.
    97  * @param result2       If non-NULL, the return ARG2 will be stored there.
    98  * @param result3       If non-NULL, the return ARG3 will be stored there.
    99  * @param result4       If non-NULL, the return ARG4 will be stored there.
    100  * @param result5       If non-NULL, the return ARG5 will be stored there.
    101  *
    102  * @return              Negative values represent errors returned by IPC.
    103  *                      Otherwise the RETVAL of the answer is returned.
    104  */
    105 int
    106 ipc_call_sync_fast(int phoneid, ipcarg_t method, ipcarg_t arg1, ipcarg_t arg2,
    107     ipcarg_t arg3, ipcarg_t *result1, ipcarg_t *result2, ipcarg_t *result3,
    108     ipcarg_t *result4, ipcarg_t *result5)
     84/** Fast synchronous call.
     85 *
     86 * Only three payload arguments can be passed using this function. However,
     87 * this function is faster than the generic ipc_call_sync_slow() because
     88 * the payload is passed directly in registers.
     89 *
     90 * @param phoneid Phone handle for the call.
     91 * @param method  Requested method.
     92 * @param arg1    Service-defined payload argument.
     93 * @param arg2    Service-defined payload argument.
     94 * @param arg3    Service-defined payload argument.
     95 * @param result1 If non-NULL, the return ARG1 will be stored there.
     96 * @param result2 If non-NULL, the return ARG2 will be stored there.
     97 * @param result3 If non-NULL, the return ARG3 will be stored there.
     98 * @param result4 If non-NULL, the return ARG4 will be stored there.
     99 * @param result5 If non-NULL, the return ARG5 will be stored there.
     100 *
     101 * @return Negative values representing IPC errors.
     102 * @return Otherwise the RETVAL of the answer.
     103 *
     104 */
     105int ipc_call_sync_fast(int phoneid, sysarg_t method, sysarg_t arg1,
     106    sysarg_t arg2, sysarg_t arg3, sysarg_t *result1, sysarg_t *result2,
     107    sysarg_t *result3, sysarg_t *result4, sysarg_t *result5)
    109108{
    110109        ipc_call_t resdata;
    111         int callres;
    112        
    113         callres = __SYSCALL6(SYS_IPC_CALL_SYNC_FAST, phoneid, method, arg1,
     110        int callres = __SYSCALL6(SYS_IPC_CALL_SYNC_FAST, phoneid, method, arg1,
    114111            arg2, arg3, (sysarg_t) &resdata);
    115112        if (callres)
    116113                return callres;
     114       
    117115        if (result1)
    118116                *result1 = IPC_GET_ARG1(resdata);
     
    125123        if (result5)
    126124                *result5 = IPC_GET_ARG5(resdata);
    127 
     125       
    128126        return IPC_GET_RETVAL(resdata);
    129127}
    130128
    131 /** Make a synchronous call transmitting 5 arguments of payload.
    132  *
    133  * @param phoneid       Phone handle for the call.
    134  * @param method        Requested method.
    135  * @param arg1          Service-defined payload argument.
    136  * @param arg2          Service-defined payload argument.
    137  * @param arg3          Service-defined payload argument.
    138  * @param arg4          Service-defined payload argument.
    139  * @param arg5          Service-defined payload argument.
    140  * @param result1       If non-NULL, storage for the first return argument.
    141  * @param result2       If non-NULL, storage for the second return argument.
    142  * @param result3       If non-NULL, storage for the third return argument.
    143  * @param result4       If non-NULL, storage for the fourth return argument.
    144  * @param result5       If non-NULL, storage for the fifth return argument.
    145  *
    146  * @return              Negative value means IPC error.
    147  *                      Otherwise the RETVAL of the answer.
    148  */
    149 int
    150 ipc_call_sync_slow(int phoneid, ipcarg_t method, ipcarg_t arg1, ipcarg_t arg2,
    151     ipcarg_t arg3, ipcarg_t arg4, ipcarg_t arg5, ipcarg_t *result1,
    152     ipcarg_t *result2, ipcarg_t *result3, ipcarg_t *result4, ipcarg_t *result5)
     129/** Synchronous call transmitting 5 arguments of payload.
     130 *
     131 * @param phoneid Phone handle for the call.
     132 * @param imethod Requested interface and method.
     133 * @param arg1    Service-defined payload argument.
     134 * @param arg2    Service-defined payload argument.
     135 * @param arg3    Service-defined payload argument.
     136 * @param arg4    Service-defined payload argument.
     137 * @param arg5    Service-defined payload argument.
     138 * @param result1 If non-NULL, storage for the first return argument.
     139 * @param result2 If non-NULL, storage for the second return argument.
     140 * @param result3 If non-NULL, storage for the third return argument.
     141 * @param result4 If non-NULL, storage for the fourth return argument.
     142 * @param result5 If non-NULL, storage for the fifth return argument.
     143 *
     144 * @return Negative values representing IPC errors.
     145 * @return Otherwise the RETVAL of the answer.
     146 *
     147 */
     148int ipc_call_sync_slow(int phoneid, sysarg_t imethod, sysarg_t arg1,
     149    sysarg_t arg2, sysarg_t arg3, sysarg_t arg4, sysarg_t arg5,
     150    sysarg_t *result1, sysarg_t *result2, sysarg_t *result3, sysarg_t *result4,
     151    sysarg_t *result5)
    153152{
    154153        ipc_call_t data;
    155         int callres;
    156 
    157         IPC_SET_METHOD(data, method);
     154       
     155        IPC_SET_IMETHOD(data, imethod);
    158156        IPC_SET_ARG1(data, arg1);
    159157        IPC_SET_ARG2(data, arg2);
     
    161159        IPC_SET_ARG4(data, arg4);
    162160        IPC_SET_ARG5(data, arg5);
    163 
    164         callres = __SYSCALL3(SYS_IPC_CALL_SYNC_SLOW, phoneid, (sysarg_t) &data,
    165             (sysarg_t) &data);
     161       
     162        int callres = __SYSCALL3(SYS_IPC_CALL_SYNC_SLOW, phoneid,
     163            (sysarg_t) &data, (sysarg_t) &data);
    166164        if (callres)
    167165                return callres;
    168 
     166       
    169167        if (result1)
    170168                *result1 = IPC_GET_ARG1(data);
     
    177175        if (result5)
    178176                *result5 = IPC_GET_ARG5(data);
    179 
     177       
    180178        return IPC_GET_RETVAL(data);
    181179}
    182180
    183 /** Syscall to send asynchronous message.
    184  *
    185  * @param phoneid       Phone handle for the call.
    186  * @param data          Call data with the request.
    187  *
    188  * @return              Hash of the call or an error code.
    189  */
    190 static ipc_callid_t _ipc_call_async(int phoneid, ipc_call_t *data)
     181/** Send asynchronous message via syscall.
     182 *
     183 * @param phoneid Phone handle for the call.
     184 * @param data    Call data with the request.
     185 *
     186 * @return Hash of the call or an error code.
     187 *
     188 */
     189static ipc_callid_t ipc_call_async_internal(int phoneid, ipc_call_t *data)
    191190{
    192191        return __SYSCALL2(SYS_IPC_CALL_ASYNC_SLOW, phoneid, (sysarg_t) data);
    193192}
    194193
    195 /** Prolog to ipc_call_async_*() functions.
    196  *
    197  * @param private       Argument for the answer/error callback.
    198  * @param callback      Answer/error callback.
    199  *
    200  * @return              New, partially initialized async_call structure or NULL.
     194/** Prolog for ipc_call_async_*() functions.
     195 *
     196 * @param private  Argument for the answer/error callback.
     197 * @param callback Answer/error callback.
     198 *
     199 * @return New, partially initialized async_call structure or NULL.
     200 *
    201201 */
    202202static inline async_call_t *ipc_prepare_async(void *private,
    203203    ipc_async_callback_t callback)
    204204{
    205         async_call_t *call;
    206 
    207         call = malloc(sizeof(*call));
     205        async_call_t *call =
     206            (async_call_t *) malloc(sizeof(async_call_t));
    208207        if (!call) {
    209208                if (callback)
    210209                        callback(private, ENOMEM, NULL);
     210               
    211211                return NULL;
    212212        }
     213       
    213214        call->callback = callback;
    214215        call->private = private;
    215 
     216       
    216217        return call;
    217218}
    218219
    219 /** Epilogue of ipc_call_async_*() functions.
    220  *
    221  * @param callid        Value returned by the SYS_IPC_CALL_ASYNC_* syscall.
    222  * @param phoneid       Phone handle through which the call was made.
    223  * @param call          async_call structure returned by ipc_prepare_async().
    224  * @param can_preempt   If non-zero, the current fibril can be preempted in this
    225  *                      call.
     220/** Epilog for ipc_call_async_*() functions.
     221 *
     222 * @param callid      Value returned by the SYS_IPC_CALL_ASYNC_* syscall.
     223 * @param phoneid     Phone handle through which the call was made.
     224 * @param call        Structure returned by ipc_prepare_async().
     225 * @param can_preempt If true, the current fibril can be preempted
     226 *                    in this call.
     227 *
    226228 */
    227229static inline void ipc_finish_async(ipc_callid_t callid, int phoneid,
    228     async_call_t *call, int can_preempt)
    229 {
    230         if (!call) { /* Nothing to do regardless if failed or not */
     230    async_call_t *call, bool can_preempt)
     231{
     232        if (!call) {
     233                /* Nothing to do regardless if failed or not */
    231234                futex_up(&ipc_futex);
    232235                return;
    233236        }
    234 
     237       
    235238        if (callid == (ipc_callid_t) IPC_CALLRET_FATAL) {
    236239                futex_up(&ipc_futex);
     240               
    237241                /* Call asynchronous handler with error code */
    238242                if (call->callback)
    239243                        call->callback(call->private, ENOENT, NULL);
     244               
    240245                free(call);
    241246                return;
    242247        }
    243 
     248       
    244249        if (callid == (ipc_callid_t) IPC_CALLRET_TEMPORARY) {
    245250                futex_up(&ipc_futex);
    246 
     251               
    247252                call->u.msg.phoneid = phoneid;
    248253               
    249254                futex_down(&async_futex);
    250255                list_append(&call->list, &queued_calls);
    251 
     256               
    252257                if (can_preempt) {
    253258                        call->fid = fibril_get_id();
     
    258263                        futex_up(&async_futex);
    259264                }
     265               
    260266                return;
    261267        }
     268       
    262269        call->u.callid = callid;
     270       
    263271        /* Add call to the list of dispatched calls */
    264272        list_append(&call->list, &dispatched_calls);
    265273        futex_up(&ipc_futex);
    266        
    267 }
    268 
    269 /** Make a fast asynchronous call.
     274}
     275
     276/** Fast asynchronous call.
    270277 *
    271278 * This function can only handle four arguments of payload. It is, however,
     
    273280 *
    274281 * Note that this function is a void function.
    275  * During normal opertation, answering this call will trigger the callback.
    276  * In case of fatal error, call the callback handler with the proper error code.
    277  * If the call cannot be temporarily made, queue it.
    278  *
    279  * @param phoneid       Phone handle for the call.
    280  * @param method        Requested method.
    281  * @param arg1          Service-defined payload argument.
    282  * @param arg2          Service-defined payload argument.
    283  * @param arg3          Service-defined payload argument.
    284  * @param arg4          Service-defined payload argument.
    285  * @param private       Argument to be passed to the answer/error callback.
    286  * @param callback      Answer or error callback.
    287  * @param can_preempt   If non-zero, the current fibril will be preempted in
    288  *                      case the kernel temporarily refuses to accept more
    289  *                      asynchronous calls.
    290  */
    291 void ipc_call_async_fast(int phoneid, ipcarg_t method, ipcarg_t arg1,
    292     ipcarg_t arg2, ipcarg_t arg3, ipcarg_t arg4, void *private,
    293     ipc_async_callback_t callback, int can_preempt)
     282 *
     283 * During normal operation, answering this call will trigger the callback.
     284 * In case of fatal error, the callback handler is called with the proper
     285 * error code. If the call cannot be temporarily made, it is queued.
     286 *
     287 * @param phoneid     Phone handle for the call.
     288 * @param imethod     Requested interface and method.
     289 * @param arg1        Service-defined payload argument.
     290 * @param arg2        Service-defined payload argument.
     291 * @param arg3        Service-defined payload argument.
     292 * @param arg4        Service-defined payload argument.
     293 * @param private     Argument to be passed to the answer/error callback.
     294 * @param callback    Answer or error callback.
     295 * @param can_preempt If true, the current fibril will be preempted in
     296 *                    case the kernel temporarily refuses to accept more
     297 *                    asynchronous calls.
     298 *
     299 */
     300void ipc_call_async_fast(int phoneid, sysarg_t imethod, sysarg_t arg1,
     301    sysarg_t arg2, sysarg_t arg3, sysarg_t arg4, void *private,
     302    ipc_async_callback_t callback, bool can_preempt)
    294303{
    295304        async_call_t *call = NULL;
    296         ipc_callid_t callid;
    297 
     305       
    298306        if (callback) {
    299307                call = ipc_prepare_async(private, callback);
     
    301309                        return;
    302310        }
    303 
     311       
    304312        /*
    305          * We need to make sure that we get callid before another thread
    306          * accesses the queue again.
     313         * We need to make sure that we get callid
     314         * before another thread accesses the queue again.
    307315         */
     316       
    308317        futex_down(&ipc_futex);
    309         callid = __SYSCALL6(SYS_IPC_CALL_ASYNC_FAST, phoneid, method, arg1,
    310             arg2, arg3, arg4);
    311 
     318        ipc_callid_t callid = __SYSCALL6(SYS_IPC_CALL_ASYNC_FAST, phoneid,
     319            imethod, arg1, arg2, arg3, arg4);
     320       
    312321        if (callid == (ipc_callid_t) IPC_CALLRET_TEMPORARY) {
    313322                if (!call) {
     
    316325                                return;
    317326                }
    318                 IPC_SET_METHOD(call->u.msg.data, method);
     327               
     328                IPC_SET_IMETHOD(call->u.msg.data, imethod);
    319329                IPC_SET_ARG1(call->u.msg.data, arg1);
    320330                IPC_SET_ARG2(call->u.msg.data, arg2);
    321331                IPC_SET_ARG3(call->u.msg.data, arg3);
    322332                IPC_SET_ARG4(call->u.msg.data, arg4);
     333               
    323334                /*
    324335                 * To achieve deterministic behavior, we always zero out the
    325336                 * arguments that are beyond the limits of the fast version.
    326337                 */
     338               
    327339                IPC_SET_ARG5(call->u.msg.data, 0);
    328340        }
     341       
    329342        ipc_finish_async(callid, phoneid, call, can_preempt);
    330343}
    331344
    332 /** Make an asynchronous call transmitting the entire payload.
     345/** Asynchronous call transmitting the entire payload.
    333346 *
    334347 * Note that this function is a void function.
    335  * During normal opertation, answering this call will trigger the callback.
    336  * In case of fatal error, call the callback handler with the proper error code.
    337  * If the call cannot be temporarily made, queue it.
    338  *
    339  * @param phoneid       Phone handle for the call.
    340  * @param method        Requested method.
    341  * @param arg1          Service-defined payload argument.
    342  * @param arg2          Service-defined payload argument.
    343  * @param arg3          Service-defined payload argument.
    344  * @param arg4          Service-defined payload argument.
    345  * @param arg5          Service-defined payload argument.
    346  * @param private       Argument to be passed to the answer/error callback.
    347  * @param callback      Answer or error callback.
    348  * @param can_preempt   If non-zero, the current fibril will be preempted in
    349  *                      case the kernel temporarily refuses to accept more
    350  *                      asynchronous calls.
    351  *
    352  */
    353 void ipc_call_async_slow(int phoneid, ipcarg_t method, ipcarg_t arg1,
    354     ipcarg_t arg2, ipcarg_t arg3, ipcarg_t arg4, ipcarg_t arg5, void *private,
    355     ipc_async_callback_t callback, int can_preempt)
    356 {
    357         async_call_t *call;
    358         ipc_callid_t callid;
    359 
    360         call = ipc_prepare_async(private, callback);
     348 *
     349 * During normal operation, answering this call will trigger the callback.
     350 * In case of fatal error, the callback handler is called with the proper
     351 * error code. If the call cannot be temporarily made, it is queued.
     352 *
     353 * @param phoneid     Phone handle for the call.
     354 * @param imethod     Requested interface and method.
     355 * @param arg1        Service-defined payload argument.
     356 * @param arg2        Service-defined payload argument.
     357 * @param arg3        Service-defined payload argument.
     358 * @param arg4        Service-defined payload argument.
     359 * @param arg5        Service-defined payload argument.
     360 * @param private     Argument to be passed to the answer/error callback.
     361 * @param callback    Answer or error callback.
     362 * @param can_preempt If true, the current fibril will be preempted in
     363 *                    case the kernel temporarily refuses to accept more
     364 *                    asynchronous calls.
     365 *
     366 */
     367void ipc_call_async_slow(int phoneid, sysarg_t imethod, sysarg_t arg1,
     368    sysarg_t arg2, sysarg_t arg3, sysarg_t arg4, sysarg_t arg5, void *private,
     369    ipc_async_callback_t callback, bool can_preempt)
     370{
     371        async_call_t *call = ipc_prepare_async(private, callback);
    361372        if (!call)
    362373                return;
    363 
    364         IPC_SET_METHOD(call->u.msg.data, method);
     374       
     375        IPC_SET_IMETHOD(call->u.msg.data, imethod);
    365376        IPC_SET_ARG1(call->u.msg.data, arg1);
    366377        IPC_SET_ARG2(call->u.msg.data, arg2);
     
    368379        IPC_SET_ARG4(call->u.msg.data, arg4);
    369380        IPC_SET_ARG5(call->u.msg.data, arg5);
     381       
    370382        /*
    371          * We need to make sure that we get callid before another thread
    372          * accesses the queue again.
     383         * We need to make sure that we get callid
     384         * before another threadaccesses the queue again.
    373385         */
     386       
    374387        futex_down(&ipc_futex);
    375         callid = _ipc_call_async(phoneid, &call->u.msg.data);
    376 
     388        ipc_callid_t callid =
     389            ipc_call_async_internal(phoneid, &call->u.msg.data);
     390       
    377391        ipc_finish_async(callid, phoneid, call, can_preempt);
    378392}
    379393
    380 
    381 /** Answer a received call - fast version.
     394/** Answer received call (fast version).
    382395 *
    383396 * The fast answer makes use of passing retval and first four arguments in
    384397 * registers. If you need to return more, use the ipc_answer_slow() instead.
    385398 *
    386  * @param callid        Hash of the call being answered.
    387  * @param retval        Return value.
    388  * @param arg1          First return argument.
    389  * @param arg2          Second return argument.
    390  * @param arg3          Third return argument.
    391  * @param arg4          Fourth return argument.
    392  *
    393  * @return              Zero on success or a value from @ref errno.h on failure.
    394  */
    395 ipcarg_t ipc_answer_fast(ipc_callid_t callid, ipcarg_t retval, ipcarg_t arg1,
    396     ipcarg_t arg2, ipcarg_t arg3, ipcarg_t arg4)
     399 * @param callid Hash of the call being answered.
     400 * @param retval Return value.
     401 * @param arg1   First return argument.
     402 * @param arg2   Second return argument.
     403 * @param arg3   Third return argument.
     404 * @param arg4   Fourth return argument.
     405 *
     406 * @return Zero on success.
     407 * @return Value from @ref errno.h on failure.
     408 *
     409 */
     410sysarg_t ipc_answer_fast(ipc_callid_t callid, sysarg_t retval, sysarg_t arg1,
     411    sysarg_t arg2, sysarg_t arg3, sysarg_t arg4)
    397412{
    398413        return __SYSCALL6(SYS_IPC_ANSWER_FAST, callid, retval, arg1, arg2, arg3,
     
    400415}
    401416
    402 /** Answer a received call - slow full version.
    403  *
    404  * @param callid        Hash of the call being answered.
    405  * @param retval        Return value.
    406  * @param arg1          First return argument.
    407  * @param arg2          Second return argument.
    408  * @param arg3          Third return argument.
    409  * @param arg4          Fourth return argument.
    410  * @param arg5          Fifth return argument.
    411  *
    412  * @return              Zero on success or a value from @ref errno.h on failure.
    413  */
    414 ipcarg_t ipc_answer_slow(ipc_callid_t callid, ipcarg_t retval, ipcarg_t arg1,
    415     ipcarg_t arg2, ipcarg_t arg3, ipcarg_t arg4, ipcarg_t arg5)
     417/** Answer received call (entire payload).
     418 *
     419 * @param callid Hash of the call being answered.
     420 * @param retval Return value.
     421 * @param arg1   First return argument.
     422 * @param arg2   Second return argument.
     423 * @param arg3   Third return argument.
     424 * @param arg4   Fourth return argument.
     425 * @param arg5   Fifth return argument.
     426 *
     427 * @return Zero on success.
     428 * @return Value from @ref errno.h on failure.
     429 *
     430 */
     431sysarg_t ipc_answer_slow(ipc_callid_t callid, sysarg_t retval, sysarg_t arg1,
     432    sysarg_t arg2, sysarg_t arg3, sysarg_t arg4, sysarg_t arg5)
    416433{
    417434        ipc_call_t data;
    418 
     435       
    419436        IPC_SET_RETVAL(data, retval);
    420437        IPC_SET_ARG1(data, arg1);
     
    423440        IPC_SET_ARG4(data, arg4);
    424441        IPC_SET_ARG5(data, arg5);
    425 
     442       
    426443        return __SYSCALL2(SYS_IPC_ANSWER_SLOW, callid, (sysarg_t) &data);
    427444}
    428445
    429 
    430 /** Try to dispatch queued calls from the async queue. */
    431 static void try_dispatch_queued_calls(void)
    432 {
    433         async_call_t *call;
    434         ipc_callid_t callid;
    435 
     446/** Try to dispatch queued calls from the async queue.
     447 *
     448 */
     449static void dispatch_queued_calls(void)
     450{
    436451        /** @todo
    437          * Integrate intelligently ipc_futex, so that it is locked during
    438          * ipc_call_async_*(), until it is added to dispatched_calls.
     452         * Integrate intelligently ipc_futex so that it is locked during
     453         * ipc_call_async_*() until it is added to dispatched_calls.
    439454         */
     455       
    440456        futex_down(&async_futex);
     457       
    441458        while (!list_empty(&queued_calls)) {
    442                 call = list_get_instance(queued_calls.next, async_call_t, list);
    443                 callid = _ipc_call_async(call->u.msg.phoneid,
    444                     &call->u.msg.data);
    445                 if (callid == (ipc_callid_t) IPC_CALLRET_TEMPORARY) {
     459                async_call_t *call =
     460                    list_get_instance(queued_calls.next, async_call_t, list);
     461                ipc_callid_t callid =
     462                    ipc_call_async_internal(call->u.msg.phoneid, &call->u.msg.data);
     463               
     464                if (callid == (ipc_callid_t) IPC_CALLRET_TEMPORARY)
    446465                        break;
    447                 }
     466               
    448467                list_remove(&call->list);
    449 
     468               
    450469                futex_up(&async_futex);
     470               
    451471                if (call->fid)
    452472                        fibril_add_ready(call->fid);
     
    455475                        if (call->callback)
    456476                                call->callback(call->private, ENOENT, NULL);
     477                       
    457478                        free(call);
    458479                } else {
    459480                        call->u.callid = callid;
     481                       
    460482                        futex_down(&ipc_futex);
    461483                        list_append(&call->list, &dispatched_calls);
    462484                        futex_up(&ipc_futex);
    463485                }
     486               
    464487                futex_down(&async_futex);
    465488        }
     489       
    466490        futex_up(&async_futex);
    467491}
    468492
    469 /** Handle a received answer.
     493/** Handle received answer.
    470494 *
    471495 * Find the hash of the answer and call the answer callback.
    472496 *
    473  * @todo Make it use hash table.
    474  *
    475  * @param callid        Hash of the received answer.
    476  *                      The answer has the same hash as the request OR'ed with
    477  *                      the IPC_CALLID_ANSWERED bit.
    478  * @param data          Call data of the answer.
     497 * The answer has the same hash as the request OR'ed with
     498 * the IPC_CALLID_ANSWERED bit.
     499 *
     500 * @todo Use hash table.
     501 *
     502 * @param callid Hash of the received answer.
     503 * @param data   Call data of the answer.
     504 *
    479505 */
    480506static void handle_answer(ipc_callid_t callid, ipc_call_t *data)
    481507{
     508        callid &= ~IPC_CALLID_ANSWERED;
     509       
     510        futex_down(&ipc_futex);
     511       
    482512        link_t *item;
    483         async_call_t *call;
    484 
    485         callid &= ~IPC_CALLID_ANSWERED;
    486        
    487         futex_down(&ipc_futex);
    488513        for (item = dispatched_calls.next; item != &dispatched_calls;
    489514            item = item->next) {
    490                 call = list_get_instance(item, async_call_t, list);
     515                async_call_t *call =
     516                    list_get_instance(item, async_call_t, list);
     517               
    491518                if (call->u.callid == callid) {
    492519                        list_remove(&call->list);
     520                       
    493521                        futex_up(&ipc_futex);
     522                       
    494523                        if (call->callback)
    495                                 call->callback(call->private, 
     524                                call->callback(call->private,
    496525                                    IPC_GET_RETVAL(*data), data);
     526                       
    497527                        free(call);
    498528                        return;
    499529                }
    500530        }
     531       
    501532        futex_up(&ipc_futex);
    502533}
    503534
    504 
    505 /** Wait for a first call to come.
    506  *
    507  * @param call          Storage where the incoming call data will be stored.
    508  * @param usec          Timeout in microseconds
    509  * @param flags         Flags passed to SYS_IPC_WAIT (blocking, nonblocking).
    510  *
    511  * @return              Hash of the call. Note that certain bits have special
    512  *                      meaning. IPC_CALLID_ANSWERED will be set in an answer
    513  *                      and IPC_CALLID_NOTIFICATION is used for notifications.
    514  *                     
    515  */
    516 ipc_callid_t ipc_wait_cycle(ipc_call_t *call, uint32_t usec, int flags)
    517 {
    518         ipc_callid_t callid;
    519 
    520         callid = __SYSCALL3(SYS_IPC_WAIT, (sysarg_t) call, usec, flags);
     535/** Wait for first IPC call to come.
     536 *
     537 * @param call  Incoming call storage.
     538 * @param usec  Timeout in microseconds
     539 * @param flags Flags passed to SYS_IPC_WAIT (blocking, nonblocking).
     540 *
     541 * @return Hash of the call. Note that certain bits have special
     542 *         meaning: IPC_CALLID_ANSWERED is set in an answer
     543 *         and IPC_CALLID_NOTIFICATION is used for notifications.
     544 *
     545 */
     546ipc_callid_t ipc_wait_cycle(ipc_call_t *call, sysarg_t usec,
     547    unsigned int flags)
     548{
     549        ipc_callid_t callid =
     550            __SYSCALL3(SYS_IPC_WAIT, (sysarg_t) call, usec, flags);
     551       
    521552        /* Handle received answers */
    522553        if (callid & IPC_CALLID_ANSWERED) {
    523554                handle_answer(callid, call);
    524                 try_dispatch_queued_calls();
     555                dispatch_queued_calls();
    525556        }
    526 
     557       
    527558        return callid;
    528559}
    529560
    530 /** Wait some time for an IPC call.
    531  *
    532  * The call will return after an answer is received.
    533  *
    534  * @param call          Storage where the incoming call data will be stored.
    535  * @param usec          Timeout in microseconds.
    536  *
    537  * @return              Hash of the answer.
    538  */
    539 ipc_callid_t ipc_wait_for_call_timeout(ipc_call_t *call, uint32_t usec)
     561/** Interrupt one thread of this task from waiting for IPC.
     562 *
     563 */
     564void ipc_poke(void)
     565{
     566        __SYSCALL0(SYS_IPC_POKE);
     567}
     568
     569/** Wait for first IPC call to come.
     570 *
     571 * Only requests are returned, answers are processed internally.
     572 *
     573 * @param call Incoming call storage.
     574 * @param usec Timeout in microseconds
     575 *
     576 * @return Hash of the call.
     577 *
     578 */
     579ipc_callid_t ipc_wait_for_call_timeout(ipc_call_t *call, sysarg_t usec)
    540580{
    541581        ipc_callid_t callid;
    542 
     582       
    543583        do {
    544584                callid = ipc_wait_cycle(call, usec, SYNCH_FLAGS_NONE);
    545585        } while (callid & IPC_CALLID_ANSWERED);
    546 
     586       
    547587        return callid;
    548588}
     
    550590/** Check if there is an IPC call waiting to be picked up.
    551591 *
    552  * @param call          Storage where the incoming call will be stored.
    553  * @return              Hash of the answer.
     592 * Only requests are returned, answers are processed internally.
     593 *
     594 * @param call Incoming call storage.
     595 *
     596 * @return Hash of the call.
     597 *
    554598 */
    555599ipc_callid_t ipc_trywait_for_call(ipc_call_t *call)
    556600{
    557601        ipc_callid_t callid;
    558 
     602       
    559603        do {
    560604                callid = ipc_wait_cycle(call, SYNCH_NO_TIMEOUT,
    561605                    SYNCH_FLAGS_NON_BLOCKING);
    562606        } while (callid & IPC_CALLID_ANSWERED);
    563 
     607       
    564608        return callid;
    565609}
    566610
    567 /** Interrupt one thread of this task from waiting for IPC. */
    568 void ipc_poke(void)
    569 {
    570         __SYSCALL0(SYS_IPC_POKE);
    571 }
    572 
    573 /** Ask destination to do a callback connection.
    574  *
    575  * @param phoneid       Phone handle used for contacting the other side.
    576  * @param arg1          Service-defined argument.
    577  * @param arg2          Service-defined argument.
    578  * @param arg3          Service-defined argument.
    579  * @param phonehash     Storage where the library will store an opaque
    580  *                      identifier of the phone that will be used for incoming
    581  *                      calls. This identifier can be used for connection
    582  *                      tracking.
    583  *
    584  * @return              Zero on success or a negative error code.
    585  */
    586 int ipc_connect_to_me(int phoneid, int arg1, int arg2, int arg3,
    587     ipcarg_t *phonehash)
     611/** Request callback connection.
     612 *
     613 * The @a taskhash and @a phonehash identifiers returned
     614 * by the kernel can be used for connection tracking.
     615 *
     616 * @param phoneid   Phone handle used for contacting the other side.
     617 * @param arg1      User defined argument.
     618 * @param arg2      User defined argument.
     619 * @param arg3      User defined argument.
     620 * @param taskhash  Opaque identifier of the client task.
     621 * @param phonehash Opaque identifier of the phone that will
     622 *                  be used for incoming calls.
     623 *
     624 * @return Zero on success or a negative error code.
     625 *
     626 */
     627int ipc_connect_to_me(int phoneid, sysarg_t arg1, sysarg_t arg2, sysarg_t arg3,
     628    sysarg_t *taskhash, sysarg_t *phonehash)
    588629{
    589630        return ipc_call_sync_3_5(phoneid, IPC_M_CONNECT_TO_ME, arg1, arg2,
    590             arg3, NULL, NULL, NULL, NULL, phonehash);
    591 }
    592 
    593 /** Ask through phone for a new connection to some service.
    594  *
    595  * @param phoneid       Phone handle used for contacting the other side.
    596  * @param arg1          User defined argument.
    597  * @param arg2          User defined argument.
    598  * @param arg3          User defined argument.
    599  *
    600  * @return              New phone handle on success or a negative error code.
    601  */
    602 int ipc_connect_me_to(int phoneid, int arg1, int arg2, int arg3)
    603 {
    604         ipcarg_t newphid;
    605         int res;
    606 
    607         res = ipc_call_sync_3_5(phoneid, IPC_M_CONNECT_ME_TO, arg1, arg2, arg3,
     631            arg3, NULL, NULL, NULL, taskhash, phonehash);
     632}
     633
     634/** Request new connection.
     635 *
     636 * @param phoneid Phone handle used for contacting the other side.
     637 * @param arg1    User defined argument.
     638 * @param arg2    User defined argument.
     639 * @param arg3    User defined argument.
     640 *
     641 * @return New phone handle on success or a negative error code.
     642 *
     643 */
     644int ipc_connect_me_to(int phoneid, sysarg_t arg1, sysarg_t arg2, sysarg_t arg3)
     645{
     646        sysarg_t newphid;
     647        int res = ipc_call_sync_3_5(phoneid, IPC_M_CONNECT_ME_TO, arg1, arg2, arg3,
    608648            NULL, NULL, NULL, NULL, &newphid);
    609649        if (res)
    610650                return res;
     651       
    611652        return newphid;
    612653}
    613654
    614 /** Ask through phone for a new connection to some service.
     655/** Request new connection (blocking)
    615656 *
    616657 * If the connection is not available at the moment, the
    617  * call will block.
    618  *
    619  * @param phoneid       Phone handle used for contacting the other side.
    620  * @param arg1          User defined argument.
    621  * @param arg2          User defined argument.
    622  * @param arg3          User defined argument.
    623  *
    624  * @return              New phone handle on success or a negative error code.
    625  */
    626 int ipc_connect_me_to_blocking(int phoneid, int arg1, int arg2, int arg3)
    627 {
    628         ipcarg_t newphid;
    629         int res;
    630 
    631         res = ipc_call_sync_4_5(phoneid, IPC_M_CONNECT_ME_TO, arg1, arg2, arg3,
     658 * call should block. This has to be, however, implemented
     659 * on the server side.
     660 *
     661 * @param phoneid Phone handle used for contacting the other side.
     662 * @param arg1    User defined argument.
     663 * @param arg2    User defined argument.
     664 * @param arg3    User defined argument.
     665 *
     666 * @return New phone handle on success or a negative error code.
     667 *
     668 */
     669int ipc_connect_me_to_blocking(int phoneid, sysarg_t arg1, sysarg_t arg2,
     670    sysarg_t arg3)
     671{
     672        sysarg_t newphid;
     673        int res = ipc_call_sync_4_5(phoneid, IPC_M_CONNECT_ME_TO, arg1, arg2, arg3,
    632674            IPC_FLAG_BLOCKING, NULL, NULL, NULL, NULL, &newphid);
    633675        if (res)
    634676                return res;
     677       
    635678        return newphid;
    636679}
     
    638681/** Hang up a phone.
    639682 *
    640  * @param phoneid       Handle of the phone to be hung up.
    641  *
    642  * @return              Zero on success or a negative error code.
     683 * @param phoneid Handle of the phone to be hung up.
     684 *
     685 * @return Zero on success or a negative error code.
     686 *
    643687 */
    644688int ipc_hangup(int phoneid)
     
    647691}
    648692
    649 /** Register IRQ notification.
    650  *
    651  * @param inr           IRQ number.
    652  * @param devno         Device number of the device generating inr.
    653  * @param method        Use this method for notifying me.
    654  * @param ucode         Top-half pseudocode handler.
    655  *
    656  * @return              Value returned by the kernel.
    657  */
    658 int ipc_register_irq(int inr, int devno, int method, irq_code_t *ucode)
    659 {
    660         return __SYSCALL4(SYS_IPC_REGISTER_IRQ, inr, devno, method,
    661             (sysarg_t) ucode);
    662 }
    663 
    664 /** Unregister IRQ notification.
    665  *
    666  * @param inr           IRQ number.
    667  * @param devno         Device number of the device generating inr.
    668  *
    669  * @return              Value returned by the kernel.
    670  */
    671 int ipc_unregister_irq(int inr, int devno)
    672 {
    673         return __SYSCALL2(SYS_IPC_UNREGISTER_IRQ, inr, devno);
    674 }
    675 
    676693/** Forward a received call to another destination.
    677694 *
    678  * @param callid        Hash of the call to forward.
    679  * @param phoneid       Phone handle to use for forwarding.
    680  * @param method        New method for the forwarded call.
    681  * @param arg1          New value of the first argument for the forwarded call.
    682  * @param arg2          New value of the second argument for the forwarded call.
    683  * @param mode          Flags specifying mode of the forward operation.
    684  *
    685  * @return              Zero on success or an error code.
    686  *
    687  * For non-system methods, the old method, arg1 and arg2 are rewritten by the
    688  * new values. For system methods, the new method, arg1 and arg2 are written
    689  * to the old arg1, arg2 and arg3, respectivelly. Calls with immutable
    690  * methods are forwarded verbatim.
    691  */
    692 int ipc_forward_fast(ipc_callid_t callid, int phoneid, int method,
    693     ipcarg_t arg1, ipcarg_t arg2, int mode)
    694 {
    695         return __SYSCALL6(SYS_IPC_FORWARD_FAST, callid, phoneid, method, arg1,
     695 * For non-system methods, the old method, arg1 and arg2 are rewritten
     696 * by the new values. For system methods, the new method, arg1 and arg2
     697 * are written to the old arg1, arg2 and arg3, respectivelly. Calls with
     698 * immutable methods are forwarded verbatim.
     699 *
     700 * @param callid  Hash of the call to forward.
     701 * @param phoneid Phone handle to use for forwarding.
     702 * @param imethod New interface and method for the forwarded call.
     703 * @param arg1    New value of the first argument for the forwarded call.
     704 * @param arg2    New value of the second argument for the forwarded call.
     705 * @param mode    Flags specifying mode of the forward operation.
     706 *
     707 * @return Zero on success or an error code.
     708 *
     709 */
     710int ipc_forward_fast(ipc_callid_t callid, int phoneid, sysarg_t imethod,
     711    sysarg_t arg1, sysarg_t arg2, unsigned int mode)
     712{
     713        return __SYSCALL6(SYS_IPC_FORWARD_FAST, callid, phoneid, imethod, arg1,
    696714            arg2, mode);
    697715}
    698716
    699 
    700 int ipc_forward_slow(ipc_callid_t callid, int phoneid, int method,
    701     ipcarg_t arg1, ipcarg_t arg2, ipcarg_t arg3, ipcarg_t arg4, ipcarg_t arg5,
    702     int mode)
     717int ipc_forward_slow(ipc_callid_t callid, int phoneid, sysarg_t imethod,
     718    sysarg_t arg1, sysarg_t arg2, sysarg_t arg3, sysarg_t arg4, sysarg_t arg5,
     719    unsigned int mode)
    703720{
    704721        ipc_call_t data;
    705 
    706         IPC_SET_METHOD(data, method);
     722       
     723        IPC_SET_IMETHOD(data, imethod);
    707724        IPC_SET_ARG1(data, arg1);
    708725        IPC_SET_ARG2(data, arg2);
     
    710727        IPC_SET_ARG4(data, arg4);
    711728        IPC_SET_ARG5(data, arg5);
    712 
    713         return __SYSCALL4(SYS_IPC_FORWARD_SLOW, callid, phoneid, (sysarg_t) &data, mode);
    714 }
    715 
    716 /** Wrapper for making IPC_M_SHARE_IN calls.
    717  *
    718  * @param phoneid       Phone that will be used to contact the receiving side.
    719  * @param dst           Destination address space area base.
    720  * @param size          Size of the destination address space area.
    721  * @param arg           User defined argument.
    722  * @param flags         Storage where the received flags will be stored. Can be
    723  *                      NULL.
    724  *
    725  * @return              Zero on success or a negative error code from errno.h.
    726  */
    727 int ipc_share_in_start(int phoneid, void *dst, size_t size, ipcarg_t arg,
    728     int *flags)
     729       
     730        return __SYSCALL4(SYS_IPC_FORWARD_SLOW, callid, phoneid, (sysarg_t) &data,
     731            mode);
     732}
     733
     734/** Wrapper for IPC_M_SHARE_IN calls.
     735 *
     736 * @param phoneid Phone that will be used to contact the receiving side.
     737 * @param dst     Destination address space area base.
     738 * @param size    Size of the destination address space area.
     739 * @param arg     User defined argument.
     740 * @param flags   Storage for received flags. Can be NULL.
     741 *
     742 * @return Zero on success or a negative error code from errno.h.
     743 *
     744 */
     745int ipc_share_in_start(int phoneid, void *dst, size_t size, sysarg_t arg,
     746    unsigned int *flags)
    729747{
    730748        sysarg_t tmp_flags = 0;
    731         int res = ipc_call_sync_3_2(phoneid, IPC_M_SHARE_IN, (ipcarg_t) dst,
    732             (ipcarg_t) size, arg, NULL, &tmp_flags);
     749        int res = ipc_call_sync_3_2(phoneid, IPC_M_SHARE_IN, (sysarg_t) dst,
     750            (sysarg_t) size, arg, NULL, &tmp_flags);
    733751       
    734752        if (flags)
    735                 *flags = tmp_flags;
     753                *flags = (unsigned int) tmp_flags;
    736754       
    737755        return res;
     
    740758/** Wrapper for answering the IPC_M_SHARE_IN calls.
    741759 *
    742  * This wrapper only makes it more comfortable to answer IPC_M_DATA_READ calls
    743  * so that the user doesn't have to remember the meaning of each IPC argument.
    744  *
    745  * @param callid        Hash of the IPC_M_DATA_READ call to answer.
    746  * @param src           Source address space base.
    747  * @param flags         Flags to be used for sharing. Bits can be only cleared.
    748  *
    749  * @return              Zero on success or a value from @ref errno.h on failure.
    750  */
    751 int ipc_share_in_finalize(ipc_callid_t callid, void *src, int flags)
    752 {
    753         return ipc_answer_2(callid, EOK, (ipcarg_t) src, (ipcarg_t) flags);
    754 }
    755 
    756 /** Wrapper for making IPC_M_SHARE_OUT calls.
    757  *
    758  * @param phoneid       Phone that will be used to contact the receiving side.
    759  * @param src           Source address space area base address.
    760  * @param flags         Flags to be used for sharing. Bits can be only cleared.
    761  *
    762  * @return              Zero on success or a negative error code from errno.h.
    763  */
    764 int ipc_share_out_start(int phoneid, void *src, int flags)
    765 {
    766         return ipc_call_sync_3_0(phoneid, IPC_M_SHARE_OUT, (ipcarg_t) src, 0,
    767             (ipcarg_t) flags);
     760 * This wrapper only makes it more comfortable to answer IPC_M_DATA_READ
     761 * calls so that the user doesn't have to remember the meaning of each
     762 * IPC argument.
     763 *
     764 * @param callid Hash of the IPC_M_DATA_READ call to answer.
     765 * @param src    Source address space base.
     766 * @param flags Flags to be used for sharing. Bits can be only cleared.
     767 *
     768 * @return Zero on success or a value from @ref errno.h on failure.
     769 *
     770 */
     771int ipc_share_in_finalize(ipc_callid_t callid, void *src, unsigned int flags)
     772{
     773        return ipc_answer_2(callid, EOK, (sysarg_t) src, (sysarg_t) flags);
     774}
     775
     776/** Wrapper for IPC_M_SHARE_OUT calls.
     777 *
     778 * @param phoneid Phone that will be used to contact the receiving side.
     779 * @param src     Source address space area base address.
     780 * @param flags   Flags to be used for sharing. Bits can be only cleared.
     781 *
     782 * @return Zero on success or a negative error code from errno.h.
     783 *
     784 */
     785int ipc_share_out_start(int phoneid, void *src, unsigned int flags)
     786{
     787        return ipc_call_sync_3_0(phoneid, IPC_M_SHARE_OUT, (sysarg_t) src, 0,
     788            (sysarg_t) flags);
    768789}
    769790
    770791/** Wrapper for answering the IPC_M_SHARE_OUT calls.
    771792 *
    772  * This wrapper only makes it more comfortable to answer IPC_M_SHARE_OUT calls
    773  * so that the user doesn't have to remember the meaning of each IPC argument.
    774  *
    775  * @param callid        Hash of the IPC_M_DATA_WRITE call to answer.
    776  * @param dst           Destination address space area base address.   
    777  *
    778  * @return              Zero on success or a value from @ref errno.h on failure.
     793 * This wrapper only makes it more comfortable to answer IPC_M_SHARE_OUT
     794 * calls so that the user doesn't have to remember the meaning of each
     795 * IPC argument.
     796 *
     797 * @param callid Hash of the IPC_M_DATA_WRITE call to answer.
     798 * @param dst    Destination address space area base address.
     799 *
     800 * @return Zero on success or a value from @ref errno.h on failure.
     801 *
    779802 */
    780803int ipc_share_out_finalize(ipc_callid_t callid, void *dst)
    781804{
    782         return ipc_answer_1(callid, EOK, (ipcarg_t) dst);
    783 }
    784 
    785 
    786 /** Wrapper for making IPC_M_DATA_READ calls.
    787  *
    788  * @param phoneid       Phone that will be used to contact the receiving side.
    789  * @param dst           Address of the beginning of the destination buffer.
    790  * @param size          Size of the destination buffer.
    791  *
    792  * @return              Zero on success or a negative error code from errno.h.
     805        return ipc_answer_1(callid, EOK, (sysarg_t) dst);
     806}
     807
     808/** Wrapper for IPC_M_DATA_READ calls.
     809 *
     810 * @param phoneid Phone that will be used to contact the receiving side.
     811 * @param dst     Address of the beginning of the destination buffer.
     812 * @param size    Size of the destination buffer.
     813 *
     814 * @return Zero on success or a negative error code from errno.h.
     815 *
    793816 */
    794817int ipc_data_read_start(int phoneid, void *dst, size_t size)
    795818{
    796         return ipc_call_sync_2_0(phoneid, IPC_M_DATA_READ, (ipcarg_t) dst,
    797             (ipcarg_t) size);
     819        return ipc_call_sync_2_0(phoneid, IPC_M_DATA_READ, (sysarg_t) dst,
     820            (sysarg_t) size);
    798821}
    799822
    800823/** Wrapper for answering the IPC_M_DATA_READ calls.
    801824 *
    802  * This wrapper only makes it more comfortable to answer IPC_M_DATA_READ calls
    803  * so that the user doesn't have to remember the meaning of each IPC argument.
    804  *
    805  * @param callid        Hash of the IPC_M_DATA_READ call to answer.
    806  * @param src           Source address for the IPC_M_DATA_READ call.
    807  * @param size          Size for the IPC_M_DATA_READ call. Can be smaller than
    808  *                      the maximum size announced by the sender.
    809  *
    810  * @return              Zero on success or a value from @ref errno.h on failure.
     825 * This wrapper only makes it more comfortable to answer IPC_M_DATA_READ
     826 * calls so that the user doesn't have to remember the meaning of each
     827 * IPC argument.
     828 *
     829 * @param callid Hash of the IPC_M_DATA_READ call to answer.
     830 * @param src    Source address for the IPC_M_DATA_READ call.
     831 * @param size   Size for the IPC_M_DATA_READ call. Can be smaller than
     832 *               the maximum size announced by the sender.
     833 *
     834 * @return Zero on success or a value from @ref errno.h on failure.
     835 *
    811836 */
    812837int ipc_data_read_finalize(ipc_callid_t callid, const void *src, size_t size)
    813838{
    814         return ipc_answer_2(callid, EOK, (ipcarg_t) src, (ipcarg_t) size);
    815 }
    816 
    817 /** Wrapper for making IPC_M_DATA_WRITE calls.
    818  *
    819  * @param phoneid       Phone that will be used to contact the receiving side.
    820  * @param src           Address of the beginning of the source buffer.
    821  * @param size          Size of the source buffer.
    822  *
    823  * @return              Zero on success or a negative error code from errno.h.
     839        return ipc_answer_2(callid, EOK, (sysarg_t) src, (sysarg_t) size);
     840}
     841
     842/** Wrapper for IPC_M_DATA_WRITE calls.
     843 *
     844 * @param phoneid Phone that will be used to contact the receiving side.
     845 * @param src     Address of the beginning of the source buffer.
     846 * @param size    Size of the source buffer.
     847 *
     848 * @return Zero on success or a negative error code from errno.h.
     849 *
    824850 */
    825851int ipc_data_write_start(int phoneid, const void *src, size_t size)
    826852{
    827         return ipc_call_sync_2_0(phoneid, IPC_M_DATA_WRITE, (ipcarg_t) src,
    828             (ipcarg_t) size);
     853        return ipc_call_sync_2_0(phoneid, IPC_M_DATA_WRITE, (sysarg_t) src,
     854            (sysarg_t) size);
    829855}
    830856
    831857/** Wrapper for answering the IPC_M_DATA_WRITE calls.
    832858 *
    833  * This wrapper only makes it more comfortable to answer IPC_M_DATA_WRITE calls
    834  * so that the user doesn't have to remember the meaning of each IPC argument.
    835  *
    836  * @param callid        Hash of the IPC_M_DATA_WRITE call to answer.
    837  * @param dst           Final destination address for the IPC_M_DATA_WRITE call.
    838  * @param size          Final size for the IPC_M_DATA_WRITE call.
    839  *
    840  * @return              Zero on success or a value from @ref errno.h on failure.
     859 * This wrapper only makes it more comfortable to answer IPC_M_DATA_WRITE
     860 * calls so that the user doesn't have to remember the meaning of each
     861 * IPC argument.
     862 *
     863 * @param callid Hash of the IPC_M_DATA_WRITE call to answer.
     864 * @param dst    Final destination address for the IPC_M_DATA_WRITE call.
     865 * @param size   Final size for the IPC_M_DATA_WRITE call.
     866 *
     867 * @return Zero on success or a value from @ref errno.h on failure.
     868 *
    841869 */
    842870int ipc_data_write_finalize(ipc_callid_t callid, void *dst, size_t size)
    843871{
    844         return ipc_answer_2(callid, EOK, (ipcarg_t) dst, (ipcarg_t) size);
    845 }
    846 
    847 #include <kernel/syscall/sysarg64.h>
     872        return ipc_answer_2(callid, EOK, (sysarg_t) dst, (sysarg_t) size);
     873}
     874
    848875/** Connect to a task specified by id.
     876 *
    849877 */
    850878int ipc_connect_kbox(task_id_t id)
    851879{
    852         sysarg64_t arg;
    853 
    854         arg.value = (unsigned long long) id;
    855 
     880#ifdef __32_BITS__
     881        sysarg64_t arg = (sysarg64_t) id;
    856882        return __SYSCALL1(SYS_IPC_CONNECT_KBOX, (sysarg_t) &arg);
    857 }
    858  
     883#endif
     884       
     885#ifdef __64_BITS__
     886        return __SYSCALL1(SYS_IPC_CONNECT_KBOX, (sysarg_t) id);
     887#endif
     888}
     889
    859890/** @}
    860891 */
Note: See TracChangeset for help on using the changeset viewer.