Ignore:
File:
1 edited

Legend:

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

    r10477601 r64d2b10  
    4949
    5050/**
    51  * Structures of this type are used for keeping track
    52  * of sent asynchronous calls and queing unsent calls.
     51 * Structures of this type are used for keeping track of sent asynchronous calls
     52 * and queing unsent calls.
    5353 */
    5454typedef struct {
    5555        link_t list;
    56        
     56
    5757        ipc_async_callback_t callback;
    5858        void *private;
    59        
    6059        union {
    6160                ipc_callid_t callid;
     
    6564                } msg;
    6665        } u;
    67        
    68         /** Fibril waiting for sending this call. */
    69         fid_t fid;
     66        fid_t fid;      /**< Fibril waiting for sending this call. */
    7067} async_call_t;
    7168
     
    7471/** List of asynchronous calls that were not accepted by kernel.
    7572 *
    76  * Protected by async_futex, because if the call is not accepted
    77  * by the kernel, the async framework is used automatically.
    78  *
     73 * It is protected by async_futex, because if the call cannot be sent into the
     74 * kernel, the async framework is used automatically.
    7975 */
    8076LIST_INITIALIZE(queued_calls);
     
    8278static atomic_t ipc_futex = FUTEX_INITIALIZER;
    8379
    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)
     80/** Make a fast synchronous call.
     81 *
     82 * Only three payload arguments can be passed using this function. However, this
     83 * function is faster than the generic ipc_call_sync_slow() because the payload
     84 * is passed directly in registers.
     85 *
     86 * @param phoneid       Phone handle for the call.
     87 * @param method        Requested method.
     88 * @param arg1          Service-defined payload argument.
     89 * @param arg2          Service-defined payload argument.
     90 * @param arg3          Service-defined payload argument.
     91 * @param result1       If non-NULL, the return ARG1 will be stored there.
     92 * @param result2       If non-NULL, the return ARG2 will be stored there.
     93 * @param result3       If non-NULL, the return ARG3 will be stored there.
     94 * @param result4       If non-NULL, the return ARG4 will be stored there.
     95 * @param result5       If non-NULL, the return ARG5 will be stored there.
     96 *
     97 * @return              Negative values represent errors returned by IPC.
     98 *                      Otherwise the RETVAL of the answer is returned.
     99 */
     100int
     101ipc_call_sync_fast(int phoneid, sysarg_t method, sysarg_t arg1, sysarg_t arg2,
     102    sysarg_t arg3, sysarg_t *result1, sysarg_t *result2, sysarg_t *result3,
     103    sysarg_t *result4, sysarg_t *result5)
    108104{
    109105        ipc_call_t resdata;
    110         int callres = __SYSCALL6(SYS_IPC_CALL_SYNC_FAST, phoneid, method, arg1,
     106        int callres;
     107       
     108        callres = __SYSCALL6(SYS_IPC_CALL_SYNC_FAST, phoneid, method, arg1,
    111109            arg2, arg3, (sysarg_t) &resdata);
    112110        if (callres)
    113111                return callres;
    114        
    115112        if (result1)
    116113                *result1 = IPC_GET_ARG1(resdata);
     
    123120        if (result5)
    124121                *result5 = IPC_GET_ARG5(resdata);
    125        
     122
    126123        return IPC_GET_RETVAL(resdata);
    127124}
    128125
    129 /** Synchronous call transmitting 5 arguments of payload.
     126/** Make a synchronous call transmitting 5 arguments of payload.
    130127 *
    131128 * @param phoneid Phone handle for the call.
     
    142139 * @param result5 If non-NULL, storage for the fifth return argument.
    143140 *
    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)
     141 * @return Negative value means IPC error.
     142 *         Otherwise the RETVAL of the answer.
     143 *
     144 */
     145int
     146ipc_call_sync_slow(int phoneid, sysarg_t imethod, sysarg_t arg1, sysarg_t arg2,
     147    sysarg_t arg3, sysarg_t arg4, sysarg_t arg5, sysarg_t *result1,
     148    sysarg_t *result2, sysarg_t *result3, sysarg_t *result4, sysarg_t *result5)
    152149{
    153150        ipc_call_t data;
     
    179176}
    180177
    181 /** Send asynchronous message via syscall.
     178/** Syscall to send asynchronous message.
    182179 *
    183180 * @param phoneid Phone handle for the call.
     
    187184 *
    188185 */
    189 static ipc_callid_t ipc_call_async_internal(int phoneid, ipc_call_t *data)
     186static ipc_callid_t _ipc_call_async(int phoneid, ipc_call_t *data)
    190187{
    191188        return __SYSCALL2(SYS_IPC_CALL_ASYNC_SLOW, phoneid, (sysarg_t) data);
    192189}
    193190
    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  *
     191/** Prolog to ipc_call_async_*() functions.
     192 *
     193 * @param private       Argument for the answer/error callback.
     194 * @param callback      Answer/error callback.
     195 *
     196 * @return              New, partially initialized async_call structure or NULL.
    201197 */
    202198static inline async_call_t *ipc_prepare_async(void *private,
    203199    ipc_async_callback_t callback)
    204200{
    205         async_call_t *call =
    206             (async_call_t *) malloc(sizeof(async_call_t));
     201        async_call_t *call;
     202
     203        call = malloc(sizeof(*call));
    207204        if (!call) {
    208205                if (callback)
    209206                        callback(private, ENOMEM, NULL);
    210                
    211207                return NULL;
    212208        }
    213        
    214209        call->callback = callback;
    215210        call->private = private;
    216        
     211
    217212        return call;
    218213}
    219214
    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  *
     215/** Epilogue of ipc_call_async_*() functions.
     216 *
     217 * @param callid        Value returned by the SYS_IPC_CALL_ASYNC_* syscall.
     218 * @param phoneid       Phone handle through which the call was made.
     219 * @param call          async_call structure returned by ipc_prepare_async().
     220 * @param can_preempt   If non-zero, the current fibril can be preempted in this
     221 *                      call.
    228222 */
    229223static 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 */
     224    async_call_t *call, int can_preempt)
     225{
     226        if (!call) { /* Nothing to do regardless if failed or not */
    234227                futex_up(&ipc_futex);
    235228                return;
    236229        }
    237        
     230
    238231        if (callid == (ipc_callid_t) IPC_CALLRET_FATAL) {
    239232                futex_up(&ipc_futex);
    240                
    241233                /* Call asynchronous handler with error code */
    242234                if (call->callback)
    243235                        call->callback(call->private, ENOENT, NULL);
    244                
    245236                free(call);
    246237                return;
    247238        }
    248        
     239
    249240        if (callid == (ipc_callid_t) IPC_CALLRET_TEMPORARY) {
    250241                futex_up(&ipc_futex);
    251                
     242
    252243                call->u.msg.phoneid = phoneid;
    253244               
    254245                futex_down(&async_futex);
    255246                list_append(&call->list, &queued_calls);
    256                
     247
    257248                if (can_preempt) {
    258249                        call->fid = fibril_get_id();
     
    263254                        futex_up(&async_futex);
    264255                }
    265                
    266256                return;
    267257        }
    268        
    269258        call->u.callid = callid;
    270        
    271259        /* Add call to the list of dispatched calls */
    272260        list_append(&call->list, &dispatched_calls);
    273261        futex_up(&ipc_futex);
    274 }
    275 
    276 /** Fast asynchronous call.
     262       
     263}
     264
     265/** Make a fast asynchronous call.
    277266 *
    278267 * This function can only handle four arguments of payload. It is, however,
     
    280269 *
    281270 * 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.
     271 * During normal opertation, answering this call will trigger the callback.
     272 * In case of fatal error, call the callback handler with the proper error code.
     273 * If the call cannot be temporarily made, queue it.
    286274 *
    287275 * @param phoneid     Phone handle for the call.
     
    293281 * @param private     Argument to be passed to the answer/error callback.
    294282 * @param callback    Answer or error callback.
    295  * @param can_preempt If true, the current fibril will be preempted in
     283 * @param can_preempt If non-zero, the current fibril will be preempted in
    296284 *                    case the kernel temporarily refuses to accept more
    297285 *                    asynchronous calls.
     
    300288void ipc_call_async_fast(int phoneid, sysarg_t imethod, sysarg_t arg1,
    301289    sysarg_t arg2, sysarg_t arg3, sysarg_t arg4, void *private,
    302     ipc_async_callback_t callback, bool can_preempt)
     290    ipc_async_callback_t callback, int can_preempt)
    303291{
    304292        async_call_t *call = NULL;
     
    311299       
    312300        /*
    313          * We need to make sure that we get callid
    314          * before another thread accesses the queue again.
     301         * We need to make sure that we get callid before another thread
     302         * accesses the queue again.
    315303         */
    316        
    317304        futex_down(&ipc_futex);
    318305        ipc_callid_t callid = __SYSCALL6(SYS_IPC_CALL_ASYNC_FAST, phoneid,
     
    325312                                return;
    326313                }
    327                
    328314                IPC_SET_IMETHOD(call->u.msg.data, imethod);
    329315                IPC_SET_ARG1(call->u.msg.data, arg1);
     
    331317                IPC_SET_ARG3(call->u.msg.data, arg3);
    332318                IPC_SET_ARG4(call->u.msg.data, arg4);
    333                
    334319                /*
    335320                 * To achieve deterministic behavior, we always zero out the
    336321                 * arguments that are beyond the limits of the fast version.
    337322                 */
    338                
    339323                IPC_SET_ARG5(call->u.msg.data, 0);
    340324        }
    341        
    342325        ipc_finish_async(callid, phoneid, call, can_preempt);
    343326}
    344327
    345 /** Asynchronous call transmitting the entire payload.
     328/** Make an asynchronous call transmitting the entire payload.
    346329 *
    347330 * 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.
     331 * During normal opertation, answering this call will trigger the callback.
     332 * In case of fatal error, call the callback handler with the proper error code.
     333 * If the call cannot be temporarily made, queue it.
    352334 *
    353335 * @param phoneid     Phone handle for the call.
     
    360342 * @param private     Argument to be passed to the answer/error callback.
    361343 * @param callback    Answer or error callback.
    362  * @param can_preempt If true, the current fibril will be preempted in
     344 * @param can_preempt If non-zero, the current fibril will be preempted in
    363345 *                    case the kernel temporarily refuses to accept more
    364346 *                    asynchronous calls.
     
    367349void ipc_call_async_slow(int phoneid, sysarg_t imethod, sysarg_t arg1,
    368350    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);
     351    ipc_async_callback_t callback, int can_preempt)
     352{
     353        async_call_t *call;
     354        ipc_callid_t callid;
     355
     356        call = ipc_prepare_async(private, callback);
    372357        if (!call)
    373358                return;
    374        
     359
    375360        IPC_SET_IMETHOD(call->u.msg.data, imethod);
    376361        IPC_SET_ARG1(call->u.msg.data, arg1);
     
    379364        IPC_SET_ARG4(call->u.msg.data, arg4);
    380365        IPC_SET_ARG5(call->u.msg.data, arg5);
    381        
    382366        /*
    383          * We need to make sure that we get callid
    384          * before another threadaccesses the queue again.
     367         * We need to make sure that we get callid before another thread
     368         * accesses the queue again.
    385369         */
    386        
    387370        futex_down(&ipc_futex);
    388         ipc_callid_t callid =
    389             ipc_call_async_internal(phoneid, &call->u.msg.data);
    390        
     371        callid = _ipc_call_async(phoneid, &call->u.msg.data);
     372
    391373        ipc_finish_async(callid, phoneid, call, can_preempt);
    392374}
    393375
    394 /** Answer received call (fast version).
     376
     377/** Answer a received call - fast version.
    395378 *
    396379 * The fast answer makes use of passing retval and first four arguments in
    397380 * registers. If you need to return more, use the ipc_answer_slow() instead.
    398381 *
    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  *
     382 * @param callid        Hash of the call being answered.
     383 * @param retval        Return value.
     384 * @param arg1          First return argument.
     385 * @param arg2          Second return argument.
     386 * @param arg3          Third return argument.
     387 * @param arg4          Fourth return argument.
     388 *
     389 * @return              Zero on success or a value from @ref errno.h on failure.
    409390 */
    410391sysarg_t ipc_answer_fast(ipc_callid_t callid, sysarg_t retval, sysarg_t arg1,
     
    415396}
    416397
    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  *
     398/** Answer a received call - slow full version.
     399 *
     400 * @param callid        Hash of the call being answered.
     401 * @param retval        Return value.
     402 * @param arg1          First return argument.
     403 * @param arg2          Second return argument.
     404 * @param arg3          Third return argument.
     405 * @param arg4          Fourth return argument.
     406 * @param arg5          Fifth return argument.
     407 *
     408 * @return              Zero on success or a value from @ref errno.h on failure.
    430409 */
    431410sysarg_t ipc_answer_slow(ipc_callid_t callid, sysarg_t retval, sysarg_t arg1,
     
    433412{
    434413        ipc_call_t data;
    435        
     414
    436415        IPC_SET_RETVAL(data, retval);
    437416        IPC_SET_ARG1(data, arg1);
     
    440419        IPC_SET_ARG4(data, arg4);
    441420        IPC_SET_ARG5(data, arg5);
    442        
     421
    443422        return __SYSCALL2(SYS_IPC_ANSWER_SLOW, callid, (sysarg_t) &data);
    444423}
    445424
    446 /** Try to dispatch queued calls from the async queue.
    447  *
    448  */
    449 static void dispatch_queued_calls(void)
    450 {
     425
     426/** Try to dispatch queued calls from the async queue. */
     427static void try_dispatch_queued_calls(void)
     428{
     429        async_call_t *call;
     430        ipc_callid_t callid;
     431
    451432        /** @todo
    452          * Integrate intelligently ipc_futex so that it is locked during
    453          * ipc_call_async_*() until it is added to dispatched_calls.
     433         * Integrate intelligently ipc_futex, so that it is locked during
     434         * ipc_call_async_*(), until it is added to dispatched_calls.
    454435         */
    455        
    456436        futex_down(&async_futex);
    457        
    458437        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)
     438                call = list_get_instance(queued_calls.next, async_call_t, list);
     439                callid = _ipc_call_async(call->u.msg.phoneid,
     440                    &call->u.msg.data);
     441                if (callid == (ipc_callid_t) IPC_CALLRET_TEMPORARY) {
    465442                        break;
    466                
     443                }
    467444                list_remove(&call->list);
    468                
     445
    469446                futex_up(&async_futex);
    470                
    471447                if (call->fid)
    472448                        fibril_add_ready(call->fid);
     
    475451                        if (call->callback)
    476452                                call->callback(call->private, ENOENT, NULL);
    477                        
    478453                        free(call);
    479454                } else {
    480455                        call->u.callid = callid;
    481                        
    482456                        futex_down(&ipc_futex);
    483457                        list_append(&call->list, &dispatched_calls);
    484458                        futex_up(&ipc_futex);
    485459                }
    486                
    487460                futex_down(&async_futex);
    488461        }
    489        
    490462        futex_up(&async_futex);
    491463}
    492464
    493 /** Handle received answer.
     465/** Handle a received answer.
    494466 *
    495467 * Find the hash of the answer and call the answer callback.
    496468 *
    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  *
     469 * @todo Make it use hash table.
     470 *
     471 * @param callid        Hash of the received answer.
     472 *                      The answer has the same hash as the request OR'ed with
     473 *                      the IPC_CALLID_ANSWERED bit.
     474 * @param data          Call data of the answer.
    505475 */
    506476static void handle_answer(ipc_callid_t callid, ipc_call_t *data)
    507477{
     478        link_t *item;
     479        async_call_t *call;
     480
    508481        callid &= ~IPC_CALLID_ANSWERED;
    509482       
    510483        futex_down(&ipc_futex);
    511        
    512         link_t *item;
    513484        for (item = dispatched_calls.next; item != &dispatched_calls;
    514485            item = item->next) {
    515                 async_call_t *call =
    516                     list_get_instance(item, async_call_t, list);
    517                
     486                call = list_get_instance(item, async_call_t, list);
    518487                if (call->u.callid == callid) {
    519488                        list_remove(&call->list);
    520                        
    521489                        futex_up(&ipc_futex);
    522                        
    523490                        if (call->callback)
    524                                 call->callback(call->private,
     491                                call->callback(call->private, 
    525492                                    IPC_GET_RETVAL(*data), data);
    526                        
    527493                        free(call);
    528494                        return;
    529495                }
    530496        }
    531        
    532497        futex_up(&ipc_futex);
    533498}
    534499
    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        
     500
     501/** Wait for a first call to come.
     502 *
     503 * @param call          Storage where the incoming call data will be stored.
     504 * @param usec          Timeout in microseconds
     505 * @param flags         Flags passed to SYS_IPC_WAIT (blocking, nonblocking).
     506 *
     507 * @return              Hash of the call. Note that certain bits have special
     508 *                      meaning. IPC_CALLID_ANSWERED will be set in an answer
     509 *                      and IPC_CALLID_NOTIFICATION is used for notifications.
     510 *                     
     511 */
     512ipc_callid_t ipc_wait_cycle(ipc_call_t *call, uint32_t usec, int flags)
     513{
     514        ipc_callid_t callid;
     515
     516        callid = __SYSCALL3(SYS_IPC_WAIT, (sysarg_t) call, usec, flags);
    552517        /* Handle received answers */
    553518        if (callid & IPC_CALLID_ANSWERED) {
    554519                handle_answer(callid, call);
    555                 dispatch_queued_calls();
     520                try_dispatch_queued_calls();
    556521        }
    557        
     522
    558523        return callid;
    559524}
    560525
    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)
     526/** Wait some time for an IPC call.
     527 *
     528 * The call will return after an answer is received.
     529 *
     530 * @param call          Storage where the incoming call data will be stored.
     531 * @param usec          Timeout in microseconds.
     532 *
     533 * @return              Hash of the answer.
     534 */
     535ipc_callid_t ipc_wait_for_call_timeout(ipc_call_t *call, uint32_t usec)
    580536{
    581537        ipc_callid_t callid;
    582        
     538
    583539        do {
    584540                callid = ipc_wait_cycle(call, usec, SYNCH_FLAGS_NONE);
    585541        } while (callid & IPC_CALLID_ANSWERED);
    586        
     542
    587543        return callid;
    588544}
     
    590546/** Check if there is an IPC call waiting to be picked up.
    591547 *
    592  * Only requests are returned, answers are processed internally.
    593  *
    594  * @param call Incoming call storage.
    595  *
    596  * @return Hash of the call.
    597  *
     548 * @param call          Storage where the incoming call will be stored.
     549 * @return              Hash of the answer.
    598550 */
    599551ipc_callid_t ipc_trywait_for_call(ipc_call_t *call)
    600552{
    601553        ipc_callid_t callid;
    602        
     554
    603555        do {
    604556                callid = ipc_wait_cycle(call, SYNCH_NO_TIMEOUT,
    605557                    SYNCH_FLAGS_NON_BLOCKING);
    606558        } while (callid & IPC_CALLID_ANSWERED);
    607        
     559
    608560        return callid;
    609561}
    610562
    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,
     563/** Interrupt one thread of this task from waiting for IPC. */
     564void ipc_poke(void)
     565{
     566        __SYSCALL0(SYS_IPC_POKE);
     567}
     568
     569/** Ask destination to do a callback connection.
     570 *
     571 * @param phoneid       Phone handle used for contacting the other side.
     572 * @param arg1          Service-defined argument.
     573 * @param arg2          Service-defined argument.
     574 * @param arg3          Service-defined argument.
     575 * @param taskhash      Storage where the kernel will store an opaque
     576 *                      identifier of the client task.
     577 * @param phonehash     Storage where the kernel will store an opaque
     578 *                      identifier of the phone that will be used for incoming
     579 *                      calls. This identifier can be used for connection
     580 *                      tracking.
     581 *
     582 * @return              Zero on success or a negative error code.
     583 */
     584int ipc_connect_to_me(int phoneid, int arg1, int arg2, int arg3,
    628585    sysarg_t *taskhash, sysarg_t *phonehash)
    629586{
     
    632589}
    633590
    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)
     591/** Ask through phone for a new connection to some service.
     592 *
     593 * @param phoneid       Phone handle used for contacting the other side.
     594 * @param arg1          User defined argument.
     595 * @param arg2          User defined argument.
     596 * @param arg3          User defined argument.
     597 *
     598 * @return              New phone handle on success or a negative error code.
     599 */
     600int ipc_connect_me_to(int phoneid, int arg1, int arg2, int arg3)
    645601{
    646602        sysarg_t newphid;
    647         int res = ipc_call_sync_3_5(phoneid, IPC_M_CONNECT_ME_TO, arg1, arg2, arg3,
     603        int res;
     604
     605        res = ipc_call_sync_3_5(phoneid, IPC_M_CONNECT_ME_TO, arg1, arg2, arg3,
    648606            NULL, NULL, NULL, NULL, &newphid);
    649607        if (res)
    650608                return res;
    651        
    652609        return newphid;
    653610}
    654611
    655 /** Request new connection (blocking)
     612/** Ask through phone for a new connection to some service.
    656613 *
    657614 * 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)
     615 * call will block.
     616 *
     617 * @param phoneid       Phone handle used for contacting the other side.
     618 * @param arg1          User defined argument.
     619 * @param arg2          User defined argument.
     620 * @param arg3          User defined argument.
     621 *
     622 * @return              New phone handle on success or a negative error code.
     623 */
     624int ipc_connect_me_to_blocking(int phoneid, int arg1, int arg2, int arg3)
    671625{
    672626        sysarg_t newphid;
    673         int res = ipc_call_sync_4_5(phoneid, IPC_M_CONNECT_ME_TO, arg1, arg2, arg3,
     627        int res;
     628
     629        res = ipc_call_sync_4_5(phoneid, IPC_M_CONNECT_ME_TO, arg1, arg2, arg3,
    674630            IPC_FLAG_BLOCKING, NULL, NULL, NULL, NULL, &newphid);
    675631        if (res)
    676632                return res;
    677        
    678633        return newphid;
    679634}
     
    681636/** Hang up a phone.
    682637 *
    683  * @param phoneid Handle of the phone to be hung up.
    684  *
    685  * @return Zero on success or a negative error code.
    686  *
     638 * @param phoneid       Handle of the phone to be hung up.
     639 *
     640 * @return              Zero on success or a negative error code.
    687641 */
    688642int ipc_hangup(int phoneid)
     
    692646
    693647/** Forward a received call to another destination.
    694  *
    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.
    699648 *
    700649 * @param callid  Hash of the call to forward.
     
    707656 * @return Zero on success or an error code.
    708657 *
    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)
     658 * For non-system methods, the old method, arg1 and arg2 are rewritten by the
     659 * new values. For system methods, the new method, arg1 and arg2 are written
     660 * to the old arg1, arg2 and arg3, respectivelly. Calls with immutable
     661 * methods are forwarded verbatim.
     662 */
     663int ipc_forward_fast(ipc_callid_t callid, int phoneid, int imethod,
     664    sysarg_t arg1, sysarg_t arg2, int mode)
    712665{
    713666        return __SYSCALL6(SYS_IPC_FORWARD_FAST, callid, phoneid, imethod, arg1,
     
    715668}
    716669
    717 int ipc_forward_slow(ipc_callid_t callid, int phoneid, sysarg_t imethod,
     670
     671int ipc_forward_slow(ipc_callid_t callid, int phoneid, int imethod,
    718672    sysarg_t arg1, sysarg_t arg2, sysarg_t arg3, sysarg_t arg4, sysarg_t arg5,
    719     unsigned int mode)
     673    int mode)
    720674{
    721675        ipc_call_t data;
     
    728682        IPC_SET_ARG5(data, arg5);
    729683       
    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  *
     684        return __SYSCALL4(SYS_IPC_FORWARD_SLOW, callid, phoneid, (sysarg_t) &data, mode);
     685}
     686
     687/** Wrapper for making IPC_M_SHARE_IN calls.
     688 *
     689 * @param phoneid       Phone that will be used to contact the receiving side.
     690 * @param dst           Destination address space area base.
     691 * @param size          Size of the destination address space area.
     692 * @param arg           User defined argument.
     693 * @param flags         Storage where the received flags will be stored. Can be
     694 *                      NULL.
     695 *
     696 * @return              Zero on success or a negative error code from errno.h.
    744697 */
    745698int ipc_share_in_start(int phoneid, void *dst, size_t size, sysarg_t arg,
    746     unsigned int *flags)
     699    int *flags)
    747700{
    748701        sysarg_t tmp_flags = 0;
     
    751704       
    752705        if (flags)
    753                 *flags = (unsigned int) tmp_flags;
     706                *flags = tmp_flags;
    754707       
    755708        return res;
     
    758711/** Wrapper for answering the IPC_M_SHARE_IN calls.
    759712 *
    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)
     713 * This wrapper only makes it more comfortable to answer IPC_M_DATA_READ calls
     714 * so that the user doesn't have to remember the meaning of each IPC argument.
     715 *
     716 * @param callid        Hash of the IPC_M_DATA_READ call to answer.
     717 * @param src           Source address space base.
     718 * @param flags         Flags to be used for sharing. Bits can be only cleared.
     719 *
     720 * @return              Zero on success or a value from @ref errno.h on failure.
     721 */
     722int ipc_share_in_finalize(ipc_callid_t callid, void *src, int flags)
    772723{
    773724        return ipc_answer_2(callid, EOK, (sysarg_t) src, (sysarg_t) flags);
    774725}
    775726
    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)
     727/** Wrapper for making IPC_M_SHARE_OUT calls.
     728 *
     729 * @param phoneid       Phone that will be used to contact the receiving side.
     730 * @param src           Source address space area base address.
     731 * @param flags         Flags to be used for sharing. Bits can be only cleared.
     732 *
     733 * @return              Zero on success or a negative error code from errno.h.
     734 */
     735int ipc_share_out_start(int phoneid, void *src, int flags)
    786736{
    787737        return ipc_call_sync_3_0(phoneid, IPC_M_SHARE_OUT, (sysarg_t) src, 0,
     
    791741/** Wrapper for answering the IPC_M_SHARE_OUT calls.
    792742 *
    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  *
     743 * This wrapper only makes it more comfortable to answer IPC_M_SHARE_OUT calls
     744 * so that the user doesn't have to remember the meaning of each IPC argument.
     745 *
     746 * @param callid        Hash of the IPC_M_DATA_WRITE call to answer.
     747 * @param dst           Destination address space area base address.   
     748 *
     749 * @return              Zero on success or a value from @ref errno.h on failure.
    802750 */
    803751int ipc_share_out_finalize(ipc_callid_t callid, void *dst)
     
    806754}
    807755
    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  *
     756
     757/** Wrapper for making IPC_M_DATA_READ calls.
     758 *
     759 * @param phoneid       Phone that will be used to contact the receiving side.
     760 * @param dst           Address of the beginning of the destination buffer.
     761 * @param size          Size of the destination buffer.
     762 *
     763 * @return              Zero on success or a negative error code from errno.h.
    816764 */
    817765int ipc_data_read_start(int phoneid, void *dst, size_t size)
     
    823771/** Wrapper for answering the IPC_M_DATA_READ calls.
    824772 *
    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  *
     773 * This wrapper only makes it more comfortable to answer IPC_M_DATA_READ calls
     774 * so that the user doesn't have to remember the meaning of each IPC argument.
     775 *
     776 * @param callid        Hash of the IPC_M_DATA_READ call to answer.
     777 * @param src           Source address for the IPC_M_DATA_READ call.
     778 * @param size          Size for the IPC_M_DATA_READ call. Can be smaller than
     779 *                      the maximum size announced by the sender.
     780 *
     781 * @return              Zero on success or a value from @ref errno.h on failure.
    836782 */
    837783int ipc_data_read_finalize(ipc_callid_t callid, const void *src, size_t size)
     
    840786}
    841787
    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  *
     788/** Wrapper for making IPC_M_DATA_WRITE calls.
     789 *
     790 * @param phoneid       Phone that will be used to contact the receiving side.
     791 * @param src           Address of the beginning of the source buffer.
     792 * @param size          Size of the source buffer.
     793 *
     794 * @return              Zero on success or a negative error code from errno.h.
    850795 */
    851796int ipc_data_write_start(int phoneid, const void *src, size_t size)
     
    857802/** Wrapper for answering the IPC_M_DATA_WRITE calls.
    858803 *
    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  *
     804 * This wrapper only makes it more comfortable to answer IPC_M_DATA_WRITE calls
     805 * so that the user doesn't have to remember the meaning of each IPC argument.
     806 *
     807 * @param callid        Hash of the IPC_M_DATA_WRITE call to answer.
     808 * @param dst           Final destination address for the IPC_M_DATA_WRITE call.
     809 * @param size          Final size for the IPC_M_DATA_WRITE call.
     810 *
     811 * @return              Zero on success or a value from @ref errno.h on failure.
    869812 */
    870813int ipc_data_write_finalize(ipc_callid_t callid, void *dst, size_t size)
Note: See TracChangeset for help on using the changeset viewer.