Ignore:
File:
1 edited

Legend:

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

    rd7978525 rfbcdeb8  
    4848#include <fibril.h>
    4949#include <macros.h>
     50#include "private/libc.h"
    5051
    5152/**
     
    8283
    8384static atomic_t ipc_futex = FUTEX_INITIALIZER;
     85
     86/** Fast synchronous call.
     87 *
     88 * Only three payload arguments can be passed using this function. However,
     89 * this function is faster than the generic ipc_call_sync_slow() because
     90 * the payload is passed directly in registers.
     91 *
     92 * @param phoneid Phone handle for the call.
     93 * @param method  Requested method.
     94 * @param arg1    Service-defined payload argument.
     95 * @param arg2    Service-defined payload argument.
     96 * @param arg3    Service-defined payload argument.
     97 * @param result1 If non-NULL, the return ARG1 will be stored there.
     98 * @param result2 If non-NULL, the return ARG2 will be stored there.
     99 * @param result3 If non-NULL, the return ARG3 will be stored there.
     100 * @param result4 If non-NULL, the return ARG4 will be stored there.
     101 * @param result5 If non-NULL, the return ARG5 will be stored there.
     102 *
     103 * @return Negative values representing IPC errors.
     104 * @return Otherwise the RETVAL of the answer.
     105 *
     106 */
     107int ipc_call_sync_fast(int phoneid, sysarg_t method, sysarg_t arg1,
     108    sysarg_t arg2, sysarg_t arg3, sysarg_t *result1, sysarg_t *result2,
     109    sysarg_t *result3, sysarg_t *result4, sysarg_t *result5)
     110{
     111        ipc_call_t resdata;
     112        int callres = __SYSCALL6(SYS_IPC_CALL_SYNC_FAST, phoneid, method, arg1,
     113            arg2, arg3, (sysarg_t) &resdata);
     114        if (callres)
     115                return callres;
     116       
     117        if (result1)
     118                *result1 = IPC_GET_ARG1(resdata);
     119        if (result2)
     120                *result2 = IPC_GET_ARG2(resdata);
     121        if (result3)
     122                *result3 = IPC_GET_ARG3(resdata);
     123        if (result4)
     124                *result4 = IPC_GET_ARG4(resdata);
     125        if (result5)
     126                *result5 = IPC_GET_ARG5(resdata);
     127       
     128        return IPC_GET_RETVAL(resdata);
     129}
     130
     131/** Synchronous call transmitting 5 arguments of payload.
     132 *
     133 * @param phoneid Phone handle for the call.
     134 * @param imethod Requested interface and 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 values representing IPC errors.
     147 * @return Otherwise the RETVAL of the answer.
     148 *
     149 */
     150int ipc_call_sync_slow(int phoneid, sysarg_t imethod, sysarg_t arg1,
     151    sysarg_t arg2, sysarg_t arg3, sysarg_t arg4, sysarg_t arg5,
     152    sysarg_t *result1, sysarg_t *result2, sysarg_t *result3, sysarg_t *result4,
     153    sysarg_t *result5)
     154{
     155        ipc_call_t data;
     156       
     157        IPC_SET_IMETHOD(data, imethod);
     158        IPC_SET_ARG1(data, arg1);
     159        IPC_SET_ARG2(data, arg2);
     160        IPC_SET_ARG3(data, arg3);
     161        IPC_SET_ARG4(data, arg4);
     162        IPC_SET_ARG5(data, arg5);
     163       
     164        int callres = __SYSCALL3(SYS_IPC_CALL_SYNC_SLOW, phoneid,
     165            (sysarg_t) &data, (sysarg_t) &data);
     166        if (callres)
     167                return callres;
     168       
     169        if (result1)
     170                *result1 = IPC_GET_ARG1(data);
     171        if (result2)
     172                *result2 = IPC_GET_ARG2(data);
     173        if (result3)
     174                *result3 = IPC_GET_ARG3(data);
     175        if (result4)
     176                *result4 = IPC_GET_ARG4(data);
     177        if (result5)
     178                *result5 = IPC_GET_ARG5(data);
     179       
     180        return IPC_GET_RETVAL(data);
     181}
    84182
    85183/** Send asynchronous message via syscall.
     
    513611}
    514612
     613/** Request callback connection.
     614 *
     615 * The @a task_id and @a phonehash identifiers returned
     616 * by the kernel can be used for connection tracking.
     617 *
     618 * @param phoneid   Phone handle used for contacting the other side.
     619 * @param arg1      User defined argument.
     620 * @param arg2      User defined argument.
     621 * @param arg3      User defined argument.
     622 * @param task_id   Identifier of the client task.
     623 * @param phonehash Opaque identifier of the phone that will
     624 *                  be used for incoming calls.
     625 *
     626 * @return Zero on success or a negative error code.
     627 *
     628 */
     629int ipc_connect_to_me(int phoneid, sysarg_t arg1, sysarg_t arg2, sysarg_t arg3,
     630    task_id_t *task_id, sysarg_t *phonehash)
     631{
     632        ipc_call_t data;
     633        int rc = __SYSCALL6(SYS_IPC_CALL_SYNC_FAST, phoneid,
     634            IPC_M_CONNECT_TO_ME, arg1, arg2, arg3, (sysarg_t) &data);
     635        if (rc == EOK) {
     636                *task_id = data.in_task_id;
     637                *phonehash = IPC_GET_ARG5(data);
     638        }       
     639        return rc;
     640}
     641
     642/** Request cloned connection.
     643 *
     644 * @param phoneid Phone handle used for contacting the other side.
     645 *
     646 * @return Cloned phone handle on success or a negative error code.
     647 *
     648 */
     649int ipc_connect_me(int phoneid)
     650{
     651        sysarg_t newphid;
     652        int res = ipc_call_sync_0_5(phoneid, IPC_M_CONNECT_ME, NULL, NULL,
     653            NULL, NULL, &newphid);
     654        if (res)
     655                return res;
     656       
     657        return newphid;
     658}
     659
     660/** Request new connection.
     661 *
     662 * @param phoneid Phone handle used for contacting the other side.
     663 * @param arg1    User defined argument.
     664 * @param arg2    User defined argument.
     665 * @param arg3    User defined argument.
     666 *
     667 * @return New phone handle on success or a negative error code.
     668 *
     669 */
     670int ipc_connect_me_to(int phoneid, sysarg_t arg1, sysarg_t arg2, sysarg_t arg3)
     671{
     672        sysarg_t newphid;
     673        int res = ipc_call_sync_3_5(phoneid, IPC_M_CONNECT_ME_TO, arg1, arg2, arg3,
     674            NULL, NULL, NULL, NULL, &newphid);
     675        if (res)
     676                return res;
     677       
     678        return newphid;
     679}
     680
     681/** Request new connection (blocking)
     682 *
     683 * If the connection is not available at the moment, the
     684 * call should block. This has to be, however, implemented
     685 * on the server side.
     686 *
     687 * @param phoneid Phone handle used for contacting the other side.
     688 * @param arg1    User defined argument.
     689 * @param arg2    User defined argument.
     690 * @param arg3    User defined argument.
     691 *
     692 * @return New phone handle on success or a negative error code.
     693 *
     694 */
     695int ipc_connect_me_to_blocking(int phoneid, sysarg_t arg1, sysarg_t arg2,
     696    sysarg_t arg3)
     697{
     698        sysarg_t newphid;
     699        int res = ipc_call_sync_4_5(phoneid, IPC_M_CONNECT_ME_TO, arg1, arg2, arg3,
     700            IPC_FLAG_BLOCKING, NULL, NULL, NULL, NULL, &newphid);
     701        if (res)
     702                return res;
     703       
     704        return newphid;
     705}
     706
    515707/** Hang up a phone.
    516708 *
     
    566758}
    567759
     760/** Wrapper for IPC_M_SHARE_IN calls.
     761 *
     762 * @param phoneid Phone that will be used to contact the receiving side.
     763 * @param size    Size of the destination address space area.
     764 * @param arg     User defined argument.
     765 * @param flags   Storage for received flags. Can be NULL.
     766 * @param dst     Destination address space area base. Cannot be NULL.
     767 *
     768 * @return Zero on success or a negative error code from errno.h.
     769 *
     770 */
     771int ipc_share_in_start(int phoneid, size_t size, sysarg_t arg,
     772    unsigned int *flags, void **dst)
     773{
     774        sysarg_t _flags = 0;
     775        sysarg_t _dst = (sysarg_t) -1;
     776        int res = ipc_call_sync_2_4(phoneid, IPC_M_SHARE_IN, (sysarg_t) size,
     777            arg, NULL, &_flags, NULL, &_dst);
     778       
     779        if (flags)
     780                *flags = (unsigned int) _flags;
     781       
     782        *dst = (void *) _dst;
     783        return res;
     784}
     785
     786/** Wrapper for answering the IPC_M_SHARE_IN calls.
     787 *
     788 * This wrapper only makes it more comfortable to answer IPC_M_SHARE_IN
     789 * calls so that the user doesn't have to remember the meaning of each
     790 * IPC argument.
     791 *
     792 * @param callid Hash of the IPC_M_DATA_READ call to answer.
     793 * @param src    Source address space base.
     794 * @param flags Flags to be used for sharing. Bits can be only cleared.
     795 *
     796 * @return Zero on success or a value from @ref errno.h on failure.
     797 *
     798 */
     799int ipc_share_in_finalize(ipc_callid_t callid, void *src, unsigned int flags)
     800{
     801        return ipc_answer_3(callid, EOK, (sysarg_t) src, (sysarg_t) flags,
     802            (sysarg_t) __entry);
     803}
     804
     805/** Wrapper for IPC_M_SHARE_OUT calls.
     806 *
     807 * @param phoneid Phone that will be used to contact the receiving side.
     808 * @param src     Source address space area base address.
     809 * @param flags   Flags to be used for sharing. Bits can be only cleared.
     810 *
     811 * @return Zero on success or a negative error code from errno.h.
     812 *
     813 */
     814int ipc_share_out_start(int phoneid, void *src, unsigned int flags)
     815{
     816        return ipc_call_sync_3_0(phoneid, IPC_M_SHARE_OUT, (sysarg_t) src, 0,
     817            (sysarg_t) flags);
     818}
     819
     820/** Wrapper for answering the IPC_M_SHARE_OUT calls.
     821 *
     822 * This wrapper only makes it more comfortable to answer IPC_M_SHARE_OUT
     823 * calls so that the user doesn't have to remember the meaning of each
     824 * IPC argument.
     825 *
     826 * @param callid Hash of the IPC_M_DATA_WRITE call to answer.
     827 * @param dst    Destination address space area base address.
     828 *
     829 * @return Zero on success or a value from @ref errno.h on failure.
     830 *
     831 */
     832int ipc_share_out_finalize(ipc_callid_t callid, void **dst)
     833{
     834        return ipc_answer_2(callid, EOK, (sysarg_t) __entry, (sysarg_t) dst);
     835}
     836
     837/** Wrapper for IPC_M_DATA_READ calls.
     838 *
     839 * @param phoneid Phone that will be used to contact the receiving side.
     840 * @param dst     Address of the beginning of the destination buffer.
     841 * @param size    Size of the destination buffer.
     842 *
     843 * @return Zero on success or a negative error code from errno.h.
     844 *
     845 */
     846int ipc_data_read_start(int phoneid, void *dst, size_t size)
     847{
     848        return ipc_call_sync_2_0(phoneid, IPC_M_DATA_READ, (sysarg_t) dst,
     849            (sysarg_t) size);
     850}
     851
     852/** Wrapper for answering the IPC_M_DATA_READ calls.
     853 *
     854 * This wrapper only makes it more comfortable to answer IPC_M_DATA_READ
     855 * calls so that the user doesn't have to remember the meaning of each
     856 * IPC argument.
     857 *
     858 * @param callid Hash of the IPC_M_DATA_READ call to answer.
     859 * @param src    Source address for the IPC_M_DATA_READ call.
     860 * @param size   Size for the IPC_M_DATA_READ call. Can be smaller than
     861 *               the maximum size announced by the sender.
     862 *
     863 * @return Zero on success or a value from @ref errno.h on failure.
     864 *
     865 */
     866int ipc_data_read_finalize(ipc_callid_t callid, const void *src, size_t size)
     867{
     868        return ipc_answer_2(callid, EOK, (sysarg_t) src, (sysarg_t) size);
     869}
     870
     871/** Wrapper for IPC_M_DATA_WRITE calls.
     872 *
     873 * @param phoneid Phone that will be used to contact the receiving side.
     874 * @param src     Address of the beginning of the source buffer.
     875 * @param size    Size of the source buffer.
     876 *
     877 * @return Zero on success or a negative error code from errno.h.
     878 *
     879 */
     880int ipc_data_write_start(int phoneid, const void *src, size_t size)
     881{
     882        return ipc_call_sync_2_0(phoneid, IPC_M_DATA_WRITE, (sysarg_t) src,
     883            (sysarg_t) size);
     884}
     885
     886/** Wrapper for answering the IPC_M_DATA_WRITE calls.
     887 *
     888 * This wrapper only makes it more comfortable to answer IPC_M_DATA_WRITE
     889 * calls so that the user doesn't have to remember the meaning of each
     890 * IPC argument.
     891 *
     892 * @param callid Hash of the IPC_M_DATA_WRITE call to answer.
     893 * @param dst    Final destination address for the IPC_M_DATA_WRITE call.
     894 * @param size   Final size for the IPC_M_DATA_WRITE call.
     895 *
     896 * @return Zero on success or a value from @ref errno.h on failure.
     897 *
     898 */
     899int ipc_data_write_finalize(ipc_callid_t callid, void *dst, size_t size)
     900{
     901        return ipc_answer_2(callid, EOK, (sysarg_t) dst, (sysarg_t) size);
     902}
     903
    568904/** Connect to a task specified by id.
    569905 *
Note: See TracChangeset for help on using the changeset viewer.