Ignore:
File:
1 edited

Legend:

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

    r10477601 r63f8966  
    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>
    4749#include <futex.h>
     50#include <kernel/synch/synch.h>
     51#include <async.h>
    4852#include <fibril.h>
     53#include <assert.h>
    4954
    5055/**
    51  * Structures of this type are used for keeping track
    52  * of sent asynchronous calls and queing unsent calls.
     56 * Structures of this type are used for keeping track of sent asynchronous calls
     57 * and queing unsent calls.
    5358 */
    5459typedef struct {
    5560        link_t list;
    56        
     61
    5762        ipc_async_callback_t callback;
    5863        void *private;
    59        
    6064        union {
    6165                ipc_callid_t callid;
     
    6569                } msg;
    6670        } u;
     71        fid_t fid;      /**< Fibril waiting for sending this call. */
     72} async_call_t;
     73
     74LIST_INITIALIZE(dispatched_calls);
     75
     76/** List of asynchronous calls that were not accepted by kernel.
     77 *
     78 * It is protected by async_futex, because if the call cannot be sent into the
     79 * kernel, the async framework is used automatically.
     80 */
     81LIST_INITIALIZE(queued_calls);
     82
     83static atomic_t ipc_futex = FUTEX_INITIALIZER;
     84
     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 */
     105int
     106ipc_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)
     109{
     110        ipc_call_t resdata;
     111        int callres;
    67112       
    68         /** Fibril waiting for sending this call. */
    69         fid_t fid;
    70 } async_call_t;
    71 
    72 LIST_INITIALIZE(dispatched_calls);
    73 
    74 /** List of asynchronous calls that were not accepted by kernel.
    75  *
    76  * Protected by async_futex, because if the call is not accepted
    77  * by the kernel, the async framework is used automatically.
    78  *
    79  */
    80 LIST_INITIALIZE(queued_calls);
    81 
    82 static atomic_t ipc_futex = FUTEX_INITIALIZER;
    83 
    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  */
    105 int 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)
    108 {
    109         ipc_call_t resdata;
    110         int callres = __SYSCALL6(SYS_IPC_CALL_SYNC_FAST, phoneid, method, arg1,
     113        callres = __SYSCALL6(SYS_IPC_CALL_SYNC_FAST, phoneid, method, arg1,
    111114            arg2, arg3, (sysarg_t) &resdata);
    112115        if (callres)
    113116                return callres;
    114        
    115117        if (result1)
    116118                *result1 = IPC_GET_ARG1(resdata);
     
    123125        if (result5)
    124126                *result5 = IPC_GET_ARG5(resdata);
    125        
     127
    126128        return IPC_GET_RETVAL(resdata);
    127129}
    128130
    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  */
    148 int 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)
     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 */
     149int
     150ipc_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)
    152153{
    153154        ipc_call_t data;
    154        
    155         IPC_SET_IMETHOD(data, imethod);
     155        int callres;
     156
     157        IPC_SET_METHOD(data, method);
    156158        IPC_SET_ARG1(data, arg1);
    157159        IPC_SET_ARG2(data, arg2);
     
    159161        IPC_SET_ARG4(data, arg4);
    160162        IPC_SET_ARG5(data, arg5);
    161        
    162         int callres = __SYSCALL3(SYS_IPC_CALL_SYNC_SLOW, phoneid,
    163             (sysarg_t) &data, (sysarg_t) &data);
     163
     164        callres = __SYSCALL3(SYS_IPC_CALL_SYNC_SLOW, phoneid, (sysarg_t) &data,
     165            (sysarg_t) &data);
    164166        if (callres)
    165167                return callres;
    166        
     168
    167169        if (result1)
    168170                *result1 = IPC_GET_ARG1(data);
     
    175177        if (result5)
    176178                *result5 = IPC_GET_ARG5(data);
    177        
     179
    178180        return IPC_GET_RETVAL(data);
    179181}
    180182
    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  */
    189 static ipc_callid_t ipc_call_async_internal(int phoneid, ipc_call_t *data)
     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 */
     190static ipc_callid_t _ipc_call_async(int phoneid, ipc_call_t *data)
    190191{
    191192        return __SYSCALL2(SYS_IPC_CALL_ASYNC_SLOW, phoneid, (sysarg_t) data);
    192193}
    193194
    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  *
     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.
    201201 */
    202202static inline async_call_t *ipc_prepare_async(void *private,
    203203    ipc_async_callback_t callback)
    204204{
    205         async_call_t *call =
    206             (async_call_t *) malloc(sizeof(async_call_t));
     205        async_call_t *call;
     206
     207        call = malloc(sizeof(*call));
    207208        if (!call) {
    208209                if (callback)
    209210                        callback(private, ENOMEM, NULL);
    210                
    211211                return NULL;
    212212        }
    213        
    214213        call->callback = callback;
    215214        call->private = private;
    216        
     215
    217216        return call;
    218217}
    219218
    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  *
     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.
    228226 */
    229227static inline void ipc_finish_async(ipc_callid_t callid, int phoneid,
    230     async_call_t *call, bool can_preempt)
    231 {
    232         if (!call) {
    233                 /* Nothing to do regardless if failed or not */
     228    async_call_t *call, int can_preempt)
     229{
     230        if (!call) { /* Nothing to do regardless if failed or not */
    234231                futex_up(&ipc_futex);
    235232                return;
    236233        }
    237        
     234
    238235        if (callid == (ipc_callid_t) IPC_CALLRET_FATAL) {
    239236                futex_up(&ipc_futex);
    240                
    241237                /* Call asynchronous handler with error code */
    242238                if (call->callback)
    243239                        call->callback(call->private, ENOENT, NULL);
    244                
    245240                free(call);
    246241                return;
    247242        }
    248        
     243
    249244        if (callid == (ipc_callid_t) IPC_CALLRET_TEMPORARY) {
    250245                futex_up(&ipc_futex);
    251                
     246
    252247                call->u.msg.phoneid = phoneid;
    253248               
    254249                futex_down(&async_futex);
    255250                list_append(&call->list, &queued_calls);
    256                
     251
    257252                if (can_preempt) {
    258253                        call->fid = fibril_get_id();
     
    263258                        futex_up(&async_futex);
    264259                }
    265                
    266260                return;
    267261        }
    268        
    269262        call->u.callid = callid;
    270        
    271263        /* Add call to the list of dispatched calls */
    272264        list_append(&call->list, &dispatched_calls);
    273265        futex_up(&ipc_futex);
    274 }
    275 
    276 /** Fast asynchronous call.
     266       
     267}
     268
     269/** Make a fast asynchronous call.
    277270 *
    278271 * This function can only handle four arguments of payload. It is, however,
     
    280273 *
    281274 * Note that this function is a void function.
    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  */
    300 void 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)
     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 */
     291void 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)
    303294{
    304295        async_call_t *call = NULL;
    305        
     296        ipc_callid_t callid;
     297
    306298        if (callback) {
    307299                call = ipc_prepare_async(private, callback);
     
    309301                        return;
    310302        }
    311        
     303
    312304        /*
    313          * We need to make sure that we get callid
    314          * before another thread accesses the queue again.
     305         * We need to make sure that we get callid before another thread
     306         * accesses the queue again.
    315307         */
    316        
    317308        futex_down(&ipc_futex);
    318         ipc_callid_t callid = __SYSCALL6(SYS_IPC_CALL_ASYNC_FAST, phoneid,
    319             imethod, arg1, arg2, arg3, arg4);
    320        
     309        callid = __SYSCALL6(SYS_IPC_CALL_ASYNC_FAST, phoneid, method, arg1,
     310            arg2, arg3, arg4);
     311
    321312        if (callid == (ipc_callid_t) IPC_CALLRET_TEMPORARY) {
    322313                if (!call) {
     
    325316                                return;
    326317                }
    327                
    328                 IPC_SET_IMETHOD(call->u.msg.data, imethod);
     318                IPC_SET_METHOD(call->u.msg.data, method);
    329319                IPC_SET_ARG1(call->u.msg.data, arg1);
    330320                IPC_SET_ARG2(call->u.msg.data, arg2);
    331321                IPC_SET_ARG3(call->u.msg.data, arg3);
    332322                IPC_SET_ARG4(call->u.msg.data, arg4);
    333                
    334323                /*
    335324                 * To achieve deterministic behavior, we always zero out the
    336325                 * arguments that are beyond the limits of the fast version.
    337326                 */
    338                
    339327                IPC_SET_ARG5(call->u.msg.data, 0);
    340328        }
    341        
    342329        ipc_finish_async(callid, phoneid, call, can_preempt);
    343330}
    344331
    345 /** Asynchronous call transmitting the entire payload.
     332/** Make an asynchronous call transmitting the entire payload.
    346333 *
    347334 * Note that this function is a void function.
    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  */
    367 void 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);
     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 */
     353void 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);
    372361        if (!call)
    373362                return;
    374        
    375         IPC_SET_IMETHOD(call->u.msg.data, imethod);
     363
     364        IPC_SET_METHOD(call->u.msg.data, method);
    376365        IPC_SET_ARG1(call->u.msg.data, arg1);
    377366        IPC_SET_ARG2(call->u.msg.data, arg2);
     
    379368        IPC_SET_ARG4(call->u.msg.data, arg4);
    380369        IPC_SET_ARG5(call->u.msg.data, arg5);
    381        
    382370        /*
    383          * We need to make sure that we get callid
    384          * before another threadaccesses the queue again.
     371         * We need to make sure that we get callid before another thread
     372         * accesses the queue again.
    385373         */
    386        
    387374        futex_down(&ipc_futex);
    388         ipc_callid_t callid =
    389             ipc_call_async_internal(phoneid, &call->u.msg.data);
    390        
     375        callid = _ipc_call_async(phoneid, &call->u.msg.data);
     376
    391377        ipc_finish_async(callid, phoneid, call, can_preempt);
    392378}
    393379
    394 /** Answer received call (fast version).
     380
     381/** Answer a received call - fast version.
    395382 *
    396383 * The fast answer makes use of passing retval and first four arguments in
    397384 * registers. If you need to return more, use the ipc_answer_slow() instead.
    398385 *
    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  */
    410 sysarg_t ipc_answer_fast(ipc_callid_t callid, sysarg_t retval, sysarg_t arg1,
    411     sysarg_t arg2, sysarg_t arg3, sysarg_t arg4)
     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 */
     395ipcarg_t ipc_answer_fast(ipc_callid_t callid, ipcarg_t retval, ipcarg_t arg1,
     396    ipcarg_t arg2, ipcarg_t arg3, ipcarg_t arg4)
    412397{
    413398        return __SYSCALL6(SYS_IPC_ANSWER_FAST, callid, retval, arg1, arg2, arg3,
     
    415400}
    416401
    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  */
    431 sysarg_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)
     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 */
     414ipcarg_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)
    433416{
    434417        ipc_call_t data;
    435        
     418
    436419        IPC_SET_RETVAL(data, retval);
    437420        IPC_SET_ARG1(data, arg1);
     
    440423        IPC_SET_ARG4(data, arg4);
    441424        IPC_SET_ARG5(data, arg5);
    442        
     425
    443426        return __SYSCALL2(SYS_IPC_ANSWER_SLOW, callid, (sysarg_t) &data);
    444427}
    445428
    446 /** Try to dispatch queued calls from the async queue.
    447  *
    448  */
    449 static void dispatch_queued_calls(void)
    450 {
     429
     430/** Try to dispatch queued calls from the async queue. */
     431static void try_dispatch_queued_calls(void)
     432{
     433        async_call_t *call;
     434        ipc_callid_t callid;
     435
    451436        /** @todo
    452          * Integrate intelligently ipc_futex so that it is locked during
    453          * ipc_call_async_*() until it is added to dispatched_calls.
     437         * Integrate intelligently ipc_futex, so that it is locked during
     438         * ipc_call_async_*(), until it is added to dispatched_calls.
    454439         */
    455        
    456440        futex_down(&async_futex);
    457        
    458441        while (!list_empty(&queued_calls)) {
    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)
     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) {
    465446                        break;
    466                
     447                }
    467448                list_remove(&call->list);
    468                
     449
    469450                futex_up(&async_futex);
    470                
    471451                if (call->fid)
    472452                        fibril_add_ready(call->fid);
     
    475455                        if (call->callback)
    476456                                call->callback(call->private, ENOENT, NULL);
    477                        
    478457                        free(call);
    479458                } else {
    480459                        call->u.callid = callid;
    481                        
    482460                        futex_down(&ipc_futex);
    483461                        list_append(&call->list, &dispatched_calls);
    484462                        futex_up(&ipc_futex);
    485463                }
    486                
    487464                futex_down(&async_futex);
    488465        }
    489        
    490466        futex_up(&async_futex);
    491467}
    492468
    493 /** Handle received answer.
     469/** Handle a received answer.
    494470 *
    495471 * Find the hash of the answer and call the answer callback.
    496472 *
    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  *
     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.
    505479 */
    506480static void handle_answer(ipc_callid_t callid, ipc_call_t *data)
    507481{
     482        link_t *item;
     483        async_call_t *call;
     484
    508485        callid &= ~IPC_CALLID_ANSWERED;
    509486       
    510487        futex_down(&ipc_futex);
    511        
    512         link_t *item;
    513488        for (item = dispatched_calls.next; item != &dispatched_calls;
    514489            item = item->next) {
    515                 async_call_t *call =
    516                     list_get_instance(item, async_call_t, list);
    517                
     490                call = list_get_instance(item, async_call_t, list);
    518491                if (call->u.callid == callid) {
    519492                        list_remove(&call->list);
    520                        
    521493                        futex_up(&ipc_futex);
    522                        
    523494                        if (call->callback)
    524                                 call->callback(call->private,
     495                                call->callback(call->private, 
    525496                                    IPC_GET_RETVAL(*data), data);
    526                        
    527497                        free(call);
    528498                        return;
    529499                }
    530500        }
    531        
    532501        futex_up(&ipc_futex);
    533502}
    534503
    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  */
    546 ipc_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        
     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 */
     516ipc_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);
    552521        /* Handle received answers */
    553522        if (callid & IPC_CALLID_ANSWERED) {
    554523                handle_answer(callid, call);
    555                 dispatch_queued_calls();
     524                try_dispatch_queued_calls();
    556525        }
    557        
     526
    558527        return callid;
    559528}
    560529
    561 /** Interrupt one thread of this task from waiting for IPC.
    562  *
    563  */
    564 void 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  */
    579 ipc_callid_t ipc_wait_for_call_timeout(ipc_call_t *call, sysarg_t usec)
     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 */
     539ipc_callid_t ipc_wait_for_call_timeout(ipc_call_t *call, uint32_t usec)
    580540{
    581541        ipc_callid_t callid;
    582        
     542
    583543        do {
    584544                callid = ipc_wait_cycle(call, usec, SYNCH_FLAGS_NONE);
    585545        } while (callid & IPC_CALLID_ANSWERED);
    586        
     546
    587547        return callid;
    588548}
     
    590550/** Check if there is an IPC call waiting to be picked up.
    591551 *
    592  * Only requests are returned, answers are processed internally.
    593  *
    594  * @param call Incoming call storage.
    595  *
    596  * @return Hash of the call.
    597  *
     552 * @param call          Storage where the incoming call will be stored.
     553 * @return              Hash of the answer.
    598554 */
    599555ipc_callid_t ipc_trywait_for_call(ipc_call_t *call)
    600556{
    601557        ipc_callid_t callid;
    602        
     558
    603559        do {
    604560                callid = ipc_wait_cycle(call, SYNCH_NO_TIMEOUT,
    605561                    SYNCH_FLAGS_NON_BLOCKING);
    606562        } while (callid & IPC_CALLID_ANSWERED);
    607        
     563
    608564        return callid;
    609565}
    610566
    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  */
    627 int ipc_connect_to_me(int phoneid, sysarg_t arg1, sysarg_t arg2, sysarg_t arg3,
    628     sysarg_t *taskhash, sysarg_t *phonehash)
     567/** Interrupt one thread of this task from waiting for IPC. */
     568void 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 */
     586int ipc_connect_to_me(int phoneid, int arg1, int arg2, int arg3,
     587    ipcarg_t *phonehash)
    629588{
    630589        return ipc_call_sync_3_5(phoneid, IPC_M_CONNECT_TO_ME, arg1, arg2,
    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  */
    644 int 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,
     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 */
     602int 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,
    648608            NULL, NULL, NULL, NULL, &newphid);
    649609        if (res)
    650610                return res;
    651        
    652611        return newphid;
    653612}
    654613
    655 /** Request new connection (blocking)
     614/** Ask through phone for a new connection to some service.
    656615 *
    657616 * If the connection is not available at the moment, the
    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  */
    669 int 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,
     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 */
     626int 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,
    674632            IPC_FLAG_BLOCKING, NULL, NULL, NULL, NULL, &newphid);
    675633        if (res)
    676634                return res;
    677        
    678635        return newphid;
    679636}
     
    681638/** Hang up a phone.
    682639 *
    683  * @param phoneid Handle of the phone to be hung up.
    684  *
    685  * @return Zero on success or a negative error code.
    686  *
     640 * @param phoneid       Handle of the phone to be hung up.
     641 *
     642 * @return              Zero on success or a negative error code.
    687643 */
    688644int ipc_hangup(int phoneid)
     
    691647}
    692648
     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 */
     658int 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 */
     671int ipc_unregister_irq(int inr, int devno)
     672{
     673        return __SYSCALL2(SYS_IPC_UNREGISTER_IRQ, inr, devno);
     674}
     675
    693676/** Forward a received call to another destination.
    694677 *
    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  */
    710 int 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,
     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 */
     692int 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,
    714696            arg2, mode);
    715697}
    716698
    717 int 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)
     699
     700int 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)
    720703{
    721704        ipc_call_t data;
    722        
    723         IPC_SET_IMETHOD(data, imethod);
     705
     706        IPC_SET_METHOD(data, method);
    724707        IPC_SET_ARG1(data, arg1);
    725708        IPC_SET_ARG2(data, arg2);
     
    727710        IPC_SET_ARG4(data, arg4);
    728711        IPC_SET_ARG5(data, arg5);
    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  */
    745 int ipc_share_in_start(int phoneid, void *dst, size_t size, sysarg_t arg,
    746     unsigned int *flags)
     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 */
     727int ipc_share_in_start(int phoneid, void *dst, size_t size, ipcarg_t arg,
     728    int *flags)
    747729{
    748730        sysarg_t tmp_flags = 0;
    749         int res = ipc_call_sync_3_2(phoneid, IPC_M_SHARE_IN, (sysarg_t) dst,
    750             (sysarg_t) size, arg, NULL, &tmp_flags);
     731        int res = ipc_call_sync_3_2(phoneid, IPC_M_SHARE_IN, (ipcarg_t) dst,
     732            (ipcarg_t) size, arg, NULL, &tmp_flags);
    751733       
    752734        if (flags)
    753                 *flags = (unsigned int) tmp_flags;
     735                *flags = tmp_flags;
    754736       
    755737        return res;
     
    758740/** Wrapper for answering the IPC_M_SHARE_IN calls.
    759741 *
    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  */
    771 int 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  */
    785 int 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);
     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 */
     751int 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 */
     764int 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);
    789768}
    790769
    791770/** Wrapper for answering the IPC_M_SHARE_OUT calls.
    792771 *
    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  *
     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.
    802779 */
    803780int ipc_share_out_finalize(ipc_callid_t callid, void *dst)
    804781{
    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  *
     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.
    816793 */
    817794int ipc_data_read_start(int phoneid, void *dst, size_t size)
    818795{
    819         return ipc_call_sync_2_0(phoneid, IPC_M_DATA_READ, (sysarg_t) dst,
    820             (sysarg_t) size);
     796        return ipc_call_sync_2_0(phoneid, IPC_M_DATA_READ, (ipcarg_t) dst,
     797            (ipcarg_t) size);
    821798}
    822799
    823800/** Wrapper for answering the IPC_M_DATA_READ calls.
    824801 *
    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  *
     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.
    836811 */
    837812int ipc_data_read_finalize(ipc_callid_t callid, const void *src, size_t size)
    838813{
    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  *
     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.
    850824 */
    851825int ipc_data_write_start(int phoneid, const void *src, size_t size)
    852826{
    853         return ipc_call_sync_2_0(phoneid, IPC_M_DATA_WRITE, (sysarg_t) src,
    854             (sysarg_t) size);
     827        return ipc_call_sync_2_0(phoneid, IPC_M_DATA_WRITE, (ipcarg_t) src,
     828            (ipcarg_t) size);
    855829}
    856830
    857831/** Wrapper for answering the IPC_M_DATA_WRITE calls.
    858832 *
    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  *
     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.
    869841 */
    870842int ipc_data_write_finalize(ipc_callid_t callid, void *dst, size_t size)
    871843{
    872         return ipc_answer_2(callid, EOK, (sysarg_t) dst, (sysarg_t) size);
    873 }
    874 
     844        return ipc_answer_2(callid, EOK, (ipcarg_t) dst, (ipcarg_t) size);
     845}
     846
     847#include <kernel/syscall/sysarg64.h>
    875848/** Connect to a task specified by id.
    876  *
    877849 */
    878850int ipc_connect_kbox(task_id_t id)
    879851{
    880 #ifdef __32_BITS__
    881         sysarg64_t arg = (sysarg64_t) id;
     852        sysarg64_t arg;
     853
     854        arg.value = (unsigned long long) id;
     855
    882856        return __SYSCALL1(SYS_IPC_CONNECT_KBOX, (sysarg_t) &arg);
    883 #endif
    884        
    885 #ifdef __64_BITS__
    886         return __SYSCALL1(SYS_IPC_CONNECT_KBOX, (sysarg_t) id);
    887 #endif
    888 }
    889 
     857}
     858 
    890859/** @}
    891860 */
Note: See TracChangeset for help on using the changeset viewer.