Changeset affaf2e in mainline for uspace/lib


Ignore:
Timestamp:
2012-08-15T15:13:20Z (13 years ago)
Author:
Martin Sucha <sucha14@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
b546231
Parents:
f66ca57f (diff), 135486d (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge mainline changes.

Location:
uspace/lib
Files:
31 added
7 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/block/libblock.c

    rf66ca57f raffaf2e  
    4040#include "../../srv/vfs/vfs.h"
    4141#include <ipc/loc.h>
    42 #include <ipc/bd.h>
    4342#include <ipc/services.h>
    4443#include <errno.h>
     
    4746#include <as.h>
    4847#include <assert.h>
     48#include <bd.h>
    4949#include <fibril_synch.h>
    5050#include <adt/list.h>
     
    8080        service_id_t service_id;
    8181        async_sess_t *sess;
    82         fibril_mutex_t comm_area_lock;
    83         void *comm_area;
    84         size_t comm_size;
     82        bd_t *bd;
    8583        void *bb_buf;
    8684        aoff64_t bb_addr;
     
    8987} devcon_t;
    9088
    91 static int read_blocks(devcon_t *, aoff64_t, size_t);
    92 static int write_blocks(devcon_t *, aoff64_t, size_t);
    93 static int get_block_size(async_sess_t *, size_t *);
    94 static int get_num_blocks(async_sess_t *, aoff64_t *);
     89static int read_blocks(devcon_t *, aoff64_t, size_t, void *, size_t);
     90static int write_blocks(devcon_t *, aoff64_t, size_t, void *, size_t);
    9591static aoff64_t ba_ltop(devcon_t *, aoff64_t);
    9692
     
    112108
    113109static int devcon_add(service_id_t service_id, async_sess_t *sess,
    114     size_t bsize, void *comm_area, size_t comm_size)
     110    size_t bsize, bd_t *bd)
    115111{
    116112        devcon_t *devcon;
    117        
    118         if (comm_size < bsize)
    119                 return EINVAL;
    120113       
    121114        devcon = malloc(sizeof(devcon_t));
     
    126119        devcon->service_id = service_id;
    127120        devcon->sess = sess;
    128         fibril_mutex_initialize(&devcon->comm_area_lock);
    129         devcon->comm_area = comm_area;
    130         devcon->comm_size = comm_size;
     121        devcon->bd = bd;
    131122        devcon->bb_buf = NULL;
    132123        devcon->bb_addr = 0;
     
    158149    size_t comm_size)
    159150{
    160         void *comm_area = mmap(NULL, comm_size, PROTO_READ | PROTO_WRITE,
    161             MAP_ANONYMOUS | MAP_PRIVATE, 0, 0);
    162         if (!comm_area)
    163                 return ENOMEM;
    164        
     151        bd_t *bd;
     152
    165153        async_sess_t *sess = loc_service_connect(mgmt, service_id,
    166154            IPC_FLAG_BLOCKING);
    167155        if (!sess) {
    168                 munmap(comm_area, comm_size);
    169156                return ENOENT;
    170157        }
    171158       
    172         async_exch_t *exch = async_exchange_begin(sess);
    173         int rc = async_share_out_start(exch, comm_area,
    174             AS_AREA_READ | AS_AREA_WRITE);
    175         async_exchange_end(exch);
    176        
     159        int rc = bd_open(sess, &bd);
    177160        if (rc != EOK) {
    178                 munmap(comm_area, comm_size);
    179161                async_hangup(sess);
    180162                return rc;
     
    182164       
    183165        size_t bsize;
    184         rc = get_block_size(sess, &bsize);
    185        
     166        rc = bd_get_block_size(bd, &bsize);
    186167        if (rc != EOK) {
    187                 munmap(comm_area, comm_size);
     168                bd_close(bd);
    188169                async_hangup(sess);
    189170                return rc;
    190171        }
    191172       
    192         rc = devcon_add(service_id, sess, bsize, comm_area, comm_size);
     173        rc = devcon_add(service_id, sess, bsize, bd);
    193174        if (rc != EOK) {
    194                 munmap(comm_area, comm_size);
     175                bd_close(bd);
    195176                async_hangup(sess);
    196177                return rc;
     
    213194                free(devcon->bb_buf);
    214195       
    215         munmap(devcon->comm_area, devcon->comm_size);
     196        bd_close(devcon->bd);
    216197        async_hangup(devcon->sess);
    217198       
     
    233214                return ENOMEM;
    234215
    235         fibril_mutex_lock(&devcon->comm_area_lock);
    236         rc = read_blocks(devcon, 0, 1);
     216        rc = read_blocks(devcon, 0, 1, bb_buf, devcon->pblock_size);
    237217        if (rc != EOK) {
    238                 fibril_mutex_unlock(&devcon->comm_area_lock);
    239218                free(bb_buf);
    240219                return rc;
    241220        }
    242         memcpy(bb_buf, devcon->comm_area, devcon->pblock_size);
    243         fibril_mutex_unlock(&devcon->comm_area_lock);
    244221
    245222        devcon->bb_buf = bb_buf;
     
    338315                list_remove(&b->free_link);
    339316                if (b->dirty) {
    340                         memcpy(devcon->comm_area, b->data, b->size);
    341                         rc = write_blocks(devcon, b->pba, cache->blocks_cluster);
     317                        rc = write_blocks(devcon, b->pba, cache->blocks_cluster,
     318                            b->data, b->size);
    342319                        if (rc != EOK)
    343320                                return rc;
     
    481458                                list_append(&b->free_link, &cache->free_list);
    482459                                fibril_mutex_unlock(&cache->lock);
    483                                 fibril_mutex_lock(&devcon->comm_area_lock);
    484                                 memcpy(devcon->comm_area, b->data, b->size);
    485460                                rc = write_blocks(devcon, b->pba,
    486                                     cache->blocks_cluster);
    487                                 fibril_mutex_unlock(&devcon->comm_area_lock);
     461                                    cache->blocks_cluster, b->data, b->size);
    488462                                if (rc != EOK) {
    489463                                        /*
     
    555529                         * the new contents from the device.
    556530                         */
    557                         fibril_mutex_lock(&devcon->comm_area_lock);
    558                         rc = read_blocks(devcon, b->pba, cache->blocks_cluster);
    559                         memcpy(b->data, devcon->comm_area, cache->lblock_size);
    560                         fibril_mutex_unlock(&devcon->comm_area_lock);
     531                        rc = read_blocks(devcon, b->pba, cache->blocks_cluster,
     532                            b->data, cache->lblock_size);
    561533                        if (rc != EOK)
    562534                                b->toxic = true;
     
    616588        if (block->dirty && (block->refcnt == 1) &&
    617589            (blocks_cached > CACHE_HI_WATERMARK || mode != CACHE_MODE_WB)) {
    618                 fibril_mutex_lock(&devcon->comm_area_lock);
    619                 memcpy(devcon->comm_area, block->data, block->size);
    620                 rc = write_blocks(devcon, block->pba, cache->blocks_cluster);
    621                 fibril_mutex_unlock(&devcon->comm_area_lock);
     590                rc = write_blocks(devcon, block->pba, cache->blocks_cluster,
     591                    block->data, block->size);
    622592                block->dirty = false;
    623593        }
     
    688658 *
    689659 * @param service_id    Service ID of the block device.
     660 * @param buf           Buffer for holding one block
    690661 * @param bufpos        Pointer to the first unread valid offset within the
    691662 *                      communication buffer.
     
    699670 * @return              EOK on success or a negative return code on failure.
    700671 */
    701 int block_seqread(service_id_t service_id, size_t *bufpos, size_t *buflen,
    702     aoff64_t *pos, void *dst, size_t size)
     672int block_seqread(service_id_t service_id, void *buf, size_t *bufpos,
     673    size_t *buflen, aoff64_t *pos, void *dst, size_t size)
    703674{
    704675        size_t offset = 0;
     
    711682        block_size = devcon->pblock_size;
    712683       
    713         fibril_mutex_lock(&devcon->comm_area_lock);
    714684        while (left > 0) {
    715685                size_t rd;
     
    725695                         * destination buffer.
    726696                         */
    727                         memcpy(dst + offset, devcon->comm_area + *bufpos, rd);
     697                        memcpy(dst + offset, buf + *bufpos, rd);
    728698                        offset += rd;
    729699                        *bufpos += rd;
     
    736706                        int rc;
    737707
    738                         rc = read_blocks(devcon, *pos / block_size, 1);
     708                        rc = read_blocks(devcon, *pos / block_size, 1, buf,
     709                            devcon->pblock_size);
    739710                        if (rc != EOK) {
    740                                 fibril_mutex_unlock(&devcon->comm_area_lock);
    741711                                return rc;
    742712                        }
     
    746716                }
    747717        }
    748         fibril_mutex_unlock(&devcon->comm_area_lock);
    749718       
    750719        return EOK;
     
    763732{
    764733        devcon_t *devcon;
    765         int rc;
    766734
    767735        devcon = devcon_search(service_id);
    768736        assert(devcon);
    769        
    770         fibril_mutex_lock(&devcon->comm_area_lock);
    771 
    772         rc = read_blocks(devcon, ba, cnt);
    773         if (rc == EOK)
    774                 memcpy(buf, devcon->comm_area, devcon->pblock_size * cnt);
    775 
    776         fibril_mutex_unlock(&devcon->comm_area_lock);
    777 
    778         return rc;
     737
     738        return read_blocks(devcon, ba, cnt, buf, devcon->pblock_size * cnt);
    779739}
    780740
     
    792752{
    793753        devcon_t *devcon;
    794         int rc;
    795754
    796755        devcon = devcon_search(service_id);
    797756        assert(devcon);
    798        
    799         fibril_mutex_lock(&devcon->comm_area_lock);
    800 
    801         memcpy(devcon->comm_area, data, devcon->pblock_size * cnt);
    802         rc = write_blocks(devcon, ba, cnt);
    803 
    804         fibril_mutex_unlock(&devcon->comm_area_lock);
    805 
    806         return rc;
     757
     758        return write_blocks(devcon, ba, cnt, (void *)data, devcon->pblock_size * cnt);
    807759}
    808760
     
    820772        devcon = devcon_search(service_id);
    821773        assert(devcon);
    822        
    823         return get_block_size(devcon->sess, bsize);
     774
     775        return bd_get_block_size(devcon->bd, bsize);
    824776}
    825777
     
    836788        assert(devcon);
    837789       
    838         return get_num_blocks(devcon->sess, nblocks);
     790        return bd_get_num_blocks(devcon->bd, nblocks);
    839791}
    840792
     
    887839        memcpy(data, buffer + offset, bytes);
    888840        free(buffer);
    889        
     841
    890842        return EOK;
    891843}
     
    903855{
    904856        devcon_t *devcon = devcon_search(service_id);
    905         assert(devcon);
    906        
    907857        toc_block_t *toc = NULL;
    908        
    909         fibril_mutex_lock(&devcon->comm_area_lock);
    910        
    911         async_exch_t *exch = async_exchange_begin(devcon->sess);
    912         int rc = async_req_1_0(exch, BD_READ_TOC, session);
    913         async_exchange_end(exch);
    914        
    915         if (rc == EOK) {
    916                 toc = (toc_block_t *) malloc(sizeof(toc_block_t));
    917                 if (toc != NULL) {
    918                         memset(toc, 0, sizeof(toc_block_t));
    919                         memcpy(toc, devcon->comm_area,
    920                             min(devcon->pblock_size, sizeof(toc_block_t)));
    921                 }
    922         }
    923        
    924        
    925         fibril_mutex_unlock(&devcon->comm_area_lock);
     858        int rc;
     859       
     860        assert(devcon);
     861       
     862        toc = (toc_block_t *) malloc(sizeof(toc_block_t));
     863        if (toc == NULL)
     864                return NULL;
     865       
     866        rc = bd_read_toc(devcon->bd, session, toc, sizeof(toc_block_t));
     867        if (rc != EOK) {
     868                free(toc);
     869                return NULL;
     870        }
    926871       
    927872        return toc;
     
    937882 * @return              EOK on success or negative error code on failure.
    938883 */
    939 static int read_blocks(devcon_t *devcon, aoff64_t ba, size_t cnt)
    940 {
    941         assert(devcon);
    942        
    943         async_exch_t *exch = async_exchange_begin(devcon->sess);
    944         int rc = async_req_3_0(exch, BD_READ_BLOCKS, LOWER32(ba),
    945             UPPER32(ba), cnt);
    946         async_exchange_end(exch);
    947        
     884static int read_blocks(devcon_t *devcon, aoff64_t ba, size_t cnt, void *buf,
     885    size_t size)
     886{
     887        assert(devcon);
     888       
     889        int rc = bd_read_blocks(devcon->bd, ba, cnt, buf, size);
    948890        if (rc != EOK) {
    949891                printf("Error %d reading %zu blocks starting at block %" PRIuOFF64
     
    967909 * @return              EOK on success or negative error code on failure.
    968910 */
    969 static int write_blocks(devcon_t *devcon, aoff64_t ba, size_t cnt)
    970 {
    971         assert(devcon);
    972        
    973         async_exch_t *exch = async_exchange_begin(devcon->sess);
    974         int rc = async_req_3_0(exch, BD_WRITE_BLOCKS, LOWER32(ba),
    975             UPPER32(ba), cnt);
    976         async_exchange_end(exch);
    977        
     911static int write_blocks(devcon_t *devcon, aoff64_t ba, size_t cnt, void *data,
     912    size_t size)
     913{
     914        assert(devcon);
     915       
     916        int rc = bd_write_blocks(devcon->bd, ba, cnt, data, size);
    978917        if (rc != EOK) {
    979918                printf("Error %d writing %zu blocks starting at block %" PRIuOFF64
     
    987926}
    988927
    989 /** Get block size used by the device. */
    990 static int get_block_size(async_sess_t *sess, size_t *bsize)
    991 {
    992         sysarg_t bs;
    993        
    994         async_exch_t *exch = async_exchange_begin(sess);
    995         int rc = async_req_0_1(exch, BD_GET_BLOCK_SIZE, &bs);
    996         async_exchange_end(exch);
    997        
    998         if (rc == EOK)
    999                 *bsize = (size_t) bs;
    1000        
    1001         return rc;
    1002 }
    1003 
    1004 /** Get total number of blocks on block device. */
    1005 static int get_num_blocks(async_sess_t *sess, aoff64_t *nblocks)
    1006 {
    1007         sysarg_t nb_l;
    1008         sysarg_t nb_h;
    1009        
    1010         async_exch_t *exch = async_exchange_begin(sess);
    1011         int rc = async_req_0_2(exch, BD_GET_NUM_BLOCKS, &nb_l, &nb_h);
    1012         async_exchange_end(exch);
    1013        
    1014         if (rc == EOK)
    1015                 *nblocks = (aoff64_t) MERGE_LOUP32(nb_l, nb_h);
    1016        
    1017         return rc;
    1018 }
    1019 
    1020928/** Convert logical block address to physical block address. */
    1021929static aoff64_t ba_ltop(devcon_t *devcon, aoff64_t lba)
  • uspace/lib/block/libblock.h

    rf66ca57f raffaf2e  
    122122extern int block_put(block_t *);
    123123
    124 extern int block_seqread(service_id_t, size_t *, size_t *, aoff64_t *, void *,
    125     size_t);
     124extern int block_seqread(service_id_t, void *, size_t *, size_t *, aoff64_t *,
     125    void *, size_t);
    126126
    127127extern int block_get_bsize(service_id_t, size_t *);
  • uspace/lib/c/Makefile

    rf66ca57f raffaf2e  
    6262        generic/ddi.c \
    6363        generic/as.c \
     64        generic/bd.c \
     65        generic/bd_srv.c \
    6466        generic/cap.c \
    6567        generic/cfg.c \
  • uspace/lib/c/generic/async.c

    rf66ca57f raffaf2e  
    114114#include <stdlib.h>
    115115#include <macros.h>
     116#include "private/libc.h"
    116117
    117118#define CLIENT_HASH_TABLE_BUCKETS  32
     
    21662167int async_share_in_finalize(ipc_callid_t callid, void *src, unsigned int flags)
    21672168{
    2168         return ipc_share_in_finalize(callid, src, flags);
     2169        return ipc_answer_3(callid, EOK, (sysarg_t) src, (sysarg_t) flags,
     2170            (sysarg_t) __entry);
    21692171}
    21702172
     
    22332235int async_share_out_finalize(ipc_callid_t callid, void **dst)
    22342236{
    2235         return ipc_share_out_finalize(callid, dst);
     2237        return ipc_answer_2(callid, EOK, (sysarg_t) __entry, (sysarg_t) dst);
    22362238}
    22372239
     
    23172319int async_data_read_finalize(ipc_callid_t callid, const void *src, size_t size)
    23182320{
    2319         return ipc_data_read_finalize(callid, src, size);
     2321        return ipc_answer_2(callid, EOK, (sysarg_t) src, (sysarg_t) size);
    23202322}
    23212323
     
    24202422int async_data_write_finalize(ipc_callid_t callid, void *dst, size_t size)
    24212423{
    2422         return ipc_data_write_finalize(callid, dst, size);
     2424        return ipc_answer_2(callid, EOK, (sysarg_t) dst, (sysarg_t) size);
    24232425}
    24242426
  • uspace/lib/c/generic/ipc.c

    rf66ca57f raffaf2e  
    4848#include <fibril.h>
    4949#include <macros.h>
    50 #include "private/libc.h"
    5150
    5251/**
     
    8382
    8483static 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  */
    107 int 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  */
    150 int 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 }
    18284
    18385/** Send asynchronous message via syscall.
     
    611513}
    612514
    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  */
    629 int 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  */
    649 int ipc_clone_establish(int phoneid)
    650 {
    651         sysarg_t newphid;
    652         int res = ipc_call_sync_0_5(phoneid, IPC_M_CLONE_ESTABLISH, NULL,
    653             NULL, 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  */
    670 int 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  */
    695 int 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 
    707515/** Hang up a phone.
    708516 *
     
    758566}
    759567
    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  */
    771 int 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  */
    799 int 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  */
    814 int 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  */
    832 int 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  */
    846 int 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  */
    866 int 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  */
    880 int 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  */
    899 int 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 
    904568/** Connect to a task specified by id.
    905569 *
  • uspace/lib/c/generic/iplink_srv.c

    rf66ca57f raffaf2e  
    139139                if (!method) {
    140140                        /* The other side has hung up */
     141                        fibril_mutex_lock(&srv->lock);
     142                        srv->connected = false;
     143                        fibril_mutex_unlock(&srv->lock);
    141144                        async_answer_0(callid, EOK);
    142145                        break;
  • uspace/lib/c/include/ipc/ipc.h

    rf66ca57f raffaf2e  
    4747
    4848typedef void (*ipc_async_callback_t)(void *, int, ipc_call_t *);
    49 
    50 /*
    51  * User-friendly wrappers for ipc_call_sync_fast() and ipc_call_sync_slow().
    52  * They are in the form ipc_call_sync_m_n(), where m denotes the number of
    53  * arguments of payload and n denotes number of return values. Whenever
    54  * possible, the fast version is used.
    55  */
    56 
    57 #define ipc_call_sync_0_0(phoneid, method) \
    58         ipc_call_sync_fast((phoneid), (method), 0, 0, 0, 0, 0, 0, 0, 0)
    59 #define ipc_call_sync_0_1(phoneid, method, res1) \
    60         ipc_call_sync_fast((phoneid), (method), 0, 0, 0, (res1), 0, 0, 0, 0)
    61 #define ipc_call_sync_0_2(phoneid, method, res1, res2) \
    62         ipc_call_sync_fast((phoneid), (method), 0, 0, 0, (res1), (res2), 0, 0, 0)
    63 #define ipc_call_sync_0_3(phoneid, method, res1, res2, res3) \
    64         ipc_call_sync_fast((phoneid), (method), 0, 0, 0, (res1), (res2), (res3), \
    65             0, 0)
    66 #define ipc_call_sync_0_4(phoneid, method, res1, res2, res3, res4) \
    67         ipc_call_sync_fast((phoneid), (method), 0, 0, 0, (res1), (res2), (res3), \
    68             (res4), 0)
    69 #define ipc_call_sync_0_5(phoneid, method, res1, res2, res3, res4, res5) \
    70         ipc_call_sync_fast((phoneid), (method), 0, 0, 0, (res1), (res2), (res3), \
    71             (res4), (res5))
    72 
    73 #define ipc_call_sync_1_0(phoneid, method, arg1) \
    74         ipc_call_sync_fast((phoneid), (method), (arg1), 0, 0, 0, 0, 0, 0, 0)
    75 #define ipc_call_sync_1_1(phoneid, method, arg1, res1) \
    76         ipc_call_sync_fast((phoneid), (method), (arg1), 0, 0, (res1), 0, 0, 0, 0)
    77 #define ipc_call_sync_1_2(phoneid, method, arg1, res1, res2) \
    78         ipc_call_sync_fast((phoneid), (method), (arg1), 0, 0, (res1), (res2), 0, \
    79             0, 0)
    80 #define ipc_call_sync_1_3(phoneid, method, arg1, res1, res2, res3) \
    81         ipc_call_sync_fast((phoneid), (method), (arg1), 0, 0, (res1), (res2), \
    82             (res3), 0, 0)
    83 #define ipc_call_sync_1_4(phoneid, method, arg1, res1, res2, res3, res4) \
    84         ipc_call_sync_fast((phoneid), (method), (arg1), 0, 0, (res1), (res2), \
    85             (res3), (res4), 0)
    86 #define ipc_call_sync_1_5(phoneid, method, arg1, res1, res2, res3, res4, \
    87     res5) \
    88         ipc_call_sync_fast((phoneid), (method), (arg1), 0, 0, (res1), (res2), \
    89             (res3), (res4), (res5))
    90 
    91 #define ipc_call_sync_2_0(phoneid, method, arg1, arg2) \
    92         ipc_call_sync_fast((phoneid), (method), (arg1), (arg2), 0, 0, 0, 0, \
    93             0, 0)
    94 #define ipc_call_sync_2_1(phoneid, method, arg1, arg2, res1) \
    95         ipc_call_sync_fast((phoneid), (method), (arg1), (arg2), 0, (res1), 0, 0, \
    96             0, 0)
    97 #define ipc_call_sync_2_2(phoneid, method, arg1, arg2, res1, res2) \
    98         ipc_call_sync_fast((phoneid), (method), (arg1), (arg2), 0, (res1), \
    99             (res2), 0, 0, 0)
    100 #define ipc_call_sync_2_3(phoneid, method, arg1, arg2, res1, res2, res3) \
    101         ipc_call_sync_fast((phoneid), (method), (arg1), (arg2), 0, (res1), \
    102             (res2), (res3), 0, 0)
    103 #define ipc_call_sync_2_4(phoneid, method, arg1, arg2, res1, res2, res3, \
    104     res4) \
    105         ipc_call_sync_fast((phoneid), (method), (arg1), (arg2), 0, (res1), \
    106             (res2), (res3), (res4), 0)
    107 #define ipc_call_sync_2_5(phoneid, method, arg1, arg2, res1, res2, res3, \
    108     res4, res5)\
    109         ipc_call_sync_fast((phoneid), (method), (arg1), (arg2), 0, (res1), \
    110             (res2), (res3), (res4), (res5))
    111 
    112 #define ipc_call_sync_3_0(phoneid, method, arg1, arg2, arg3) \
    113         ipc_call_sync_fast((phoneid), (method), (arg1), (arg2), (arg3), 0, 0, 0, \
    114             0, 0)
    115 #define ipc_call_sync_3_1(phoneid, method, arg1, arg2, arg3, res1) \
    116         ipc_call_sync_fast((phoneid), (method), (arg1), (arg2), (arg3), (res1), \
    117             0, 0, 0, 0)
    118 #define ipc_call_sync_3_2(phoneid, method, arg1, arg2, arg3, res1, res2) \
    119         ipc_call_sync_fast((phoneid), (method), (arg1), (arg2), (arg3), (res1), \
    120             (res2), 0, 0, 0)
    121 #define ipc_call_sync_3_3(phoneid, method, arg1, arg2, arg3, res1, res2, \
    122     res3) \
    123         ipc_call_sync_fast((phoneid), (method), (arg1), (arg2), (arg3), \
    124             (res1), (res2), (res3), 0, 0)
    125 #define ipc_call_sync_3_4(phoneid, method, arg1, arg2, arg3, res1, res2, \
    126     res3, res4) \
    127         ipc_call_sync_fast((phoneid), (method), (arg1), (arg2), (arg3), \
    128             (res1), (res2), (res3), (res4), 0)
    129 #define ipc_call_sync_3_5(phoneid, method, arg1, arg2, arg3, res1, res2, \
    130     res3, res4, res5) \
    131         ipc_call_sync_fast((phoneid), (method), (arg1), (arg2), (arg3), \
    132             (res1), (res2), (res3), (res4), (res5))
    133 
    134 #define ipc_call_sync_4_0(phoneid, method, arg1, arg2, arg3, arg4) \
    135         ipc_call_sync_slow((phoneid), (method), (arg1), (arg2), (arg3), (arg4), 0, \
    136             0, 0, 0, 0, 0)
    137 #define ipc_call_sync_4_1(phoneid, method, arg1, arg2, arg3, arg4, res1) \
    138         ipc_call_sync_slow((phoneid), (method), (arg1), (arg2), (arg3), (arg4), 0, \
    139             (res1), 0, 0, 0, 0)
    140 #define ipc_call_sync_4_2(phoneid, method, arg1, arg2, arg3, arg4, res1, res2) \
    141         ipc_call_sync_slow((phoneid), (method), (arg1), (arg2), (arg3), (arg4), 0, \
    142             (res1), (res2), 0, 0, 0)
    143 #define ipc_call_sync_4_3(phoneid, method, arg1, arg2, arg3, arg4, res1, res2, \
    144     res3) \
    145         ipc_call_sync_slow((phoneid), (method), (arg1), (arg2), (arg3), \
    146             (arg4), 0, (res1), (res2), (res3), 0, 0)
    147 #define ipc_call_sync_4_4(phoneid, method, arg1, arg2, arg3, arg4, res1, res2, \
    148     res3, res4) \
    149         ipc_call_sync_slow((phoneid), (method), (arg1), (arg2), (arg3), \
    150             (arg4), 0, (res1), (res2), (res3), (res4), 0)
    151 #define ipc_call_sync_4_5(phoneid, method, arg1, arg2, arg3, arg4, res1, res2, \
    152     res3, res4, res5) \
    153         ipc_call_sync_slow((phoneid), (method), (arg1), (arg2), (arg3), \
    154             (arg4), 0, (res1), (res2), (res3), (res4), (res5))
    155 
    156 #define ipc_call_sync_5_0(phoneid, method, arg1, arg2, arg3, arg4, arg5) \
    157         ipc_call_sync_slow((phoneid), (method), (arg1), (arg2), (arg3), (arg4), \
    158             (arg5), 0, 0, 0, 0, 0)
    159 #define ipc_call_sync_5_1(phoneid, method, arg1, arg2, arg3, arg4, arg5, res1) \
    160         ipc_call_sync_slow((phoneid), (method), (arg1), (arg2), (arg3), (arg4), \
    161             (arg5), (res1), 0, 0, 0, 0)
    162 #define ipc_call_sync_5_2(phoneid, method, arg1, arg2, arg3, arg4, arg5, res1, \
    163     res2) \
    164         ipc_call_sync_slow((phoneid), (method), (arg1), (arg2), (arg3), \
    165             (arg4), (arg5), (res1), (res2), 0, 0, 0)
    166 #define ipc_call_sync_5_3(phoneid, method, arg1, arg2, arg3, arg4, arg5, res1, \
    167     res2, res3) \
    168         ipc_call_sync_slow((phoneid), (method), (arg1), (arg2), (arg3), \
    169             (arg4), (arg5), (res1), (res2), (res3), 0, 0)
    170 #define ipc_call_sync_5_4(phoneid, method, arg1, arg2, arg3, arg4, arg5, res1, \
    171     res2, res3, res4) \
    172         ipc_call_sync_slow((phoneid), (method), (arg1), (arg2), (arg3), \
    173             (arg4), (arg5), (res1), (res2), (res3), (res4), 0)
    174 #define ipc_call_sync_5_5(phoneid, method, arg1, arg2, arg3, arg4, arg5, res1, \
    175     res2, res3, res4, res5) \
    176         ipc_call_sync_slow((phoneid), (method), (arg1), (arg2), (arg3), \
    177             (arg4), (arg5), (res1), (res2), (res3), (res4), (res5))
    178 
    179 extern int ipc_call_sync_fast(int, sysarg_t, sysarg_t, sysarg_t, sysarg_t,
    180     sysarg_t *, sysarg_t *, sysarg_t *, sysarg_t *, sysarg_t *);
    181 
    182 extern int ipc_call_sync_slow(int, sysarg_t, sysarg_t, sysarg_t, sysarg_t,
    183     sysarg_t, sysarg_t, sysarg_t *, sysarg_t *, sysarg_t *, sysarg_t *,
    184     sysarg_t *);
    18549
    18650extern ipc_callid_t ipc_wait_cycle(ipc_call_t *, sysarg_t, unsigned int);
     
    254118    sysarg_t, sysarg_t, void *, ipc_async_callback_t, bool);
    255119
    256 extern int ipc_clone_establish(int);
    257 extern int ipc_connect_to_me(int, sysarg_t, sysarg_t, sysarg_t, task_id_t *,
    258     sysarg_t *);
    259 extern int ipc_connect_me_to(int, sysarg_t, sysarg_t, sysarg_t);
    260 extern int ipc_connect_me_to_blocking(int, sysarg_t, sysarg_t, sysarg_t);
    261 
    262120extern int ipc_hangup(int);
    263121
     
    267125    sysarg_t, sysarg_t, sysarg_t, unsigned int);
    268126
    269 /*
    270  * User-friendly wrappers for ipc_share_in_start().
    271  */
    272 
    273 #define ipc_share_in_start_0_0(phoneid, size, dst) \
    274         ipc_share_in_start((phoneid), (size), 0, NULL, (dst))
    275 #define ipc_share_in_start_0_1(phoneid, size, flags, dst) \
    276         ipc_share_in_start((phoneid), (size), 0, (flags), (dst))
    277 #define ipc_share_in_start_1_0(phoneid, size, arg, dst) \
    278         ipc_share_in_start((phoneid), (size), (arg), NULL, (dst))
    279 #define ipc_share_in_start_1_1(phoneid, size, arg, flags, dst) \
    280         ipc_share_in_start((phoneid), (size), (arg), (flags), (dst))
    281 
    282 extern int ipc_share_in_start(int, size_t, sysarg_t, unsigned int *, void **);
    283 extern int ipc_share_in_finalize(ipc_callid_t, void *, unsigned int);
    284 extern int ipc_share_out_start(int, void *, unsigned int);
    285 extern int ipc_share_out_finalize(ipc_callid_t, void **);
    286 extern int ipc_data_read_start(int, void *, size_t);
    287 extern int ipc_data_read_finalize(ipc_callid_t, const void *, size_t);
    288 extern int ipc_data_write_start(int, const void *, size_t);
    289 extern int ipc_data_write_finalize(ipc_callid_t, void *, size_t);
    290 
    291127extern int ipc_connect_kbox(task_id_t);
    292128
Note: See TracChangeset for help on using the changeset viewer.